bgpd: Add an option to limit outgoing prefixes

Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
This commit is contained in:
Donatas Abraitis 2020-01-17 16:04:18 +02:00
parent edf98aa365
commit fde246e835
5 changed files with 110 additions and 5 deletions

View File

@ -143,6 +143,7 @@ static void conf_copy(struct peer *dst, struct peer *src, afi_t afi,
dst->v_routeadv = src->v_routeadv; dst->v_routeadv = src->v_routeadv;
dst->flags = src->flags; dst->flags = src->flags;
dst->af_flags[afi][safi] = src->af_flags[afi][safi]; dst->af_flags[afi][safi] = src->af_flags[afi][safi];
dst->pmax_out[afi][safi] = src->pmax_out[afi][safi];
XFREE(MTYPE_BGP_PEER_HOST, dst->host); XFREE(MTYPE_BGP_PEER_HOST, dst->host);
dst->host = XSTRDUP(MTYPE_BGP_PEER_HOST, src->host); dst->host = XSTRDUP(MTYPE_BGP_PEER_HOST, src->host);

View File

@ -208,7 +208,7 @@ struct update_subgroup {
struct bgp_synchronize *sync; struct bgp_synchronize *sync;
/* send prefix count */ /* send prefix count */
unsigned long scount; uint32_t scount;
/* announcement attribute hash */ /* announcement attribute hash */
struct hash *hash; struct hash *hash;

View File

@ -744,6 +744,22 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
addpath_tx_id = adj->addpath_tx_id; addpath_tx_id = adj->addpath_tx_id;
path = adv->pathi; path = adv->pathi;
/* Check if we need to add a prefix to the packet if
* maximum-prefix-out is set for the peer.
*/
if (CHECK_FLAG(peer->af_flags[afi][safi],
PEER_FLAG_MAX_PREFIX_OUT)
&& subgrp->scount >= peer->pmax_out[afi][safi]) {
if (BGP_DEBUG(update, UPDATE_OUT)
|| BGP_DEBUG(update, UPDATE_PREFIX)) {
zlog_debug(
"%s reached maximum prefix to be send (%" PRIu32
")",
peer->host, peer->pmax_out[afi][safi]);
}
goto next;
}
space_remaining = STREAM_CONCAT_REMAIN(s, snlri, STREAM_SIZE(s)) space_remaining = STREAM_CONCAT_REMAIN(s, snlri, STREAM_SIZE(s))
- BGP_MAX_PACKET_SIZE_OVERFLOW; - BGP_MAX_PACKET_SIZE_OVERFLOW;
space_needed = space_needed =
@ -894,7 +910,7 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
subgrp->scount++; subgrp->scount++;
adj->attr = bgp_attr_intern(adv->baa->attr); adj->attr = bgp_attr_intern(adv->baa->attr);
next:
adv = bgp_advertise_clean_subgroup(subgrp, adj); adv = bgp_advertise_clean_subgroup(subgrp, adj);
} }

View File

