diff options
author | Donald Sharp <sharpd@cumulusnetworks.com> | 2015-05-20 03:03:45 +0200 |
---|---|---|
committer | Donald Sharp <sharpd@cumulusnetworks.com> | 2015-05-20 03:03:45 +0200 |
commit | a82478b985085105741eed222d8fab7ecc49f25d (patch) | |
tree | 9ef546ed14694cbfef607dfb27716207fd2010fd | |
parent | A valid BGP nexthop is flagged as invalid (diff) | |
download | frr-a82478b985085105741eed222d8fab7ecc49f25d.tar.xz frr-a82478b985085105741eed222d8fab7ecc49f25d.zip |
BGP: add addpath RX support
-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 8ff8a5cff..506583b3e 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 087f544b6..22ae54e0e 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 0bcccb8aa..7aef76d53 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 2b1382d8b..fa9c78ec9 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 1d7d2d5f9..7213d1a00 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 76b429dc0..f0b1e5ddf 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 f452ea254..c35b5f111 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 a7b5a90ba..348687d38 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 94540749b..6eafb59b2 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; |