Diff for /embedaddon/quagga/zebra/rt_socket.c between versions 1.1.1.1 and 1.1.1.2

version 1.1.1.1, 2012/02/21 17:26:11 version 1.1.1.2, 2016/11/02 10:09:10
Line 41  extern int rtm_write (int message, union sockunion *de Line 41  extern int rtm_write (int message, union sockunion *de
                       union sockunion *mask, union sockunion *gate,                        union sockunion *mask, union sockunion *gate,
                       unsigned int index, int zebra_flags, int metric);                        unsigned int index, int zebra_flags, int metric);
   
   #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
 /* Adjust netmask socket length. Return value is a adjusted sin_len  /* Adjust netmask socket length. Return value is a adjusted sin_len
    value. */     value. */
 static int  static int
Line 63  sin_masklen (struct in_addr mask) Line 64  sin_masklen (struct in_addr mask)
     len--;      len--;
   return len;    return len;
 }  }
   #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
   
 /* Interface between zebra message and rtm message. */  /* Interface between zebra message and rtm message. */
 static int  static int
kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib *rib, int family)kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib *rib)
   
 {  {
   struct sockaddr_in *mask = NULL;    struct sockaddr_in *mask = NULL;
   struct sockaddr_in sin_dest, sin_mask, sin_gate;    struct sockaddr_in sin_dest, sin_mask, sin_gate;
  struct nexthop *nexthop;  struct nexthop *nexthop, *tnexthop;
   int recursing;
   int nexthop_num = 0;    int nexthop_num = 0;
  unsigned int ifindex = 0;  ifindex_t ifindex = 0;
   int gate = 0;    int gate = 0;
   int error;    int error;
  char prefix_buf[INET_ADDRSTRLEN];  char prefix_buf[PREFIX_STRLEN];
   
   if (IS_ZEBRA_DEBUG_RIB)    if (IS_ZEBRA_DEBUG_RIB)
    inet_ntop (AF_INET, &p->u.prefix, prefix_buf, INET_ADDRSTRLEN);    prefix2str (p, prefix_buf, sizeof(prefix_buf));
   memset (&sin_dest, 0, sizeof (struct sockaddr_in));    memset (&sin_dest, 0, sizeof (struct sockaddr_in));
   sin_dest.sin_family = AF_INET;    sin_dest.sin_family = AF_INET;
 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN  #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
Line 96  kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib Line 99  kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib
 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */  #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
   
   /* Make gateway. */    /* Make gateway. */
  for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)  for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
     {      {
         if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
           continue;
   
       gate = 0;        gate = 0;
       char gate_buf[INET_ADDRSTRLEN] = "NULL";        char gate_buf[INET_ADDRSTRLEN] = "NULL";
   
Line 112  kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib Line 118  kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib
               && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)                && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
               ))                ))
         {          {
          if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))          if (nexthop->type == NEXTHOP_TYPE_IPV4 ||
               nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
             {              {
              if (nexthop->rtype == NEXTHOP_TYPE_IPV4 ||              sin_gate.sin_addr = nexthop->gate.ipv4;
                  nexthop->rtype == NEXTHOP_TYPE_IPV4_IFINDEX)              gate = 1;
                { 
                  sin_gate.sin_addr = nexthop->rgate.ipv4; 
                  gate = 1; 
                } 
              if (nexthop->rtype == NEXTHOP_TYPE_IFINDEX 
                  || nexthop->rtype == NEXTHOP_TYPE_IFNAME 
                  || nexthop->rtype == NEXTHOP_TYPE_IPV4_IFINDEX) 
                ifindex = nexthop->rifindex; 
             }              }
          else          if (nexthop->type == NEXTHOP_TYPE_IFINDEX
               || nexthop->type == NEXTHOP_TYPE_IFNAME
               || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
             ifindex = nexthop->ifindex;
           if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE)
             {              {
              if (nexthop->type == NEXTHOP_TYPE_IPV4 ||              struct in_addr loopback;
                  nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)              loopback.s_addr = htonl (INADDR_LOOPBACK);
                {              sin_gate.sin_addr = loopback;
                  sin_gate.sin_addr = nexthop->gate.ipv4;              gate = 1;
                  gate = 1; 
                } 
              if (nexthop->type == NEXTHOP_TYPE_IFINDEX 
                  || nexthop->type == NEXTHOP_TYPE_IFNAME 
                  || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX) 
                ifindex = nexthop->ifindex; 
              if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE) 
                { 
                  struct in_addr loopback; 
                  loopback.s_addr = htonl (INADDR_LOOPBACK); 
                  sin_gate.sin_addr = loopback; 
                  gate = 1; 
                } 
             }              }
   
           if (gate && p->prefixlen == 32)            if (gate && p->prefixlen == 32)
