diff options
| author | Russ White <russ@riw.us> | 2020-04-29 11:09:58 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-04-29 11:09:58 -0400 |
| commit | 37d6afef2a9df1608e22ff632aae5ba93dd8bd9d (patch) | |
| tree | d1aea001132fae250f19403d577b5fdb31493679 | |
| parent | 854a463b976f385b0819a8bbc3685a766f2a0982 (diff) | |
| parent | b3a3290e23039e326337b8e254de06a83f7330de (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.c | 52 | ||||
| -rw-r--r-- | bgpd/bgp_nht.h | 3 | ||||
| -rw-r--r-- | bgpd/bgp_vty.c | 7 | ||||
| -rw-r--r-- | bgpd/bgp_zebra.c | 19 | ||||
| -rw-r--r-- | bgpd/bgpd.c | 35 |
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) |
