diff options
-rw-r--r-- | bgpd/bgp_updgrp.c | 1 | ||||
-rw-r--r-- | bgpd/bgp_updgrp.h | 2 | ||||
-rw-r--r-- | bgpd/bgp_updgrp_packet.c | 18 | ||||
-rw-r--r-- | bgpd/bgp_vty.c | 87 | ||||
-rw-r--r-- | bgpd/bgpd.h | 7 |
5 files changed, 110 insertions, 5 deletions
diff --git a/bgpd/bgp_updgrp.c b/bgpd/bgp_updgrp.c index 5f3f5cde9..5b3eb2c71 100644 --- a/bgpd/bgp_updgrp.c +++ b/bgpd/bgp_updgrp.c @@ -143,6 +143,7 @@ static void conf_copy(struct peer *dst, struct peer *src, afi_t afi, dst->v_routeadv = src->v_routeadv; dst->flags = src->flags; 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); dst->host = XSTRDUP(MTYPE_BGP_PEER_HOST, src->host); diff --git a/bgpd/bgp_updgrp.h b/bgpd/bgp_updgrp.h index bb547454f..fe654bb3e 100644 --- a/bgpd/bgp_updgrp.h +++ b/bgpd/bgp_updgrp.h @@ -208,7 +208,7 @@ struct update_subgroup { struct bgp_synchronize *sync; /* send prefix count */ - unsigned long scount; + uint32_t scount; /* announcement attribute hash */ struct hash *hash; diff --git a/bgpd/bgp_updgrp_packet.c b/bgpd/bgp_updgrp_packet.c index 9329c8d89..39eb06528 100644 --- a/bgpd/bgp_updgrp_packet.c +++ b/bgpd/bgp_updgrp_packet.c @@ -744,6 +744,22 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp) addpath_tx_id = adj->addpath_tx_id; 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)) - BGP_MAX_PACKET_SIZE_OVERFLOW; space_needed = @@ -894,7 +910,7 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp) subgrp->scount++; adj->attr = bgp_attr_intern(adv->baa->attr); - +next: adv = bgp_advertise_clean_subgroup(subgrp, adj); } diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 53d973295..9dc6549d9 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -6058,6 +6058,56 @@ static int peer_maximum_prefix_unset_vty(struct vty *vty, const char *ip_str, 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 for each peer configuration. So this configuration can be set for each peer configuration. */ @@ -9191,6 +9241,11 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi, (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 */ if (CHECK_FLAG(p->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX)) { json_object_int_add(json_addr, "prefixAllowedMax", p->pmax[afi][safi]); @@ -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", 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 */ if (CHECK_FLAG(p->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX)) { vty_out(vty, @@ -13579,6 +13641,11 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp, 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. */ if (peergroup_af_flag_check(peer, afi, safi, 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, &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. */ install_element(BGP_NODE, &neighbor_maximum_prefix_hidden_cmd); install_element(BGP_NODE, diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 7d8157900..4c4787ed5 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -988,6 +988,7 @@ struct peer { #define PEER_FLAG_WEIGHT (1 << 24) /* weight */ #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_MAX_PREFIX_OUT (1 << 27) /* outgoing maximum prefix */ enum bgp_addpath_strat addpath_type[AFI_MAX][SAFI_MAX]; @@ -1120,9 +1121,6 @@ struct peer { /* timestamp when the last msg was written */ _Atomic time_t last_update; - /* Send prefix count. */ - unsigned long scount[AFI_MAX][SAFI_MAX]; - /* Notify data. */ struct bgp_notify notify; @@ -1173,6 +1171,9 @@ struct peer { uint16_t pmax_restart[AFI_MAX][SAFI_MAX]; #define MAXIMUM_PREFIX_THRESHOLD_DEFAULT 75 + /* Send prefix count. */ + uint32_t pmax_out[AFI_MAX][SAFI_MAX]; + /* allowas-in. */ char allowas_in[AFI_MAX][SAFI_MAX]; |