Diff for /embedaddon/quagga/zebra/kernel_socket.c between versions 1.1.1.3 and 1.1.1.4

version 1.1.1.3, 2013/07/21 23:54:41 version 1.1.1.4, 2016/11/02 10:09:10
Line 20 Line 20
  */   */
   
 #include <zebra.h>  #include <zebra.h>
   #include <net/if_types.h>
   
 #include "if.h"  #include "if.h"
 #include "prefix.h"  #include "prefix.h"
Line 32 Line 33
 #include "table.h"  #include "table.h"
 #include "rib.h"  #include "rib.h"
 #include "privs.h"  #include "privs.h"
   #include "vrf.h"
   
 #include "zebra/interface.h"  #include "zebra/interface.h"
 #include "zebra/zserv.h"  #include "zebra/zserv.h"
 #include "zebra/debug.h"  #include "zebra/debug.h"
 #include "zebra/kernel_socket.h"  #include "zebra/kernel_socket.h"
   #include "zebra/rib.h"
   
 extern struct zebra_privs_t zserv_privs;  extern struct zebra_privs_t zserv_privs;
 extern struct zebra_t zebrad;  extern struct zebra_t zebrad;
   
 /*  /*
 * Given a sockaddr length, round it up to include pad bytes following * Historically, the BSD routing socket has aligned data following a
 * it.  Assumes the kernel pads to sizeof(long). * struct sockaddr to sizeof(long), which was 4 bytes on some
  * platforms, and 8 bytes on others.  NetBSD 6 changed the routing
  * socket to align to sizeof(uint64_t), which is 8 bytes.  OS X
  * appears to align to sizeof(int), which is 4 bytes.
  *   *
 * XXX: why is ROUNDUP(0) sizeof(long)?  0 is an illegal sockaddr * Alignment of zero-sized sockaddrs is nonsensical, but historically
 * length anyway (< sizeof (struct sockaddr)), so this shouldn't * BSD defines RT_ROUNDUP(0) to be the alignment interval (rather than
 * matter. * 0).  We follow this practice without questioning it, but it is a
 * On OS X, both 32, 64bit syatems align on 4 byte boundary * bug if quagga calls ROUNDUP with 0.
  */   */
   
   /*
    * Because of these varying conventions, the only sane approach is for
    * the <net/route.h> header to define some flavor of ROUNDUP macro.
    */
   
   #if defined(SA_SIZE)
   /* SAROUNDUP is the only thing we need, and SA_SIZE provides that */
   #define SAROUNDUP(a)    SA_SIZE(a)
   #else /* !SA_SIZE */
   
   #if defined(RT_ROUNDUP)
   #define ROUNDUP(a)      RT_ROUNDUP(a)
   #endif /* defined(RT_ROUNDUP) */
   
   #if defined(SUNOS_5)
   /* Solaris has struct sockaddr_in[6] definitions at 16 / 32 bytes size,
    * so the whole concept doesn't really apply. */
   #define ROUNDUP(a)      (a)
   #endif
   
   /*
    * If ROUNDUP has not yet been defined in terms of platform-provided
    * defines, attempt to cope with heuristics.
    */
   #if !defined(ROUNDUP)
   
   /*
    * It's a bug for a platform not to define rounding/alignment for
    * sockaddrs on the routing socket.  This warning really is
    * intentional, to provoke filing bug reports with operating systems
    * that don't define RT_ROUNDUP or equivalent.
    */
   #warning "net/route.h does not define RT_ROUNDUP; making unwarranted assumptions!"
   
   /* OS X (Xcode as of 2014-12) is known not to define RT_ROUNDUP */
 #ifdef __APPLE__  #ifdef __APPLE__
#define ROUNDUP(a) \#define ROUNDUP_TYPE   int
  ((a) > 0 ? (1 + (((a) - 1) | (sizeof(int) - 1))) : sizeof(int)) 
 #else  #else
