summaryrefslogtreecommitdiff
path: root/bgpd/bgp_zebra.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_zebra.c')
-rw-r--r--bgpd/bgp_zebra.c127
1 files changed, 113 insertions, 14 deletions
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 5ef49e5108..e8ca544c23 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -472,8 +472,9 @@ static int bgp_interface_vrf_update(ZAPI_CALLBACK_ARGS)
static int zebra_read_route(ZAPI_CALLBACK_ARGS)
{
enum nexthop_types_t nhtype;
+ enum blackhole_type bhtype = BLACKHOLE_UNSPEC;
struct zapi_route api;
- union g_addr nexthop;
+ union g_addr nexthop = {};
ifindex_t ifindex;
int add, i;
struct bgp *bgp;
@@ -494,10 +495,16 @@ static int zebra_read_route(ZAPI_CALLBACK_ARGS)
&& IN6_IS_ADDR_LINKLOCAL(&api.prefix.u.prefix6))
return 0;
- nexthop = api.nexthops[0].gate;
ifindex = api.nexthops[0].ifindex;
nhtype = api.nexthops[0].type;
+ /* api_nh structure has union of gate and bh_type */
+ if (nhtype == NEXTHOP_TYPE_BLACKHOLE) {
+ /* bh_type is only applicable if NEXTHOP_TYPE_BLACKHOLE*/
+ bhtype = api.nexthops[0].bh_type;
+ } else
+ nexthop = api.nexthops[0].gate;
+
add = (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD);
if (add) {
/*
@@ -517,8 +524,8 @@ static int zebra_read_route(ZAPI_CALLBACK_ARGS)
/* Now perform the add/update. */
bgp_redistribute_add(bgp, &api.prefix, &nexthop, ifindex,
- nhtype, api.distance, api.metric, api.type,
- api.instance, api.tag);
+ nhtype, bhtype, api.distance, api.metric,
+ api.type, api.instance, api.tag);
} else {
bgp_redistribute_delete(bgp, &api.prefix, api.type,
api.instance);
@@ -1076,8 +1083,10 @@ static bool update_ipv4nh_for_route_install(int nh_othervrf, struct bgp *nh_bgp,
* a VRF (which are programmed as onlink on l3-vni SVI) as well as
* connected routes leaked into a VRF.
*/
- if (is_evpn) {
-
+ if (attr->nh_type == NEXTHOP_TYPE_BLACKHOLE) {
+ api_nh->type = attr->nh_type;
+ api_nh->bh_type = attr->bh_type;
+ } else if (is_evpn) {
/*
* If the nexthop is EVPN overlay index gateway IP,
* treat the nexthop as NEXTHOP_TYPE_IPV4
@@ -1090,8 +1099,7 @@ static bool update_ipv4nh_for_route_install(int nh_othervrf, struct bgp *nh_bgp,
SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_ONLINK);
api_nh->ifindex = nh_bgp->l3vni_svi_ifindex;
}
- } else if (nh_othervrf &&
- api_nh->gate.ipv4.s_addr == INADDR_ANY) {
+ } else if (nh_othervrf && api_nh->gate.ipv4.s_addr == INADDR_ANY) {
api_nh->type = NEXTHOP_TYPE_IFINDEX;
api_nh->ifindex = attr->nh_ifindex;
} else
@@ -1113,8 +1121,10 @@ static bool update_ipv6nh_for_route_install(int nh_othervrf, struct bgp *nh_bgp,
attr = pi->attr;
api_nh->vrf_id = nh_bgp->vrf_id;
- if (is_evpn) {
-
+ if (attr->nh_type == NEXTHOP_TYPE_BLACKHOLE) {
+ api_nh->type = attr->nh_type;
+ api_nh->bh_type = attr->bh_type;
+ } else if (is_evpn) {
/*
* If the nexthop is EVPN overlay index gateway IP,
* treat the nexthop as NEXTHOP_TYPE_IPV4
@@ -1169,7 +1179,8 @@ static bool update_ipv6nh_for_route_install(int nh_othervrf, struct bgp *nh_bgp,
api_nh->ifindex = 0;
}
}
- if (nexthop)
+ /* api_nh structure has union of gate and bh_type */
+ if (nexthop && api_nh->type != NEXTHOP_TYPE_BLACKHOLE)
api_nh->gate.ipv6 = *nexthop;
return true;
@@ -1440,11 +1451,10 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p,
api_nh->weight = nh_weight;
- if (mpinfo->extra
- && !sid_zero(&mpinfo->extra->sid[0])
+ if (mpinfo->extra && !sid_zero(&mpinfo->extra->sid[0].sid)
&& !CHECK_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE)) {
has_valid_sid = 1;
- memcpy(&api_nh->seg6_segs, &mpinfo->extra->sid[0],
+ memcpy(&api_nh->seg6_segs, &mpinfo->extra->sid[0].sid,
sizeof(api_nh->seg6_segs));
}
@@ -3077,6 +3087,88 @@ static void bgp_zebra_process_srv6_locator_chunk(ZAPI_CALLBACK_ARGS)
vpn_leak_postchange_all();
}
+static int bgp_zebra_process_srv6_locator_add(ZAPI_CALLBACK_ARGS)
+{
+ struct srv6_locator loc = {};
+ struct bgp *bgp = bgp_get_default();
+ const char *loc_name = bgp->srv6_locator_name;
+
+ if (zapi_srv6_locator_decode(zclient->ibuf, &loc) < 0)
+ return -1;
+
+ if (!bgp || !bgp->srv6_enabled)
+ return 0;
+
+ if (bgp_zebra_srv6_manager_get_locator_chunk(loc_name) < 0)
+ return -1;
+
+ return 0;
+}
+
+static int bgp_zebra_process_srv6_locator_delete(ZAPI_CALLBACK_ARGS)
+{
+ struct srv6_locator loc = {};
+ struct bgp *bgp = bgp_get_default();
+ struct listnode *node, *nnode;
+ struct prefix_ipv6 *chunk;
+ struct bgp_srv6_function *func;
+ struct bgp *bgp_vrf;
+ struct in6_addr *tovpn_sid;
+ struct prefix_ipv6 tmp_prefi;
+
+ if (zapi_srv6_locator_decode(zclient->ibuf, &loc) < 0)
+ return -1;
+
+ // refresh chunks
+ for (ALL_LIST_ELEMENTS(bgp->srv6_locator_chunks, node, nnode, chunk))
+ if (prefix_match((struct prefix *)&loc.prefix,
+ (struct prefix *)chunk))
+ listnode_delete(bgp->srv6_locator_chunks, chunk);
+
+ // refresh functions
+ for (ALL_LIST_ELEMENTS(bgp->srv6_functions, node, nnode, func)) {
+ tmp_prefi.family = AF_INET6;
+ tmp_prefi.prefixlen = 128;
+ tmp_prefi.prefix = func->sid;
+ if (prefix_match((struct prefix *)&loc.prefix,
+ (struct prefix *)&tmp_prefi))
+ listnode_delete(bgp->srv6_functions, func);
+ }
+
+ // refresh tovpn_sid
+ for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp_vrf)) {
+ if (bgp_vrf->inst_type != BGP_INSTANCE_TYPE_VRF)
+ continue;
+
+ // refresh vpnv4 tovpn_sid
+ tovpn_sid = bgp_vrf->vpn_policy[AFI_IP].tovpn_sid;
+ if (tovpn_sid) {
+ tmp_prefi.family = AF_INET6;
+ tmp_prefi.prefixlen = 128;
+ tmp_prefi.prefix = *tovpn_sid;
+ if (prefix_match((struct prefix *)&loc.prefix,
+ (struct prefix *)&tmp_prefi))
+ XFREE(MTYPE_BGP_SRV6_SID,
+ bgp_vrf->vpn_policy[AFI_IP].tovpn_sid);
+ }
+
+ // refresh vpnv6 tovpn_sid
+ tovpn_sid = bgp_vrf->vpn_policy[AFI_IP6].tovpn_sid;
+ if (tovpn_sid) {
+ tmp_prefi.family = AF_INET6;
+ tmp_prefi.prefixlen = 128;
+ tmp_prefi.prefix = *tovpn_sid;
+ if (prefix_match((struct prefix *)&loc.prefix,
+ (struct prefix *)&tmp_prefi))
+ XFREE(MTYPE_BGP_SRV6_SID,
+ bgp_vrf->vpn_policy[AFI_IP6].tovpn_sid);
+ }
+ }
+
+ vpn_leak_postchange_all();
+ return 0;
+}
+
void bgp_zebra_init(struct thread_master *master, unsigned short instance)
{
zclient_num_connects = 0;
@@ -3119,6 +3211,8 @@ void bgp_zebra_init(struct thread_master *master, unsigned short instance)
zclient->iptable_notify_owner = iptable_notify_owner;
zclient->route_notify_owner = bgp_zebra_route_notify_owner;
zclient->instance = instance;
+ zclient->srv6_locator_add = bgp_zebra_process_srv6_locator_add;
+ zclient->srv6_locator_delete = bgp_zebra_process_srv6_locator_delete;
zclient->process_srv6_locator_chunk =
bgp_zebra_process_srv6_locator_chunk;
}
@@ -3530,3 +3624,8 @@ int bgp_zebra_srv6_manager_get_locator_chunk(const char *name)
{
return srv6_manager_get_locator_chunk(zclient, name);
}
+
+int bgp_zebra_srv6_manager_release_locator_chunk(const char *name)
+{
+ return srv6_manager_release_locator_chunk(zclient, name);
+}