@ -6058,6 +6058,56 @@ static int peer_maximum_prefix_unset_vty(struct vty *vty, const char *ip_str,
return bgp_vty_return(vty, ret); return bgp_vty_return(vty, ret);
} }
/* Maximum number of prefix to be sent to the neighbor. */
DEFUN(neighbor_maximum_prefix_out,
neighbor_maximum_prefix_out_cmd,
"neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix-out (1-4294967295)",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Maximum number of prefixes to be sent to this peer\n"
"Maximum no. of prefix limit\n")
{
int idx_peer = 1;
int idx_number = 3;
struct peer *peer;
uint32_t max;
afi_t afi = bgp_node_afi(vty);
safi_t safi = bgp_node_safi(vty);
peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
if (!peer)
return CMD_WARNING_CONFIG_FAILED;
max = strtoul(argv[idx_number]->arg, NULL, 10);
SET_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_OUT);
peer->pmax_out[afi][safi] = max;
return CMD_SUCCESS;
}
DEFUN(no_neighbor_maximum_prefix_out,
no_neighbor_maximum_prefix_out_cmd,
"no neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix-out",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Maximum number of prefixes to be sent to this peer\n")
{
int idx_peer = 2;
struct peer *peer;
afi_t afi = bgp_node_afi(vty);
safi_t safi = bgp_node_safi(vty);
peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
if (!peer)
return CMD_WARNING_CONFIG_FAILED;
peer->pmax_out[afi][safi] = 0;
return CMD_SUCCESS;
}
/* Maximum number of prefix configuration. prefix count is different /* Maximum number of prefix configuration. prefix count is different
for each peer configuration. So this configuration can be set for for each peer configuration. So this configuration can be set for
each peer configuration. */ each peer configuration. */
@ -9190,6 +9240,11 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi,
json_object_int_add(json_addr, "sentPrefixCounter", json_object_int_add(json_addr, "sentPrefixCounter",
(PAF_SUBGRP(paf))->scount); (PAF_SUBGRP(paf))->scount);
/* Maximum prefix */
if (CHECK_FLAG(p->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_OUT))
json_object_int_add(json_addr, "prefixOutAllowedMax",
p->pmax_out[afi][safi]);
/* Maximum prefix */ /* Maximum prefix */
if (CHECK_FLAG(p->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX)) { if (CHECK_FLAG(p->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX)) {
json_object_int_add(json_addr, "prefixAllowedMax", json_object_int_add(json_addr, "prefixAllowedMax",
@ -9476,6 +9531,13 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi,
vty_out(vty, " %" PRIu32 " accepted prefixes\n", vty_out(vty, " %" PRIu32 " accepted prefixes\n",
p->pcount[afi][safi]); p->pcount[afi][safi]);
/* maximum-prefix-out */
if (CHECK_FLAG(p->af_flags[afi][safi],
PEER_FLAG_MAX_PREFIX_OUT))
vty_out(vty,
" Maximum allowed prefixes sent %" PRIu32 "\n",
p->pmax_out[afi][safi]);
/* Maximum prefix */ /* Maximum prefix */
if (CHECK_FLAG(p->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX)) { if (CHECK_FLAG(p->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX)) {
vty_out(vty, vty_out(vty,
@ -13579,6 +13641,11 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
vty_out(vty, "\n"); vty_out(vty, "\n");
} }
/* maximum-prefix-out */
if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_MAX_PREFIX_OUT))
vty_out(vty, " neighbor %s maximum-prefix-out %" PRIu32 "\n",
addr, peer->pmax_out[afi][safi]);
/* Route server client. */ /* Route server client. */
if (peergroup_af_flag_check(peer, afi, safi, if (peergroup_af_flag_check(peer, afi, safi,
PEER_FLAG_RSERVER_CLIENT)) { PEER_FLAG_RSERVER_CLIENT)) {
@ -15115,6 +15182,26 @@ void bgp_vty_init(void)
install_element(BGP_VPNV6_NODE, &neighbor_unsuppress_map_cmd); install_element(BGP_VPNV6_NODE, &neighbor_unsuppress_map_cmd);
install_element(BGP_VPNV6_NODE, &no_neighbor_unsuppress_map_cmd); install_element(BGP_VPNV6_NODE, &no_neighbor_unsuppress_map_cmd);
/* neighbor maximum-prefix-out commands. */
install_element(BGP_NODE, &neighbor_maximum_prefix_out_cmd);
install_element(BGP_NODE, &no_neighbor_maximum_prefix_out_cmd);
install_element(BGP_IPV4_NODE, &neighbor_maximum_prefix_out_cmd);
install_element(BGP_IPV4_NODE, &no_neighbor_maximum_prefix_out_cmd);
install_element(BGP_IPV4M_NODE, &neighbor_maximum_prefix_out_cmd);
install_element(BGP_IPV4M_NODE, &no_neighbor_maximum_prefix_out_cmd);
install_element(BGP_IPV4L_NODE, &neighbor_maximum_prefix_out_cmd);
install_element(BGP_IPV4L_NODE, &no_neighbor_maximum_prefix_out_cmd);
install_element(BGP_IPV6_NODE, &neighbor_maximum_prefix_out_cmd);
install_element(BGP_IPV6_NODE, &no_neighbor_maximum_prefix_out_cmd);
install_element(BGP_IPV6M_NODE, &neighbor_maximum_prefix_out_cmd);
install_element(BGP_IPV6M_NODE, &no_neighbor_maximum_prefix_out_cmd);
install_element(BGP_IPV6L_NODE, &neighbor_maximum_prefix_out_cmd);
install_element(BGP_IPV6L_NODE, &no_neighbor_maximum_prefix_out_cmd);
install_element(BGP_VPNV4_NODE, &neighbor_maximum_prefix_out_cmd);
install_element(BGP_VPNV4_NODE, &no_neighbor_maximum_prefix_out_cmd);
install_element(BGP_VPNV6_NODE, &neighbor_maximum_prefix_out_cmd);
install_element(BGP_VPNV6_NODE, &no_neighbor_maximum_prefix_out_cmd);
/* "neighbor maximum-prefix" commands. */ /* "neighbor maximum-prefix" commands. */
install_element(BGP_NODE, &neighbor_maximum_prefix_hidden_cmd); install_element(BGP_NODE, &neighbor_maximum_prefix_hidden_cmd);
install_element(BGP_NODE, install_element(BGP_NODE,

View File

@ -988,6 +988,7 @@ struct peer {
#define PEER_FLAG_WEIGHT (1 << 24) /* weight */ #define PEER_FLAG_WEIGHT (1 << 24) /* weight */
#define PEER_FLAG_ALLOWAS_IN_ORIGIN (1 << 25) /* allowas-in origin */ #define PEER_FLAG_ALLOWAS_IN_ORIGIN (1 << 25) /* allowas-in origin */
#define PEER_FLAG_SEND_LARGE_COMMUNITY (1 << 26) /* Send large Communities */ #define PEER_FLAG_SEND_LARGE_COMMUNITY (1 << 26) /* Send large Communities */
#define PEER_FLAG_MAX_PREFIX_OUT (1 << 27) /* outgoing maximum prefix */
enum bgp_addpath_strat addpath_type[AFI_MAX][SAFI_MAX]; enum bgp_addpath_strat addpath_type[AFI_MAX][SAFI_MAX];
@ -1120,9 +1121,6 @@ struct peer {
/* timestamp when the last msg was written */ /* timestamp when the last msg was written */
_Atomic time_t last_update; _Atomic time_t last_update;
/* Send prefix count. */
unsigned long scount[AFI_MAX][SAFI_MAX];
/* Notify data. */ /* Notify data. */
struct bgp_notify notify; struct bgp_notify notify;
@ -1173,6 +1171,9 @@ struct peer {
uint16_t pmax_restart[AFI_MAX][SAFI_MAX]; uint16_t pmax_restart[AFI_MAX][SAFI_MAX];
#define MAXIMUM_PREFIX_THRESHOLD_DEFAULT 75 #define MAXIMUM_PREFIX_THRESHOLD_DEFAULT 75
/* Send prefix count. */
uint32_t pmax_out[AFI_MAX][SAFI_MAX];
/* allowas-in. */ /* allowas-in. */
char allowas_in[AFI_MAX][SAFI_MAX]; char allowas_in[AFI_MAX][SAFI_MAX];