]> git.puffer.fish Git - matthieu/frr.git/commitdiff
BGP: add addpath RX support
authorDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 20 May 2015 01:03:45 +0000 (18:03 -0700)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 20 May 2015 01:03:45 +0000 (18:03 -0700)
bgpd/bgp_attr.c
bgpd/bgp_mplsvpn.c
bgpd/bgp_open.c
bgpd/bgp_open.h
bgpd/bgp_packet.c
bgpd/bgp_route.c
bgpd/bgp_route.h
bgpd/bgp_vty.c
bgpd/bgpd.h

index 8ff8a5cff5bf2c4220043244d281144966e55fca..506583b3e5eb3ca5fbd03513828c50ba8b4afdae 100644 (file)
@@ -1607,8 +1607,8 @@ bgp_mp_reach_parse (struct bgp_attr_parser_args *args,
  
   if (safi != SAFI_MPLS_LABELED_VPN)
     {
-      ret = bgp_nlri_sanity_check (peer, afi, stream_pnt (s), nlri_len,
-                                   &num_mp_pfx);
+      ret = bgp_nlri_sanity_check (peer, afi, safi, stream_pnt (s),
+                                   nlri_len, &num_mp_pfx);
       if (ret < 0) 
         {
           zlog_info ("%s: (%s) NLRI doesn't pass sanity check",
@@ -1655,8 +1655,8 @@ bgp_mp_unreach_parse (struct bgp_attr_parser_args *args,
 
   if (safi != SAFI_MPLS_LABELED_VPN)
     {
-      ret = bgp_nlri_sanity_check (peer, afi, stream_pnt (s), withdraw_len,
-                                   &num_mp_pfx);
+      ret = bgp_nlri_sanity_check (peer, afi, safi, stream_pnt (s),
+                                  withdraw_len, &num_mp_pfx);
       if (ret < 0)
        return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
     }
index 087f544b63acf3d0c63d9e8c0137097823124848..22ae54e0e00418b69e158b3f46a8a99840fe71d5 100644 (file)
@@ -90,6 +90,10 @@ bgp_nlri_parse_vpnv4 (struct peer *peer, struct attr *attr,
   struct rd_ip rd_ip;
   struct prefix_rd prd;
   u_char *tagpnt;
+  afi_t afi;
+  safi_t safi;
+  u_char addpath_encoded;
+  u_int32_t addpath_id;
 
   /* Check peer status. */
   if (peer->status != Established)
@@ -101,12 +105,24 @@ bgp_nlri_parse_vpnv4 (struct peer *peer, struct attr *attr,
 
   pnt = packet->nlri;
   lim = pnt + packet->length;
+  afi = packet->afi;
+  safi = packet->safi;
+  addpath_id = 0;
+
+  addpath_encoded = (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV) &&
+                     CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_TX_RCV));
 
   for (; pnt < lim; pnt += psize)
     {
       /* Clear prefix structure. */
       memset (&p, 0, sizeof (struct prefix));
 
+      if (addpath_encoded)
+        {
+          addpath_id = ntohl(*((uint32_t*) pnt));
+          pnt += BGP_ADDPATH_ID_LEN;
+        }
+
       /* Fetch prefix length. */
       prefixlen = *pnt++;
       p.family = AF_INET;
@@ -156,10 +172,10 @@ bgp_nlri_parse_vpnv4 (struct peer *peer, struct attr *attr,
        return -1;
 
       if (attr)
-       bgp_update (peer, &p, attr, AFI_IP, SAFI_MPLS_VPN,
+       bgp_update (peer, &p, addpath_id, attr, AFI_IP, SAFI_MPLS_VPN,
                    ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt, 0);
       else
-       bgp_withdraw (peer, &p, attr, AFI_IP, SAFI_MPLS_VPN,
+       bgp_withdraw (peer, &p, addpath_id, attr, AFI_IP, SAFI_MPLS_VPN,
                      ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt);
     }
 
index 0bcccb8aab26eda9aade4ac3b08bf8e03ab843e4..7aef76d53d28699f19159e9ef17c6487c9330cea 100644 (file)
@@ -417,6 +417,39 @@ bgp_capability_as4 (struct peer *peer, struct capability_header *hdr)
   return as4;
 }
 
+static int
+bgp_capability_addpath (struct peer *peer, struct capability_header *hdr)
+{
+  struct stream *s = BGP_INPUT (peer);
+  size_t end = stream_get_getp (s) + hdr->length;
+
+  SET_FLAG (peer->cap, PEER_CAP_ADDPATH_RCV);
+
+  while (stream_get_getp (s) + 4 <= end)
+    {
+      afi_t afi = stream_getw (s);
+      safi_t safi = stream_getc (s);
+      u_char send_receive = stream_getc (s);
+
+      if (bgp_debug_neighbor_events(peer->host))
+        zlog_debug ("%s OPEN has AddPath CAP for afi/safi: %u/%u%s%s",
+                    peer->host, afi, safi,
+                    (send_receive & BGP_ADDPATH_RX) ? ", receive" : "",
+                    (send_receive & BGP_ADDPATH_TX) ? ", transmit" : "");
+
+      if (!bgp_afi_safi_valid_indices (afi, &safi))
+        return -1;
+
+      if (send_receive & BGP_ADDPATH_RX)
+        SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_RCV);
+
+      if (send_receive & BGP_ADDPATH_TX)
+        SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_TX_RCV);
+    }
+
+  return 0;
+}
+
 static const struct message capcode_str[] =
 {
   { CAPABILITY_CODE_MP,                        "MultiProtocol Extensions"      },
@@ -424,6 +457,7 @@ static const struct message capcode_str[] =
   { CAPABILITY_CODE_ORF,               "Cooperative Route Filtering"   },
   { CAPABILITY_CODE_RESTART,           "Graceful Restart"              },
   { CAPABILITY_CODE_AS4,               "4-octet AS number"             },
+  { CAPABILITY_CODE_ADDPATH,            "AddPath"                      },
   { CAPABILITY_CODE_DYNAMIC,           "Dynamic"                       },
   { CAPABILITY_CODE_REFRESH_OLD,       "Route Refresh (Old)"           },
   { CAPABILITY_CODE_ORF_OLD,           "ORF (Old)"                     },
@@ -438,6 +472,7 @@ static const size_t cap_minsizes[] =
   [CAPABILITY_CODE_ORF]                = sizeof (struct capability_orf_entry),
   [CAPABILITY_CODE_RESTART]    = sizeof (struct capability_gr),
   [CAPABILITY_CODE_AS4]                = CAPABILITY_CODE_AS4_LEN,
+  [CAPABILITY_CODE_ADDPATH]     = CAPABILITY_CODE_ADDPATH_LEN,
   [CAPABILITY_CODE_DYNAMIC]    = CAPABILITY_CODE_DYNAMIC_LEN,
   [CAPABILITY_CODE_REFRESH_OLD]        = CAPABILITY_CODE_REFRESH_LEN,
   [CAPABILITY_CODE_ORF_OLD]    = sizeof (struct capability_orf_entry),
@@ -502,6 +537,7 @@ bgp_capability_parse (struct peer *peer, size_t length, int *mp_capability,
           case CAPABILITY_CODE_ORF_OLD:
           case CAPABILITY_CODE_RESTART:
           case CAPABILITY_CODE_AS4:
+          case CAPABILITY_CODE_ADDPATH:
           case CAPABILITY_CODE_DYNAMIC:
               /* Check length. */
               if (caphdr.length < cap_minsizes[caphdr.code])
@@ -572,6 +608,10 @@ bgp_capability_parse (struct peer *peer, size_t length, int *mp_capability,
               if (!bgp_capability_as4 (peer, &caphdr))
                 return -1;
               break;            
+          case CAPABILITY_CODE_ADDPATH:
+            if (bgp_capability_addpath (peer, &caphdr))
+              return -1;
+            break;
           default:
             if (caphdr.code > 128)
               {
@@ -905,6 +945,7 @@ bgp_open_capability (struct stream *s, struct peer *peer)
   safi_t safi;
   as_t local_as;
   u_int32_t restart_time;
+  u_char afi_safi_count = 0;
 
   /* Remember current pointer for Opt Parm Len. */
   cp = stream_get_endp (s);
@@ -1003,6 +1044,30 @@ bgp_open_capability (struct stream *s, struct peer *peer)
     local_as = peer->local_as;
   stream_putl (s, local_as );
 
+  /* AddPath
+   * For now we will only advertise RX support. TX support will be added later.
+   */
+  for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
+    for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
+      if (peer->afc[afi][safi])
+        afi_safi_count++;
+
+  SET_FLAG (peer->cap, PEER_CAP_ADDPATH_ADV);
+  stream_putc (s, BGP_OPEN_OPT_CAP);
+  stream_putc (s, (CAPABILITY_CODE_ADDPATH_LEN * afi_safi_count) + 2);
+  stream_putc (s, CAPABILITY_CODE_ADDPATH);
+  stream_putc (s, CAPABILITY_CODE_ADDPATH_LEN * afi_safi_count);
+
+  for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
+    for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
+      if (peer->afc[afi][safi])
+        {
+          stream_putw (s, afi);
+          stream_putc (s, safi);
+          stream_putc (s, BGP_ADDPATH_RX);
+          SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV);
+        }
+
   /* ORF capability. */
   for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
     for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
index 2b1382d8b731eea6966073c25f4a47bafbac171e..fa9c78ec9dbd8660350b0bb6d3f165e0d70080fa 100644 (file)
@@ -73,6 +73,7 @@ struct capability_gr
 #define CAPABILITY_CODE_RESTART        64 /* Graceful Restart Capability */
 #define CAPABILITY_CODE_AS4            65 /* 4-octet AS number Capability */
 #define CAPABILITY_CODE_DYNAMIC        66 /* Dynamic Capability */
+#define CAPABILITY_CODE_ADDPATH        69 /* Addpath Capability */
 #define CAPABILITY_CODE_REFRESH_OLD   128 /* Route Refresh Capability(cisco) */
 #define CAPABILITY_CODE_ORF_OLD       130 /* Cooperative Route Filtering Capability(cisco) */
 
@@ -82,6 +83,7 @@ struct capability_gr
 #define CAPABILITY_CODE_DYNAMIC_LEN     0
 #define CAPABILITY_CODE_RESTART_LEN     2 /* Receiving only case */
 #define CAPABILITY_CODE_AS4_LEN         4
+#define CAPABILITY_CODE_ADDPATH_LEN     4
 
 /* Cooperative Route Filtering Capability.  */
 
index 1d7d2d5f9bb9902791629d14edff2f33793db3e6..7213d1a00b6fea04a280f9e236193c29e0d11664 100644 (file)
@@ -1796,8 +1796,8 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
   /* Unfeasible Route packet format check. */
   if (withdraw_len > 0)
     {
-      ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), withdraw_len,
-                                   &num_pfx_wd);
+      ret = bgp_nlri_sanity_check (peer, AFI_IP, SAFI_UNICAST, stream_pnt (s),
+                                   withdraw_len, &num_pfx_wd);
       if (ret < 0)
        return -1;
 
@@ -1884,8 +1884,8 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
   if (update_len)
     {
       /* Check NLRI packet format and prefix length. */
-      ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), update_len,
-                                   &num_pfx_adv);
+      ret = bgp_nlri_sanity_check (peer, AFI_IP, SAFI_UNICAST, stream_pnt (s),
+                                   update_len, &num_pfx_adv);
       if (ret < 0)
         {
           bgp_attr_unintern_sub (&attr);
index 76b429dc0035891f5f626c7b98f1e3f223751680..f0b1e5ddf99ec255f99f7f8e0de09639a84d26a6 100644 (file)
@@ -2286,9 +2286,10 @@ bgp_withdraw_rsclient (struct peer *rsclient, afi_t afi, safi_t safi,
 }
 
 static int
-bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr,
-           afi_t afi, safi_t safi, int type, int sub_type,
-           struct prefix_rd *prd, u_char *tag, int soft_reconfig)
+bgp_update_main (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
+                 struct attr *attr, afi_t afi, safi_t safi, int type,
+                 int sub_type, struct prefix_rd *prd, u_char *tag,
+                 int soft_reconfig)
 {
   int ret;
   int aspath_loop_count = 0;
@@ -2314,7 +2315,8 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr,
 
   /* Check previously received route. */
   for (ri = rn->info; ri; ri = ri->next)
-    if (ri->peer == peer && ri->type == type && ri->sub_type == sub_type)
+    if (ri->peer == peer && ri->type == type && ri->sub_type == sub_type &&
+        ri->addpath_rx_id == addpath_id)
       break;
 
   /* AS path local-as loop check. */
@@ -2541,7 +2543,7 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr,
       bgp_unlock_node (rn);
 
       return 0;
-    }
+    } // End of implicit withdraw
 
   /* Received Logging. */
   if (bgp_debug_update(peer, p, 1))
@@ -2590,6 +2592,10 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr,
   else
     bgp_info_set_flag (rn, new, BGP_INFO_VALID);
 
+  /* Addpath ID */
+  new->addpath_rx_id = addpath_id;
+  new->addpath_tx_id = 0;
+
   /* Increment prefix */
   bgp_aggregate_increment (bgp, p, new, afi, safi);
   
@@ -2635,8 +2641,8 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr,
 }
 
 int
-bgp_update (struct peer *peer, struct prefix *p, struct attr *attr,
-            afi_t afi, safi_t safi, int type, int sub_type,
+bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
+            struct attr *attr, afi_t afi, safi_t safi, int type, int sub_type,
             struct prefix_rd *prd, u_char *tag, int soft_reconfig)
 {
   struct peer *rsclient;
@@ -2644,8 +2650,8 @@ bgp_update (struct peer *peer, struct prefix *p, struct attr *attr,
   struct bgp *bgp;
   int ret;
 
-  ret = bgp_update_main (peer, p, attr, afi, safi, type, sub_type, prd, tag,
-          soft_reconfig);
+  ret = bgp_update_main (peer, p, addpath_id, attr, afi, safi, type, sub_type,
+                         prd, tag, soft_reconfig);
 
   bgp = peer->bgp;
 
@@ -2653,17 +2659,17 @@ bgp_update (struct peer *peer, struct prefix *p, struct attr *attr,
   for (ALL_LIST_ELEMENTS (bgp->rsclient, node, nnode, rsclient))
     {
       if (CHECK_FLAG (rsclient->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
-        bgp_update_rsclient (rsclient, afi, safi, attr, peer, p, type,
-                sub_type, prd, tag);
+        bgp_update_rsclient (rsclient, afi, safi, attr, peer, p,
+                             type, sub_type, prd, tag);
     }
 
   return ret;
 }
 
 int
-bgp_withdraw (struct peer *peer, struct prefix *p, struct attr *attr, 
-            afi_t afi, safi_t safi, int type, int sub_type, 
-            struct prefix_rd *prd, u_char *tag)
+bgp_withdraw (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
+              struct attr *attr, afi_t afi, safi_t safi, int type, int sub_type,
+             struct prefix_rd *prd, u_char *tag)
 {
   struct bgp *bgp;
   char buf[SU_ADDRSTRLEN];
@@ -2678,7 +2684,8 @@ bgp_withdraw (struct peer *peer, struct prefix *p, struct attr *attr,
   for (ALL_LIST_ELEMENTS (bgp->rsclient, node, nnode, rsclient))
     {
       if (CHECK_FLAG (rsclient->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
-        bgp_withdraw_rsclient (rsclient, afi, safi, peer, p, type, sub_type, prd, tag);
+        bgp_withdraw_rsclient (rsclient, afi, safi, peer, p, type,
+                               sub_type, prd, tag);
     }
 
   /* Logging. */
@@ -2699,7 +2706,8 @@ bgp_withdraw (struct peer *peer, struct prefix *p, struct attr *attr,
 
   /* Lookup withdrawn route. */
   for (ri = rn->info; ri; ri = ri->next)
-    if (ri->peer == peer && ri->type == type && ri->sub_type == sub_type)
+    if (ri->peer == peer && ri->type == type && ri->sub_type == sub_type &&
+        ri->addpath_rx_id == addpath_id)
       break;
 
   /* Withdraw specified route from routing table. */
@@ -2959,8 +2967,8 @@ bgp_soft_reconfig_table (struct peer *peer, afi_t afi, safi_t safi,
            struct bgp_info *ri = rn->info;
            u_char *tag = (ri && ri->extra) ? ri->extra->tag : NULL;
 
-           ret = bgp_update (peer, &rn->p, ain->attr, afi, safi,
-                             ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
+           ret = bgp_update (peer, &rn->p, ri->addpath_rx_id, ain->attr,
+                              afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
                              prd, tag, 1);
 
            if (ret < 0)
@@ -3343,6 +3351,10 @@ bgp_nlri_parse (struct peer *peer, struct attr *attr, struct bgp_nlri *packet)
   struct prefix p;
   int psize;
   int ret;
+  afi_t afi;
+  safi_t safi;
+  u_char addpath_encoded;
+  u_int32_t addpath_id;
 
   /* Check peer status. */
   if (peer->status != Established)
@@ -3350,20 +3362,32 @@ bgp_nlri_parse (struct peer *peer, struct attr *attr, struct bgp_nlri *packet)
   
   pnt = packet->nlri;
   lim = pnt + packet->length;
+  afi = packet->afi;
+  safi = packet->safi;
+  addpath_id = 0;
+
+  addpath_encoded = (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV) &&
+                     CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_TX_RCV));
 
   for (; pnt < lim; pnt += psize)
     {
       /* Clear prefix structure. */
       memset (&p, 0, sizeof (struct prefix));
 
+      if (addpath_encoded)
+        {
+          addpath_id = ntohl(*((uint32_t*) pnt));
+          pnt += BGP_ADDPATH_ID_LEN;
+        }
+
       /* Fetch prefix length. */
       p.prefixlen = *pnt++;
-      p.family = afi2family (packet->afi);
+      p.family = afi2family (afi);
       
       /* Already checked in nlri_sanity_check().  We do double check
          here. */
-      if ((packet->afi == AFI_IP && p.prefixlen > 32)
-         || (packet->afi == AFI_IP6 && p.prefixlen > 128))
+      if ((afi == AFI_IP && p.prefixlen > 32)
+         || (afi == AFI_IP6 && p.prefixlen > 128))
        return -1;
 
       /* Packet size overflow check. */
@@ -3377,7 +3401,7 @@ bgp_nlri_parse (struct peer *peer, struct attr *attr, struct bgp_nlri *packet)
       memcpy (&p.u.prefix, pnt, psize);
 
       /* Check address. */
-      if (packet->afi == AFI_IP && packet->safi == SAFI_UNICAST)
+      if (afi == AFI_IP && safi == SAFI_UNICAST)
        {
          if (IN_CLASSD (ntohl (p.u.prefix4.s_addr)))
            {
@@ -3397,7 +3421,7 @@ bgp_nlri_parse (struct peer *peer, struct attr *attr, struct bgp_nlri *packet)
 
 #ifdef HAVE_IPV6
       /* Check address. */
-      if (packet->afi == AFI_IP6 && packet->safi == SAFI_UNICAST)
+      if (afi == AFI_IP6 && safi == SAFI_UNICAST)
        {
          if (IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))
            {
@@ -3413,10 +3437,10 @@ bgp_nlri_parse (struct peer *peer, struct attr *attr, struct bgp_nlri *packet)
 
       /* Normal process. */
       if (attr)
-       ret = bgp_update (peer, &p, attr, packet->afi, packet->safi, 
+       ret = bgp_update (peer, &p, addpath_id, attr, afi, safi,
                          ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, NULL, 0);
       else
-       ret = bgp_withdraw (peer, &p, attr, packet->afi, packet->safi, 
+       ret = bgp_withdraw (peer, &p, addpath_id, attr, afi, safi,
                            ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, NULL);
 
       /* Address family configuration mismatch or maximum-prefix count
@@ -3434,22 +3458,31 @@ bgp_nlri_parse (struct peer *peer, struct attr *attr, struct bgp_nlri *packet)
 
 /* NLRI encode syntax check routine. */
 int
-bgp_nlri_sanity_check (struct peer *peer, int afi, u_char *pnt,
+bgp_nlri_sanity_check (struct peer *peer, int afi, safi_t safi, u_char *pnt,
                       bgp_size_t length, int *numpfx)
 {
   u_char *end;
   u_char prefixlen;
   int psize;
+  u_char addpath_encoded;
 
   *numpfx = 0;
   end = pnt + length;
 
+  addpath_encoded = (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV) &&
+                     CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_TX_RCV));
+
   /* RFC1771 6.3 The NLRI field in the UPDATE message is checked for
      syntactic validity.  If the field is syntactically incorrect,
      then the Error Subcode is set to Invalid Network Field. */
 
   while (pnt < end)
     {
+      /* If the NLRI is encoded using addpath then the first 4 bytes are
+       * the addpath ID. */
+      if (addpath_encoded)
+        pnt += BGP_ADDPATH_ID_LEN;
+
       prefixlen = *pnt++;
       
       /* Prefix length check. */
@@ -6563,7 +6596,13 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
       if (binfo->extra && binfo->extra->damp_info)
        bgp_damp_info_vty (vty, binfo);
 
-      /* Line 7 display Uptime */
+      /* Line 7 display Addpath IDs */
+      if (binfo->addpath_rx_id || binfo->addpath_tx_id)
+        vty_out (vty, "      AddPath ID: RX %u, TX %u%s",
+                 binfo->addpath_rx_id, binfo->addpath_tx_id,
+                 VTY_NEWLINE);
+
+      /* Line 8 display Uptime */
 #ifdef HAVE_CLOCK_MONOTONIC
       tbuf = time(NULL) - (bgp_clock() - binfo->uptime);
       vty_out (vty, "      Last update: %s", ctime(&tbuf));
index f452ea25430aa752a1e4b32a84b049b42922d338..c35b5f11150560ee96876648fdde0e4b46c282ea 100644 (file)
@@ -108,6 +108,10 @@ struct bgp_info
 
   u_short instance;
 
+  /* Addpath identifiers */
+  u_int32_t addpath_rx_id;
+  u_int32_t addpath_tx_id;
+
 };
 
 /* BGP static route configuration. */
@@ -220,7 +224,7 @@ extern struct bgp_info_extra *bgp_info_extra_get (struct bgp_info *);
 extern void bgp_info_set_flag (struct bgp_node *, struct bgp_info *, u_int32_t);
 extern void bgp_info_unset_flag (struct bgp_node *, struct bgp_info *, u_int32_t);
 
-extern int bgp_nlri_sanity_check (struct peer *, int, u_char *, bgp_size_t, int *);
+extern int bgp_nlri_sanity_check (struct peer *, int, safi_t, u_char *, bgp_size_t, int *);
 extern int bgp_nlri_parse (struct peer *, struct attr *, struct bgp_nlri *);
 
 extern int bgp_maximum_prefix_overflow (struct peer *, afi_t, safi_t, int);
@@ -243,10 +247,10 @@ extern int bgp_static_unset_vpnv4 (struct vty *, const char *,
                             const char *, const char *);
 
 /* this is primarily for MPLS-VPN */
-extern int bgp_update (struct peer *, struct prefix *, struct attr *,
+extern int bgp_update (struct peer *, struct prefix *, u_int32_t, struct attr *,
                       afi_t, safi_t, int, int, struct prefix_rd *, 
                       u_char *, int);
-extern int bgp_withdraw (struct peer *, struct prefix *, struct attr *,
+extern int bgp_withdraw (struct peer *, struct prefix *, u_int32_t, struct attr *,
                         afi_t, safi_t, int, int, struct prefix_rd *, u_char *);
 
 /* for bgp_nexthop and bgp_damp */
index a7b5a90ba7dd1c825d9c1187438116994067b261..348687d38a7ce0a7f29f5f8e3fb8ad1a5dd27624 100644 (file)
@@ -8645,6 +8645,47 @@ bgp_show_peer (struct vty *vty, struct peer *p)
                         CHECK_FLAG (p->cap, PEER_CAP_AS4_ADV) ? "and " : "");
              vty_out (vty, "%s", VTY_NEWLINE);
            }
+
+         /* AddPath */
+         if (CHECK_FLAG (p->cap, PEER_CAP_ADDPATH_RCV)
+             || CHECK_FLAG (p->cap, PEER_CAP_ADDPATH_ADV))
+            {
+             vty_out (vty, "    AddPath:%s", VTY_NEWLINE);
+
+              for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
+                for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
+                  {
+
+                    if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_TX_ADV) ||
+                        CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_TX_RCV))
+                      {
+                        vty_out (vty, "      %s: TX ", afi_safi_print (afi, safi));
+
+                        if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_TX_ADV))
+                          vty_out (vty, "advertised", afi_safi_print (afi, safi));
+
+                        if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_TX_RCV))
+                          vty_out (vty, "%sreceived", CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_TX_ADV) ? " and " : "" );
+
+                        vty_out (vty, "%s", VTY_NEWLINE);
+                      }
+
+                    if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV) ||
+                        CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_RCV))
+                      {
+                        vty_out (vty, "      %s: RX ", afi_safi_print (afi, safi));
+
+                        if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV))
+                          vty_out (vty, "advertised", afi_safi_print (afi, safi));
+
+                        if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_RCV))
+                          vty_out (vty, "%sreceived", CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV) ? " and " : "" );
+
+                        vty_out (vty, "%s", VTY_NEWLINE);
+                      }
+                  }
+            }
+
          /* Dynamic */
          if (CHECK_FLAG (p->cap, PEER_CAP_DYNAMIC_RCV)
              || CHECK_FLAG (p->cap, PEER_CAP_DYNAMIC_ADV))
index 94540749b9c2ce189fa2596ecf430adb24907f47..6eafb59b208aeea724d020e09aba28a0b98770a9 100644 (file)
@@ -272,6 +272,11 @@ struct bgp_nexthop
 #endif /* HAVE_IPV6 */  
 };
 
+/* BGP addpath values */
+#define BGP_ADDPATH_RX     1
+#define BGP_ADDPATH_TX     2
+#define BGP_ADDPATH_ID_LEN 4
+
 /* BGP router distinguisher value.  */
 #define BGP_RD_SIZE                8
 
@@ -442,6 +447,8 @@ struct peer
 #define PEER_CAP_AS4_RCV                    (1 << 8) /* as4 received */
 #define PEER_CAP_RESTART_BIT_ADV            (1 << 9) /* sent restart state */
 #define PEER_CAP_RESTART_BIT_RCV            (1 << 10) /* peer restart state */
+#define PEER_CAP_ADDPATH_ADV                (1 << 11) /* addpath advertised */
+#define PEER_CAP_ADDPATH_RCV                (1 << 12) /* addpath received */
 
   /* Capability flags (reset in bgp_stop) */
   u_int16_t af_cap[AFI_MAX][SAFI_MAX];
@@ -453,6 +460,10 @@ struct peer
 #define PEER_CAP_ORF_PREFIX_RM_OLD_RCV      (1 << 5) /* receive-mode received */
 #define PEER_CAP_RESTART_AF_RCV             (1 << 6) /* graceful restart afi/safi received */
 #define PEER_CAP_RESTART_AF_PRESERVE_RCV    (1 << 7) /* graceful restart afi/safi F-bit received */
+#define PEER_CAP_ADDPATH_AF_TX_ADV          (1 << 8) /* addpath tx advertised */
+#define PEER_CAP_ADDPATH_AF_TX_RCV          (1 << 9) /* addpath tx received */
+#define PEER_CAP_ADDPATH_AF_RX_ADV          (1 << 10) /* addpath rx advertised */
+#define PEER_CAP_ADDPATH_AF_RX_RCV          (1 << 11) /* addpath rx received */
 
   /* Global configuration flags. */
   u_int32_t flags;