diff options
| -rw-r--r-- | bgpd/bgp_vty.c | 14 | ||||
| -rw-r--r-- | bgpd/bgpd.c | 86 | ||||
| -rw-r--r-- | bgpd/bgpd.h | 4 |
3 files changed, 96 insertions, 8 deletions
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 0ffccf7bf8..0072148823 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -7666,6 +7666,7 @@ DEFUN(neighbor_maximum_prefix_out, "Maximum number of prefixes to be sent to this peer\n" "Maximum no. of prefix limit\n") { + int ret; int idx_peer = 1; int idx_number = 3; struct peer *peer; @@ -7679,11 +7680,9 @@ DEFUN(neighbor_maximum_prefix_out, 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; + ret = peer_maximum_prefix_out_set(peer, afi, safi, max); - peer_maximum_prefix_out_refresh_routes(peer, afi, safi); - return CMD_SUCCESS; + return bgp_vty_return(vty, ret); } DEFUN(no_neighbor_maximum_prefix_out, @@ -7695,6 +7694,7 @@ DEFUN(no_neighbor_maximum_prefix_out, "Maximum number of prefixes to be sent to this peer\n" "Maximum no. of prefix limit\n") { + int ret; int idx_peer = 2; struct peer *peer; afi_t afi = bgp_node_afi(vty); @@ -7704,11 +7704,9 @@ DEFUN(no_neighbor_maximum_prefix_out, if (!peer) return CMD_WARNING_CONFIG_FAILED; - UNSET_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_OUT); - peer->pmax_out[afi][safi] = 0; + ret = peer_maximum_prefix_out_unset(peer, afi, safi); - peer_maximum_prefix_out_refresh_routes(peer, afi, safi); - return CMD_SUCCESS; + return bgp_vty_return(vty, ret); } /* Maximum number of prefix configuration. Prefix count is different diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 23024c2108..920660f9d9 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -2012,6 +2012,10 @@ static void peer_group2peer_config_copy_af(struct peer_group *group, PEER_ATTR_INHERIT(peer, group, pmax_restart[afi][safi]); } + /* maximum-prefix-out */ + if (!CHECK_FLAG(pflags_ovrd, PEER_FLAG_MAX_PREFIX_OUT)) + PEER_ATTR_INHERIT(peer, group, pmax_out[afi][safi]); + /* allowas-in */ if (!CHECK_FLAG(pflags_ovrd, PEER_FLAG_ALLOWAS_IN)) PEER_ATTR_INHERIT(peer, group, allowas_in[afi][safi]); @@ -4220,6 +4224,7 @@ static const struct peer_flag_action peer_af_flag_action_list[] = { {PEER_FLAG_MAX_PREFIX, 0, peer_change_none}, {PEER_FLAG_MAX_PREFIX_WARNING, 0, peer_change_none}, {PEER_FLAG_MAX_PREFIX_FORCE, 0, peer_change_none}, + {PEER_FLAG_MAX_PREFIX_OUT, 0, peer_change_none}, {PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED, 0, peer_change_reset_out}, {PEER_FLAG_FORCE_NEXTHOP_SELF, 1, peer_change_reset_out}, {PEER_FLAG_REMOVE_PRIVATE_AS_ALL, 1, peer_change_reset_out}, @@ -7328,6 +7333,87 @@ void peer_maximum_prefix_out_refresh_routes(struct peer *peer, afi_t afi, bgp_announce_route(peer, afi, safi, false); } +int peer_maximum_prefix_out_set(struct peer *peer, afi_t afi, safi_t safi, + uint32_t max) +{ + struct peer *member; + struct listnode *node, *nnode; + + /* Set flag on peer and peer-group member if any */ + peer_af_flag_set(peer, afi, safi, PEER_FLAG_MAX_PREFIX_OUT); + /* Set configuration on peer. */ + peer->pmax_out[afi][safi] = max; + + /* Check if handling a regular peer. */ + if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { + /* Skip peer-group mechanics for regular peers. */ + peer_maximum_prefix_out_refresh_routes(peer, afi, safi); + return 0; + } + + /* + * Set flag and configuration on all peer-group members, unless they + * are explicitely overriding peer-group configuration. + */ + for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) { + /* Skip peers with overridden configuration. */ + if (CHECK_FLAG(member->af_flags_override[afi][safi], + PEER_FLAG_MAX_PREFIX_OUT)) + continue; + + /* Set configuration on peer-group member. */ + member->pmax_out[afi][safi] = max; + + peer_maximum_prefix_out_refresh_routes(member, afi, safi); + } + return 0; +} + +int peer_maximum_prefix_out_unset(struct peer *peer, afi_t afi, safi_t safi) +{ + struct peer *member; + struct listnode *node; + /* Inherit configuration from peer-group if peer is member. */ + if (peer_group_active(peer)) { + peer_af_flag_inherit(peer, afi, safi, PEER_FLAG_MAX_PREFIX_OUT); + PEER_ATTR_INHERIT(peer, peer->group, pmax_out[afi][safi]); + + peer_maximum_prefix_out_refresh_routes(peer, afi, safi); + return 0; + } + + /* Remove flag and configuration from peer. */ + peer_af_flag_unset(peer, afi, safi, PEER_FLAG_MAX_PREFIX_OUT); + peer->pmax_out[afi][safi] = 0; + + /* Check if handling a regular peer. */ + if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { + /* Skip peer-group mechanics for regular peers. */ + peer_maximum_prefix_out_refresh_routes(peer, afi, safi); + return 0; + } + + /* + * Remove flag and configuration from all peer-group members, unless + * they are explicitely overriding peer-group configuration. + */ + for (ALL_LIST_ELEMENTS_RO(peer->group->peer, node, member)) { + /* Skip peers with overridden configuration. */ + if (CHECK_FLAG(member->af_flags_override[afi][safi], + PEER_FLAG_MAX_PREFIX_OUT)) + continue; + + /* Remove flag and configuration on peer-group member. + */ + UNSET_FLAG(member->af_flags[afi][safi], + PEER_FLAG_MAX_PREFIX_OUT); + member->pmax_out[afi][safi] = 0; + + peer_maximum_prefix_out_refresh_routes(member, afi, safi); + } + return 0; +} + int is_ebgp_multihop_configured(struct peer *peer) { struct peer_group *group; diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 96fe91af2a..8d79b9fe09 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -2208,6 +2208,10 @@ extern int peer_maximum_prefix_unset(struct peer *, afi_t, safi_t); extern void peer_maximum_prefix_out_refresh_routes(struct peer *peer, afi_t afi, safi_t safi); +extern int peer_maximum_prefix_out_set(struct peer *peer, afi_t afi, + safi_t safi, uint32_t max); +extern int peer_maximum_prefix_out_unset(struct peer *peer, afi_t afi, + safi_t safi); extern int peer_clear(struct peer *, struct listnode **); extern int peer_clear_soft(struct peer *, afi_t, safi_t, enum bgp_clear_type); |