#define ROUNDUP(a) \#define ROUNDUP_TYPE        long
  ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) 
 #endif  #endif
   
   #define ROUNDUP(a) \
     ((a) > 0 ? (1 + (((a) - 1) | (sizeof(ROUNDUP_TYPE) - 1))) : sizeof(ROUNDUP_TYPE))
   
   #endif /* defined(ROUNDUP) */
   
 /*  /*
  * Given a pointer (sockaddr or void *), return the number of bytes   * Given a pointer (sockaddr or void *), return the number of bytes
  * taken up by the sockaddr and any padding needed for alignment.   * taken up by the sockaddr and any padding needed for alignment.
Line 84  extern struct zebra_t zebrad; Line 129  extern struct zebra_t zebrad;
            ROUNDUP(sizeof(struct sockaddr_dl)) : sizeof(struct sockaddr)))             ROUNDUP(sizeof(struct sockaddr_dl)) : sizeof(struct sockaddr)))
 #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */  #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
   
   #endif /* !SA_SIZE */
   
 /*  /*
  * We use a call to an inline function to copy (PNT) to (DEST)   * We use a call to an inline function to copy (PNT) to (DEST)
  * 1. Calculating the length of the copy requires an #ifdef to determine   * 1. Calculating the length of the copy requires an #ifdef to determine
Line 91  extern struct zebra_t zebrad; Line 138  extern struct zebra_t zebrad;
  * 2. So the compiler doesn't complain when DEST is NULL, which is only true   * 2. So the compiler doesn't complain when DEST is NULL, which is only true
  *    when we are skipping the copy and incrementing to the next SA   *    when we are skipping the copy and incrementing to the next SA
  */   */
static void inlinestatic inline void
 rta_copy (union sockunion *dest, caddr_t src) {  rta_copy (union sockunion *dest, caddr_t src) {
   int len;    int len;
     if (!dest)
       return;
 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN  #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
   len = (((struct sockaddr *)src)->sa_len > sizeof (*dest)) ?    len = (((struct sockaddr *)src)->sa_len > sizeof (*dest)) ?
             sizeof (*dest) : ((struct sockaddr *)src)->sa_len ;              sizeof (*dest) : ((struct sockaddr *)src)->sa_len ;
Line 108  rta_copy (union sockunion *dest, caddr_t src) { Line 157  rta_copy (union sockunion *dest, caddr_t src) {
   if ((RTMADDRS) & (RTA)) \    if ((RTMADDRS) & (RTA)) \
     { \      { \
       int len = SAROUNDUP ((PNT)); \        int len = SAROUNDUP ((PNT)); \
      if ( ((DEST) != NULL) && \      if (af_check (((struct sockaddr *)(PNT))->sa_family)) \
           af_check (((struct sockaddr *)(PNT))->sa_family)) \ 
         rta_copy((DEST), (PNT)); \          rta_copy((DEST), (PNT)); \
       (PNT) += len; \        (PNT) += len; \
     }      }
Line 117  rta_copy (union sockunion *dest, caddr_t src) { Line 165  rta_copy (union sockunion *dest, caddr_t src) {
   if ((RTMADDRS) & (RTA)) \    if ((RTMADDRS) & (RTA)) \
     { \      { \
       int len = SAROUNDUP ((PNT)); \        int len = SAROUNDUP ((PNT)); \
      if ((DEST) != NULL) \      rta_copy((DEST), (PNT)); \
        rta_copy((DEST), (PNT)); \ 
       (PNT) += len; \        (PNT) += len; \
     }      }
   
Line 196  static const struct message rtm_flag_str[] = Line 243  static const struct message rtm_flag_str[] =
   {RTF_CLONING,   "CLONING"},    {RTF_CLONING,   "CLONING"},
 #endif /* RTF_CLONING */  #endif /* RTF_CLONING */
   {RTF_XRESOLVE,  "XRESOLVE"},    {RTF_XRESOLVE,  "XRESOLVE"},
   #ifdef RTF_LLINFO
   {RTF_LLINFO,    "LLINFO"},    {RTF_LLINFO,    "LLINFO"},
   #endif /* RTF_LLINFO */
   {RTF_STATIC,    "STATIC"},    {RTF_STATIC,    "STATIC"},
   {RTF_BLACKHOLE, "BLACKHOLE"},    {RTF_BLACKHOLE, "BLACKHOLE"},
 #ifdef RTF_PRIVATE  #ifdef RTF_PRIVATE
Line 241  int routing_sock = -1; Line 290  int routing_sock = -1;
 /* #define DEBUG */  /* #define DEBUG */
   
 /* Supported address family check. */  /* Supported address family check. */
static int inlinestatic inline int
 af_check (int family)  af_check (int family)
 {  {
   if (family == AF_INET)    if (family == AF_INET)
Line 252  af_check (int family) Line 301  af_check (int family)
 #endif /* HAVE_IPV6 */  #endif /* HAVE_IPV6 */
   return 0;    return 0;
 }  }
 /* Dump routing table flag for debug purpose. */  /* Dump routing table flag for debug purpose. */
 static void  static void
 rtm_flag_dump (int flag)  rtm_flag_dump (int flag)
Line 299  ifan_read (struct if_announcemsghdr *ifan) Line 348  ifan_read (struct if_announcemsghdr *ifan)
                                        sizeof(ifan->ifan_name)));                                         sizeof(ifan->ifan_name)));
       ifp->ifindex = ifan->ifan_index;        ifp->ifindex = ifan->ifan_index;
   
         if_get_metric (ifp);
       if_add_update (ifp);        if_add_update (ifp);
     }      }
   else if (ifp != NULL && ifan->ifan_what == IFAN_DEPARTURE)    else if (ifp != NULL && ifan->ifan_what == IFAN_DEPARTURE)
