mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-15 23:54:45 +00:00
BGP: add addpath RX support
This commit is contained in:
parent
0e5c866a48
commit
a82478b985
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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++)
|
||||
|
@ -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. */
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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,16 +2659,16 @@ 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,
|
||||
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;
|
||||
@ -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));
|
||||
|
@ -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 */
|
||||
|
@ -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))
|
||||
|
11
bgpd/bgpd.h
11
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;
|
||||
|
Loading…
Reference in New Issue
Block a user