summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_nht.c45
-rw-r--r--bgpd/bgp_nht.h9
-rw-r--r--bgpd/bgpd.c6
3 files changed, 60 insertions, 0 deletions
diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c
index 8aa7798af4..0dce96f432 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 96dd915596..7daae93b25 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 19384eec2f..0c26fa6720 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);