Annotation of embedaddon/freevrrpd/vrrp_interface.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_interface.c,v 1.5 2004/04/01 13:14:54 spe Exp $
        !            33:  */
        !            34: 
        !            35: #include "vrrp_interface.h"
        !            36: 
        !            37: void 
        !            38: vrrp_interface_owner_verify(struct vrrp_vr * vr)
        !            39: {
        !            40:        int             cpt, cpt2;
        !            41: 
        !            42:        for (cpt = 0; cpt < vr->cnt_ip; cpt++)
        !            43:                for (cpt2 = 0; cpt2 < vr->vr_if->nb_ip; cpt2++)
        !            44:                        if (vr->vr_ip[cpt].addr.s_addr == vr->vr_if->ip_addrs[cpt2].s_addr)
        !            45:                                vr->vr_ip[cpt].owner = VRRP_INTERFACE_IPADDR_OWNER;
        !            46: 
        !            47:        return;
        !            48: }
        !            49: 
        !            50: char 
        !            51: vrrp_interface_mac_set(char *if_name, struct ether_addr * ethaddr)
        !            52: {
        !            53:        int             sd;
        !            54:        struct ifreq    ifr;
        !            55: 
        !            56:        bzero(&ifr, sizeof(ifr));
        !            57:        sd = socket(AF_INET, SOCK_DGRAM, 0);
        !            58:        if (sd == -1) {
        !            59:                syslog(LOG_WARNING, "cannot open socket for deleting ip address of interface %s: %s", if_name, strerror(errno));
        !            60:                return -1;
        !            61:        }
        !            62:        strncpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name));
        !            63:        ifr.ifr_addr.sa_len = ETHER_ADDR_LEN;
        !            64:        ifr.ifr_addr.sa_family = AF_LINK;
        !            65:        bcopy(ethaddr, ifr.ifr_addr.sa_data, ETHER_ADDR_LEN);
        !            66:        if (ioctl(sd, SIOCSIFLLADDR, (caddr_t) & ifr) == -1) {
        !            67:                syslog(LOG_ERR, "cannot set mac address for interface %s (ioctl): %s", if_name, strerror(errno));
        !            68:                return -1;
        !            69:        }
        !            70: 
        !            71:        return 0;
        !            72: }
        !            73: 
        !            74: /* Set VMAC for parent interface + all child VLANs */
        !            75: int
        !            76: vrrp_interface_all_ethaddr_set(struct vrrp_vr *vr, struct ether_addr *ethaddr) {
        !            77:        struct vrrp_vlan_list *vl = vr->vr_if->vlanp->next;
        !            78: 
        !            79:        while (vl != vr->vr_if->vland) {
        !            80:                if (vrrp_interface_mac_set(vl->vlan_ifname, ethaddr) == -1)
        !            81:                        return -1;
        !            82:                vl = vl->next;
        !            83:        }
        !            84: 
        !            85:        return 0;
        !            86: }
        !            87: 
        !            88: in_addr_t 
        !            89: vrrp_interface_compute_netmask(u_int nbbits)
        !            90: {
        !            91:        int             cpt = 0;
        !            92:        in_addr_t       netmask = 0;
        !            93: 
        !            94:        if (nbbits > 32) {
        !            95:                syslog(LOG_ERR, "specified netmask is invalid: /%u", nbbits);
        !            96:                syslog(LOG_ERR, "netmask /32 or 255.255.255.255 is applied");
        !            97:                return 0xFFFFFFFF;
        !            98:        }
        !            99:        while (cpt < nbbits) {
        !           100:                netmask |= (in_addr_t) pow(2, 31 - cpt);
        !           101:                cpt++;
        !           102:        }
        !           103: 
        !           104:        return netmask;
        !           105: }
        !           106: 
        !           107: char 
        !           108: vrrp_interface_ipaddr_set(char *if_name, struct in_addr addr, in_addr_t netmask)
        !           109: {
        !           110:        int             sd;
        !           111:        struct ifaliasreq ifra;
        !           112: 
        !           113:        bzero(&ifra, sizeof(ifra));
        !           114:        sd = socket(AF_INET, SOCK_DGRAM, 0);
        !           115:        if (sd == -1) {
        !           116:                syslog(LOG_WARNING, "cannot open socket for adding ip address of interface %s: %s", if_name, strerror(errno));
        !           117:                return -1;
        !           118:        }
        !           119:        strncpy(ifra.ifra_name, if_name, sizeof(ifra.ifra_name));
        !           120:        ifra.ifra_addr.sa_len = sizeof(struct sockaddr_in);
        !           121:        ifra.ifra_addr.sa_family = AF_INET;
        !           122:        ((struct sockaddr_in *) & ifra.ifra_addr)->sin_addr = addr;
        !           123:        ifra.ifra_mask.sa_len = sizeof(struct sockaddr_in);
        !           124:        ifra.ifra_mask.sa_family = AF_INET;
        !           125:        ((struct sockaddr_in *) & ifra.ifra_mask)->sin_addr.s_addr = htonl(netmask);
        !           126:        if (ioctl(sd, SIOCAIFADDR, &ifra) == -1) {
        !           127:                syslog(LOG_ERR, "cannot set ip addr %s for interface %s (ioctl SIOCAIFADDR): %s", inet_ntoa(addr), if_name, strerror(errno));
        !           128:                close(sd);
        !           129:                return -1;
        !           130:        }
        !           131:        close(sd);
        !           132: 
        !           133:        return 0;
        !           134: }
        !           135: 
        !           136: char 
        !           137: vrrp_interface_ipaddr_delete(char *if_name, struct in_addr addr, int verbose)
        !           138: {
        !           139:        int             sd;
        !           140:        struct ifreq    ifr;
        !           141: 
        !           142:        bzero(&ifr, sizeof(ifr));
        !           143:        sd = socket(AF_INET, SOCK_DGRAM, 0);
        !           144:        if (sd == -1) {
        !           145:                syslog(LOG_WARNING, "cannot open socket for deleting ip address of interface %s: %s", if_name, strerror(errno));
        !           146:                return -1;
        !           147:        }
        !           148:        strncpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name));
        !           149:        ifr.ifr_addr.sa_len = sizeof(struct sockaddr_in);
        !           150:        ifr.ifr_addr.sa_family = AF_INET;
        !           151:        ((struct sockaddr_in *) & ifr.ifr_addr)->sin_addr = addr;
        !           152:        if ((ioctl(sd, SIOCDIFADDR, (char *)&ifr) == -1) && verbose) {
        !           153:                syslog(LOG_ERR, "cannot delete ip addr %s for interface %s (ioctl SIOCDIFADDR): %s", inet_ntoa(addr), if_name, strerror(errno));
        !           154:                close(sd);
        !           155:                return -1;
        !           156:        }
        !           157:        close(sd);
        !           158: 
        !           159:        return 0;
        !           160: }
        !           161: 
        !           162: char 
        !           163: vrrp_interface_vripaddr_set(struct vrrp_vr * vr)
        !           164: {
        !           165:        int             cpt;
        !           166: 
        !           167:        for (cpt = 0; cpt < vr->cnt_ip; cpt++) {
        !           168:                if (!vr->vr_ip[cpt].owner) {
        !           169:                        if (vrrp_interface_ipaddr_set(vr->viface_name, vr->vr_ip[cpt].addr, vrrp_interface_compute_netmask(vr->vr_netmask[cpt])) == -1) {
        !           170:                                if (errno != EEXIST) {
        !           171:                                        syslog(LOG_ERR, "vrid [%d] Error occured during setting virtual router ip address %s", vr->vr_id, inet_ntoa(vr->vr_ip[cpt].addr));
        !           172:                                        return -1;
        !           173:                                }
        !           174:                        }
        !           175:                }
        !           176:        }
        !           177: 
        !           178:        return 0;
        !           179: }
        !           180: 
        !           181: char 
        !           182: vrrp_interface_vripaddr_delete(struct vrrp_vr * vr)
        !           183: {
        !           184:        int             cpt;
        !           185: 
        !           186:        for (cpt = 0; cpt < vr->cnt_ip; cpt++) {
        !           187:                if (vr->vr_ip[cpt].owner != VRRP_INTERFACE_IPADDR_OWNER) {
        !           188:                        if (vrrp_interface_ipaddr_delete(vr->viface_name, vr->vr_ip[cpt].addr, 0) == -1) {
        !           189:                                if (errno != EADDRNOTAVAIL) {
        !           190:                                        syslog(LOG_ERR, "vrid [%d] Error occured during deleting virtual router ip address %s", vr->vr_id, inet_ntoa(vr->vr_ip[cpt].addr));
        !           191:                                        return -1;
        !           192:                                }
        !           193:                        }
        !           194:                }
        !           195:        }
        !           196: 
        !           197:        return 0;
        !           198: }
        !           199: 
        !           200: 
        !           201: 
        !           202: char
        !           203: vrrp_interface_set_flags(char *if_name, int value) {
        !           204:        int             sd;
        !           205:        struct ifreq    ifr;
        !           206:        int flags;
        !           207: 
        !           208:        bzero(&ifr, sizeof(ifr));
        !           209:        strncpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name));
        !           210:        sd = socket(AF_INET, SOCK_DGRAM, 0);
        !           211:        if (sd == -1)
        !           212:                return -1;
        !           213:        if (ioctl(sd, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
        !           214:                close(sd);
        !           215:                return -1;
        !           216:        }
        !           217:        flags = (ifr.ifr_flags & 0xffff) | (ifr.ifr_flagshigh << 16);
        !           218: 
        !           219:         if (value < 0) {
        !           220:                 value = -value;
        !           221:                 flags &= ~value;
        !           222:         } else
        !           223:                 flags |= value;
        !           224:         ifr.ifr_flags = flags & 0xffff;
        !           225:         ifr.ifr_flagshigh = flags >> 16;
        !           226: 
        !           227:        if (ioctl(sd, SIOCSIFFLAGS, (caddr_t)&ifr) < 0) {
        !           228:                close(sd);
        !           229:                return -1;
        !           230:        }
        !           231: 
        !           232:        close(sd);
        !           233: 
        !           234:        return 0;
        !           235: }
        !           236: 
        !           237: char
        !           238: vrrp_interface_promiscuous(char *if_name) {
        !           239:        return vrrp_interface_set_flags(if_name, IFF_PPROMISC);
        !           240: }
        !           241: 
        !           242: char
        !           243: vrrp_interface_nopromiscuous(char *if_name) {
        !           244:        return vrrp_interface_set_flags(if_name, -IFF_PPROMISC);
        !           245: }
        !           246: 
        !           247: char 
        !           248: vrrp_interface_up(char *if_name) {
        !           249:        return vrrp_interface_set_flags(if_name, IFF_UP);
        !           250: }
        !           251: 
        !           252: char 
        !           253: vrrp_interface_down(char *if_name) {
        !           254:        return vrrp_interface_set_flags(if_name, -IFF_UP);
        !           255: }
        !           256: 

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