diff options
| -rw-r--r-- | bgpd/bgp_attr.c | 8 | ||||
| -rw-r--r-- | bgpd/bgp_mplsvpn.c | 20 | ||||
| -rw-r--r-- | bgpd/bgp_open.c | 65 | ||||
| -rw-r--r-- | bgpd/bgp_open.h | 2 | ||||
| -rw-r--r-- | bgpd/bgp_packet.c | 8 | ||||
| -rw-r--r-- | bgpd/bgp_route.c | 93 | ||||
| -rw-r--r-- | bgpd/bgp_route.h | 10 | ||||
| -rw-r--r-- | bgpd/bgp_vty.c | 41 | ||||
| -rw-r--r-- | bgpd/bgpd.h | 11 | 
9 files changed, 218 insertions, 40 deletions
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 8ff8a5cff5..506583b3e5 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -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;      } diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index 087f544b63..22ae54e0e0 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -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);      } diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c index 0bcccb8aab..7aef76d53d 100644 --- a/bgpd/bgp_open.c +++ b/bgpd/bgp_open.c @@ -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++) diff --git a/bgpd/bgp_open.h b/bgpd/bgp_open.h index 2b1382d8b7..fa9c78ec9d 100644 --- a/bgpd/bgp_open.h +++ b/bgpd/bgp_open.h @@ -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.  */ diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 1d7d2d5f9b..7213d1a00b 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -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); diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 76b429dc00..f0b1e5ddf9 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -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)); diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index f452ea2543..c35b5f1115 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -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 */ diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index a7b5a90ba7..348687d38a 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -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)) diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 94540749b9..6eafb59b20 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -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;  | 
