summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgpd.c116
-rw-r--r--bgpd/bgpd.h23
2 files changed, 92 insertions, 47 deletions
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index a331fad5d4..32a1ea5a5f 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -5947,39 +5947,63 @@ int peer_maximum_prefix_set(struct peer *peer, afi_t afi, safi_t safi,
struct peer_group *group;
struct listnode *node, *nnode;
+ /* apply configuration and set flags */
SET_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
- peer->pmax[afi][safi] = max;
- peer->pmax_threshold[afi][safi] = threshold;
- peer->pmax_restart[afi][safi] = restart;
if (warning)
SET_FLAG(peer->af_flags[afi][safi],
PEER_FLAG_MAX_PREFIX_WARNING);
else
UNSET_FLAG(peer->af_flags[afi][safi],
PEER_FLAG_MAX_PREFIX_WARNING);
+ peer->pmax[afi][safi] = max;
+ peer->pmax_threshold[afi][safi] = threshold;
+ peer->pmax_restart[afi][safi] = restart;
+ /* if handling a peer-group, apply to all children */
if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
group = peer->group;
for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
- SET_FLAG(peer->af_flags[afi][safi],
- PEER_FLAG_MAX_PREFIX);
- peer->pmax[afi][safi] = max;
- peer->pmax_threshold[afi][safi] = threshold;
- peer->pmax_restart[afi][safi] = restart;
- if (warning)
+ /*
+ * If peer configuration is user-set, it overrides
+ * peer-group config.
+ */
+ if (!CHECK_FLAG(peer->af_flags_override[afi][safi],
+ PEER_FLAG_MAX_PREFIX)) {
SET_FLAG(peer->af_flags[afi][safi],
- PEER_FLAG_MAX_PREFIX_WARNING);
- else
- UNSET_FLAG(peer->af_flags[afi][safi],
- PEER_FLAG_MAX_PREFIX_WARNING);
+ PEER_FLAG_MAX_PREFIX);
+ peer->pmax[afi][safi] = max;
+ peer->pmax_threshold[afi][safi] = threshold;
+ peer->pmax_restart[afi][safi] = restart;
+ }
+ if (!CHECK_FLAG(peer->af_flags_override[afi][safi],
+ PEER_FLAG_MAX_PREFIX_WARNING)) {
+ if (warning)
+ SET_FLAG(peer->af_flags[afi][safi],
+ PEER_FLAG_MAX_PREFIX_WARNING);
+ else
+ UNSET_FLAG(
+ peer->af_flags[afi][safi],
+ PEER_FLAG_MAX_PREFIX_WARNING);
+ }
if ((peer->status == Established)
&& (peer->afc[afi][safi]))
bgp_maximum_prefix_overflow(peer, afi, safi, 1);
}
} else {
+ /* if not handling a peer-group, set the override flags */
if ((peer->status == Established) && (peer->afc[afi][safi]))
bgp_maximum_prefix_overflow(peer, afi, safi, 1);
+
+ SET_FLAG(peer->af_flags_override[afi][safi],
+ PEER_FLAG_MAX_PREFIX);
+
+ if (warning)
+ SET_FLAG(peer->af_flags_override[afi][safi],
+ PEER_FLAG_MAX_PREFIX_WARNING);
+ else
+ UNSET_FLAG(peer->af_flags_override[afi][safi],
+ PEER_FLAG_MAX_PREFIX_WARNING);
}
return 0;
@@ -5990,49 +6014,49 @@ int peer_maximum_prefix_unset(struct peer *peer, afi_t afi, safi_t safi)
struct peer_group *group;
struct listnode *node, *nnode;
- /* apply peer-group config */
- if (peer_group_active(peer)) {
- if (CHECK_FLAG(peer->group->conf->af_flags[afi][safi],
- PEER_FLAG_MAX_PREFIX))
- SET_FLAG(peer->af_flags[afi][safi],
- PEER_FLAG_MAX_PREFIX);
- else
- UNSET_FLAG(peer->af_flags[afi][safi],
- PEER_FLAG_MAX_PREFIX);
-
- if (CHECK_FLAG(peer->group->conf->af_flags[afi][safi],
- PEER_FLAG_MAX_PREFIX_WARNING))
- SET_FLAG(peer->af_flags[afi][safi],
- PEER_FLAG_MAX_PREFIX_WARNING);
- else
- UNSET_FLAG(peer->af_flags[afi][safi],
- PEER_FLAG_MAX_PREFIX_WARNING);
-
- peer->pmax[afi][safi] = peer->group->conf->pmax[afi][safi];
- peer->pmax_threshold[afi][safi] =
- peer->group->conf->pmax_threshold[afi][safi];
- peer->pmax_restart[afi][safi] =
- peer->group->conf->pmax_restart[afi][safi];
- return 0;
- }
-
UNSET_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
UNSET_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
peer->pmax[afi][safi] = 0;
peer->pmax_threshold[afi][safi] = 0;
peer->pmax_restart[afi][safi] = 0;
- if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
+ /* if not handling a peer-group, unset override flags */
+ if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
+ UNSET_FLAG(peer->af_flags_override[afi][safi],
+ PEER_FLAG_MAX_PREFIX);
+ UNSET_FLAG(peer->af_flags_override[afi][safi],
+ PEER_FLAG_MAX_PREFIX_WARNING);
+ /* if peer is part of a peer-group, apply peer-group config */
+ if (peer_group_active(peer)) {
+ peer->pmax[afi][safi] =
+ peer->group->conf->pmax[afi][safi];
+ peer->pmax_threshold[afi][safi] =
+ peer->group->conf->pmax_threshold[afi][safi];
+ peer->pmax_restart[afi][safi] =
+ peer->group->conf->pmax_restart[afi][safi];
+ }
+
return 0;
+ }
+ /*
+ * If this peer is a peer-group, set all peers in the group unless they
+ * have overrides for our config.
+ */
group = peer->group;
for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
- UNSET_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
- UNSET_FLAG(peer->af_flags[afi][safi],
- PEER_FLAG_MAX_PREFIX_WARNING);
- peer->pmax[afi][safi] = 0;
- peer->pmax_threshold[afi][safi] = 0;
- peer->pmax_restart[afi][safi] = 0;
+ if (!CHECK_FLAG(peer->af_flags_override[afi][safi],
+ PEER_FLAG_MAX_PREFIX_WARNING))
+ UNSET_FLAG(peer->af_flags[afi][safi],
+ PEER_FLAG_MAX_PREFIX_WARNING);
+ if (!CHECK_FLAG(peer->af_flags_override[afi][safi],
+ PEER_FLAG_MAX_PREFIX)) {
+ UNSET_FLAG(peer->af_flags[afi][safi],
+ PEER_FLAG_MAX_PREFIX);
+ peer->pmax[afi][safi] = 0;
+ peer->pmax_threshold[afi][safi] = 0;
+ peer->pmax_restart[afi][safi] = 0;
+ }
}
return 0;
}
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index 470fd10850..d9ce77a55a 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -836,7 +836,28 @@ struct peer {
/* NSF mode (graceful restart) */
uint8_t nsf[AFI_MAX][SAFI_MAX];
- /* Per AF configuration flags. */
+ /* Peer Per AF flags */
+ /*
+ * Parallel array to af_flags that indicates whether each flag
+ * originates from a peer-group or if it is config that is specific to
+ * this individual peer. If a flag is set independent of the
+ * peer-group the same bit should be set here. If this peer is a
+ * peer-group, this memory region should be all zeros. The assumption
+ * is that the default state for all flags is unset.
+ *
+ * Notes:
+ * - if a flag for an individual peer is unset, the corresponding
+ * override flag is unset and the peer is considered to be back in
+ * sync with the peer-group.
+ * - This does *not* contain the flag values, rather it contains
+ * whether the flag at the same position in af_flags is
+ * *peer-specific*.
+ */
+ uint32_t af_flags_override[AFI_MAX][SAFI_MAX];
+ /*
+ * Effective flags, computed by applying peer-group flags and then
+ * overriding with individual flags
+ */
uint32_t af_flags[AFI_MAX][SAFI_MAX];
#define PEER_FLAG_SEND_COMMUNITY (1 << 0) /* send-community */
#define PEER_FLAG_SEND_EXT_COMMUNITY (1 << 1) /* send-community ext. */