Annotation of embedaddon/freevrrpd/vrrp_main.c, revision 1.1.1.1
1.1 misho 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.12 2004/03/30 23:13:00 spe 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>