Annotation of embedaddon/quagga/babeld/kernel.c, revision 1.1

1.1     ! misho       1: /*  
        !             2:  *  This file is free software: you may copy, redistribute and/or modify it  
        !             3:  *  under the terms of the GNU General Public License as published by the  
        !             4:  *  Free Software Foundation, either version 2 of the License, or (at your  
        !             5:  *  option) any later version.  
        !             6:  *  
        !             7:  *  This file is distributed in the hope that it will be useful, but  
        !             8:  *  WITHOUT ANY WARRANTY; without even the implied warranty of  
        !             9:  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU  
        !            10:  *  General Public License for more details.  
        !            11:  *  
        !            12:  *  You should have received a copy of the GNU General Public License  
        !            13:  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.  
        !            14:  *  
        !            15:  * This file incorporates work covered by the following copyright and  
        !            16:  * permission notice:  
        !            17:  *  
        !            18: 
        !            19: Copyright 2007, 2008 by GrĂ©goire Henry, Julien Cristau and Juliusz Chroboczek
        !            20: Copyright 2011, 2012 by Matthieu Boutier and Juliusz Chroboczek
        !            21: 
        !            22: Permission is hereby granted, free of charge, to any person obtaining a copy
        !            23: of this software and associated documentation files (the "Software"), to deal
        !            24: in the Software without restriction, including without limitation the rights
        !            25: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        !            26: copies of the Software, and to permit persons to whom the Software is
        !            27: furnished to do so, subject to the following conditions:
        !            28: 
        !            29: The above copyright notice and this permission notice shall be included in
        !            30: all copies or substantial portions of the Software.
        !            31: 
        !            32: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        !            33: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        !            34: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
        !            35: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        !            36: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        !            37: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
        !            38: THE SOFTWARE.
        !            39: */
        !            40: 
        !            41: #include <sys/time.h>
        !            42: #include <sys/param.h>
        !            43: #include <time.h>
        !            44: 
        !            45: #include "babeld.h"
        !            46: 
        !            47: 
        !            48: #include <sys/types.h>
        !            49: #include <sys/socket.h>
        !            50: #include <netinet/in.h>
        !            51: #include <netdb.h>
        !            52: #include <arpa/inet.h>
        !            53: 
        !            54: #include <zebra.h>
        !            55: #include "prefix.h"
        !            56: #include "zclient.h"
        !            57: #include "kernel.h"
        !            58: #include "privs.h"
        !            59: #include "command.h"
        !            60: #include "vty.h"
        !            61: #include "memory.h"
        !            62: #include "thread.h"
        !            63: 
        !            64: #include "util.h"
        !            65: #include "babel_interface.h"
        !            66: #include "babel_zebra.h"
        !            67: 
        !            68: 
        !            69: static int
        !            70: kernel_route_v4(int add, const unsigned char *pref, unsigned short plen,
        !            71:                 const unsigned char *gate, int ifindex,
        !            72:                 unsigned int metric);
        !            73: static int
        !            74: kernel_route_v6(int add, const unsigned char *pref, unsigned short plen,
        !            75:                 const unsigned char *gate, int ifindex,
        !            76:                 unsigned int metric);
        !            77: 
        !            78: int
        !            79: kernel_interface_operational(struct interface *interface)
        !            80: {
        !            81:     return if_is_operative(interface);
        !            82: }
        !            83: 
        !            84: int
        !            85: kernel_interface_mtu(struct interface *interface)
        !            86: {
        !            87:     return MIN(interface->mtu, interface->mtu6);
        !            88: }
        !            89: 
        !            90: int
        !            91: kernel_interface_wireless(struct interface *interface)
        !            92: {
        !            93:     return 0;
        !            94: }
        !            95: 
        !            96: int
        !            97: kernel_route(int operation, const unsigned char *pref, unsigned short plen,
        !            98:              const unsigned char *gate, int ifindex, unsigned int metric,
        !            99:              const unsigned char *newgate, int newifindex,
        !           100:              unsigned int newmetric)
        !           101: {
        !           102:     int rc;
        !           103:     int ipv4;
        !           104: 
        !           105:     /* Check that the protocol family is consistent. */
        !           106:     if(plen >= 96 && v4mapped(pref)) {
        !           107:         if(!v4mapped(gate)) {
        !           108:             errno = EINVAL;
        !           109:             return -1;
        !           110:         }
        !           111:         ipv4 = 1;
        !           112:     } else {
        !           113:         if(v4mapped(gate)) {
        !           114:             errno = EINVAL;
        !           115:             return -1;
        !           116:         }
        !           117:         ipv4 = 0;
        !           118:     }
        !           119: 
        !           120:     switch (operation) {
        !           121:         case ROUTE_ADD:
        !           122:             return ipv4 ?
        !           123:                    kernel_route_v4(1, pref, plen, gate, ifindex, metric):
        !           124:                    kernel_route_v6(1, pref, plen, gate, ifindex, metric);
        !           125:             break;
        !           126:         case ROUTE_FLUSH:
        !           127:             return ipv4 ?
        !           128:                    kernel_route_v4(0, pref, plen, gate, ifindex, metric):
        !           129:                    kernel_route_v6(0, pref, plen, gate, ifindex, metric);
        !           130:             break;
        !           131:         case ROUTE_MODIFY:
        !           132:             if(newmetric == metric && memcmp(newgate, gate, 16) == 0 &&
        !           133:                newifindex == ifindex)
        !           134:                 return 0;
        !           135:             debugf(BABEL_DEBUG_ROUTE, "Modify route: delete old; add new.");
        !           136:             rc = ipv4 ?
        !           137:                 kernel_route_v4(0, pref, plen, gate, ifindex, metric):
        !           138:                 kernel_route_v6(0, pref, plen, gate, ifindex, metric);
        !           139: 
        !           140:             if (rc < 0)
        !           141:                 return -1;
        !           142: 
        !           143:             rc = ipv4 ?
        !           144:                 kernel_route_v4(1, pref, plen, newgate, newifindex, newmetric):
        !           145:                 kernel_route_v6(1, pref, plen, newgate, newifindex, newmetric);
        !           146: 
        !           147:             return rc;
        !           148:             break;
        !           149:         default:
        !           150:             zlog_err("this should never appens (false value - kernel_route)");
        !           151:             assert(0);
        !           152:             exit(1);
        !           153:             break;
        !           154:     }
        !           155: }
        !           156: 
        !           157: static int
        !           158: kernel_route_v4(int add,
        !           159:                 const unsigned char *pref, unsigned short plen,
        !           160:                 const unsigned char *gate, int ifindex, unsigned int metric)
        !           161: {
        !           162:     struct zapi_ipv4 api;               /* quagga's communication system */
        !           163:     struct prefix_ipv4 quagga_prefix;   /* quagga's prefix */
        !           164:     struct in_addr babel_prefix_addr;   /* babeld's prefix addr */
        !           165:     struct in_addr nexthop;             /* next router to go */
        !           166:     struct in_addr *nexthop_pointer = &nexthop; /* it's an array! */
        !           167: 
        !           168:     /* convert to be understandable by quagga */
        !           169:     /* convert given addresses */
        !           170:     uchar_to_inaddr(&babel_prefix_addr, pref);
        !           171:     uchar_to_inaddr(&nexthop, gate);
        !           172: 
        !           173:     /* make prefix structure */
        !           174:     memset (&quagga_prefix, 0, sizeof(quagga_prefix));
        !           175:     quagga_prefix.family = AF_INET;
        !           176:     IPV4_ADDR_COPY (&quagga_prefix.prefix, &babel_prefix_addr);
        !           177:     quagga_prefix.prefixlen = plen - 96; /* our plen is for v4mapped's addr */
        !           178:     apply_mask_ipv4(&quagga_prefix);
        !           179: 
        !           180:     api.type  = ZEBRA_ROUTE_BABEL;
        !           181:     api.flags = 0;
        !           182:     api.message = 0;
        !           183:     api.safi = SAFI_UNICAST;
        !           184: 
        !           185:     /* Unlike the native Linux and BSD interfaces, Quagga doesn't like
        !           186:        there to be both and IPv4 nexthop and an ifindex.  Omit the
        !           187:        ifindex, and assume that the connected prefixes be set up
        !           188:        correctly. */
        !           189: 
        !           190:     SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
        !           191:     api.ifindex_num = 0;
        !           192:     if(metric >= KERNEL_INFINITY) {
        !           193:         api.flags = ZEBRA_FLAG_BLACKHOLE;
        !           194:         api.nexthop_num = 0;
        !           195:     } else {
        !           196:         api.nexthop_num = 1;
        !           197:         api.nexthop = &nexthop_pointer;
        !           198:         SET_FLAG(api.message, ZAPI_MESSAGE_METRIC);
        !           199:         api.metric = metric;
        !           200:     }
        !           201: 
        !           202:     debugf(BABEL_DEBUG_ROUTE, "%s route (ipv4) to zebra",
        !           203:            add ? "adding" : "removing" );
        !           204:     return zapi_ipv4_route (add ? ZEBRA_IPV4_ROUTE_ADD :
        !           205:                                   ZEBRA_IPV4_ROUTE_DELETE,
        !           206:                             zclient, &quagga_prefix, &api);
        !           207: }
        !           208: 
        !           209: static int
        !           210: kernel_route_v6(int add, const unsigned char *pref, unsigned short plen,
        !           211:                 const unsigned char *gate, int ifindex, unsigned int metric)
        !           212: {
        !           213:     unsigned int tmp_ifindex = ifindex; /* (for typing) */
        !           214:     struct zapi_ipv6 api;               /* quagga's communication system */
        !           215:     struct prefix_ipv6 quagga_prefix;   /* quagga's prefix */
        !           216:     struct in6_addr babel_prefix_addr;  /* babeld's prefix addr */
        !           217:     struct in6_addr nexthop;            /* next router to go */
        !           218:     struct in6_addr *nexthop_pointer = &nexthop;
        !           219: 
        !           220:     /* convert to be understandable by quagga */
        !           221:     /* convert given addresses */
        !           222:     uchar_to_in6addr(&babel_prefix_addr, pref);
        !           223:     uchar_to_in6addr(&nexthop, gate);
        !           224: 
        !           225:     /* make prefix structure */
        !           226:     memset (&quagga_prefix, 0, sizeof(quagga_prefix));
        !           227:     quagga_prefix.family = AF_INET6;
        !           228:     IPV6_ADDR_COPY (&quagga_prefix.prefix, &babel_prefix_addr);
        !           229:     quagga_prefix.prefixlen = plen;
        !           230:     apply_mask_ipv6(&quagga_prefix);
        !           231: 
        !           232:     api.type  = ZEBRA_ROUTE_BABEL;
        !           233:     api.flags = 0;
        !           234:     api.message = 0;
        !           235:     api.safi = SAFI_UNICAST;
        !           236:     SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
        !           237:     if(metric >= KERNEL_INFINITY) {
        !           238:         api.flags = ZEBRA_FLAG_BLACKHOLE;
        !           239:         api.nexthop_num = 0;
        !           240:         api.ifindex_num = 0;
        !           241:     } else {
        !           242:         api.nexthop_num = 1;
        !           243:         api.nexthop = &nexthop_pointer;
        !           244:         SET_FLAG(api.message, ZAPI_MESSAGE_IFINDEX);
        !           245:         api.ifindex_num = 1;
        !           246:         api.ifindex = &tmp_ifindex;
        !           247:         SET_FLAG(api.message, ZAPI_MESSAGE_METRIC);
        !           248:         api.metric = metric;
        !           249:     }
        !           250: 
        !           251:     debugf(BABEL_DEBUG_ROUTE, "%s route (ipv6) to zebra",
        !           252:            add ? "adding" : "removing" );
        !           253:     return zapi_ipv6_route (add ? ZEBRA_IPV6_ROUTE_ADD :
        !           254:                                   ZEBRA_IPV6_ROUTE_DELETE,
        !           255:                             zclient, &quagga_prefix, &api);
        !           256: }
        !           257: 
        !           258: int
        !           259: if_eui64(char *ifname, int ifindex, unsigned char *eui)
        !           260: {
        !           261:     struct interface *ifp = if_lookup_by_index(ifindex);
        !           262:     if (ifp == NULL) {
        !           263:         return -1;
        !           264:     }
        !           265: #ifdef HAVE_STRUCT_SOCKADDR_DL
        !           266:     u_char len = ifp->sdl.sdl_alen;
        !           267:     char *tmp = ifp->sdl.sdl_data + ifp->sdl.sdl_nlen;
        !           268: #else
        !           269:     u_char len = (u_char) ifp->hw_addr_len;
        !           270:     char *tmp = (void*) ifp->hw_addr;
        !           271: #endif
        !           272:     if (len == 8) {
        !           273:         memcpy(eui, tmp, 8);
        !           274:         eui[0] ^= 2;
        !           275:     } else if (len == 6) {
        !           276:         memcpy(eui,   tmp,   3);
        !           277:         eui[3] = 0xFF;
        !           278:         eui[4] = 0xFE;
        !           279:         memcpy(eui+5, tmp+3, 3);
        !           280:     } else {
        !           281:         return -1;
        !           282:     }
        !           283:     return 0;
        !           284: }
        !           285: 
        !           286: /* Like gettimeofday, but returns monotonic time.  If POSIX clocks are not
        !           287:    available, falls back to gettimeofday but enforces monotonicity. */
        !           288: int
        !           289: gettime(struct timeval *tv)
        !           290: {
        !           291:     return quagga_gettime(QUAGGA_CLK_MONOTONIC, tv);
        !           292: }
        !           293: 
        !           294: /* If /dev/urandom doesn't exist, this will fail with ENOENT, which the
        !           295:    caller will deal with gracefully. */
        !           296: 
        !           297: int
        !           298: read_random_bytes(void *buf, size_t len)
        !           299: {
        !           300:     int fd;
        !           301:     int rc;
        !           302: 
        !           303:     fd = open("/dev/urandom", O_RDONLY);
        !           304:     if(fd < 0) {
        !           305:         rc = -1;
        !           306:     } else {
        !           307:         rc = read(fd, buf, len);
        !           308:         if(rc < 0 || (unsigned) rc < len)
        !           309:             rc = -1;
        !           310:         close(fd);
        !           311:     }
        !           312:     return rc;
        !           313: }
        !           314: 

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