File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / freevrrpd / vrrp_main.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Jun 14 12:01:54 2017 UTC (6 years, 11 months ago) by misho
Branches: freevrrpd, MAIN
CVS tags: v1_1, HEAD
freevrrpd 1.1

    1: /*
    2:  * Copyright (c) 2001,2002 Sebastien Petit <spe@bsdfr.org>
    3:  *
    4:  * Redistribution and use in source forms, with and without modification,
    5:  * are permitted provided that the following conditions are met:
    6:  * 1. Redistributions of source code must retain the above copyright notice,
    7:  *    this list of conditions and the following disclaimer.
    8:  * 2. Redistributions in binary form must reproduce the above copyright notice,
    9:  *    this list of conditions and the following disclaimer in the documentation
   10:  *    and/or other materials provided with the distribution. Obviously, it
   11:  *    would be nice if you gave credit where credit is due but requiring it
   12:  *    would be too onerous.
   13:  * 3. All advertising materials mentioning features or use of this software
   14:  *    must display the following acknowledgement:
   15:  *      This product includes software developed by Sebastien Petit.
   16:  * 4. Neither the name of its contributors may be used to endorse or promote
   17:  *    products derived from this software without specific prior written
   18:  *    permission.
   19:  *
   20:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   21:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   22:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   23:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   24:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   25:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   26:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   27:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   28:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   29:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   30:  * SUCH DAMAGE.
   31:  *
   32:  * $Id: vrrp_main.c,v 1.1.1.1 2017/06/14 12:01:54 misho Exp $
   33:  */
   34: 
   35: #include <errno.h>
   36: #include "vrrp_main.h"
   37: #include "vrrp_conf.h"
   38: #include "vrrp_thread.h"
   39: 
   40: /* Variables Globales */
   41: /* addresses table of all struct vrrp_vr * initialized */
   42: struct vrrp_vr *vr_ptr[VRRP_PROTOCOL_MAX_VRID+1];
   43: /* actual position on this table */
   44: u_char          vr_ptr_pos = 0;
   45: 
   46: void
   47: vrrp_main_pre_init(struct vrrp_vr * vr)
   48: {
   49: 	bzero(vr, sizeof(*vr));
   50: 	vr->priority = 100;
   51: 	vr->adv_int = VRRP_DEFAULT_ADV_INT;
   52: 	vr->preempt_mode = 1;
   53: 	vr->fault = 0;
   54: 	vr->useMonitoredCircuits = 1;
   55: 	vr->spanningTreeLatency = 0;
   56: 	vr->monitoredCircuitsClearErrorsCount = VRRP_MONCIRCUIT_CLEAR_ERRORS;
   57: 	vr->bridge_link_number = 2;
   58: 
   59: 	return;
   60: }
   61: 
   62: void
   63: vrrp_main_post_init(struct vrrp_vr * vr, int firstime)
   64: {
   65: 	int             size = MAX_IP_ALIAS;
   66: 	int		rc;
   67: 
   68: 	vr->ethaddr.octet[0] = 0x00;
   69: 	vr->ethaddr.octet[1] = 0x00;
   70: 	vr->ethaddr.octet[2] = 0x5E;
   71: 	vr->ethaddr.octet[3] = 0x00;
   72: 	vr->ethaddr.octet[4] = 0x01;
   73: 	vr->ethaddr.octet[5] = vr->vr_id;
   74: 	vr->skew_time = (256 - vr->priority) / 256;
   75: 	vr->master_down_int = (3 * vr->adv_int) + vr->skew_time;
   76: 	if (firstime) {
   77: 		vrrp_misc_get_if_infos(vr->vr_if->if_name, &vr->vr_if->ethaddr, vr->vr_if->ip_addrs, &size);
   78: 		if (! vr->vr_if->ip_addrs[0].s_addr) {
   79: 			syslog(LOG_CRIT, "no IP address is configured on the real interface %s\n", vr->vr_if->if_name);
   80: 			syslog(LOG_CRIT, "cannot join multicast vrrp group without a real ip adress on %s\n", vr->vr_if->if_name);
   81: 			syslog(LOG_CRIT, "choose an IP address that is not used on any VRIDs and restart\n");
   82: 			syslog(LOG_CRIT, "you can set a private address for announcing VRRP packets (eg: 192.168.0.1/24)\n");
   83: 			syslog(LOG_CRIT, "exiting...\n");
   84: 			exit(-1);
   85: 		}
   86: 		vrrp_vlanlist_initialize(vr);
   87: 		vrrp_misc_get_vlan_infos(vr);
   88: 		vr->vr_if->nb_ip = size;
   89: 		vr->vr_if->alive = 1;
   90: 		vr->vr_if->nberrors = 0;
   91: 		vr->vr_if->reportsyslog = 0;
   92: 		vr->vr_if->carrier_timeout = VRRP_DEFAULT_CARRIER_TIMEOUT;
   93: 		vr->vr_if->checksok = 0;
   94: 	}
   95: 	vr->ioctl_sd = socket(AF_INET, SOCK_DGRAM, 0);
   96: 	if (vr->ioctl_sd == -1) {
   97: 		syslog(LOG_WARNING, "cannot open socket: %s", strerror(errno));
   98: 		exit(-1);
   99: 	}
  100: 
  101: 	/* Setting real interface in promiscuous mode */
  102: 	if (vrrp_interface_promiscuous(vr->vr_if->if_name) < 0) {
  103: 		syslog(LOG_CRIT, "cannot set interface %s in promiscuous mode\n", vr->vr_if->if_name);
  104: 		syslog(LOG_CRIT, "exiting...");
  105: 		exit(-1);
  106: 	}
  107: 
  108: 	rc = vrrp_netgraph_bridge_create(vr->vr_if->if_name);
  109: 	if ((rc < 0) && (errno != EEXIST)) {
  110: 		syslog(LOG_CRIT, "cannot create a bridge device: %s", strerror(errno));
  111: 		syslog(LOG_CRIT, "aborting...");
  112: 		exit(-1);
  113: 	}
  114: 	rc = vrrp_netgraph_create_virtualiface(vr);
  115: 	if (rc < 0) {
  116: 		syslog(LOG_CRIT, "cannot create a virtual interface via netgraph: %s\n", strerror(errno));
  117: 		syslog(LOG_CRIT, "check that ng_socket, ng_ether, ng_eiface and ng_bridge are loaded\n");
  118: 		exit(-1);
  119: 	}
  120: 
  121: 	return;
  122: }
  123: 
  124: void
  125: vrrp_main_print_struct(struct vrrp_vr * vr)
  126: {
  127: 	int             cpt;
  128: 
  129: 	fprintf(stderr, "VServer ID\t\t: %u\n", vr->vr_id);
  130: 	fprintf(stderr, "VServer PRIO\t\t: %u\n", vr->priority);
  131: 	fprintf(stderr, "VServer ETHADDR\t\t: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", vr->ethaddr.octet[0], vr->ethaddr.octet[1], vr->ethaddr.octet[2], vr->ethaddr.octet[3], vr->ethaddr.octet[4], vr->ethaddr.octet[5]);
  132: 	fprintf(stderr, "VServer CNT_IP\t\t: %u\n", vr->cnt_ip);
  133: 	fprintf(stderr, "VServer IPs\t\t:\n");
  134: 	for (cpt = 0; cpt < vr->cnt_ip; cpt++)
  135: 		fprintf(stderr, "\t%s\n", inet_ntoa(vr->vr_ip[cpt].addr));
  136: 	fprintf(stderr, "VServer ADV_INT\t\t: %u\n", vr->adv_int);
  137: 	fprintf(stderr, "VServer MASTER_DW_TM\t: %u\n", vr->master_down_int);
  138: 	fprintf(stderr, "VServer SKEW_TIME\t: %u\n", vr->skew_time);
  139: 	fprintf(stderr, "VServer State\t\t: %u\n", vr->state);
  140: 	fprintf(stderr, "Server IF_NAME\t\t: %s\n", vr->vr_if->if_name);
  141: 	fprintf(stderr, "Server NB_IP\t\t: %u\n", vr->vr_if->nb_ip);
  142: 	fprintf(stderr, "Server IPs\t\t:\n");
  143: 	for (cpt = 0; cpt < vr->vr_if->nb_ip; cpt++)
  144: 		fprintf(stderr, "\t%s\n", inet_ntoa(vr->vr_if->ip_addrs[cpt]));
  145: 	fprintf(stderr, "Server ETHADDR\t\t: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", vr->vr_if->ethaddr.octet[0], vr->vr_if->ethaddr.octet[1], vr->vr_if->ethaddr.octet[2], vr->vr_if->ethaddr.octet[3], vr->vr_if->ethaddr.octet[4], vr->vr_if->ethaddr.octet[5]);
  146: 
  147: 	return;
  148: }
  149: 
  150: void
  151: init_copt(struct conf_options *copt)
  152: {
  153: 	copt->conffile = VRRP_CONF_FILE_NAME;
  154: 	copt->foreground = 0;
  155: 	copt->chrootdir = NULL;
  156: 
  157: 	return;
  158: }
  159: 
  160: void
  161: print_usage(void)
  162: {
  163: 	printf("FreeVRRPd - VRRP daemon for FreeBSD\n");
  164: 	printf("Choose one of the following:\n");
  165: 	printf("-f : specify a path to a configuration file\n");
  166: 	printf("-F : launching in foreground\n");
  167: 	printf("-c : chroot to the specified directory\n");
  168: 	printf("-h : this screen ;)\n");
  169: 	printf("Found a bug ? mail me at spe@bsdfr.org\n");
  170: 
  171: 	return;
  172: }
  173: 
  174: void pidfile(void) {
  175: 	pid_t pid;
  176: 	FILE *fs;
  177: 
  178: 	pid = getpid();
  179: 	fs = fopen("/var/run/freevrrpd.pid", "w");
  180: 	if (fs) {
  181: 		fprintf(fs, "%ld\n", (long)pid);
  182: 		fclose(fs);
  183: 	}
  184: 	else {
  185: 		syslog(LOG_ERR, "cannot open pid file for writing: %s\n", strerror(errno));
  186: 		exit(EXIT_FAILURE);
  187: 	}
  188: 
  189: 	return;
  190: }
  191: 
  192: int
  193: main(int argc, char **argv)
  194: {
  195: 	FILE           *stream;
  196: 	int             coderet = 0;
  197: 	struct vrrp_vr *vr = NULL;
  198: 	struct conf_options copt;
  199: 	char ch;
  200: 	int firstime = 0;
  201: 
  202: 	openlog("freevrrpd", LOG_PID, LOG_USER);
  203: 	init_copt(&copt);
  204: 	while ((ch = getopt(argc, argv, "f:Fc:h")) != -1) {
  205: 		switch (ch) {
  206: 			case 'F':
  207: 				copt.foreground = 1;
  208: 				break;
  209: 			case 'f':
  210: 				copt.conffile = (char *)calloc(strlen(optarg)+1, 1);
  211: 				strncpy(copt.conffile, optarg, strlen(optarg));
  212: 				break;
  213: 			case 'c':
  214: 				copt.chrootdir = (char *)calloc(strlen(optarg)+1, 1);
  215: 				strncpy(copt.chrootdir, optarg, strlen(optarg));
  216: 				break;
  217: 			case 'h':
  218: 			default:
  219: 				print_usage();
  220: 				exit(-1);
  221: 				break;
  222: 		}
  223: 	}
  224: 	if (copt.chrootdir)
  225: 		if (chroot(copt.chrootdir) == -1)
  226: 			syslog(LOG_ERR, "cannot chroot to the specified directory %s: %s", copt.chrootdir, strerror(errno));
  227: 	if ((stream = vrrp_conf_open_file(copt.conffile)) == NULL)
  228: 		return -1;
  229: 	if (! copt.foreground) {
  230: 		syslog(LOG_NOTICE, "launching daemon in background mode");
  231: 		if (daemon(0, 0) == -1) {
  232: 			syslog(LOG_ERR, "cannot transition to daemon mode: %s", strerror(errno));
  233: 			return -1;
  234: 		}
  235: 	}
  236: 	/*if (vrrp_netgraph_open(&ng_control_socket, &ng_data_socket) < 0) {
  237: 		syslog(LOG_ERR, "cannot open netgraph control socket: %s", strerror(errno));
  238: 		exit(-1);
  239: 	}*/
  240: 
  241: 	/* Initialisation of struct vrrp_vr * adresses table */
  242: 	bzero(&vr_ptr, sizeof(vr_ptr));
  243: 	syslog(LOG_NOTICE, "initializing threads and all VRID");
  244: 	vrrp_thread_initialize();
  245: 	syslog(LOG_NOTICE, "reading configuration file %s", copt.conffile);
  246: 	while (!coderet) {
  247: 		vr = (struct vrrp_vr *)calloc(1, sizeof(struct vrrp_vr));
  248: 		vrrp_main_pre_init(vr);
  249: 		coderet = vrrp_conf_lecture_fichier(vr, stream);
  250: 		if (coderet < 0)
  251: 			return coderet;
  252: 		firstime = (! vr->vr_if->p) || (! vr->vr_if->d);
  253: 		vrrp_main_post_init(vr, firstime);
  254: 		if (firstime) {
  255: 			if (vrrp_list_initialize(vr, &vr->vr_if->ethaddr) < 0)
  256: 				return -1;
  257: 		}
  258: 		vrrp_interface_owner_verify(vr);
  259: 		if (vrrp_multicast_open_socket(vr) == -1)
  260: 			return -1;
  261: 		vrrp_main_print_struct(vr);
  262: 		if (vrrp_thread_create_vrid(vr) == -1)
  263: 			return -1;
  264: 	}
  265: 	vrrp_signal_initialize();
  266: 	/* Write a pid file in /var/run */
  267: 	pidfile();
  268: 	if (vr->useMonitoredCircuits) {
  269: 		if (vrrp_thread_create_moncircuit() == -1)
  270: 			return -1;
  271: 		syslog(LOG_NOTICE, "monitored circuits engine initialized");
  272: 	}
  273: 	else
  274: 		syslog(LOG_NOTICE, "monitored circuits engine disabled");
  275: 
  276: 	pthread_exit(NULL);
  277: 
  278: 	return 0;
  279: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>