Annotation of embedaddon/freevrrpd/vrrp_main.c, revision 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>