Line 329  bsd_linkdetect_translate (struct if_msghdr *ifm) Line 379  bsd_linkdetect_translate (struct if_msghdr *ifm)
 }  }
 #endif /* HAVE_BSD_IFI_LINK_STATE */  #endif /* HAVE_BSD_IFI_LINK_STATE */
   
   static enum zebra_link_type
   sdl_to_zebra_link_type (unsigned int sdlt)
   {
     switch (sdlt)
     {
       case IFT_ETHER: return ZEBRA_LLT_ETHER;
       case IFT_X25: return ZEBRA_LLT_X25;
       case IFT_FDDI: return ZEBRA_LLT_FDDI;
       case IFT_PPP: return ZEBRA_LLT_PPP;
       case IFT_LOOP: return ZEBRA_LLT_LOOPBACK;
       case IFT_SLIP: return ZEBRA_LLT_SLIP;
       case IFT_ARCNET: return ZEBRA_LLT_ARCNET;
       case IFT_ATM: return ZEBRA_LLT_ATM;
       case IFT_LOCALTALK: return ZEBRA_LLT_LOCALTLK;
       case IFT_HIPPI: return ZEBRA_LLT_HIPPI;
   #ifdef IFT_IEEE1394
       case IFT_IEEE1394: return ZEBRA_LLT_IEEE1394;
   #endif
   
       default: return ZEBRA_LLT_UNKNOWN;
     }
   }
   
 /*  /*
  * Handle struct if_msghdr obtained from reading routing socket or   * Handle struct if_msghdr obtained from reading routing socket or
  * sysctl (from interface_list).  There may or may not be sockaddrs   * sysctl (from interface_list).  There may or may not be sockaddrs
Line 485  ifm_read (struct if_msghdr *ifm) Line 558  ifm_read (struct if_msghdr *ifm)
        *    is fine here.         *    is fine here.
        * a nonzero ifnlen from RTA_NAME_GET() means sdl is valid         * a nonzero ifnlen from RTA_NAME_GET() means sdl is valid
        */         */
         ifp->ll_type = ZEBRA_LLT_UNKNOWN;
         ifp->hw_addr_len = 0;
       if (ifnlen)        if (ifnlen)
      {        {
 #ifdef HAVE_STRUCT_SOCKADDR_DL_SDL_LEN  #ifdef HAVE_STRUCT_SOCKADDR_DL_SDL_LEN
        memcpy (&ifp->sdl, sdl, sdl->sdl_len);          memcpy (&((struct zebra_if *)ifp->info)->sdl, sdl, sdl->sdl_len);
 #else  #else
        memcpy (&ifp->sdl, sdl, sizeof (struct sockaddr_dl));          memcpy (&((struct zebra_if *)ifp->info)->sdl, sdl, sizeof (struct sockaddr_dl));
 #endif /* HAVE_STRUCT_SOCKADDR_DL_SDL_LEN */  #endif /* HAVE_STRUCT_SOCKADDR_DL_SDL_LEN */
       }  
   
             ifp->ll_type = sdl_to_zebra_link_type (sdl->sdl_type);
             if (sdl->sdl_alen <= sizeof(ifp->hw_addr))
               {
                 memcpy (ifp->hw_addr, LLADDR(sdl), sdl->sdl_alen);
                 ifp->hw_addr_len = sdl->sdl_alen;
               }
           }
   
       if_add_update (ifp);        if_add_update (ifp);
     }      }
   else    else
