mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-03 02:17:12 +00:00
Merge pull request #6303 from dslicenc/stop-enhe-ras
bgpd: turn off RAs when numbered peers are deleted
This commit is contained in:
commit
37d6afef2a
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
|
35
bgpd/bgpd.c
35
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)
|
||||
|
Loading…
Reference in New Issue
Block a user