Diff for /embedaddon/quagga/bgpd/bgp_zebra.c between versions 1.1.1.3 and 1.1.1.4

version 1.1.1.3, 2013/07/21 23:54:38 version 1.1.1.4, 2016/11/02 10:09:10
Line 29  Boston, MA 02111-1307, USA.  */ Line 29  Boston, MA 02111-1307, USA.  */
 #include "zclient.h"  #include "zclient.h"
 #include "routemap.h"  #include "routemap.h"
 #include "thread.h"  #include "thread.h"
   #include "filter.h"
   
 #include "bgpd/bgpd.h"  #include "bgpd/bgpd.h"
 #include "bgpd/bgp_route.h"  #include "bgpd/bgp_route.h"
Line 38  Boston, MA 02111-1307, USA.  */ Line 39  Boston, MA 02111-1307, USA.  */
 #include "bgpd/bgp_fsm.h"  #include "bgpd/bgp_fsm.h"
 #include "bgpd/bgp_debug.h"  #include "bgpd/bgp_debug.h"
 #include "bgpd/bgp_mpath.h"  #include "bgpd/bgp_mpath.h"
 /* All information about zebra. */  /* All information about zebra. */
 struct zclient *zclient = NULL;  struct zclient *zclient = NULL;
 struct in_addr router_id_zebra;  struct in_addr router_id_zebra;
Line 48  struct stream *bgp_nexthop_buf = NULL; Line 49  struct stream *bgp_nexthop_buf = NULL;
   
 /* Router-id update message from zebra. */  /* Router-id update message from zebra. */
 static int  static int