Line 170  kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib Line 160  kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib
            {             {
              if (!gate)               if (!gate)
              {               {
               zlog_debug ("%s: %s/%d: attention! gate not found for rib %p",               zlog_debug ("%s: %s: attention! gate not found for rib %p",
                 __func__, prefix_buf, p->prefixlen, rib);                 __func__, prefix_buf, rib);
               rib_dump (__func__, (struct prefix_ipv4 *)p, rib);               rib_dump (p, rib);
              }               }
              else               else
                inet_ntop (AF_INET, &sin_gate.sin_addr, gate_buf, INET_ADDRSTRLEN);                 inet_ntop (AF_INET, &sin_gate.sin_addr, gate_buf, INET_ADDRSTRLEN);
Line 184  kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib Line 174  kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib
              case ZEBRA_ERR_NOERROR:               case ZEBRA_ERR_NOERROR:
                nexthop_num++;                 nexthop_num++;
                if (IS_ZEBRA_DEBUG_RIB)                 if (IS_ZEBRA_DEBUG_RIB)
                 zlog_debug ("%s: %s/%d: successfully did NH %s",                 zlog_debug ("%s: %s: successfully did NH %s",
                   __func__, prefix_buf, p->prefixlen, gate_buf);                   __func__, prefix_buf, gate_buf);
                if (cmd == RTM_ADD)                 if (cmd == RTM_ADD)
                  SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);                   SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
                break;                 break;
Line 207  kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib Line 197  kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib
              case ZEBRA_ERR_RTNOEXIST:               case ZEBRA_ERR_RTNOEXIST:
              case ZEBRA_ERR_RTUNREACH:               case ZEBRA_ERR_RTUNREACH:
              default:               default:
               /* This point is reachable regardless of debugging mode. */               zlog_err ("%s: %s: rtm_write() unexpectedly returned %d for command %s",
               if (!IS_ZEBRA_DEBUG_RIB)                 __func__, prefix2str(p, prefix_buf, sizeof(prefix_buf)),
                 inet_ntop (AF_INET, &p->u.prefix, prefix_buf, INET_ADDRSTRLEN);                 error, lookup (rtm_type_str, cmd));
               zlog_err ("%s: %s/%d: rtm_write() unexpectedly returned %d for command %s", 
                 __func__, prefix_buf, p->prefixlen, error, lookup (rtm_type_str, cmd)); 
                break;                 break;
            }             }
          } /* if (cmd and flags make sense) */           } /* if (cmd and flags make sense) */
Line 219  kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib Line 207  kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib
          if (IS_ZEBRA_DEBUG_RIB)           if (IS_ZEBRA_DEBUG_RIB)
            zlog_debug ("%s: odd command %s for flags %d",             zlog_debug ("%s: odd command %s for flags %d",
              __func__, lookup (rtm_type_str, cmd), nexthop->flags);               __func__, lookup (rtm_type_str, cmd), nexthop->flags);
     } /* for (nexthop = ... */     } /* for (ALL_NEXTHOPS_RO(...))*/
     
    /* If there was no useful nexthop, then complain. */     /* If there was no useful nexthop, then complain. */
    if (nexthop_num == 0 && IS_ZEBRA_DEBUG_KERNEL)     if (nexthop_num == 0 && IS_ZEBRA_DEBUG_KERNEL)
