summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss White <russ@riw.us>2020-04-29 11:09:58 -0400
committerGitHub <noreply@github.com>2020-04-29 11:09:58 -0400
commit37d6afef2a9df1608e22ff632aae5ba93dd8bd9d (patch)
treed1aea001132fae250f19403d577b5fdb31493679
parent854a463b976f385b0819a8bbc3685a766f2a0982 (diff)
parentb3a3290e23039e326337b8e254de06a83f7330de (diff)
Merge pull request #6303 from dslicenc/stop-enhe-ras
bgpd: turn off RAs when numbered peers are deleted
-rw-r--r--bgpd/bgp_nht.c52
-rw-r--r--bgpd/bgp_nht.h3
-rw-r--r--bgpd/bgp_vty.c7
-rw-r--r--bgpd/bgp_zebra.c19
-rw-r--r--bgpd/bgpd.c35
5 files changed, 104 insertions, 12 deletions
diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c
index 1af9be46f1..cc208a8190 100644
--- a/bgpd/bgp_nht.c
+++ b/bgpd/bgp_nht.c
@@ -873,7 +873,7 @@ void bgp_nht_register_nexthops(struct bgp *bgp)
}
}
-void bgp_nht_register_enhe_capability_interfaces(struct peer *peer)
+void bgp_nht_reg_enhe_cap_intfs(struct peer *peer)
{
struct bgp *bgp;
struct bgp_node *rn;
@@ -891,9 +891,8 @@ void bgp_nht_register_enhe_capability_interfaces(struct peer *peer)
return;
if (!sockunion2hostprefix(&peer->su, &p)) {
- if (BGP_DEBUG(nht, NHT))
- zlog_debug("%s: Unable to convert prefix to sockunion",
- __func__);
+ zlog_warn("%s: Unable to convert sockunion to prefix for %s",
+ __func__, peer->host);
return;
}
@@ -922,3 +921,48 @@ void bgp_nht_register_enhe_capability_interfaces(struct peer *peer)
BGP_UNNUM_DEFAULT_RA_INTERVAL);
}
}
+
+void bgp_nht_dereg_enhe_cap_intfs(struct peer *peer)
+{
+ struct bgp *bgp;
+ struct bgp_node *rn;
+ struct bgp_nexthop_cache *bnc;
+ struct nexthop *nhop;
+ struct interface *ifp;
+ struct prefix p;
+
+ if (peer->ifp)
+ return;
+
+ bgp = peer->bgp;
+
+ if (!bgp->nexthop_cache_table[AFI_IP6])
+ return;
+
+ if (!sockunion2hostprefix(&peer->su, &p)) {
+ zlog_warn("%s: Unable to convert sockunion to prefix for %s",
+ __func__, peer->host);
+ return;
+ }
+
+ if (p.family != AF_INET6)
+ return;
+
+ rn = bgp_node_lookup(bgp->nexthop_cache_table[AFI_IP6], &p);
+ if (!rn)
+ return;
+
+ bnc = bgp_node_get_bgp_nexthop_info(rn);
+ if (!bnc)
+ return;
+
+ if (peer != bnc->nht_info)
+ return;
+
+ for (nhop = bnc->nexthop; nhop; nhop = nhop->next) {
+ ifp = if_lookup_by_index(nhop->ifindex, nhop->vrf_id);
+
+ zclient_send_interface_radv_req(zclient, nhop->vrf_id, ifp, 0,
+ 0);
+ }
+}
diff --git a/bgpd/bgp_nht.h b/bgpd/bgp_nht.h
index e39d55567a..4e015e4aae 100644
--- a/bgpd/bgp_nht.h
+++ b/bgpd/bgp_nht.h
@@ -87,6 +87,7 @@ extern void bgp_nht_register_nexthops(struct bgp *bgp);
* this code can walk the registered nexthops and
* register the important ones with zebra for RA.
*/
-extern void bgp_nht_register_enhe_capability_interfaces(struct peer *peer);
+extern void bgp_nht_reg_enhe_cap_intfs(struct peer *peer);
+extern void bgp_nht_dereg_enhe_cap_intfs(struct peer *peer);
#endif /* _BGP_NHT_H */
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index d7c18ee0ad..4f36073e9a 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -3822,6 +3822,10 @@ DEFUN (no_neighbor,
}
other = peer->doppelganger;
+
+ if (CHECK_FLAG(peer->flags, PEER_FLAG_CAPABILITY_ENHE))
+ bgp_zebra_terminate_radv(peer->bgp, peer);
+
peer_notify_unconfig(peer);
peer_delete(peer);
if (other && other->status != Deleted) {
@@ -4242,6 +4246,9 @@ DEFUN (no_neighbor_set_peer_group,
return CMD_WARNING_CONFIG_FAILED;
}
+ if (CHECK_FLAG(peer->flags, PEER_FLAG_CAPABILITY_ENHE))
+ bgp_zebra_terminate_radv(peer->bgp, peer);
+
peer_notify_unconfig(peer);
ret = peer_delete(peer);
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 4f54bc81fb..cca3f4aaa3 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -1939,8 +1939,14 @@ void bgp_zebra_initiate_radv(struct bgp *bgp, struct peer *peer)
zlog_debug("%u: Initiating RA for peer %s", bgp->vrf_id,
peer->host);
- zclient_send_interface_radv_req(zclient, bgp->vrf_id, peer->ifp, 1,
- ra_interval);
+ /*
+ * If unnumbered peer (peer->ifp) call thru zapi to start RAs.
+ * If we don't have an ifp pointer, call function to find the
+ * ifps for a numbered enhe peer to turn RAs on.
+ */
+ peer->ifp ? zclient_send_interface_radv_req(zclient, bgp->vrf_id,
+ peer->ifp, 1, ra_interval)
+ : bgp_nht_reg_enhe_cap_intfs(peer);
}
void bgp_zebra_terminate_radv(struct bgp *bgp, struct peer *peer)
@@ -1953,7 +1959,14 @@ void bgp_zebra_terminate_radv(struct bgp *bgp, struct peer *peer)
zlog_debug("%u: Terminating RA for peer %s", bgp->vrf_id,
peer->host);
- zclient_send_interface_radv_req(zclient, bgp->vrf_id, peer->ifp, 0, 0);
+ /*
+ * If unnumbered peer (peer->ifp) call thru zapi to stop RAs.
+ * If we don't have an ifp pointer, call function to find the
+ * ifps for a numbered enhe peer to turn RAs off.
+ */
+ peer->ifp ? zclient_send_interface_radv_req(zclient, bgp->vrf_id,
+ peer->ifp, 0, 0)
+ : bgp_nht_dereg_enhe_cap_intfs(peer);
}
int bgp_zebra_advertise_subnet(struct bgp *bgp, int advertise, vni_t vni)
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 5d28b138d6..cf6335d373 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -2490,6 +2490,11 @@ static void peer_group2peer_config_copy(struct peer_group *group,
: BGP_DEFAULT_EBGP_ROUTEADV;
}
+ /* capability extended-nexthop apply */
+ if (!CHECK_FLAG(peer->flags_override, PEER_FLAG_CAPABILITY_ENHE))
+ if (CHECK_FLAG(conf->flags, PEER_FLAG_CAPABILITY_ENHE))
+ SET_FLAG(peer->flags, PEER_FLAG_CAPABILITY_ENHE);
+
/* password apply */
if (!CHECK_FLAG(peer->flags_override, PEER_FLAG_PASSWORD))
PEER_STR_ATTR_INHERIT(peer, group, password,
@@ -2577,6 +2582,10 @@ int peer_group_delete(struct peer_group *group)
for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
other = peer->doppelganger;
+
+ if (CHECK_FLAG(peer->flags, PEER_FLAG_CAPABILITY_ENHE))
+ bgp_zebra_terminate_radv(bgp, peer);
+
peer_delete(peer);
if (other && other->status != Deleted) {
other->group = NULL;
@@ -2621,6 +2630,9 @@ int peer_group_remote_as_delete(struct peer_group *group)
for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
other = peer->doppelganger;
+ if (CHECK_FLAG(peer->flags, PEER_FLAG_CAPABILITY_ENHE))
+ bgp_zebra_terminate_radv(peer->bgp, peer);
+
peer_delete(peer);
if (other && other->status != Deleted) {
@@ -4065,8 +4077,22 @@ static int peer_flag_modify(struct peer *peer, uint32_t flag, int set)
/* Update flag override state accordingly. */
COND_FLAG(peer->flags_override, flag, set != invert);
- if (set && flag == PEER_FLAG_CAPABILITY_ENHE)
- bgp_nht_register_enhe_capability_interfaces(peer);
+ /*
+ * For the extended next-hop encoding flag we need to turn RAs
+ * on if flag is being set, but only turn RAs off if the flag
+ * is being unset on this peer and if this peer is a member of a
+ * peer-group, the peer-group also doesn't have the flag set.
+ */
+ if (flag == PEER_FLAG_CAPABILITY_ENHE) {
+ if (set) {
+ bgp_zebra_initiate_radv(peer->bgp, peer);
+ } else if (peer_group_active(peer)) {
+ if (!CHECK_FLAG(peer->group->conf->flags, flag))
+ bgp_zebra_terminate_radv(peer->bgp,
+ peer);
+ } else
+ bgp_zebra_terminate_radv(peer->bgp, peer);
+ }
/* Execute flag action on peer. */
if (action.type == peer_change_reset)
@@ -4099,8 +4125,9 @@ static int peer_flag_modify(struct peer *peer, uint32_t flag, int set)
/* Update flag on peer-group member. */
COND_FLAG(member->flags, flag, set != member_invert);
- if (set && flag == PEER_FLAG_CAPABILITY_ENHE)
- bgp_nht_register_enhe_capability_interfaces(member);
+ if (flag == PEER_FLAG_CAPABILITY_ENHE)
+ set ? bgp_zebra_initiate_radv(member->bgp, member)
+ : bgp_zebra_terminate_radv(member->bgp, member);
/* Execute flag action on peer-group member. */
if (action.type == peer_change_reset)