File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / zebra / kernel_socket.c
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 10:09:10 2016 UTC (7 years, 8 months ago) by misho
Branches: quagga, MAIN
CVS tags: v1_0_20160315, HEAD
quagga 1.0.20160315

    1: /* Kernel communication using routing socket.
    2:  * Copyright (C) 1999 Kunihiro Ishiguro
    3:  *
    4:  * This file is part of GNU Zebra.
    5:  *
    6:  * GNU Zebra is free software; you can redistribute it and/or modify it
    7:  * under the terms of the GNU General Public License as published by the
    8:  * Free Software Foundation; either version 2, or (at your option) any
    9:  * later version.
   10:  *
   11:  * GNU Zebra is distributed in the hope that it will be useful, but
   12:  * WITHOUT ANY WARRANTY; without even the implied warranty of
   13:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   14:  * General Public License for more details.
   15:  *
   16:  * You should have received a copy of the GNU General Public License
   17:  * along with GNU Zebra; see the file COPYING.  If not, write to the Free
   18:  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
   19:  * 02111-1307, USA.  
   20:  */
   21: 
   22: #include <zebra.h>
   23: #include <net/if_types.h>
   24: 
   25: #include "if.h"
   26: #include "prefix.h"
   27: #include "sockunion.h"
   28: #include "connected.h"
   29: #include "memory.h"
   30: #include "ioctl.h"
   31: #include "log.h"
   32: #include "str.h"
   33: #include "table.h"
   34: #include "rib.h"
   35: #include "privs.h"
   36: #include "vrf.h"
   37: 
   38: #include "zebra/interface.h"
   39: #include "zebra/zserv.h"
   40: #include "zebra/debug.h"
   41: #include "zebra/kernel_socket.h"
   42: #include "zebra/rib.h"
   43: 
   44: extern struct zebra_privs_t zserv_privs;
   45: extern struct zebra_t zebrad;
   46: 
   47: /*
   48:  * Historically, the BSD routing socket has aligned data following a
   49:  * struct sockaddr to sizeof(long), which was 4 bytes on some
   50:  * platforms, and 8 bytes on others.  NetBSD 6 changed the routing
   51:  * socket to align to sizeof(uint64_t), which is 8 bytes.  OS X
   52:  * appears to align to sizeof(int), which is 4 bytes.
   53:  *
   54:  * Alignment of zero-sized sockaddrs is nonsensical, but historically
   55:  * BSD defines RT_ROUNDUP(0) to be the alignment interval (rather than
   56:  * 0).  We follow this practice without questioning it, but it is a
   57:  * bug if quagga calls ROUNDUP with 0.
   58:  */
   59: 
   60: /*
   61:  * Because of these varying conventions, the only sane approach is for
   62:  * the <net/route.h> header to define some flavor of ROUNDUP macro.
   63:  */
   64: 
   65: #if defined(SA_SIZE)
   66: /* SAROUNDUP is the only thing we need, and SA_SIZE provides that */
   67: #define SAROUNDUP(a)	SA_SIZE(a)
   68: #else /* !SA_SIZE */
   69: 
   70: #if defined(RT_ROUNDUP)
   71: #define ROUNDUP(a)	RT_ROUNDUP(a)
   72: #endif /* defined(RT_ROUNDUP) */
   73: 
   74: #if defined(SUNOS_5)
   75: /* Solaris has struct sockaddr_in[6] definitions at 16 / 32 bytes size,
   76:  * so the whole concept doesn't really apply. */
   77: #define ROUNDUP(a)      (a)
   78: #endif
   79: 
   80: /*
   81:  * If ROUNDUP has not yet been defined in terms of platform-provided
   82:  * defines, attempt to cope with heuristics.
   83:  */
   84: #if !defined(ROUNDUP)
   85: 
   86: /*
   87:  * It's a bug for a platform not to define rounding/alignment for
   88:  * sockaddrs on the routing socket.  This warning really is
   89:  * intentional, to provoke filing bug reports with operating systems
   90:  * that don't define RT_ROUNDUP or equivalent.
   91:  */
   92: #warning "net/route.h does not define RT_ROUNDUP; making unwarranted assumptions!"
   93: 
   94: /* OS X (Xcode as of 2014-12) is known not to define RT_ROUNDUP */
   95: #ifdef __APPLE__
   96: #define ROUNDUP_TYPE	int
   97: #else
   98: #define ROUNDUP_TYPE	long
   99: #endif
  100: 
  101: #define ROUNDUP(a) \
  102:   ((a) > 0 ? (1 + (((a) - 1) | (sizeof(ROUNDUP_TYPE) - 1))) : sizeof(ROUNDUP_TYPE))
  103: 
  104: #endif /* defined(ROUNDUP) */
  105: 
  106: /*
  107:  * Given a pointer (sockaddr or void *), return the number of bytes
  108:  * taken up by the sockaddr and any padding needed for alignment.
  109:  */
  110: #if defined(HAVE_STRUCT_SOCKADDR_SA_LEN)
  111: #define SAROUNDUP(X)   ROUNDUP(((struct sockaddr *)(X))->sa_len)
  112: #elif defined(HAVE_IPV6)
  113: /*
  114:  * One would hope all fixed-size structure definitions are aligned,
  115:  * but round them up nonetheless.
  116:  */
  117: #define SAROUNDUP(X) \
  118:     (((struct sockaddr *)(X))->sa_family == AF_INET ?   \
  119:       ROUNDUP(sizeof(struct sockaddr_in)):\
  120:       (((struct sockaddr *)(X))->sa_family == AF_INET6 ? \
  121:        ROUNDUP(sizeof(struct sockaddr_in6)) :  \
  122:        (((struct sockaddr *)(X))->sa_family == AF_LINK ? \
  123:          ROUNDUP(sizeof(struct sockaddr_dl)) : sizeof(struct sockaddr))))
  124: #else /* HAVE_IPV6 */ 
  125: #define SAROUNDUP(X) \
  126:       (((struct sockaddr *)(X))->sa_family == AF_INET ?   \
  127:         ROUNDUP(sizeof(struct sockaddr_in)):\
  128:          (((struct sockaddr *)(X))->sa_family == AF_LINK ? \
  129:            ROUNDUP(sizeof(struct sockaddr_dl)) : sizeof(struct sockaddr)))
  130: #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
  131: 
  132: #endif /* !SA_SIZE */
  133: 
  134: /*
  135:  * We use a call to an inline function to copy (PNT) to (DEST)
  136:  * 1. Calculating the length of the copy requires an #ifdef to determine
  137:  *    if sa_len is a field and can't be used directly inside a #define
  138:  * 2. So the compiler doesn't complain when DEST is NULL, which is only true
  139:  *    when we are skipping the copy and incrementing to the next SA
  140:  */
  141: static inline void
  142: rta_copy (union sockunion *dest, caddr_t src) {
  143:   int len;
  144:   if (!dest)
  145:     return;
  146: #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
  147:   len = (((struct sockaddr *)src)->sa_len > sizeof (*dest)) ?
  148:             sizeof (*dest) : ((struct sockaddr *)src)->sa_len ;
  149: #else
  150:   len = (SAROUNDUP (src) > sizeof (*dest)) ?
  151:             sizeof (*dest) : SAROUNDUP (src) ;
  152: #endif
  153:   memcpy (dest, src, len);
  154: }
  155: 
  156: #define RTA_ADDR_GET(DEST, RTA, RTMADDRS, PNT) \
  157:   if ((RTMADDRS) & (RTA)) \
  158:     { \
  159:       int len = SAROUNDUP ((PNT)); \
  160:       if (af_check (((struct sockaddr *)(PNT))->sa_family)) \
  161:         rta_copy((DEST), (PNT)); \
  162:       (PNT) += len; \
  163:     }
  164: #define RTA_ATTR_GET(DEST, RTA, RTMADDRS, PNT) \
  165:   if ((RTMADDRS) & (RTA)) \
  166:     { \
  167:       int len = SAROUNDUP ((PNT)); \
  168:       rta_copy((DEST), (PNT)); \
  169:       (PNT) += len; \
  170:     }
  171: 
  172: #define RTA_NAME_GET(DEST, RTA, RTMADDRS, PNT, LEN) \
  173:   if ((RTMADDRS) & (RTA)) \
  174:     { \
  175:       u_char *pdest = (u_char *) (DEST); \
  176:       int len = SAROUNDUP ((PNT)); \
  177:       struct sockaddr_dl *sdl = (struct sockaddr_dl *)(PNT); \
  178:       if (IS_ZEBRA_DEBUG_KERNEL) \
  179:         zlog_debug ("%s: RTA_SDL_GET nlen %d, alen %d", \
  180:                     __func__, sdl->sdl_nlen, sdl->sdl_alen); \
  181:       if ( ((DEST) != NULL) && (sdl->sdl_family == AF_LINK) \
  182:            && (sdl->sdl_nlen < IFNAMSIZ) && (sdl->sdl_nlen <= len) ) \
  183:         { \
  184:           memcpy (pdest, sdl->sdl_data, sdl->sdl_nlen); \
  185:           pdest[sdl->sdl_nlen] = '\0'; \
  186:           (LEN) = sdl->sdl_nlen; \
  187:         } \
  188:       (PNT) += len; \
  189:     } \
  190:   else \
  191:     { \
  192:       (LEN) = 0; \
  193:     }
  194: /* Routing socket message types. */
  195: const struct message rtm_type_str[] =
  196: {
  197:   {RTM_ADD,      "RTM_ADD"},
  198:   {RTM_DELETE,   "RTM_DELETE"},
  199:   {RTM_CHANGE,   "RTM_CHANGE"},
  200:   {RTM_GET,      "RTM_GET"},
  201:   {RTM_LOSING,   "RTM_LOSING"},
  202:   {RTM_REDIRECT, "RTM_REDIRECT"},
  203:   {RTM_MISS,     "RTM_MISS"},
  204:   {RTM_LOCK,     "RTM_LOCK"},
  205: #ifdef OLDADD
  206:   {RTM_OLDADD,   "RTM_OLDADD"},
  207: #endif /* RTM_OLDADD */
  208: #ifdef RTM_OLDDEL
  209:   {RTM_OLDDEL,   "RTM_OLDDEL"},
  210: #endif /* RTM_OLDDEL */
  211:   {RTM_RESOLVE,  "RTM_RESOLVE"},
  212:   {RTM_NEWADDR,  "RTM_NEWADDR"},
  213:   {RTM_DELADDR,  "RTM_DELADDR"},
  214:   {RTM_IFINFO,   "RTM_IFINFO"},
  215: #ifdef RTM_OIFINFO
  216:   {RTM_OIFINFO,   "RTM_OIFINFO"},
  217: #endif /* RTM_OIFINFO */
  218: #ifdef RTM_NEWMADDR
  219:   {RTM_NEWMADDR, "RTM_NEWMADDR"},
  220: #endif /* RTM_NEWMADDR */
  221: #ifdef RTM_DELMADDR
  222:   {RTM_DELMADDR, "RTM_DELMADDR"},
  223: #endif /* RTM_DELMADDR */
  224: #ifdef RTM_IFANNOUNCE
  225:   {RTM_IFANNOUNCE, "RTM_IFANNOUNCE"},
  226: #endif /* RTM_IFANNOUNCE */
  227:   {0,            NULL}
  228: };
  229: 
  230: static const struct message rtm_flag_str[] =
  231: {
  232:   {RTF_UP,        "UP"},
  233:   {RTF_GATEWAY,   "GATEWAY"},
  234:   {RTF_HOST,      "HOST"},
  235:   {RTF_REJECT,    "REJECT"},
  236:   {RTF_DYNAMIC,   "DYNAMIC"},
  237:   {RTF_MODIFIED,  "MODIFIED"},
  238:   {RTF_DONE,      "DONE"},
  239: #ifdef RTF_MASK
  240:   {RTF_MASK,      "MASK"},
  241: #endif /* RTF_MASK */
  242: #ifdef RTF_CLONING
  243:   {RTF_CLONING,   "CLONING"},
  244: #endif /* RTF_CLONING */
  245:   {RTF_XRESOLVE,  "XRESOLVE"},
  246: #ifdef RTF_LLINFO
  247:   {RTF_LLINFO,    "LLINFO"},
  248: #endif /* RTF_LLINFO */
  249:   {RTF_STATIC,    "STATIC"},
  250:   {RTF_BLACKHOLE, "BLACKHOLE"},
  251: #ifdef RTF_PRIVATE
  252:   {RTF_PRIVATE,	  "PRIVATE"},
  253: #endif /* RTF_PRIVATE */
  254:   {RTF_PROTO1,    "PROTO1"},
  255:   {RTF_PROTO2,    "PROTO2"},
  256: #ifdef RTF_PRCLONING
  257:   {RTF_PRCLONING, "PRCLONING"},
  258: #endif /* RTF_PRCLONING */
  259: #ifdef RTF_WASCLONED
  260:   {RTF_WASCLONED, "WASCLONED"},
  261: #endif /* RTF_WASCLONED */
  262: #ifdef RTF_PROTO3
  263:   {RTF_PROTO3,    "PROTO3"},
  264: #endif /* RTF_PROTO3 */
  265: #ifdef RTF_PINNED
  266:   {RTF_PINNED,    "PINNED"},
  267: #endif /* RTF_PINNED */
  268: #ifdef RTF_LOCAL
  269:   {RTF_LOCAL,    "LOCAL"},
  270: #endif /* RTF_LOCAL */
  271: #ifdef RTF_BROADCAST
  272:   {RTF_BROADCAST, "BROADCAST"},
  273: #endif /* RTF_BROADCAST */
  274: #ifdef RTF_MULTICAST
  275:   {RTF_MULTICAST, "MULTICAST"},
  276: #endif /* RTF_MULTICAST */
  277: #ifdef RTF_MULTIRT
  278:   {RTF_MULTIRT,   "MULTIRT"},
  279: #endif /* RTF_MULTIRT */
  280: #ifdef RTF_SETSRC
  281:   {RTF_SETSRC,    "SETSRC"},
  282: #endif /* RTF_SETSRC */
  283:   {0,             NULL}
  284: };
  285: 
  286: /* Kernel routing update socket. */
  287: int routing_sock = -1;
  288: 
  289: /* Yes I'm checking ugly routing socket behavior. */
  290: /* #define DEBUG */
  291: 
  292: /* Supported address family check. */
  293: static inline int
  294: af_check (int family)
  295: {
  296:   if (family == AF_INET)
  297:     return 1;
  298: #ifdef HAVE_IPV6
  299:   if (family == AF_INET6)
  300:     return 1;
  301: #endif /* HAVE_IPV6 */
  302:   return 0;
  303: }
  304: 
  305: /* Dump routing table flag for debug purpose. */
  306: static void
  307: rtm_flag_dump (int flag)
  308: {
  309:   const struct message *mes;
  310:   static char buf[BUFSIZ];
  311: 
  312:   buf[0] = '\0';
  313:   for (mes = rtm_flag_str; mes->key != 0; mes++)
  314:     {
  315:       if (mes->key & flag)
  316: 	{
  317: 	  strlcat (buf, mes->str, BUFSIZ);
  318: 	  strlcat (buf, " ", BUFSIZ);
  319: 	}
  320:     }
  321:   zlog_debug ("Kernel: %s", buf);
  322: }
  323: 
  324: #ifdef RTM_IFANNOUNCE
  325: /* Interface adding function */
  326: static int
  327: ifan_read (struct if_announcemsghdr *ifan)
  328: {
  329:   struct interface *ifp;
  330:   
  331:   ifp = if_lookup_by_index (ifan->ifan_index);
  332:   
  333:   if (ifp)
  334:     assert ( (ifp->ifindex == ifan->ifan_index) 
  335:              || (ifp->ifindex == IFINDEX_INTERNAL) );
  336: 
  337:   if ( (ifp == NULL) 
  338:       || ((ifp->ifindex == IFINDEX_INTERNAL)
  339:           && (ifan->ifan_what == IFAN_ARRIVAL)) )
  340:     {
  341:       if (IS_ZEBRA_DEBUG_KERNEL)
  342:         zlog_debug ("%s: creating interface for ifindex %d, name %s",
  343:                     __func__, ifan->ifan_index, ifan->ifan_name);
  344:       
  345:       /* Create Interface */
  346:       ifp = if_get_by_name_len(ifan->ifan_name,
  347: 			       strnlen(ifan->ifan_name,
  348: 				       sizeof(ifan->ifan_name)));
  349:       ifp->ifindex = ifan->ifan_index;
  350: 
  351:       if_get_metric (ifp);
  352:       if_add_update (ifp);
  353:     }
  354:   else if (ifp != NULL && ifan->ifan_what == IFAN_DEPARTURE)
  355:     if_delete_update (ifp);
  356: 
  357:   if_get_flags (ifp);
  358:   if_get_mtu (ifp);
  359:   if_get_metric (ifp);
  360: 
  361:   if (IS_ZEBRA_DEBUG_KERNEL)
  362:     zlog_debug ("%s: interface %s index %d", 
  363:                 __func__, ifan->ifan_name, ifan->ifan_index);
  364: 
  365:   return 0;
  366: }
  367: #endif /* RTM_IFANNOUNCE */
  368: 
  369: #ifdef HAVE_BSD_IFI_LINK_STATE
  370: /* BSD link detect translation */
  371: static void
  372: bsd_linkdetect_translate (struct if_msghdr *ifm)
  373: {
  374:   if ((ifm->ifm_data.ifi_link_state >= LINK_STATE_UP) ||
  375:       (ifm->ifm_data.ifi_link_state == LINK_STATE_UNKNOWN))
  376:     SET_FLAG(ifm->ifm_flags, IFF_RUNNING);
  377:   else
  378:     UNSET_FLAG(ifm->ifm_flags, IFF_RUNNING);
  379: }
  380: #endif /* HAVE_BSD_IFI_LINK_STATE */
  381: 
  382: static enum zebra_link_type
  383: sdl_to_zebra_link_type (unsigned int sdlt)
  384: {
  385:   switch (sdlt)
  386:   {
  387:     case IFT_ETHER: return ZEBRA_LLT_ETHER;
  388:     case IFT_X25: return ZEBRA_LLT_X25;
  389:     case IFT_FDDI: return ZEBRA_LLT_FDDI;
  390:     case IFT_PPP: return ZEBRA_LLT_PPP;
  391:     case IFT_LOOP: return ZEBRA_LLT_LOOPBACK;
  392:     case IFT_SLIP: return ZEBRA_LLT_SLIP;
  393:     case IFT_ARCNET: return ZEBRA_LLT_ARCNET;
  394:     case IFT_ATM: return ZEBRA_LLT_ATM;
  395:     case IFT_LOCALTALK: return ZEBRA_LLT_LOCALTLK;
  396:     case IFT_HIPPI: return ZEBRA_LLT_HIPPI;
  397: #ifdef IFT_IEEE1394
  398:     case IFT_IEEE1394: return ZEBRA_LLT_IEEE1394;
  399: #endif
  400: 
  401:     default: return ZEBRA_LLT_UNKNOWN;
  402:   }
  403: }
  404: 
  405: /*
  406:  * Handle struct if_msghdr obtained from reading routing socket or
  407:  * sysctl (from interface_list).  There may or may not be sockaddrs
  408:  * present after the header.
  409:  */
  410: int
  411: ifm_read (struct if_msghdr *ifm)
  412: {
  413:   struct interface *ifp = NULL;
  414:   struct sockaddr_dl *sdl;
  415:   char ifname[IFNAMSIZ];
  416:   short ifnlen = 0;
  417:   caddr_t cp;
  418:   
  419:   /* terminate ifname at head (for strnlen) and tail (for safety) */
  420:   ifname[IFNAMSIZ - 1] = '\0';
  421:   
  422:   /* paranoia: sanity check structure */
  423:   if (ifm->ifm_msglen < sizeof(struct if_msghdr))
  424:     {
  425:       zlog_err ("ifm_read: ifm->ifm_msglen %d too short\n",
  426: 		ifm->ifm_msglen);
  427:       return -1;
  428:     }
  429: 
  430:   /*
  431:    * Check for a sockaddr_dl following the message.  First, point to
  432:    * where a socakddr might be if one follows the message.
  433:    */
  434:   cp = (void *)(ifm + 1);
  435: 
  436: #ifdef SUNOS_5
  437:   /* 
  438:    * XXX This behavior should be narrowed to only the kernel versions
  439:    * for which the structures returned do not match the headers.
  440:    *
  441:    * if_msghdr_t on 64 bit kernels in Solaris 9 and earlier versions
  442:    * is 12 bytes larger than the 32 bit version.
  443:    */
  444:   if (((struct sockaddr *) cp)->sa_family == AF_UNSPEC)
  445:   	cp = cp + 12;
  446: #endif
  447: 
  448:   RTA_ADDR_GET (NULL, RTA_DST, ifm->ifm_addrs, cp);
  449:   RTA_ADDR_GET (NULL, RTA_GATEWAY, ifm->ifm_addrs, cp);
  450:   RTA_ATTR_GET (NULL, RTA_NETMASK, ifm->ifm_addrs, cp);
  451:   RTA_ADDR_GET (NULL, RTA_GENMASK, ifm->ifm_addrs, cp);
  452:   sdl = (struct sockaddr_dl *)cp;
  453:   RTA_NAME_GET (ifname, RTA_IFP, ifm->ifm_addrs, cp, ifnlen);
  454:   RTA_ADDR_GET (NULL, RTA_IFA, ifm->ifm_addrs, cp);
  455:   RTA_ADDR_GET (NULL, RTA_AUTHOR, ifm->ifm_addrs, cp);
  456:   RTA_ADDR_GET (NULL, RTA_BRD, ifm->ifm_addrs, cp);
  457:   
  458:   if (IS_ZEBRA_DEBUG_KERNEL)
  459:     zlog_debug ("%s: sdl ifname %s", __func__, (ifnlen ? ifname : "(nil)"));
  460:   
  461:   /* 
  462:    * Look up on ifindex first, because ifindices are the primary handle for
  463:    * interfaces across the user/kernel boundary, for most systems.  (Some
  464:    * messages, such as up/down status changes on NetBSD, do not include a
  465:    * sockaddr_dl).
  466:    */
  467:   if ( (ifp = if_lookup_by_index (ifm->ifm_index)) != NULL )
  468:     {
  469:       /* we have an ifp, verify that the name matches as some systems,
  470:        * eg Solaris, have a 1:many association of ifindex:ifname
  471:        * if they dont match, we dont have the correct ifp and should
  472:        * set it back to NULL to let next check do lookup by name
  473:        */
  474:       if (ifnlen && (strncmp (ifp->name, ifname, IFNAMSIZ) != 0) )
  475:         {
  476:           if (IS_ZEBRA_DEBUG_KERNEL)
  477:             zlog_debug ("%s: ifp name %s doesnt match sdl name %s",
  478:                         __func__, ifp->name, ifname);
  479:           ifp = NULL;
  480:         }
  481:     }
  482:   
  483:   /* 
  484:    * If we dont have an ifp, try looking up by name.  Particularly as some
  485:    * systems (Solaris) have a 1:many mapping of ifindex:ifname - the ifname
  486:    * is therefore our unique handle to that interface.
  487:    *
  488:    * Interfaces specified in the configuration file for which the ifindex
  489:    * has not been determined will have ifindex == IFINDEX_INTERNAL, and such
  490:    * interfaces are found by this search, and then their ifindex values can
  491:    * be filled in.
  492:    */
  493:   if ( (ifp == NULL) && ifnlen)
  494:     ifp = if_lookup_by_name (ifname);
  495: 
  496:   /*
  497:    * If ifp still does not exist or has an invalid index (IFINDEX_INTERNAL),
  498:    * create or fill in an interface.
  499:    */
  500:   if ((ifp == NULL) || (ifp->ifindex == IFINDEX_INTERNAL))
  501:     {
  502:       /*
  503:        * To create or fill in an interface, a sockaddr_dl (via
  504:        * RTA_IFP) is required.
  505:        */
  506:       if (!ifnlen)
  507: 	{
  508: 	  zlog_warn ("Interface index %d (new) missing ifname\n",
  509: 		     ifm->ifm_index);
  510: 	  return -1;
  511: 	}
  512: 
  513: #ifndef RTM_IFANNOUNCE
  514:       /* Down->Down interface should be ignored here.
  515:        * See further comment below.
  516:        */
  517:       if (!CHECK_FLAG (ifm->ifm_flags, IFF_UP))
  518:         return 0;
  519: #endif /* !RTM_IFANNOUNCE */
  520:       
  521:       if (ifp == NULL)
  522:         {
  523: 	  /* Interface that zebra was not previously aware of, so create. */ 
  524: 	  ifp = if_create (ifname, ifnlen);
  525: 	  if (IS_ZEBRA_DEBUG_KERNEL)
  526: 	    zlog_debug ("%s: creating ifp for ifindex %d", 
  527: 	                __func__, ifm->ifm_index);
  528:         }
  529: 
  530:       if (IS_ZEBRA_DEBUG_KERNEL)
  531:         zlog_debug ("%s: updated/created ifp, ifname %s, ifindex %d",
  532:                     __func__, ifp->name, ifp->ifindex);
  533:       /* 
  534:        * Fill in newly created interface structure, or larval
  535:        * structure with ifindex IFINDEX_INTERNAL.
  536:        */
  537:       ifp->ifindex = ifm->ifm_index;
  538:       
  539: #ifdef HAVE_BSD_IFI_LINK_STATE /* translate BSD kernel msg for link-state */
  540:       bsd_linkdetect_translate(ifm);
  541: #endif /* HAVE_BSD_IFI_LINK_STATE */
  542: 
  543:       if_flags_update (ifp, ifm->ifm_flags);
  544: #if defined(__bsdi__)
  545:       if_kvm_get_mtu (ifp);
  546: #else
  547:       if_get_mtu (ifp);
  548: #endif /* __bsdi__ */
  549:       if_get_metric (ifp);
  550: 
  551:       /*
  552:        * XXX sockaddr_dl contents can be larger than the structure
  553:        * definition.  There are 2 big families here:
  554:        *  - BSD has sdl_len + sdl_data[16] + overruns sdl_data
  555:        *    we MUST use sdl_len here or we'll truncate data.
  556:        *  - Solaris has no sdl_len, but sdl_data[244]
  557:        *    presumably, it's not going to run past that, so sizeof()
  558:        *    is fine here.
  559:        * a nonzero ifnlen from RTA_NAME_GET() means sdl is valid
  560:        */
  561:       ifp->ll_type = ZEBRA_LLT_UNKNOWN;
  562:       ifp->hw_addr_len = 0;
  563:       if (ifnlen)
  564:         {
  565: #ifdef HAVE_STRUCT_SOCKADDR_DL_SDL_LEN
  566:           memcpy (&((struct zebra_if *)ifp->info)->sdl, sdl, sdl->sdl_len);
  567: #else
  568:           memcpy (&((struct zebra_if *)ifp->info)->sdl, sdl, sizeof (struct sockaddr_dl));
  569: #endif /* HAVE_STRUCT_SOCKADDR_DL_SDL_LEN */
  570: 
  571:           ifp->ll_type = sdl_to_zebra_link_type (sdl->sdl_type);
  572:           if (sdl->sdl_alen <= sizeof(ifp->hw_addr))
  573:             {
  574:               memcpy (ifp->hw_addr, LLADDR(sdl), sdl->sdl_alen);
  575:               ifp->hw_addr_len = sdl->sdl_alen;
  576:             }
  577:         }
  578: 
  579:       if_add_update (ifp);
  580:     }
  581:   else
  582:     /*
  583:      * Interface structure exists.  Adjust stored flags from
  584:      * notification.  If interface has up->down or down->up
  585:      * transition, call state change routines (to adjust routes,
  586:      * notify routing daemons, etc.).  (Other flag changes are stored
  587:      * but apparently do not trigger action.)
  588:      */
  589:     {
  590:       if (ifp->ifindex != ifm->ifm_index)
  591:         {
  592:           zlog_warn ("%s: index mismatch, ifname %s, ifp index %d, "
  593:                      "ifm index %d", 
  594:                      __func__, ifp->name, ifp->ifindex, ifm->ifm_index);
  595:           return -1;
  596:         }
  597:       
  598: #ifdef HAVE_BSD_IFI_LINK_STATE /* translate BSD kernel msg for link-state */
  599:       bsd_linkdetect_translate(ifm);
  600: #endif /* HAVE_BSD_IFI_LINK_STATE */
  601: 
  602:       /* update flags and handle operative->inoperative transition, if any */
  603:       if_flags_update (ifp, ifm->ifm_flags);
  604:       
  605: #ifndef RTM_IFANNOUNCE
  606:       if (!if_is_up (ifp))
  607:           {
  608:             /* No RTM_IFANNOUNCE on this platform, so we can never
  609:              * distinguish between ~IFF_UP and delete. We must presume
  610:              * it has been deleted.
  611:              * Eg, Solaris will not notify us of unplumb.
  612:              *
  613:              * XXX: Fixme - this should be runtime detected
  614:              * So that a binary compiled on a system with IFANNOUNCE
  615:              * will still behave correctly if run on a platform without
  616:              */
  617:             if_delete_update (ifp);
  618:           }
  619: #endif /* RTM_IFANNOUNCE */
  620:       if (if_is_up (ifp))
  621:       {
  622: #if defined(__bsdi__)
  623:         if_kvm_get_mtu (ifp);
  624: #else
  625:         if_get_mtu (ifp);
  626: #endif /* __bsdi__ */
  627:         if_get_metric (ifp);
  628:       }
  629:     }
  630: 
  631: #ifdef HAVE_NET_RT_IFLIST
  632:   ifp->stats = ifm->ifm_data;
  633: #endif /* HAVE_NET_RT_IFLIST */
  634: 
  635:   if (IS_ZEBRA_DEBUG_KERNEL)
  636:     zlog_debug ("%s: interface %s index %d", 
  637:                 __func__, ifp->name, ifp->ifindex);
  638: 
  639:   return 0;
  640: }
  641: 
  642: /* Address read from struct ifa_msghdr. */
  643: static void
  644: ifam_read_mesg (struct ifa_msghdr *ifm,
  645: 		union sockunion *addr,
  646: 		union sockunion *mask,
  647: 		union sockunion *brd,
  648: 		char *ifname,
  649: 		short *ifnlen)
  650: {
  651:   caddr_t pnt, end;
  652:   union sockunion dst;
  653:   union sockunion gateway;
  654: 
  655:   pnt = (caddr_t)(ifm + 1);
  656:   end = ((caddr_t)ifm) + ifm->ifam_msglen;
  657: 
  658:   /* Be sure structure is cleared */
  659:   memset (mask, 0, sizeof (union sockunion));
  660:   memset (addr, 0, sizeof (union sockunion));
  661:   memset (brd, 0, sizeof (union sockunion));
  662:   memset (&dst, 0, sizeof (union sockunion));
  663:   memset (&gateway, 0, sizeof (union sockunion));
  664: 
  665:   /* We fetch each socket variable into sockunion. */
  666:   RTA_ADDR_GET (&dst, RTA_DST, ifm->ifam_addrs, pnt);
  667:   RTA_ADDR_GET (&gateway, RTA_GATEWAY, ifm->ifam_addrs, pnt);
  668:   RTA_ATTR_GET (mask, RTA_NETMASK, ifm->ifam_addrs, pnt);
  669:   RTA_ADDR_GET (NULL, RTA_GENMASK, ifm->ifam_addrs, pnt);
  670:   RTA_NAME_GET (ifname, RTA_IFP, ifm->ifam_addrs, pnt, *ifnlen);
  671:   RTA_ADDR_GET (addr, RTA_IFA, ifm->ifam_addrs, pnt);
  672:   RTA_ADDR_GET (NULL, RTA_AUTHOR, ifm->ifam_addrs, pnt);
  673:   RTA_ADDR_GET (brd, RTA_BRD, ifm->ifam_addrs, pnt);
  674: 
  675:   if (IS_ZEBRA_DEBUG_KERNEL)
  676:     {
  677:       int family = sockunion_family(addr);
  678:       switch (family)
  679:         {
  680: 	case AF_INET:
  681: #ifdef HAVE_IPV6
  682: 	case AF_INET6:
  683: #endif
  684: 	  {
  685: 	    char buf[4][INET6_ADDRSTRLEN];
  686: 	    zlog_debug ("%s: ifindex %d, ifname %s, ifam_addrs 0x%x, "
  687: 			"ifam_flags 0x%x, addr %s/%d broad %s dst %s "
  688: 			"gateway %s",
  689: 			__func__, ifm->ifam_index,
  690: 			(ifnlen ? ifname : "(nil)"), ifm->ifam_addrs,
  691: 			ifm->ifam_flags,
  692: 			inet_ntop(family,&addr->sin.sin_addr,
  693: 			          buf[0],sizeof(buf[0])),
  694: 			ip_masklen(mask->sin.sin_addr),
  695: 			inet_ntop(family,&brd->sin.sin_addr,
  696: 			          buf[1],sizeof(buf[1])),
  697: 			inet_ntop(family,&dst.sin.sin_addr,
  698: 			          buf[2],sizeof(buf[2])),
  699: 			inet_ntop(family,&gateway.sin.sin_addr,
  700: 			          buf[3],sizeof(buf[3])));
  701: 	  }
  702: 	  break;
  703:         default:
  704: 	  zlog_debug ("%s: ifindex %d, ifname %s, ifam_addrs 0x%x",
  705: 		      __func__, ifm->ifam_index, 
  706: 		      (ifnlen ? ifname : "(nil)"), ifm->ifam_addrs);
  707: 	  break;
  708:         }
  709:     }
  710: 
  711:   /* Assert read up end point matches to end point */
  712:   if (pnt != end)
  713:     zlog_warn ("ifam_read() doesn't read all socket data");
  714: }
  715: 
  716: /* Interface's address information get. */
  717: int
  718: ifam_read (struct ifa_msghdr *ifam)
  719: {
  720:   struct interface *ifp = NULL;
  721:   union sockunion addr, mask, brd;
  722:   char ifname[INTERFACE_NAMSIZ];
  723:   short ifnlen = 0;
  724:   char isalias = 0;
  725:   int flags = 0;
  726:   
  727:   ifname[0] = ifname[INTERFACE_NAMSIZ - 1] = '\0';
  728:   
  729:   /* Allocate and read address information. */
  730:   ifam_read_mesg (ifam, &addr, &mask, &brd, ifname, &ifnlen);
  731:   
  732:   if ((ifp = if_lookup_by_index(ifam->ifam_index)) == NULL)
  733:     {
  734:       zlog_warn ("%s: no interface for ifname %s, index %d", 
  735:                  __func__, ifname, ifam->ifam_index);
  736:       return -1;
  737:     }
  738:   
  739:   if (ifnlen && strncmp (ifp->name, ifname, INTERFACE_NAMSIZ))
  740:     isalias = 1;
  741:   
  742:   /* N.B. The info in ifa_msghdr does not tell us whether the RTA_BRD
  743:      field contains a broadcast address or a peer address, so we are forced to
  744:      rely upon the interface type. */
  745:   if (if_is_pointopoint(ifp))
  746:     SET_FLAG(flags, ZEBRA_IFA_PEER);
  747: 
  748: #if 0
  749:   /* it might seem cute to grab the interface metric here, however
  750:    * we're processing an address update message, and so some systems
  751:    * (e.g. FBSD) dont bother to fill in ifam_metric. Disabled, but left
  752:    * in deliberately, as comment.
  753:    */
  754:   ifp->metric = ifam->ifam_metric;
  755: #endif
  756: 
  757:   /* Add connected address. */
  758:   switch (sockunion_family (&addr))
  759:     {
  760:     case AF_INET:
  761:       if (ifam->ifam_type == RTM_NEWADDR)
  762: 	connected_add_ipv4 (ifp, flags, &addr.sin.sin_addr, 
  763: 			    ip_masklen (mask.sin.sin_addr),
  764: 			    &brd.sin.sin_addr,
  765: 			    (isalias ? ifname : NULL));
  766:       else
  767: 	connected_delete_ipv4 (ifp, flags, &addr.sin.sin_addr, 
  768: 			       ip_masklen (mask.sin.sin_addr),
  769: 			       &brd.sin.sin_addr);
  770:       break;
  771: #ifdef HAVE_IPV6
  772:     case AF_INET6:
  773:       /* Unset interface index from link-local address when IPv6 stack
  774: 	 is KAME. */
  775:       if (IN6_IS_ADDR_LINKLOCAL (&addr.sin6.sin6_addr))
  776:         {
  777:           SET_IN6_LINKLOCAL_IFINDEX (addr.sin6.sin6_addr, 0);
  778:         }
  779: 
  780:       if (ifam->ifam_type == RTM_NEWADDR)
  781: 	connected_add_ipv6 (ifp, flags, &addr.sin6.sin6_addr, 
  782: 			    ip6_masklen (mask.sin6.sin6_addr),
  783: 			    &brd.sin6.sin6_addr,
  784: 			    (isalias ? ifname : NULL));
  785:       else
  786: 	connected_delete_ipv6 (ifp,
  787: 			       &addr.sin6.sin6_addr, 
  788: 			       ip6_masklen (mask.sin6.sin6_addr),
  789: 			       &brd.sin6.sin6_addr);
  790:       break;
  791: #endif /* HAVE_IPV6 */
  792:     default:
  793:       /* Unsupported family silently ignore... */
  794:       break;
  795:     }
  796:   
  797:   /* Check interface flag for implicit up of the interface. */
  798:   if_refresh (ifp);
  799: 
  800: #ifdef SUNOS_5
  801:   /* In addition to lacking IFANNOUNCE, on SUNOS IFF_UP is strange. 
  802:    * See comments for SUNOS_5 in interface.c::if_flags_mangle.
  803:    * 
  804:    * Here we take care of case where the real IFF_UP was previously
  805:    * unset (as kept in struct zebra_if.primary_state) and the mangled
  806:    * IFF_UP (ie IFF_UP set || listcount(connected) has now transitioned
  807:    * to unset due to the lost non-primary address having DELADDR'd.
  808:    *
  809:    * we must delete the interface, because in between here and next
  810:    * event for this interface-name the administrator could unplumb
  811:    * and replumb the interface.
  812:    */
  813:   if (!if_is_up (ifp))
  814:     if_delete_update (ifp);
  815: #endif /* SUNOS_5 */
  816:   
  817:   return 0;
  818: }
  819: 
  820: /* Interface function for reading kernel routing table information. */
  821: static int
  822: rtm_read_mesg (struct rt_msghdr *rtm,
  823: 	       union sockunion *dest,
  824: 	       union sockunion *mask,
  825: 	       union sockunion *gate,
  826: 	       char *ifname,
  827: 	       short *ifnlen)
  828: {
  829:   caddr_t pnt, end;
  830: 
  831:   /* Pnt points out socket data start point. */
  832:   pnt = (caddr_t)(rtm + 1);
  833:   end = ((caddr_t)rtm) + rtm->rtm_msglen;
  834: 
  835:   /* rt_msghdr version check. */
  836:   if (rtm->rtm_version != RTM_VERSION) 
  837:       zlog (NULL, LOG_WARNING,
  838: 	      "Routing message version different %d should be %d."
  839: 	      "This may cause problem\n", rtm->rtm_version, RTM_VERSION);
  840:   
  841:   /* Be sure structure is cleared */
  842:   memset (dest, 0, sizeof (union sockunion));
  843:   memset (gate, 0, sizeof (union sockunion));
  844:   memset (mask, 0, sizeof (union sockunion));
  845: 
  846:   /* We fetch each socket variable into sockunion. */
  847:   RTA_ADDR_GET (dest, RTA_DST, rtm->rtm_addrs, pnt);
  848:   RTA_ADDR_GET (gate, RTA_GATEWAY, rtm->rtm_addrs, pnt);
  849:   RTA_ATTR_GET (mask, RTA_NETMASK, rtm->rtm_addrs, pnt);
  850:   RTA_ADDR_GET (NULL, RTA_GENMASK, rtm->rtm_addrs, pnt);
  851:   RTA_NAME_GET (ifname, RTA_IFP, rtm->rtm_addrs, pnt, *ifnlen);
  852:   RTA_ADDR_GET (NULL, RTA_IFA, rtm->rtm_addrs, pnt);
  853:   RTA_ADDR_GET (NULL, RTA_AUTHOR, rtm->rtm_addrs, pnt);
  854:   RTA_ADDR_GET (NULL, RTA_BRD, rtm->rtm_addrs, pnt);
  855: 
  856:   /* If there is netmask information set it's family same as
  857:      destination family*/
  858:   if (rtm->rtm_addrs & RTA_NETMASK)
  859:     mask->sa.sa_family = dest->sa.sa_family;
  860: 
  861:   /* Assert read up to the end of pointer. */
  862:   if (pnt != end) 
  863:       zlog (NULL, LOG_WARNING, "rtm_read() doesn't read all socket data.");
  864: 
  865:   return rtm->rtm_flags;
  866: }
  867: 
  868: void
  869: rtm_read (struct rt_msghdr *rtm)
  870: {
  871:   int flags;
  872:   u_char zebra_flags;
  873:   union sockunion dest, mask, gate;
  874:   char ifname[INTERFACE_NAMSIZ + 1];
  875:   short ifnlen = 0;
  876: 
  877:   zebra_flags = 0;
  878: 
  879:   /* Read destination and netmask and gateway from rtm message
  880:      structure. */
  881:   flags = rtm_read_mesg (rtm, &dest, &mask, &gate, ifname, &ifnlen);
  882:   if (!(flags & RTF_DONE))
  883:     return;
  884:   if (IS_ZEBRA_DEBUG_KERNEL)
  885:     zlog_debug ("%s: got rtm of type %d (%s)", __func__, rtm->rtm_type,
  886:       lookup (rtm_type_str, rtm->rtm_type));
  887: 
  888: #ifdef RTF_CLONED	/*bsdi, netbsd 1.6*/
  889:   if (flags & RTF_CLONED)
  890:     return;
  891: #endif
  892: #ifdef RTF_WASCLONED	/*freebsd*/
  893:   if (flags & RTF_WASCLONED)
  894:     return;
  895: #endif
  896: 
  897:   if ((rtm->rtm_type == RTM_ADD || rtm->rtm_type == RTM_CHANGE) && ! (flags & RTF_UP))
  898:     return;
  899: 
  900:   /* This is connected route. */
  901:   if (! (flags & RTF_GATEWAY))
  902:       return;
  903: 
  904:   if (flags & RTF_PROTO1)
  905:     SET_FLAG (zebra_flags, ZEBRA_FLAG_SELFROUTE);
  906: 
  907:   /* This is persistent route. */
  908:   if (flags & RTF_STATIC)
  909:     SET_FLAG (zebra_flags, ZEBRA_FLAG_STATIC);
  910: 
  911:   /* This is a reject or blackhole route */
  912:   if (flags & RTF_REJECT)
  913:     SET_FLAG (zebra_flags, ZEBRA_FLAG_REJECT);
  914:   if (flags & RTF_BLACKHOLE)
  915:     SET_FLAG (zebra_flags, ZEBRA_FLAG_BLACKHOLE);
  916: 
  917:   if (dest.sa.sa_family == AF_INET)
  918:     {
  919:       struct prefix_ipv4 p;
  920: 
  921:       p.family = AF_INET;
  922:       p.prefix = dest.sin.sin_addr;
  923:       if (flags & RTF_HOST)
  924: 	p.prefixlen = IPV4_MAX_PREFIXLEN;
  925:       else
  926: 	p.prefixlen = ip_masklen (mask.sin.sin_addr);
  927:       
  928:       /* Catch self originated messages and match them against our current RIB.
  929:        * At the same time, ignore unconfirmed messages, they should be tracked
  930:        * by rtm_write() and kernel_rtm_ipv4().
  931:        */
  932:       if (rtm->rtm_type != RTM_GET && rtm->rtm_pid == pid)
  933:       {
  934:         char buf[PREFIX_STRLEN], gate_buf[INET_ADDRSTRLEN];
  935:         int ret;
  936:         if (! IS_ZEBRA_DEBUG_RIB)
  937:           return;
  938:         ret = rib_lookup_ipv4_route (&p, &gate, VRF_DEFAULT);
  939:         prefix2str (&p, buf, sizeof(buf));
  940:         switch (rtm->rtm_type)
  941:         {
  942:           case RTM_ADD:
  943:           case RTM_GET:
  944:           case RTM_CHANGE:
  945:             /* The kernel notifies us about a new route in FIB created by us.
  946:                Do we have a correspondent entry in our RIB? */
  947:             switch (ret)
  948:             {
  949:               case ZEBRA_RIB_NOTFOUND:
  950:                 zlog_debug ("%s: %s %s: desync: RR isn't yet in RIB, while already in FIB",
  951:                   __func__, lookup (rtm_type_str, rtm->rtm_type), buf);
  952:                 break;
  953:               case ZEBRA_RIB_FOUND_CONNECTED:
  954:               case ZEBRA_RIB_FOUND_NOGATE:
  955:                 inet_ntop (AF_INET, &gate.sin.sin_addr, gate_buf, INET_ADDRSTRLEN);
  956:                 zlog_debug ("%s: %s %s: desync: RR is in RIB, but gate differs (ours is %s)",
  957:                   __func__, lookup (rtm_type_str, rtm->rtm_type), buf, gate_buf);
  958:                 break;
  959:               case ZEBRA_RIB_FOUND_EXACT: /* RIB RR == FIB RR */
  960:                 zlog_debug ("%s: %s %s: done Ok",
  961:                   __func__, lookup (rtm_type_str, rtm->rtm_type), buf);
  962:                 rib_lookup_and_dump (&p);
  963:                 return;
  964:                 break;
  965:             }
  966:             break;
  967:           case RTM_DELETE:
  968:             /* The kernel notifies us about a route deleted by us. Do we still
  969:                have it in the RIB? Do we have anything instead? */
  970:             switch (ret)
  971:             {
  972:               case ZEBRA_RIB_FOUND_EXACT:
  973:                 zlog_debug ("%s: %s %s: desync: RR is still in RIB, while already not in FIB",
  974:                   __func__, lookup (rtm_type_str, rtm->rtm_type), buf);
  975:                 rib_lookup_and_dump (&p);
  976:                 break;
  977:               case ZEBRA_RIB_FOUND_CONNECTED:
  978:               case ZEBRA_RIB_FOUND_NOGATE:
  979:                 zlog_debug ("%s: %s %s: desync: RR is still in RIB, plus gate differs",
  980:                   __func__, lookup (rtm_type_str, rtm->rtm_type), buf);
  981:                 rib_lookup_and_dump (&p);
  982:                 break;
  983:               case ZEBRA_RIB_NOTFOUND: /* RIB RR == FIB RR */
  984:                 zlog_debug ("%s: %s %s: done Ok",
  985:                   __func__, lookup (rtm_type_str, rtm->rtm_type), buf);
  986:                 rib_lookup_and_dump (&p);
  987:                 return;
  988:                 break;
  989:             }
  990:             break;
  991:           default:
  992:             zlog_debug ("%s: %s: warning: loopback RTM of type %s received",
  993:               __func__, buf, lookup (rtm_type_str, rtm->rtm_type));
  994:         }
  995:         return;
  996:       }
  997: 
  998:       /* Change, delete the old prefix, we have no further information
  999:        * to specify the route really
 1000:        */
 1001:       if (rtm->rtm_type == RTM_CHANGE)
 1002:         rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p,
 1003:                          NULL, 0, VRF_DEFAULT, SAFI_UNICAST);
 1004:       
 1005:       if (rtm->rtm_type == RTM_GET 
 1006:           || rtm->rtm_type == RTM_ADD
 1007:           || rtm->rtm_type == RTM_CHANGE)
 1008:         rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, &gate.sin.sin_addr,
 1009:                       NULL, 0, VRF_DEFAULT, 0, 0, 0, 0, SAFI_UNICAST);
 1010:       else
 1011:         rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p,
 1012:                          &gate.sin.sin_addr, 0, VRF_DEFAULT, SAFI_UNICAST);
 1013:     }
 1014: #ifdef HAVE_IPV6
 1015:   if (dest.sa.sa_family == AF_INET6)
 1016:     {
 1017:       /* One day we might have a debug section here like one in the
 1018:        * IPv4 case above. Just ignore own messages at the moment.
 1019:        */
 1020:       if (rtm->rtm_type != RTM_GET && rtm->rtm_pid == pid)
 1021:         return;
 1022:       struct prefix_ipv6 p;
 1023:       ifindex_t ifindex = 0;
 1024: 
 1025:       p.family = AF_INET6;
 1026:       p.prefix = dest.sin6.sin6_addr;
 1027:       if (flags & RTF_HOST)
 1028: 	p.prefixlen = IPV6_MAX_PREFIXLEN;
 1029:       else
 1030: 	p.prefixlen = ip6_masklen (mask.sin6.sin6_addr);
 1031: 
 1032: #ifdef KAME
 1033:       if (IN6_IS_ADDR_LINKLOCAL (&gate.sin6.sin6_addr))
 1034: 	{
 1035: 	  ifindex = IN6_LINKLOCAL_IFINDEX (gate.sin6.sin6_addr);
 1036: 	  SET_IN6_LINKLOCAL_IFINDEX (gate.sin6.sin6_addr, 0);
 1037: 	}
 1038: #endif /* KAME */
 1039: 
 1040:       /* CHANGE: delete the old prefix, we have no further information
 1041:        * to specify the route really
 1042:        */
 1043:       if (rtm->rtm_type == RTM_CHANGE)
 1044:         rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p,
 1045:                          NULL, 0, VRF_DEFAULT, SAFI_UNICAST);
 1046:       
 1047:       if (rtm->rtm_type == RTM_GET 
 1048:           || rtm->rtm_type == RTM_ADD
 1049:           || rtm->rtm_type == RTM_CHANGE)
 1050:         rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, &gate.sin6.sin6_addr,
 1051:                       ifindex, VRF_DEFAULT, RT_TABLE_MAIN, 0, 0, 0, SAFI_UNICAST);
 1052:       else
 1053:         rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p,
 1054:                          &gate.sin6.sin6_addr, ifindex,
 1055:                          VRF_DEFAULT, SAFI_UNICAST);
 1056:     }
 1057: #endif /* HAVE_IPV6 */
 1058: }
 1059: 
 1060: /* Interface function for the kernel routing table updates.  Support
 1061:  * for RTM_CHANGE will be needed.
 1062:  * Exported only for rt_socket.c
 1063:  */
 1064: int
 1065: rtm_write (int message,
 1066: 	   union sockunion *dest,
 1067: 	   union sockunion *mask,
 1068: 	   union sockunion *gate,
 1069: 	   unsigned int index,
 1070: 	   int zebra_flags,
 1071: 	   int metric)
 1072: {
 1073:   int ret;
 1074:   caddr_t pnt;
 1075:   struct interface *ifp;
 1076: 
 1077:   /* Sequencial number of routing message. */
 1078:   static int msg_seq = 0;
 1079: 
 1080:   /* Struct of rt_msghdr and buffer for storing socket's data. */
 1081:   struct 
 1082:   {
 1083:     struct rt_msghdr rtm;
 1084:     char buf[512];
 1085:   } msg;
 1086:   
 1087:   if (routing_sock < 0)
 1088:     return ZEBRA_ERR_EPERM;
 1089: 
 1090:   /* Clear and set rt_msghdr values */
 1091:   memset (&msg, 0, sizeof (struct rt_msghdr));
 1092:   msg.rtm.rtm_version = RTM_VERSION;
 1093:   msg.rtm.rtm_type = message;
 1094:   msg.rtm.rtm_seq = msg_seq++;
 1095:   msg.rtm.rtm_addrs = RTA_DST;
 1096:   msg.rtm.rtm_addrs |= RTA_GATEWAY;
 1097:   msg.rtm.rtm_flags = RTF_UP;
 1098:   msg.rtm.rtm_index = index;
 1099: 
 1100:   if (metric != 0)
 1101:     {
 1102:       msg.rtm.rtm_rmx.rmx_hopcount = metric;
 1103:       msg.rtm.rtm_inits |= RTV_HOPCOUNT;
 1104:     }
 1105: 
 1106:   ifp = if_lookup_by_index (index);
 1107: 
 1108:   if (gate && (message == RTM_ADD || message == RTM_CHANGE))
 1109:     msg.rtm.rtm_flags |= RTF_GATEWAY;
 1110: 
 1111:   /* When RTF_CLONING is unavailable on BSD, should we set some
 1112:    * other flag instead?
 1113:    */
 1114: #ifdef RTF_CLONING
 1115:   if (! gate && (message == RTM_ADD || message == RTM_CHANGE) && ifp &&
 1116:       (ifp->flags & IFF_POINTOPOINT) == 0)
 1117:     msg.rtm.rtm_flags |= RTF_CLONING;
 1118: #endif /* RTF_CLONING */
 1119: 
 1120:   /* If no protocol specific gateway is specified, use link
 1121:      address for gateway. */
 1122:   if (! gate)
 1123:     {
 1124:       if (!ifp)
 1125:         {
 1126:           char dest_buf[INET_ADDRSTRLEN] = "NULL", mask_buf[INET_ADDRSTRLEN] = "255.255.255.255";
 1127:           if (dest)
 1128:             inet_ntop (AF_INET, &dest->sin.sin_addr, dest_buf, INET_ADDRSTRLEN);
 1129:           if (mask)
 1130:             inet_ntop (AF_INET, &mask->sin.sin_addr, mask_buf, INET_ADDRSTRLEN);
 1131:           zlog_warn ("%s: %s/%s: gate == NULL and no gateway found for ifindex %d",
 1132:             __func__, dest_buf, mask_buf, index);
 1133:           return -1;
 1134:         }
 1135:       gate = (union sockunion *) &((struct zebra_if *)ifp->info)->sdl;
 1136:     }
 1137: 
 1138:   if (mask)
 1139:     msg.rtm.rtm_addrs |= RTA_NETMASK;
 1140:   else if (message == RTM_ADD || message == RTM_CHANGE)
 1141:     msg.rtm.rtm_flags |= RTF_HOST;
 1142: 
 1143:   /* Tagging route with flags */
 1144:   msg.rtm.rtm_flags |= (RTF_PROTO1);
 1145: 
 1146:   /* Additional flags. */
 1147:   if (zebra_flags & ZEBRA_FLAG_BLACKHOLE)
 1148:     msg.rtm.rtm_flags |= RTF_BLACKHOLE;
 1149:   if (zebra_flags & ZEBRA_FLAG_REJECT)
 1150:     msg.rtm.rtm_flags |= RTF_REJECT;
 1151: 
 1152: 
 1153: #define SOCKADDRSET(X,R) \
 1154:   if (msg.rtm.rtm_addrs & (R)) \
 1155:     { \
 1156:       int len = SAROUNDUP (X); \
 1157:       memcpy (pnt, (caddr_t)(X), len); \
 1158:       pnt += len; \
 1159:     }
 1160: 
 1161:   pnt = (caddr_t) msg.buf;
 1162: 
 1163:   /* Write each socket data into rtm message buffer */
 1164:   SOCKADDRSET (dest, RTA_DST);
 1165:   SOCKADDRSET (gate, RTA_GATEWAY);
 1166:   SOCKADDRSET (mask, RTA_NETMASK);
 1167: 
 1168:   msg.rtm.rtm_msglen = pnt - (caddr_t) &msg;
 1169: 
 1170:   ret = write (routing_sock, &msg, msg.rtm.rtm_msglen);
 1171: 
 1172:   if (ret != msg.rtm.rtm_msglen) 
 1173:     {
 1174:       if (errno == EEXIST) 
 1175: 	return ZEBRA_ERR_RTEXIST;
 1176:       if (errno == ENETUNREACH)
 1177: 	return ZEBRA_ERR_RTUNREACH;
 1178:       if (errno == ESRCH)
 1179: 	return ZEBRA_ERR_RTNOEXIST;
 1180:       
 1181:       zlog_warn ("%s: write : %s (%d)", __func__, safe_strerror (errno), errno);
 1182:       return ZEBRA_ERR_KERNEL;
 1183:     }
 1184:   return ZEBRA_ERR_NOERROR;
 1185: }
 1186: 
 1187: 
 1188: #include "thread.h"
 1189: #include "zebra/zserv.h"
 1190: 
 1191: /* For debug purpose. */
 1192: static void
 1193: rtmsg_debug (struct rt_msghdr *rtm)
 1194: {
 1195:   zlog_debug ("Kernel: Len: %d Type: %s", rtm->rtm_msglen, lookup (rtm_type_str, rtm->rtm_type));
 1196:   rtm_flag_dump (rtm->rtm_flags);
 1197:   zlog_debug ("Kernel: message seq %d", rtm->rtm_seq);
 1198:   zlog_debug ("Kernel: pid %lld, rtm_addrs 0x%x",
 1199:               (long long)rtm->rtm_pid, rtm->rtm_addrs);
 1200: }
 1201: 
 1202: /* This is pretty gross, better suggestions welcome -- mhandler */
 1203: #ifndef RTAX_MAX
 1204: #ifdef RTA_NUMBITS
 1205: #define RTAX_MAX	RTA_NUMBITS
 1206: #else
 1207: #define RTAX_MAX	8
 1208: #endif /* RTA_NUMBITS */
 1209: #endif /* RTAX_MAX */
 1210: 
 1211: /* Kernel routing table and interface updates via routing socket. */
 1212: static int
 1213: kernel_read (struct thread *thread)
 1214: {
 1215:   int sock;
 1216:   int nbytes;
 1217:   struct rt_msghdr *rtm;
 1218: 
 1219:   /*
 1220:    * This must be big enough for any message the kernel might send.
 1221:    * Rather than determining how many sockaddrs of what size might be
 1222:    * in each particular message, just use RTAX_MAX of sockaddr_storage
 1223:    * for each.  Note that the sockaddrs must be after each message
 1224:    * definition, or rather after whichever happens to be the largest,
 1225:    * since the buffer needs to be big enough for a message and the
 1226:    * sockaddrs together.
 1227:    */
 1228:   union 
 1229:   {
 1230:     /* Routing information. */
 1231:     struct 
 1232:     {
 1233:       struct rt_msghdr rtm;
 1234:       struct sockaddr_storage addr[RTAX_MAX];
 1235:     } r;
 1236: 
 1237:     /* Interface information. */
 1238:     struct
 1239:     {
 1240:       struct if_msghdr ifm;
 1241:       struct sockaddr_storage addr[RTAX_MAX];
 1242:     } im;
 1243: 
 1244:     /* Interface address information. */
 1245:     struct
 1246:     {
 1247:       struct ifa_msghdr ifa;
 1248:       struct sockaddr_storage addr[RTAX_MAX];
 1249:     } ia;
 1250: 
 1251: #ifdef RTM_IFANNOUNCE
 1252:     /* Interface arrival/departure */
 1253:     struct
 1254:     {
 1255:       struct if_announcemsghdr ifan;
 1256:       struct sockaddr_storage addr[RTAX_MAX];
 1257:     } ian;
 1258: #endif /* RTM_IFANNOUNCE */
 1259: 
 1260:   } buf;
 1261: 
 1262:   /* Fetch routing socket. */
 1263:   sock = THREAD_FD (thread);
 1264: 
 1265:   nbytes= read (sock, &buf, sizeof buf);
 1266: 
 1267:   if (nbytes <= 0)
 1268:     {
 1269:       if (nbytes < 0 && errno != EWOULDBLOCK && errno != EAGAIN)
 1270: 	zlog_warn ("routing socket error: %s", safe_strerror (errno));
 1271:       return 0;
 1272:     }
 1273: 
 1274:   thread_add_read (zebrad.master, kernel_read, NULL, sock);
 1275: 
 1276:   if (IS_ZEBRA_DEBUG_KERNEL)
 1277:     rtmsg_debug (&buf.r.rtm);
 1278: 
 1279:   rtm = &buf.r.rtm;
 1280: 
 1281:   /*
 1282:    * Ensure that we didn't drop any data, so that processing routines
 1283:    * can assume they have the whole message.
 1284:    */
 1285:   if (rtm->rtm_msglen != nbytes)
 1286:     {
 1287:       zlog_warn ("kernel_read: rtm->rtm_msglen %d, nbytes %d, type %d\n",
 1288: 		 rtm->rtm_msglen, nbytes, rtm->rtm_type);
 1289:       return -1;
 1290:     }
 1291: 
 1292:   switch (rtm->rtm_type)
 1293:     {
 1294:     case RTM_ADD:
 1295:     case RTM_DELETE:
 1296:     case RTM_CHANGE:
 1297:       rtm_read (rtm);
 1298:       break;
 1299:     case RTM_IFINFO:
 1300:       ifm_read (&buf.im.ifm);
 1301:       break;
 1302:     case RTM_NEWADDR:
 1303:     case RTM_DELADDR:
 1304:       ifam_read (&buf.ia.ifa);
 1305:       break;
 1306: #ifdef RTM_IFANNOUNCE
 1307:     case RTM_IFANNOUNCE:
 1308:       ifan_read (&buf.ian.ifan);
 1309:       break;
 1310: #endif /* RTM_IFANNOUNCE */
 1311:     default:
 1312:       if (IS_ZEBRA_DEBUG_KERNEL)
 1313:         zlog_debug("Unprocessed RTM_type: %d", rtm->rtm_type);
 1314:       break;
 1315:     }
 1316:   return 0;
 1317: }
 1318: 
 1319: /* Make routing socket. */
 1320: static void
 1321: routing_socket (struct zebra_vrf *zvrf)
 1322: {
 1323:   if (zvrf->vrf_id != VRF_DEFAULT)
 1324:     return;
 1325: 
 1326:   if ( zserv_privs.change (ZPRIVS_RAISE) )
 1327:     zlog_err ("routing_socket: Can't raise privileges");
 1328: 
 1329:   routing_sock = socket (AF_ROUTE, SOCK_RAW, 0);
 1330: 
 1331:   if (routing_sock < 0) 
 1332:     {
 1333:       if ( zserv_privs.change (ZPRIVS_LOWER) )
 1334:         zlog_err ("routing_socket: Can't lower privileges");
 1335:       zlog_warn ("Can't init kernel routing socket");
 1336:       return;
 1337:     }
 1338: 
 1339:   /* XXX: Socket should be NONBLOCK, however as we currently 
 1340:    * discard failed writes, this will lead to inconsistencies.
 1341:    * For now, socket must be blocking.
 1342:    */
 1343:   /*if (fcntl (routing_sock, F_SETFL, O_NONBLOCK) < 0) 
 1344:     zlog_warn ("Can't set O_NONBLOCK to routing socket");*/
 1345:     
 1346:   if ( zserv_privs.change (ZPRIVS_LOWER) )
 1347:     zlog_err ("routing_socket: Can't lower privileges");
 1348: 
 1349:   /* kernel_read needs rewrite. */
 1350:   thread_add_read (zebrad.master, kernel_read, NULL, routing_sock);
 1351: }
 1352: 
 1353: /* Exported interface function.  This function simply calls
 1354:    routing_socket (). */
 1355: void
 1356: kernel_init (struct zebra_vrf *zvrf)
 1357: {
 1358:   routing_socket (zvrf);
 1359: }
 1360: 
 1361: void
 1362: kernel_terminate (struct zebra_vrf *zvrf)
 1363: {
 1364:   return;
 1365: }

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