Line 228  kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib Line 216  kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib
   return 0; /*XXX*/    return 0; /*XXX*/
 }  }
   
 int  
 kernel_add_ipv4 (struct prefix *p, struct rib *rib)  
 {  
   int route;  
   
   if (zserv_privs.change(ZPRIVS_RAISE))  
     zlog (NULL, LOG_ERR, "Can't raise privileges");  
   route = kernel_rtm_ipv4 (RTM_ADD, p, rib, AF_INET);  
   if (zserv_privs.change(ZPRIVS_LOWER))  
     zlog (NULL, LOG_ERR, "Can't lower privileges");  
   
   return route;  
 }  
   
 int  
 kernel_delete_ipv4 (struct prefix *p, struct rib *rib)  
 {  
   int route;  
   
   if (zserv_privs.change(ZPRIVS_RAISE))  
     zlog (NULL, LOG_ERR, "Can't raise privileges");  
   route = kernel_rtm_ipv4 (RTM_DELETE, p, rib, AF_INET);  
   if (zserv_privs.change(ZPRIVS_LOWER))  
     zlog (NULL, LOG_ERR, "Can't lower privileges");  
   
   return route;  
 }  
   
 #ifdef HAVE_IPV6  #ifdef HAVE_IPV6
   
   #ifdef SIN6_LEN
 /* Calculate sin6_len value for netmask socket value. */  /* Calculate sin6_len value for netmask socket value. */
 static int  static int
 sin6_masklen (struct in6_addr mask)  sin6_masklen (struct in6_addr mask)
Line 266  sin6_masklen (struct in6_addr mask) Line 227  sin6_masklen (struct in6_addr mask)
   char *p, *lim;    char *p, *lim;
   int len;    int len;
   
 #if defined (INRIA)  
   if (IN_ANYADDR6 (mask))   
     return sizeof (long);  
 #else /* ! INRIA */  
   if (IN6_IS_ADDR_UNSPECIFIED (&mask))     if (IN6_IS_ADDR_UNSPECIFIED (&mask)) 
     return sizeof (long);      return sizeof (long);
 #endif /* ! INRIA */  
   
   sin6.sin6_addr = mask;    sin6.sin6_addr = mask;
   len = sizeof (struct sockaddr_in6);    len = sizeof (struct sockaddr_in6);
Line 285  sin6_masklen (struct in6_addr mask) Line 241  sin6_masklen (struct in6_addr mask)
   
   return len;    return len;
 }  }
   
 /* Interface between zebra message and rtm message. */  
 static int  
 kernel_rtm_ipv6 (int message, struct prefix_ipv6 *dest,  
                  struct in6_addr *gate, int index, int flags)  
 {  
   struct sockaddr_in6 *mask;  
   struct sockaddr_in6 sin_dest, sin_mask, sin_gate;  
   
   memset (&sin_dest, 0, sizeof (struct sockaddr_in6));  
   sin_dest.sin6_family = AF_INET6;  
 #ifdef SIN6_LEN  
   sin_dest.sin6_len = sizeof (struct sockaddr_in6);  
 #endif /* SIN6_LEN */  #endif /* SIN6_LEN */
   
   memset (&sin_mask, 0, sizeof (struct sockaddr_in6));  
   
   memset (&sin_gate, 0, sizeof (struct sockaddr_in6));  
   sin_gate.sin6_family = AF_INET6;  
 #ifdef SIN6_LEN  
   sin_gate.sin6_len = sizeof (struct sockaddr_in6);  
 #endif /* SIN6_LEN */  
   
   sin_dest.sin6_addr = dest->prefix;  
   
   if (gate)  
     memcpy (&sin_gate.sin6_addr, gate, sizeof (struct in6_addr));  
   
   /* Under kame set interface index to link local address. */  
 #ifdef KAME  
   
 #define SET_IN6_LINKLOCAL_IFINDEX(a, i) \  
   do { \  
     (a).s6_addr[2] = ((i) >> 8) & 0xff; \  
     (a).s6_addr[3] = (i) & 0xff; \  
   } while (0)  
   
   if (gate && IN6_IS_ADDR_LINKLOCAL(gate))  
     SET_IN6_LINKLOCAL_IFINDEX (sin_gate.sin6_addr, index);  
 #endif /* KAME */  
   
   if (gate && dest->prefixlen == 128)  
     mask = NULL;  
   else  
     {  
       masklen2ip6 (dest->prefixlen, &sin_mask.sin6_addr);  
       sin_mask.sin6_family = AF_INET6;  
 #ifdef SIN6_LEN  
       sin_mask.sin6_len = sin6_masklen (sin_mask.sin6_addr);  
 #endif /* SIN6_LEN */  
       mask = &sin_mask;  
     }  
   
   return rtm_write (message,   
                     (union sockunion *) &sin_dest,  
                     (union sockunion *) mask,  
                     gate ? (union sockunion *)&sin_gate : NULL,  
                     index,  
                     flags,  
                     0);  
 }  
   
 /* Interface between zebra message and rtm message. */  /* Interface between zebra message and rtm message. */
 static int  static int