Line 556  ifm_read (struct if_msghdr *ifm) Line 638  ifm_read (struct if_msghdr *ifm)
   
   return 0;    return 0;
 }  }
 /* Address read from struct ifa_msghdr. */  /* Address read from struct ifa_msghdr. */
 static void  static void
 ifam_read_mesg (struct ifa_msghdr *ifm,  ifam_read_mesg (struct ifa_msghdr *ifm,
Line 592  ifam_read_mesg (struct ifa_msghdr *ifm, Line 674  ifam_read_mesg (struct ifa_msghdr *ifm,
   
   if (IS_ZEBRA_DEBUG_KERNEL)    if (IS_ZEBRA_DEBUG_KERNEL)
     {      {
      switch (sockunion_family(addr))      int family = sockunion_family(addr);
       switch (family)
         {          {
         case AF_INET:          case AF_INET:
           {  
             char buf[4][INET_ADDRSTRLEN];  
             zlog_debug ("%s: ifindex %d, ifname %s, ifam_addrs 0x%x, "  
                         "ifam_flags 0x%x, addr %s/%d broad %s dst %s "  
                         "gateway %s",  
                         __func__, ifm->ifam_index,  
                         (ifnlen ? ifname : "(nil)"), ifm->ifam_addrs,  
                         ifm->ifam_flags,  
                         inet_ntop(AF_INET,&addr->sin.sin_addr,  
                                   buf[0],sizeof(buf[0])),  
                         ip_masklen(mask->sin.sin_addr),  
                         inet_ntop(AF_INET,&brd->sin.sin_addr,  
                                   buf[1],sizeof(buf[1])),  
                         inet_ntop(AF_INET,&dst.sin.sin_addr,  
                                   buf[2],sizeof(buf[2])),  
                         inet_ntop(AF_INET,&gateway.sin.sin_addr,  
                                   buf[3],sizeof(buf[3])));  
           }  
           break;  
 #ifdef HAVE_IPV6  #ifdef HAVE_IPV6
         case AF_INET6:          case AF_INET6:
   #endif
           {            {
             char buf[4][INET6_ADDRSTRLEN];              char buf[4][INET6_ADDRSTRLEN];
             zlog_debug ("%s: ifindex %d, ifname %s, ifam_addrs 0x%x, "              zlog_debug ("%s: ifindex %d, ifname %s, ifam_addrs 0x%x, "
                         "ifam_flags 0x%x, addr %s/%d broad %s dst %s "                          "ifam_flags 0x%x, addr %s/%d broad %s dst %s "
                         "gateway %s",                          "gateway %s",
                        __func__, ifm->ifam_index,                         __func__, ifm->ifam_index,
                         (ifnlen ? ifname : "(nil)"), ifm->ifam_addrs,                          (ifnlen ? ifname : "(nil)"), ifm->ifam_addrs,
                         ifm->ifam_flags,                          ifm->ifam_flags,
                        inet_ntop(AF_INET6,&addr->sin6.sin6_addr,                        inet_ntop(family,&addr->sin.sin_addr,
                                   buf[0],sizeof(buf[0])),                                    buf[0],sizeof(buf[0])),
                        ip6_masklen(mask->sin6.sin6_addr),                        ip_masklen(mask->sin.sin_addr),
                        inet_ntop(AF_INET6,&brd->sin6.sin6_addr,                        inet_ntop(family,&brd->sin.sin_addr,
                                   buf[1],sizeof(buf[1])),                                    buf[1],sizeof(buf[1])),
                        inet_ntop(AF_INET6,&dst.sin6.sin6_addr,                        inet_ntop(family,&dst.sin.sin_addr,
                                   buf[2],sizeof(buf[2])),                                    buf[2],sizeof(buf[2])),
                        inet_ntop(AF_INET6,&gateway.sin6.sin6_addr,                        inet_ntop(family,&gateway.sin.sin_addr,
                                   buf[3],sizeof(buf[3])));                                    buf[3],sizeof(buf[3])));
           }            }
           break;            break;
 #endif /* HAVE_IPV6 */  
         default:          default:
           zlog_debug ("%s: ifindex %d, ifname %s, ifam_addrs 0x%x",            zlog_debug ("%s: ifindex %d, ifname %s, ifam_addrs 0x%x",
                       __func__, ifm->ifam_index,                         __func__, ifm->ifam_index, 
Line 709  ifam_read (struct ifa_msghdr *ifam) Line 773  ifam_read (struct ifa_msghdr *ifam)
       /* Unset interface index from link-local address when IPv6 stack        /* Unset interface index from link-local address when IPv6 stack
          is KAME. */           is KAME. */
       if (IN6_IS_ADDR_LINKLOCAL (&addr.sin6.sin6_addr))        if (IN6_IS_ADDR_LINKLOCAL (&addr.sin6.sin6_addr))
        SET_IN6_LINKLOCAL_IFINDEX (addr.sin6.sin6_addr, 0);        {
           SET_IN6_LINKLOCAL_IFINDEX (addr.sin6.sin6_addr, 0);
         }
   
       if (ifam->ifam_type == RTM_NEWADDR)        if (ifam->ifam_type == RTM_NEWADDR)
         connected_add_ipv6 (ifp, flags, &addr.sin6.sin6_addr,           connected_add_ipv6 (ifp, flags, &addr.sin6.sin6_addr, 
Line 750  ifam_read (struct ifa_msghdr *ifam) Line 816  ifam_read (struct ifa_msghdr *ifam)
       
   return 0;    return 0;
 }  }
 /* Interface function for reading kernel routing table information. */  /* Interface function for reading kernel routing table information. */
 static int  static int
 rtm_read_mesg (struct rt_msghdr *rtm,  rtm_read_mesg (struct rt_msghdr *rtm,
Line 828  rtm_read (struct rt_msghdr *rtm) Line 894  rtm_read (struct rt_msghdr *rtm)
     return;      return;
 #endif  #endif
   
  if ((rtm->rtm_type == RTM_ADD) && ! (flags & RTF_UP))  if ((rtm->rtm_type == RTM_ADD || rtm->rtm_type == RTM_CHANGE) && ! (flags & RTF_UP))
     return;      return;
   
   /* This is connected route. */    /* This is connected route. */
Line 865  rtm_read (struct rt_msghdr *rtm) Line 931  rtm_read (struct rt_msghdr *rtm)
        */         */
       if (rtm->rtm_type != RTM_GET && rtm->rtm_pid == pid)        if (rtm->rtm_type != RTM_GET && rtm->rtm_pid == pid)
       {        {
        char buf[INET_ADDRSTRLEN], gate_buf[INET_ADDRSTRLEN];        char buf[PREFIX_STRLEN], gate_buf[INET_ADDRSTRLEN];
         int ret;          int ret;
         if (! IS_ZEBRA_DEBUG_RIB)          if (! IS_ZEBRA_DEBUG_RIB)
           return;            return;
        ret = rib_lookup_ipv4_route (&p, &gate);         ret = rib_lookup_ipv4_route (&p, &gate, VRF_DEFAULT);
        inet_ntop (AF_INET, &p.prefix, buf, INET_ADDRSTRLEN);        prefix2str (&p, buf, sizeof(buf));
         switch (rtm->rtm_type)          switch (rtm->rtm_type)
         {          {
           case RTM_ADD:            case RTM_ADD:
Line 881  rtm_read (struct rt_msghdr *rtm) Line 947  rtm_read (struct rt_msghdr *rtm)
             switch (ret)              switch (ret)
             {              {
               case ZEBRA_RIB_NOTFOUND:                case ZEBRA_RIB_NOTFOUND:
                zlog_debug ("%s: %s %s/%d: desync: RR isn't yet in RIB, while already in FIB",                zlog_debug ("%s: %s %s: desync: RR isn't yet in RIB, while already in FIB",
                  __func__, lookup (rtm_type_str, rtm->rtm_type), buf, p.prefixlen);                  __func__, lookup (rtm_type_str, rtm->rtm_type), buf);
                 break;                  break;
               case ZEBRA_RIB_FOUND_CONNECTED:                case ZEBRA_RIB_FOUND_CONNECTED:
               case ZEBRA_RIB_FOUND_NOGATE:                case ZEBRA_RIB_FOUND_NOGATE:
                 inet_ntop (AF_INET, &gate.sin.sin_addr, gate_buf, INET_ADDRSTRLEN);                  inet_ntop (AF_INET, &gate.sin.sin_addr, gate_buf, INET_ADDRSTRLEN);
                zlog_debug ("%s: %s %s/%d: desync: RR is in RIB, but gate differs (ours is %s)",                zlog_debug ("%s: %s %s: desync: RR is in RIB, but gate differs (ours is %s)",
                  __func__, lookup (rtm_type_str, rtm->rtm_type), buf, p.prefixlen, gate_buf);                  __func__, lookup (rtm_type_str, rtm->rtm_type), buf, gate_buf);
                 break;                  break;
               case ZEBRA_RIB_FOUND_EXACT: /* RIB RR == FIB RR */                case ZEBRA_RIB_FOUND_EXACT: /* RIB RR == FIB RR */
                zlog_debug ("%s: %s %s/%d: done Ok",                zlog_debug ("%s: %s %s: done Ok",
                  __func__, lookup (rtm_type_str, rtm->rtm_type), buf, p.prefixlen);                  __func__, lookup (rtm_type_str, rtm->rtm_type), buf);
                 rib_lookup_and_dump (&p);                  rib_lookup_and_dump (&p);
                 return;                  return;
                 break;                  break;
Line 904  rtm_read (struct rt_msghdr *rtm) Line 970  rtm_read (struct rt_msghdr *rtm)
             switch (ret)              switch (ret)
             {              {
               case ZEBRA_RIB_FOUND_EXACT:                case ZEBRA_RIB_FOUND_EXACT:
                zlog_debug ("%s: %s %s/%d: desync: RR is still in RIB, while already not in FIB",                zlog_debug ("%s: %s %s: desync: RR is still in RIB, while already not in FIB",
                  __func__, lookup (rtm_type_str, rtm->rtm_type), buf, p.prefixlen);                  __func__, lookup (rtm_type_str, rtm->rtm_type), buf);
                 rib_lookup_and_dump (&p);                  rib_lookup_and_dump (&p);
                 break;                  break;
               case ZEBRA_RIB_FOUND_CONNECTED:                case ZEBRA_RIB_FOUND_CONNECTED:
               case ZEBRA_RIB_FOUND_NOGATE:                case ZEBRA_RIB_FOUND_NOGATE:
                zlog_debug ("%s: %s %s/%d: desync: RR is still in RIB, plus gate differs",                zlog_debug ("%s: %s %s: desync: RR is still in RIB, plus gate differs",
                  __func__, lookup (rtm_type_str, rtm->rtm_type), buf, p.prefixlen);                  __func__, lookup (rtm_type_str, rtm->rtm_type), buf);
                 rib_lookup_and_dump (&p);                  rib_lookup_and_dump (&p);
                 break;                  break;
               case ZEBRA_RIB_NOTFOUND: /* RIB RR == FIB RR */                case ZEBRA_RIB_NOTFOUND: /* RIB RR == FIB RR */
                zlog_debug ("%s: %s %s/%d: done Ok",                zlog_debug ("%s: %s %s: done Ok",
                  __func__, lookup (rtm_type_str, rtm->rtm_type), buf, p.prefixlen);                  __func__, lookup (rtm_type_str, rtm->rtm_type), buf);
                 rib_lookup_and_dump (&p);                  rib_lookup_and_dump (&p);
                 return;                  return;
                 break;                  break;
             }              }
             break;              break;
           default:            default:
            zlog_debug ("%s: %s/%d: warning: loopback RTM of type %s received",            zlog_debug ("%s: %s: warning: loopback RTM of type %s received",
              __func__, buf, p.prefixlen, lookup (rtm_type_str, rtm->rtm_type));              __func__, buf, lookup (rtm_type_str, rtm->rtm_type));
         }          }
         return;          return;
       }        }
Line 934  rtm_read (struct rt_msghdr *rtm) Line 1000  rtm_read (struct rt_msghdr *rtm)
        */         */
       if (rtm->rtm_type == RTM_CHANGE)        if (rtm->rtm_type == RTM_CHANGE)
         rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p,          rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p,
                         NULL, 0, 0, SAFI_UNICAST);                         NULL, 0, VRF_DEFAULT, SAFI_UNICAST);
               
       if (rtm->rtm_type == RTM_GET         if (rtm->rtm_type == RTM_GET 
           || rtm->rtm_type == RTM_ADD            || rtm->rtm_type == RTM_ADD
           || rtm->rtm_type == RTM_CHANGE)            || rtm->rtm_type == RTM_CHANGE)
        rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags,         rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, &gate.sin.sin_addr,
                      &p, &gate.sin.sin_addr, NULL, 0, 0, 0, 0, SAFI_UNICAST);                      NULL, 0, VRF_DEFAULT, 0, 0, 0, 0, SAFI_UNICAST);
       else        else
        rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags,         rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p,
                      &p, &gate.sin.sin_addr, 0, 0, SAFI_UNICAST);                         &gate.sin.sin_addr, 0, VRF_DEFAULT, SAFI_UNICAST);
     }      }
 #ifdef HAVE_IPV6  #ifdef HAVE_IPV6
   if (dest.sa.sa_family == AF_INET6)    if (dest.sa.sa_family == AF_INET6)
Line 954  rtm_read (struct rt_msghdr *rtm) Line 1020  rtm_read (struct rt_msghdr *rtm)
       if (rtm->rtm_type != RTM_GET && rtm->rtm_pid == pid)        if (rtm->rtm_type != RTM_GET && rtm->rtm_pid == pid)
         return;          return;
       struct prefix_ipv6 p;        struct prefix_ipv6 p;
      unsigned int ifindex = 0;      ifindex_t ifindex = 0;
   
       p.family = AF_INET6;        p.family = AF_INET6;
       p.prefix = dest.sin6.sin6_addr;        p.prefix = dest.sin6.sin6_addr;
Line 976  rtm_read (struct rt_msghdr *rtm) Line 1042  rtm_read (struct rt_msghdr *rtm)
        */         */
       if (rtm->rtm_type == RTM_CHANGE)        if (rtm->rtm_type == RTM_CHANGE)
         rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p,          rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p,
                         NULL, 0, 0, SAFI_UNICAST);                         NULL, 0, VRF_DEFAULT, SAFI_UNICAST);
               
       if (rtm->rtm_type == RTM_GET         if (rtm->rtm_type == RTM_GET 
           || rtm->rtm_type == RTM_ADD            || rtm->rtm_type == RTM_ADD
           || rtm->rtm_type == RTM_CHANGE)            || rtm->rtm_type == RTM_CHANGE)
        rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags,        rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, &gate.sin6.sin6_addr,
                      &p, &gate.sin6.sin6_addr, ifindex, 0, 0, 0, SAFI_UNICAST);                      ifindex, VRF_DEFAULT, RT_TABLE_MAIN, 0, 0, 0, SAFI_UNICAST);
       else        else
        rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags,        rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p,
                         &p, &gate.sin6.sin6_addr, ifindex, 0, SAFI_UNICAST);                         &gate.sin6.sin6_addr, ifindex,
                          VRF_DEFAULT, SAFI_UNICAST);
     }      }
 #endif /* HAVE_IPV6 */  #endif /* HAVE_IPV6 */
 }  }
