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>