kernel_rtm_ipv6_multipath (int cmd, struct prefix *p, struct rib *rib,kernel_rtm_ipv6 (int cmd, struct prefix *p, struct rib *rib)
                           int family) 
 {  {
   struct sockaddr_in6 *mask;    struct sockaddr_in6 *mask;
   struct sockaddr_in6 sin_dest, sin_mask, sin_gate;    struct sockaddr_in6 sin_dest, sin_mask, sin_gate;
  struct nexthop *nexthop;  struct nexthop *nexthop, *tnexthop;
   int recursing;
   int nexthop_num = 0;    int nexthop_num = 0;
  unsigned int ifindex = 0;  ifindex_t ifindex = 0;
   int gate = 0;    int gate = 0;
   int error;    int error;
   
Line 376  kernel_rtm_ipv6_multipath (int cmd, struct prefix *p,  Line 272  kernel_rtm_ipv6_multipath (int cmd, struct prefix *p, 
 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */  #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
   
   /* Make gateway. */    /* Make gateway. */
  for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)  for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
     {      {
         if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
           continue;
   
       gate = 0;        gate = 0;
   
       if ((cmd == RTM_ADD        if ((cmd == RTM_ADD
Line 388  kernel_rtm_ipv6_multipath (int cmd, struct prefix *p,  Line 287  kernel_rtm_ipv6_multipath (int cmd, struct prefix *p, 
 #endif  #endif
               ))                ))
         {          {
          if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))          if (nexthop->type == NEXTHOP_TYPE_IPV6
               || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
               || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
             {              {
              if (nexthop->rtype == NEXTHOP_TYPE_IPV6              sin_gate.sin6_addr = nexthop->gate.ipv6;
                  || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFNAME              gate = 1;
                  || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFINDEX) 
                { 
                  sin_gate.sin6_addr = nexthop->rgate.ipv6; 
                  gate = 1; 
                } 
              if (nexthop->rtype == NEXTHOP_TYPE_IFINDEX 
                  || nexthop->rtype == NEXTHOP_TYPE_IFNAME 
                  || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFNAME 
                  || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFINDEX) 
                ifindex = nexthop->rifindex; 
             }              }
          else          if (nexthop->type == NEXTHOP_TYPE_IFINDEX
            {              || nexthop->type == NEXTHOP_TYPE_IFNAME
              if (nexthop->type == NEXTHOP_TYPE_IPV6              || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
                  || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME              || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
                  || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)            ifindex = nexthop->ifindex;
                { 
                  sin_gate.sin6_addr = nexthop->gate.ipv6; 
                  gate = 1; 
                } 
              if (nexthop->type == NEXTHOP_TYPE_IFINDEX 
                  || nexthop->type == NEXTHOP_TYPE_IFNAME 
                  || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME 
                  || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) 
                ifindex = nexthop->ifindex; 
            } 
   
           if (cmd == RTM_ADD)            if (cmd == RTM_ADD)
             SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);              SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
Line 459  kernel_rtm_ipv6_multipath (int cmd, struct prefix *p,  Line 340  kernel_rtm_ipv6_multipath (int cmd, struct prefix *p, 
 #if 0  #if 0
       if (error)        if (error)
         {          {
          zlog_info ("kernel_rtm_ipv6_multipath(): nexthop %d add error=%d.",          zlog_info ("kernel_rtm_ipv6(): nexthop %d add error=%d.",
             nexthop_num, error);              nexthop_num, error);
         }          }
   #else
         (void)error;
 #endif  #endif
   
       nexthop_num++;        nexthop_num++;
Line 471  kernel_rtm_ipv6_multipath (int cmd, struct prefix *p,  Line 354  kernel_rtm_ipv6_multipath (int cmd, struct prefix *p, 
   if (nexthop_num == 0)    if (nexthop_num == 0)
     {      {
       if (IS_ZEBRA_DEBUG_KERNEL)        if (IS_ZEBRA_DEBUG_KERNEL)
        zlog_debug ("kernel_rtm_ipv6_multipath(): No useful nexthop.");        zlog_debug ("kernel_rtm_ipv6(): No useful nexthop.");
       return 0;        return 0;
     }      }
   
   return 0; /*XXX*/    return 0; /*XXX*/
 }  }
   
int#endif
kernel_add_ipv6 (struct prefix *p, struct rib *rib) 
{ 
  int route; 
   
  if (zserv_privs.change(ZPRIVS_RAISE))static int
    zlog (NULL, LOG_ERR, "Can't raise privileges");kernel_rtm (int cmd, struct prefix *p, struct rib *rib)
  route =  kernel_rtm_ipv6_multipath (RTM_ADD, p, rib, AF_INET6);{
  if (zserv_privs.change(ZPRIVS_LOWER))  switch (PREFIX_FAMILY(p))
    zlog (NULL, LOG_ERR, "Can't lower privileges");    {
    case AF_INET:
  return route;      return kernel_rtm_ipv4 (cmd, p, rib);
     case AF_INET6:
       return kernel_rtm_ipv6 (cmd, p, rib);
     }
   return 0;
 }  }
   
 int  int
kernel_delete_ipv6 (struct prefix *p, struct rib *rib)kernel_route_rib (struct prefix *p, struct rib *old, struct rib *new)
 {  {
  int route;  int route = 0;
   
   if (zserv_privs.change(ZPRIVS_RAISE))    if (zserv_privs.change(ZPRIVS_RAISE))
     zlog (NULL, LOG_ERR, "Can't raise privileges");      zlog (NULL, LOG_ERR, "Can't raise privileges");
   route =  kernel_rtm_ipv6_multipath (RTM_DELETE, p, rib, AF_INET6);  
   if (zserv_privs.change(ZPRIVS_LOWER))  
     zlog (NULL, LOG_ERR, "Can't lower privileges");  
   
  return route;  if (old)
}    route |= kernel_rtm (RTM_DELETE, p, old);
   
/* Delete IPv6 route from the kernel. */  if (new)
int    route |= kernel_rtm (RTM_ADD, p, new);
kernel_delete_ipv6_old (struct prefix_ipv6 *dest, struct in6_addr *gate, 
                        unsigned int index, int flags, int table) 
{ 
  int route; 
   
   if (zserv_privs.change(ZPRIVS_RAISE))  
     zlog (NULL, LOG_ERR, "Can't raise privileges");  
   route = kernel_rtm_ipv6 (RTM_DELETE, dest, gate, index, flags);  
   if (zserv_privs.change(ZPRIVS_LOWER))    if (zserv_privs.change(ZPRIVS_LOWER))
     zlog (NULL, LOG_ERR, "Can't lower privileges");      zlog (NULL, LOG_ERR, "Can't lower privileges");
   
   return route;    return route;
 }  }
 #endif /* HAVE_IPV6 */  

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.2


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