Line 1038  rtm_write (int message, Line 1105  rtm_write (int message,
   
   ifp = if_lookup_by_index (index);    ifp = if_lookup_by_index (index);
   
  if (gate && message == RTM_ADD)  if (gate && (message == RTM_ADD || message == RTM_CHANGE))
     msg.rtm.rtm_flags |= RTF_GATEWAY;      msg.rtm.rtm_flags |= RTF_GATEWAY;
   
   /* When RTF_CLONING is unavailable on BSD, should we set some    /* When RTF_CLONING is unavailable on BSD, should we set some
    * other flag instead?     * other flag instead?
    */     */
 #ifdef RTF_CLONING  #ifdef RTF_CLONING
  if (! gate && message == RTM_ADD && ifp &&  if (! gate && (message == RTM_ADD || message == RTM_CHANGE) && ifp &&
       (ifp->flags & IFF_POINTOPOINT) == 0)        (ifp->flags & IFF_POINTOPOINT) == 0)
     msg.rtm.rtm_flags |= RTF_CLONING;      msg.rtm.rtm_flags |= RTF_CLONING;
 #endif /* RTF_CLONING */  #endif /* RTF_CLONING */
Line 1065  rtm_write (int message, Line 1132  rtm_write (int message,
             __func__, dest_buf, mask_buf, index);              __func__, dest_buf, mask_buf, index);
           return -1;            return -1;
         }          }
      gate = (union sockunion *) & ifp->sdl;      gate = (union sockunion *) &((struct zebra_if *)ifp->info)->sdl;
     }      }
   
   if (mask)    if (mask)
     msg.rtm.rtm_addrs |= RTA_NETMASK;      msg.rtm.rtm_addrs |= RTA_NETMASK;
  else if (message == RTM_ADD  else if (message == RTM_ADD || message == RTM_CHANGE)
     msg.rtm.rtm_flags |= RTF_HOST;      msg.rtm.rtm_flags |= RTF_HOST;
   
   /* Tagging route with flags */    /* Tagging route with flags */
Line 1083  rtm_write (int message, Line 1150  rtm_write (int message,
     msg.rtm.rtm_flags |= RTF_REJECT;      msg.rtm.rtm_flags |= RTF_REJECT;
   
   
 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN  
 #define SOCKADDRSET(X,R) \  #define SOCKADDRSET(X,R) \
   if (msg.rtm.rtm_addrs & (R)) \    if (msg.rtm.rtm_addrs & (R)) \
     { \      { \
       int len = ROUNDUP ((X)->sa.sa_len); \  
       memcpy (pnt, (caddr_t)(X), len); \  
       pnt += len; \  
     }  
 #else   
 #define SOCKADDRSET(X,R) \  
   if (msg.rtm.rtm_addrs & (R)) \  
     { \  
       int len = SAROUNDUP (X); \        int len = SAROUNDUP (X); \
       memcpy (pnt, (caddr_t)(X), len); \        memcpy (pnt, (caddr_t)(X), len); \
       pnt += len; \        pnt += len; \
     }      }
 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */  
   
   pnt = (caddr_t) msg.buf;    pnt = (caddr_t) msg.buf;
   
Line 1127  rtm_write (int message, Line 1184  rtm_write (int message,
   return ZEBRA_ERR_NOERROR;    return ZEBRA_ERR_NOERROR;
 }  }
   
 #include "thread.h"  #include "thread.h"
 #include "zebra/zserv.h"  #include "zebra/zserv.h"
   
Line 1138  rtmsg_debug (struct rt_msghdr *rtm) Line 1195  rtmsg_debug (struct rt_msghdr *rtm)
   zlog_debug ("Kernel: Len: %d Type: %s", rtm->rtm_msglen, lookup (rtm_type_str, rtm->rtm_type));    zlog_debug ("Kernel: Len: %d Type: %s", rtm->rtm_msglen, lookup (rtm_type_str, rtm->rtm_type));
   rtm_flag_dump (rtm->rtm_flags);    rtm_flag_dump (rtm->rtm_flags);
   zlog_debug ("Kernel: message seq %d", rtm->rtm_seq);    zlog_debug ("Kernel: message seq %d", rtm->rtm_seq);
  zlog_debug ("Kernel: pid %d, rtm_addrs 0x%x", rtm->rtm_pid, rtm->rtm_addrs);  zlog_debug ("Kernel: pid %lld, rtm_addrs 0x%x",
               (long long)rtm->rtm_pid, rtm->rtm_addrs);
 }  }
   
 /* This is pretty gross, better suggestions welcome -- mhandler */  /* This is pretty gross, better suggestions welcome -- mhandler */
Line 1260  kernel_read (struct thread *thread) Line 1318  kernel_read (struct thread *thread)
   
 /* Make routing socket. */  /* Make routing socket. */
 static void  static void
routing_socket (void)routing_socket (struct zebra_vrf *zvrf)
 {  {
     if (zvrf->vrf_id != VRF_DEFAULT)
       return;
   
   if ( zserv_privs.change (ZPRIVS_RAISE) )    if ( zserv_privs.change (ZPRIVS_RAISE) )
     zlog_err ("routing_socket: Can't raise privileges");      zlog_err ("routing_socket: Can't raise privileges");
   
Line 1292  routing_socket (void) Line 1353  routing_socket (void)
 /* Exported interface function.  This function simply calls  /* Exported interface function.  This function simply calls
    routing_socket (). */     routing_socket (). */
 void  void
kernel_init (void)kernel_init (struct zebra_vrf *zvrf)
 {  {
  routing_socket ();  routing_socket (zvrf);
 }
 
 void
 kernel_terminate (struct zebra_vrf *zvrf)
 {
   return;
 }  }

Removed from v.1.1.1.3  
changed lines
  Added in v.1.1.1.4


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