bgp_router_id_update (int command, struct zclient *zclient, zebra_size_t length)bgp_router_id_update (int command, struct zclient *zclient, zebra_size_t length,
     vrf_id_t vrf_id)
 {  {
   struct prefix router_id;    struct prefix router_id;
   struct listnode *node, *nnode;    struct listnode *node, *nnode;
Line 76  bgp_router_id_update (int command, struct zclient *zcl Line 78  bgp_router_id_update (int command, struct zclient *zcl
   
 /* Inteface addition message from zebra. */  /* Inteface addition message from zebra. */
 static int  static int
bgp_interface_add (int command, struct zclient *zclient, zebra_size_t length)bgp_interface_add (int command, struct zclient *zclient, zebra_size_t length,
     vrf_id_t vrf_id)
 {  {
   struct interface *ifp;    struct interface *ifp;
   
  ifp = zebra_interface_add_read (zclient->ibuf);  ifp = zebra_interface_add_read (zclient->ibuf, vrf_id);
   
   if (BGP_DEBUG(zebra, ZEBRA) && ifp)    if (BGP_DEBUG(zebra, ZEBRA) && ifp)
     zlog_debug("Zebra rcvd: interface add %s", ifp->name);      zlog_debug("Zebra rcvd: interface add %s", ifp->name);
Line 90  bgp_interface_add (int command, struct zclient *zclien Line 93  bgp_interface_add (int command, struct zclient *zclien
   
 static int  static int
 bgp_interface_delete (int command, struct zclient *zclient,  bgp_interface_delete (int command, struct zclient *zclient,
                      zebra_size_t length)                      zebra_size_t length, vrf_id_t vrf_id)
 {  {
   struct stream *s;    struct stream *s;
   struct interface *ifp;    struct interface *ifp;
   
   s = zclient->ibuf;    s = zclient->ibuf;
  ifp = zebra_interface_state_read (s);  ifp = zebra_interface_state_read (s, vrf_id);
   ifp->ifindex = IFINDEX_INTERNAL;    ifp->ifindex = IFINDEX_INTERNAL;
   
   if (BGP_DEBUG(zebra, ZEBRA))    if (BGP_DEBUG(zebra, ZEBRA))
Line 106  bgp_interface_delete (int command, struct zclient *zcl Line 109  bgp_interface_delete (int command, struct zclient *zcl
 }  }
   
 static int  static int
bgp_interface_up (int command, struct zclient *zclient, zebra_size_t length)bgp_interface_up (int command, struct zclient *zclient, zebra_size_t length,
     vrf_id_t vrf_id)
 {  {
   struct stream *s;    struct stream *s;
   struct interface *ifp;    struct interface *ifp;
Line 114  bgp_interface_up (int command, struct zclient *zclient Line 118  bgp_interface_up (int command, struct zclient *zclient
   struct listnode *node, *nnode;    struct listnode *node, *nnode;
   
   s = zclient->ibuf;    s = zclient->ibuf;
  ifp = zebra_interface_state_read (s);  ifp = zebra_interface_state_read (s, vrf_id);
   
   if (! ifp)    if (! ifp)
     return 0;      return 0;
Line 129  bgp_interface_up (int command, struct zclient *zclient Line 133  bgp_interface_up (int command, struct zclient *zclient
 }  }
   
 static int  static int
bgp_interface_down (int command, struct zclient *zclient, zebra_size_t length)bgp_interface_down (int command, struct zclient *zclient, zebra_size_t length,
     vrf_id_t vrf_id)
 {  {
   struct stream *s;    struct stream *s;
   struct interface *ifp;    struct interface *ifp;
Line 137  bgp_interface_down (int command, struct zclient *zclie Line 142  bgp_interface_down (int command, struct zclient *zclie
   struct listnode *node, *nnode;    struct listnode *node, *nnode;
   
   s = zclient->ibuf;    s = zclient->ibuf;
  ifp = zebra_interface_state_read (s);  ifp = zebra_interface_state_read (s, vrf_id);
   if (! ifp)    if (! ifp)
     return 0;      return 0;
   
Line 147  bgp_interface_down (int command, struct zclient *zclie Line 152  bgp_interface_down (int command, struct zclient *zclie
   for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))    for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))
     bgp_connected_delete (c);      bgp_connected_delete (c);
   
  /* Fast external-failover (Currently IPv4 only) */  /* Fast external-failover */
   {    {
     struct listnode *mnode;      struct listnode *mnode;
     struct bgp *bgp;      struct bgp *bgp;
     struct peer *peer;      struct peer *peer;
     struct interface *peer_if;  
   
     for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp))      for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp))
       {        {
Line 161  bgp_interface_down (int command, struct zclient *zclie Line 165  bgp_interface_down (int command, struct zclient *zclie
   
         for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))          for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
           {            {
            if (peer->ttl != 1)            if ((peer->ttl != 1) && (peer->gtsm_hops != 1))
               continue;                continue;
   
            if (peer->su.sa.sa_family == AF_INET)            if (ifp == peer->nexthop.ifp)
              peer_if = if_lookup_by_ipv4 (&peer->su.sin.sin_addr); 
            else 
              continue; 
 
            if (ifp == peer_if) 
               BGP_EVENT_ADD (peer, BGP_Stop);                BGP_EVENT_ADD (peer, BGP_Stop);
           }            }
       }        }
Line 180  bgp_interface_down (int command, struct zclient *zclie Line 179  bgp_interface_down (int command, struct zclient *zclie
   
 static int  static int
 bgp_interface_address_add (int command, struct zclient *zclient,  bgp_interface_address_add (int command, struct zclient *zclient,
                           zebra_size_t length)                           zebra_size_t length, vrf_id_t vrf_id)
 {  {
   struct connected *ifc;    struct connected *ifc;
   
  ifc = zebra_interface_address_read (command, zclient->ibuf);  ifc = zebra_interface_address_read (command, zclient->ibuf, vrf_id);
   
   if (ifc == NULL)    if (ifc == NULL)
     return 0;      return 0;
Line 205  bgp_interface_address_add (int command, struct zclient Line 204  bgp_interface_address_add (int command, struct zclient
   
 static int  static int
 bgp_interface_address_delete (int command, struct zclient *zclient,  bgp_interface_address_delete (int command, struct zclient *zclient,
                              zebra_size_t length)                              zebra_size_t length, vrf_id_t vrf_id)
 {  {
   struct connected *ifc;    struct connected *ifc;
   
  ifc = zebra_interface_address_read (command, zclient->ibuf);  ifc = zebra_interface_address_read (command, zclient->ibuf, vrf_id);
   
   if (ifc == NULL)    if (ifc == NULL)
     return 0;      return 0;
Line 232  bgp_interface_address_delete (int command, struct zcli Line 231  bgp_interface_address_delete (int command, struct zcli
   
 /* Zebra route add and delete treatment. */  /* Zebra route add and delete treatment. */
 static int  static int
zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length)zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length,
     vrf_id_t vrf_id)
 {  {
   struct stream *s;    struct stream *s;
   struct zapi_ipv4 api;    struct zapi_ipv4 api;
   struct in_addr nexthop;    struct in_addr nexthop;
   struct prefix_ipv4 p;    struct prefix_ipv4 p;
     unsigned char plength = 0;
   
   s = zclient->ibuf;    s = zclient->ibuf;
   nexthop.s_addr = 0;    nexthop.s_addr = 0;
Line 250  zebra_read_ipv4 (int command, struct zclient *zclient, Line 251  zebra_read_ipv4 (int command, struct zclient *zclient,
   /* IPv4 prefix. */    /* IPv4 prefix. */
   memset (&p, 0, sizeof (struct prefix_ipv4));    memset (&p, 0, sizeof (struct prefix_ipv4));
   p.family = AF_INET;    p.family = AF_INET;
  p.prefixlen = stream_getc (s);  plength = stream_getc (s);
   p.prefixlen = MIN(IPV4_MAX_PREFIXLEN, plength);
   stream_get (&p.prefix, s, PSIZE (p.prefixlen));    stream_get (&p.prefix, s, PSIZE (p.prefixlen));
   
   /* Nexthop, ifindex, distance, metric. */    /* Nexthop, ifindex, distance, metric. */
Line 305  zebra_read_ipv4 (int command, struct zclient *zclient, Line 307  zebra_read_ipv4 (int command, struct zclient *zclient,
   return 0;    return 0;
 }  }
   
 #ifdef HAVE_IPV6  
 /* Zebra route add and delete treatment. */  /* Zebra route add and delete treatment. */
 static int  static int
zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length)zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length,
     vrf_id_t vrf_id)
 {  {
   struct stream *s;    struct stream *s;
   struct zapi_ipv6 api;    struct zapi_ipv6 api;
   struct in6_addr nexthop;    struct in6_addr nexthop;
   struct prefix_ipv6 p;    struct prefix_ipv6 p;
     unsigned char plength = 0;
   
   s = zclient->ibuf;    s = zclient->ibuf;
   memset (&nexthop, 0, sizeof (struct in6_addr));    memset (&nexthop, 0, sizeof (struct in6_addr));
Line 326  zebra_read_ipv6 (int command, struct zclient *zclient, Line 329  zebra_read_ipv6 (int command, struct zclient *zclient,
   /* IPv6 prefix. */    /* IPv6 prefix. */
   memset (&p, 0, sizeof (struct prefix_ipv6));    memset (&p, 0, sizeof (struct prefix_ipv6));
   p.family = AF_INET6;    p.family = AF_INET6;
  p.prefixlen = stream_getc (s);  plength = stream_getc (s);
   p.prefixlen = MIN(IPV6_MAX_PREFIXLEN, plength);
   stream_get (&p.prefix, s, PSIZE (p.prefixlen));    stream_get (&p.prefix, s, PSIZE (p.prefixlen));
   
   /* Nexthop, ifindex, distance, metric. */    /* Nexthop, ifindex, distance, metric. */
Line 386  zebra_read_ipv6 (int command, struct zclient *zclient, Line 390  zebra_read_ipv6 (int command, struct zclient *zclient,
       
   return 0;    return 0;
 }  }
#endif /* HAVE_IPV6 */
 
 struct interface *  struct interface *
 if_lookup_by_ipv4 (struct in_addr *addr)  if_lookup_by_ipv4 (struct in_addr *addr)
 {  {
Line 439  if_lookup_by_ipv4_exact (struct in_addr *addr) Line 442  if_lookup_by_ipv4_exact (struct in_addr *addr)
   return NULL;    return NULL;
 }  }
   
 #ifdef HAVE_IPV6  
 struct interface *  struct interface *
 if_lookup_by_ipv6 (struct in6_addr *addr)  if_lookup_by_ipv6 (struct in6_addr *addr)
 {  {
Line 532  if_get_ipv6_local (struct interface *ifp, struct in6_a Line 534  if_get_ipv6_local (struct interface *ifp, struct in6_a
     }      }
   return 0;    return 0;
 }  }
 #endif /* HAVE_IPV6 */  
   
   static int
   if_get_ipv4_address (struct interface *ifp, struct in_addr *addr)
   {
     struct listnode *cnode;
     struct connected *connected;
     struct prefix *cp;
   
     for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
       {
         cp = connected->address;
         if ((cp->family == AF_INET) && !ipv4_martian(&(cp->u.prefix4)))
             {
               *addr = cp->u.prefix4;
               return 1;
             }
       }
     return 0;
   }
   
 int  int
 bgp_nexthop_set (union sockunion *local, union sockunion *remote,   bgp_nexthop_set (union sockunion *local, union sockunion *remote, 
                  struct bgp_nexthop *nexthop, struct peer *peer)                   struct bgp_nexthop *nexthop, struct peer *peer)
Line 553  bgp_nexthop_set (union sockunion *local, union sockuni Line 573  bgp_nexthop_set (union sockunion *local, union sockuni
       nexthop->v4 = local->sin.sin_addr;        nexthop->v4 = local->sin.sin_addr;
       ifp = if_lookup_by_ipv4 (&local->sin.sin_addr);        ifp = if_lookup_by_ipv4 (&local->sin.sin_addr);
     }      }
 #ifdef HAVE_IPV6  
   if (local->sa.sa_family == AF_INET6)    if (local->sa.sa_family == AF_INET6)
     {      {
       if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))        if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
         {          {
           if (peer->ifname)            if (peer->ifname)
            ifp = if_lookup_by_index (if_nametoindex (peer->ifname));            ifp = if_lookup_by_name (peer->ifname);
         }          }
       else        else
         ifp = if_lookup_by_ipv6 (&local->sin6.sin6_addr);          ifp = if_lookup_by_ipv6 (&local->sin6.sin6_addr);
     }      }
 #endif /* HAVE_IPV6 */  
   
   if (!ifp)    if (!ifp)
     return -1;      return -1;
Line 574  bgp_nexthop_set (union sockunion *local, union sockuni Line 592  bgp_nexthop_set (union sockunion *local, union sockuni
   /* IPv4 connection. */    /* IPv4 connection. */
   if (local->sa.sa_family == AF_INET)    if (local->sa.sa_family == AF_INET)
     {      {
 #ifdef HAVE_IPV6  
       /* IPv6 nexthop*/        /* IPv6 nexthop*/
       ret = if_get_ipv6_global (ifp, &nexthop->v6_global);        ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
   
Line 583  bgp_nexthop_set (union sockunion *local, union sockuni Line 600  bgp_nexthop_set (union sockunion *local, union sockuni
         if_get_ipv6_local (ifp, &nexthop->v6_global);          if_get_ipv6_local (ifp, &nexthop->v6_global);
       else        else
         if_get_ipv6_local (ifp, &nexthop->v6_local);          if_get_ipv6_local (ifp, &nexthop->v6_local);
 #endif /* HAVE_IPV6 */  
     }      }
   
 #ifdef HAVE_IPV6  
   /* IPv6 connection. */    /* IPv6 connection. */
   if (local->sa.sa_family == AF_INET6)    if (local->sa.sa_family == AF_INET6)
     {      {
       struct interface *direct = NULL;        struct interface *direct = NULL;
   
      /* IPv4 nexthop.  I don't care about it. */      /* IPv4 nexthop. */
      if (peer->local_id.s_addr)      ret = if_get_ipv4_address(ifp, &nexthop->v4);
       if (!ret && peer->local_id.s_addr)
         nexthop->v4 = peer->local_id;          nexthop->v4 = peer->local_id;
   
       /* Global address*/        /* Global address*/
Line 642  bgp_nexthop_set (union sockunion *local, union sockuni Line 658  bgp_nexthop_set (union sockunion *local, union sockuni
       SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_local, 0);        SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_local, 0);
     }      }
 #endif /* KAME */  #endif /* KAME */
 #endif /* HAVE_IPV6 */  
   return ret;    return ret;
 }  }
   
Line 658  bgp_zebra_announce (struct prefix *p, struct bgp_info  Line 673  bgp_zebra_announce (struct prefix *p, struct bgp_info 
   if (zclient->sock < 0)    if (zclient->sock < 0)
     return;      return;
   
  if (! zclient->redist[ZEBRA_ROUTE_BGP])  if (! vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_BGP], VRF_DEFAULT))
     return;      return;
   
   flags = 0;    flags = 0;
Line 694  bgp_zebra_announce (struct prefix *p, struct bgp_info  Line 709  bgp_zebra_announce (struct prefix *p, struct bgp_info 
       struct zapi_ipv4 api;        struct zapi_ipv4 api;
       struct in_addr *nexthop;        struct in_addr *nexthop;
   
         api.vrf_id = VRF_DEFAULT;
       api.flags = flags;        api.flags = flags;
       nexthop = &info->attr->nexthop;        nexthop = &info->attr->nexthop;
       stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *));        stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *));
Line 741  bgp_zebra_announce (struct prefix *p, struct bgp_info  Line 757  bgp_zebra_announce (struct prefix *p, struct bgp_info 
       zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient,         zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient, 
                        (struct prefix_ipv4 *) p, &api);                         (struct prefix_ipv4 *) p, &api);
     }      }
#ifdef HAVE_IPV6
   /* We have to think about a IPv6 link-local address curse. */    /* We have to think about a IPv6 link-local address curse. */
   if (p->family == AF_INET6)    if (p->family == AF_INET6)
     {      {
      unsigned int ifindex;      ifindex_t ifindex;
       struct in6_addr *nexthop;        struct in6_addr *nexthop;
       struct zapi_ipv6 api;        struct zapi_ipv6 api;
   
Line 778  bgp_zebra_announce (struct prefix *p, struct bgp_info  Line 794  bgp_zebra_announce (struct prefix *p, struct bgp_info 
       if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex)        if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex)
         {          {
           if (info->peer->ifname)            if (info->peer->ifname)
            ifindex = if_nametoindex (info->peer->ifname);            ifindex = ifname2ifindex (info->peer->ifname);
           else if (info->peer->nexthop.ifp)            else if (info->peer->nexthop.ifp)
             ifindex = info->peer->nexthop.ifp->ifindex;              ifindex = info->peer->nexthop.ifp->ifindex;
         }          }
   
       /* Make Zebra API structure. */        /* Make Zebra API structure. */
         api.vrf_id = VRF_DEFAULT;
       api.flags = flags;        api.flags = flags;
       api.type = ZEBRA_ROUTE_BGP;        api.type = ZEBRA_ROUTE_BGP;
       api.message = 0;        api.message = 0;
Line 810  bgp_zebra_announce (struct prefix *p, struct bgp_info  Line 827  bgp_zebra_announce (struct prefix *p, struct bgp_info 
       zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient,         zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, 
                        (struct prefix_ipv6 *) p, &api);                         (struct prefix_ipv6 *) p, &api);
     }      }
 #endif /* HAVE_IPV6 */  
 }  }
   
 void  void
Line 822  bgp_zebra_withdraw (struct prefix *p, struct bgp_info  Line 838  bgp_zebra_withdraw (struct prefix *p, struct bgp_info 
   if (zclient->sock < 0)    if (zclient->sock < 0)
     return;      return;
   
  if (! zclient->redist[ZEBRA_ROUTE_BGP])  if (! vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_BGP], VRF_DEFAULT))
     return;      return;
   
   peer = info->peer;    peer = info->peer;
Line 841  bgp_zebra_withdraw (struct prefix *p, struct bgp_info  Line 857  bgp_zebra_withdraw (struct prefix *p, struct bgp_info 
   if (p->family == AF_INET)    if (p->family == AF_INET)
     {      {
       struct zapi_ipv4 api;        struct zapi_ipv4 api;
       struct in_addr *nexthop;  
   
         api.vrf_id = VRF_DEFAULT;
       api.flags = flags;        api.flags = flags;
       nexthop = &info->attr->nexthop;  
   
       api.type = ZEBRA_ROUTE_BGP;        api.type = ZEBRA_ROUTE_BGP;
       api.message = 0;        api.message = 0;
       api.safi = safi;        api.safi = safi;
      SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);      api.nexthop_num = 0;
      api.nexthop_num = 1; 
      api.nexthop = &nexthop; 
       api.ifindex_num = 0;        api.ifindex_num = 0;
       SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);        SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
       api.metric = info->attr->med;        api.metric = info->attr->med;
Line 859  bgp_zebra_withdraw (struct prefix *p, struct bgp_info  Line 872  bgp_zebra_withdraw (struct prefix *p, struct bgp_info 
       if (BGP_DEBUG(zebra, ZEBRA))        if (BGP_DEBUG(zebra, ZEBRA))
         {          {
           char buf[2][INET_ADDRSTRLEN];            char buf[2][INET_ADDRSTRLEN];
          zlog_debug("Zebra send: IPv4 route delete %s/%d nexthop %s metric %u",          zlog_debug("Zebra send: IPv4 route delete %s/%d metric %u",
                      inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),                       inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
                      p->prefixlen,                       p->prefixlen,
                      inet_ntop(AF_INET, nexthop, buf[1], sizeof(buf[1])),  
                      api.metric);                       api.metric);
         }          }
   
       zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient,         zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, 
                        (struct prefix_ipv4 *) p, &api);                         (struct prefix_ipv4 *) p, &api);
     }      }
#ifdef HAVE_IPV6
   /* We have to think about a IPv6 link-local address curse. */    /* We have to think about a IPv6 link-local address curse. */
   if (p->family == AF_INET6)    if (p->family == AF_INET6)
     {      {
       struct zapi_ipv6 api;        struct zapi_ipv6 api;
       unsigned int ifindex;  
       struct in6_addr *nexthop;  
               
      assert (info->attr->extra);      api.vrf_id = VRF_DEFAULT;
       
      ifindex = 0; 
      nexthop = NULL; 
 
      /* Only global address nexthop exists. */ 
      if (info->attr->extra->mp_nexthop_len == 16) 
        nexthop = &info->attr->extra->mp_nexthop_global; 
 
      /* If both global and link-local address present. */ 
      if (info->attr->extra->mp_nexthop_len == 32) 
        { 
          nexthop = &info->attr->extra->mp_nexthop_local; 
          if (info->peer->nexthop.ifp) 
            ifindex = info->peer->nexthop.ifp->ifindex; 
        } 
 
      if (nexthop == NULL) 
        return; 
 
      if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex) 
        if (info->peer->ifname) 
          ifindex = if_nametoindex (info->peer->ifname); 
 
       api.flags = flags;        api.flags = flags;
       api.type = ZEBRA_ROUTE_BGP;        api.type = ZEBRA_ROUTE_BGP;
       api.message = 0;        api.message = 0;
       api.safi = safi;        api.safi = safi;
      SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);      api.nexthop_num = 0;
      api.nexthop_num = 1;      api.ifindex_num = 0;
      api.nexthop = &nexthop; 
      SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX); 
      api.ifindex_num = 1; 
      api.ifindex = &ifindex; 
       SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);        SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
       api.metric = info->attr->med;        api.metric = info->attr->med;
   
       if (BGP_DEBUG(zebra, ZEBRA))        if (BGP_DEBUG(zebra, ZEBRA))
         {          {
           char buf[2][INET6_ADDRSTRLEN];            char buf[2][INET6_ADDRSTRLEN];
          zlog_debug("Zebra send: IPv6 route delete %s/%d nexthop %s metric %u",          zlog_debug("Zebra send: IPv6 route delete %s/%d metric %u",
                      inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),                       inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
                      p->prefixlen,                       p->prefixlen,
                      inet_ntop(AF_INET6, nexthop, buf[1], sizeof(buf[1])),  
                      api.metric);                       api.metric);
         }          }
   
       zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient,         zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, 
                        (struct prefix_ipv6 *) p, &api);                         (struct prefix_ipv6 *) p, &api);
     }      }
 #endif /* HAVE_IPV6 */  
 }  }
 /* Other routes redistribution into BGP. */  /* Other routes redistribution into BGP. */
 int  int
 bgp_redistribute_set (struct bgp *bgp, afi_t afi, int type)  bgp_redistribute_set (struct bgp *bgp, afi_t afi, int type)
Line 938  bgp_redistribute_set (struct bgp *bgp, afi_t afi, int  Line 919  bgp_redistribute_set (struct bgp *bgp, afi_t afi, int 
   bgp->redist[afi][type] = 1;    bgp->redist[afi][type] = 1;
   
   /* Return if already redistribute flag is set. */    /* Return if already redistribute flag is set. */
  if (zclient->redist[type])  if (vrf_bitmap_check (zclient->redist[type], VRF_DEFAULT))
     return CMD_WARNING;      return CMD_WARNING;
   
  zclient->redist[type] = 1;  vrf_bitmap_set (zclient->redist[type], VRF_DEFAULT);
   
   /* Return if zebra connection is not established. */    /* Return if zebra connection is not established. */
   if (zclient->sock < 0)    if (zclient->sock < 0)
Line 951  bgp_redistribute_set (struct bgp *bgp, afi_t afi, int  Line 932  bgp_redistribute_set (struct bgp *bgp, afi_t afi, int 
     zlog_debug("Zebra send: redistribute add %s", zebra_route_string(type));      zlog_debug("Zebra send: redistribute add %s", zebra_route_string(type));
           
   /* Send distribute add message to zebra. */    /* Send distribute add message to zebra. */
  zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type);  zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type, VRF_DEFAULT);
   
   return CMD_SUCCESS;    return CMD_SUCCESS;
 }  }
Line 1006  bgp_redistribute_unset (struct bgp *bgp, afi_t afi, in Line 987  bgp_redistribute_unset (struct bgp *bgp, afi_t afi, in
   bgp->redist_metric[afi][type] = 0;    bgp->redist_metric[afi][type] = 0;
   
   /* Return if zebra connection is disabled. */    /* Return if zebra connection is disabled. */
  if (! zclient->redist[type])  if (! vrf_bitmap_check (zclient->redist[type], VRF_DEFAULT))
     return CMD_WARNING;      return CMD_WARNING;
  zclient->redist[type] = 0;  vrf_bitmap_unset (zclient->redist[type], VRF_DEFAULT);
   
   if (bgp->redist[AFI_IP][type] == 0     if (bgp->redist[AFI_IP][type] == 0 
       && bgp->redist[AFI_IP6][type] == 0         && bgp->redist[AFI_IP6][type] == 0 
Line 1018  bgp_redistribute_unset (struct bgp *bgp, afi_t afi, in Line 999  bgp_redistribute_unset (struct bgp *bgp, afi_t afi, in
       if (BGP_DEBUG(zebra, ZEBRA))        if (BGP_DEBUG(zebra, ZEBRA))
         zlog_debug("Zebra send: redistribute delete %s",          zlog_debug("Zebra send: redistribute delete %s",
                    zebra_route_string(type));                     zebra_route_string(type));
      zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);      zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type,
                                VRF_DEFAULT);
     }      }
       
   /* Withdraw redistributed routes from current BGP's routing table. */    /* Withdraw redistributed routes from current BGP's routing table. */
Line 1055  bgp_redistribute_metric_unset (struct bgp *bgp, afi_t  Line 1037  bgp_redistribute_metric_unset (struct bgp *bgp, afi_t 
   
   return 1;    return 1;
 }  }
 void  void
 bgp_zclient_reset (void)  bgp_zclient_reset (void)
 {  {
   zclient_reset (zclient);    zclient_reset (zclient);
 }  }
   
   static void
   bgp_zebra_connected (struct zclient *zclient)
   {
     zclient_send_requests (zclient, VRF_DEFAULT);
   }
   
 void  void
bgp_zebra_init (void)bgp_zebra_init (struct thread_master *master)
 {  {
   /* Set default values. */    /* Set default values. */
  zclient = zclient_new ();  zclient = zclient_new (master);
   zclient_init (zclient, ZEBRA_ROUTE_BGP);    zclient_init (zclient, ZEBRA_ROUTE_BGP);
     zclient->zebra_connected = bgp_zebra_connected;
   zclient->router_id_update = bgp_router_id_update;    zclient->router_id_update = bgp_router_id_update;
   zclient->interface_add = bgp_interface_add;    zclient->interface_add = bgp_interface_add;
   zclient->interface_delete = bgp_interface_delete;    zclient->interface_delete = bgp_interface_delete;
Line 1077  bgp_zebra_init (void) Line 1066  bgp_zebra_init (void)
   zclient->ipv4_route_delete = zebra_read_ipv4;    zclient->ipv4_route_delete = zebra_read_ipv4;
   zclient->interface_up = bgp_interface_up;    zclient->interface_up = bgp_interface_up;
   zclient->interface_down = bgp_interface_down;    zclient->interface_down = bgp_interface_down;
 #ifdef HAVE_IPV6  
   zclient->ipv6_route_add = zebra_read_ipv6;    zclient->ipv6_route_add = zebra_read_ipv6;
   zclient->ipv6_route_delete = zebra_read_ipv6;    zclient->ipv6_route_delete = zebra_read_ipv6;
 #endif /* HAVE_IPV6 */  
   
   /* Interface related init. */  
   if_init ();  
   
   bgp_nexthop_buf = stream_new(BGP_NEXTHOP_BUF_SIZE);    bgp_nexthop_buf = stream_new(BGP_NEXTHOP_BUF_SIZE);
   }
   
   void
   bgp_zebra_destroy(void)
   {
     if (zclient == NULL)
       return;
     zclient_stop(zclient);
     zclient_free(zclient);
     zclient = NULL;
 }  }

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


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