diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index 8aa7798af425..0dce96f43240 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -838,3 +838,48 @@ void bgp_nht_register_nexthops(struct bgp *bgp) } } } + +void bgp_nht_register_enhe_capability_interfaces(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)) { + if (BGP_DEBUG(nht, NHT)) + zlog_debug("%s: Unable to convert prefix to sockunion", + __PRETTY_FUNCTION__); + return; + } + + if (p.family != AF_INET6) + return; + rn = bgp_node_lookup(bgp->nexthop_cache_table[AFI_IP6], &p); + + bnc = bgp_nexthop_get_node_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, true, + BGP_UNNUM_DEFAULT_RA_INTERVAL); + } +} diff --git a/bgpd/bgp_nht.h b/bgpd/bgp_nht.h index 96dd9155964c..7daae93b2517 100644 --- a/bgpd/bgp_nht.h +++ b/bgpd/bgp_nht.h @@ -88,4 +88,13 @@ extern void path_nh_map(struct bgp_path_info *path, */ extern void bgp_nht_register_nexthops(struct bgp *bgp); +/* + * When we have the the PEER_FLAG_CAPABILITY_ENHE flag + * set on a peer *after* it has been brought up we need + * to notice and setup the interface based RA, + * 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); + #endif /* _BGP_NHT_H */ diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 19384eec2f45..0c26fa6720e1 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -3905,6 +3905,9 @@ static int peer_flag_modify(struct peer *peer, uint32_t flag, int set) return 0; } + if (set && flag == PEER_FLAG_CAPABILITY_ENHE) + bgp_nht_register_enhe_capability_interfaces(peer); + /* * Update peer-group members, unless they are explicitely overriding * peer-group configuration. @@ -3928,6 +3931,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); + /* Execute flag action on peer-group member. */ if (action.type == peer_change_reset) peer_flag_modify_action(member, flag);