summaryrefslogtreecommitdiff
path: root/staticd/static_zebra.c
diff options
context:
space:
mode:
Diffstat (limited to 'staticd/static_zebra.c')
-rw-r--r--staticd/static_zebra.c120
1 files changed, 72 insertions, 48 deletions
diff --git a/staticd/static_zebra.c b/staticd/static_zebra.c
index 3ed525f386..cc09b42836 100644
--- a/staticd/static_zebra.c
+++ b/staticd/static_zebra.c
@@ -75,7 +75,7 @@ DECLARE_HASH(static_nht_hash, struct static_nht_data, itm, static_nht_data_cmp,
static struct static_nht_hash_head static_nht_hash[1];
/* Zebra structure to hold current status. */
-struct zclient *zclient;
+struct zclient *static_zclient;
uint32_t zebra_ecmp_count = MULTIPATH_NUM;
/* Interface addition message from zebra. */
@@ -209,14 +209,10 @@ static void static_zebra_nexthop_update(struct vrf *vrf, struct prefix *matched,
struct zapi_route *nhr)
{
struct static_nht_data *nhtd, lookup;
- afi_t afi = AFI_IP;
- if (zclient->bfd_integration)
+ if (static_zclient->bfd_integration)
bfd_nht_update(matched, nhr);
- if (matched->family == AF_INET6)
- afi = AFI_IP6;
-
if (nhr->type == ZEBRA_ROUTE_CONNECT) {
if (static_nexthop_is_local(vrf->vrf_id, matched,
nhr->prefix.family))
@@ -233,8 +229,12 @@ static void static_zebra_nexthop_update(struct vrf *vrf, struct prefix *matched,
if (nhtd) {
nhtd->nh_num = nhr->nexthop_num;
- static_nht_reset_start(matched, afi, nhr->safi, nhtd->nh_vrf_id);
- static_nht_update(NULL, NULL, matched, nhr->nexthop_num, afi, nhr->safi,
+ /* The tracked nexthop might be used by IPv4 and IPv6 routes */
+ static_nht_reset_start(matched, AFI_IP, nhr->safi, nhtd->nh_vrf_id);
+ static_nht_update(NULL, NULL, matched, nhr->nexthop_num, AFI_IP, nhr->safi,
+ nhtd->nh_vrf_id);
+ static_nht_reset_start(matched, AFI_IP6, nhr->safi, nhtd->nh_vrf_id);
+ static_nht_update(NULL, NULL, matched, nhr->nexthop_num, AFI_IP6, nhr->safi,
nhtd->nh_vrf_id);
} else
zlog_err("No nhtd?");
@@ -361,7 +361,7 @@ void static_zebra_nht_register(struct static_nexthop *nh, bool reg)
if (reg) {
if (nhtd->nh_num) {
/* refresh with existing data */
- afi_t afi = prefix_afi(&lookup.nh);
+ afi_t afi = prefix_afi(&rn->p);
if (nh->state == STATIC_NOT_INSTALLED ||
nh->state == STATIC_SENT_TO_ZEBRA)
@@ -395,7 +395,7 @@ void static_zebra_nht_register(struct static_nexthop *nh, bool reg)
"Unregistering nexthop(%pFX) for %pRN", &lookup.nh, rn);
}
- if (zclient_send_rnh(zclient, cmd, &lookup.nh, si->safi, false, false,
+ if (zclient_send_rnh(static_zclient, cmd, &lookup.nh, si->safi, false, false,
nh->nh_vrf_id) == ZCLIENT_SEND_FAILURE)
zlog_warn("%s: Failure to send nexthop %pFX for %pRN to zebra",
__func__, &lookup.nh, rn);
@@ -549,7 +549,7 @@ extern void static_zebra_route_add(struct static_path *pn, bool install)
zclient_route_send(install ?
ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE,
- zclient, &api);
+ static_zclient, &api);
}
/**
@@ -594,7 +594,7 @@ static void static_zebra_send_localsid(int cmd, const struct in6_addr *sid, uint
memcpy(&api.prefix, &p, sizeof(p));
if (cmd == ZEBRA_ROUTE_DELETE)
- return (void)zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
+ return (void)zclient_route_send(ZEBRA_ROUTE_DELETE, static_zclient, &api);
SET_FLAG(api.flags, ZEBRA_FLAG_ALLOW_RECURSION);
SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
@@ -611,7 +611,7 @@ static void static_zebra_send_localsid(int cmd, const struct in6_addr *sid, uint
api.nexthop_num = 1;
- zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
+ zclient_route_send(ZEBRA_ROUTE_ADD, static_zclient, &api);
}
/**
@@ -625,8 +625,6 @@ void static_zebra_srv6_sid_install(struct static_srv6_sid *sid)
struct seg6local_context ctx = {};
struct interface *ifp = NULL;
struct vrf *vrf;
- struct prefix_ipv6 sid_block = {};
- struct prefix_ipv6 locator_block = {};
struct prefix_ipv6 sid_locator = {};
if (!sid)
@@ -732,28 +730,17 @@ void static_zebra_srv6_sid_install(struct static_srv6_sid *sid)
case SRV6_ENDPOINT_BEHAVIOR_END_X_PSP_USD:
case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID_PSP:
case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID_PSP_USD:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_NEXT_CSID:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED_NEXT_CSID:
case SRV6_ENDPOINT_BEHAVIOR_OPAQUE:
case SRV6_ENDPOINT_BEHAVIOR_RESERVED:
zlog_warn("unsupported behavior: %u", sid->behavior);
break;
}
- sid_block = sid->addr;
- sid_block.prefixlen = sid->locator->block_bits_length;
- apply_mask(&sid_block);
-
- locator_block = sid->locator->prefix;
- locator_block.prefixlen = sid->locator->block_bits_length;
- apply_mask(&locator_block);
-
- if (prefix_same(&sid_block, &locator_block))
- ctx.block_len = sid->locator->block_bits_length;
- else {
- zlog_warn("SID block %pFX does not match locator block %pFX", &sid_block,
- &locator_block);
- return;
- }
-
+ ctx.block_len = sid->locator->block_bits_length;
sid_locator = sid->addr;
sid_locator.prefixlen = sid->locator->block_bits_length + sid->locator->node_bits_length;
apply_mask(&sid_locator);
@@ -870,6 +857,10 @@ void static_zebra_srv6_sid_uninstall(struct static_srv6_sid *sid)
case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID_PSP_USD:
case SRV6_ENDPOINT_BEHAVIOR_OPAQUE:
case SRV6_ENDPOINT_BEHAVIOR_RESERVED:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_NEXT_CSID:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED_NEXT_CSID:
zlog_warn("unsupported behavior: %u", sid->behavior);
break;
}
@@ -915,6 +906,30 @@ void static_zebra_srv6_sid_uninstall(struct static_srv6_sid *sid)
UNSET_FLAG(sid->flags, STATIC_FLAG_SRV6_SID_SENT_TO_ZEBRA);
}
+/* Validate if the sid block and locator block are the same */
+static bool static_zebra_sid_locator_block_check(struct static_srv6_sid *sid)
+{
+ struct prefix_ipv6 sid_block = {};
+ struct prefix_ipv6 locator_block = {};
+
+ sid_block = sid->addr;
+ sid_block.prefixlen = sid->locator->block_bits_length;
+ apply_mask(&sid_block);
+
+ locator_block = sid->locator->prefix;
+ locator_block.prefixlen = sid->locator->block_bits_length;
+ apply_mask(&locator_block);
+
+ if (!prefix_same(&sid_block, &locator_block)) {
+ zlog_warn("SID block %pFX does not match locator block %pFX", &sid_block,
+ &locator_block);
+
+ return false;
+ }
+
+ return true;
+}
+
extern void static_zebra_request_srv6_sid(struct static_srv6_sid *sid)
{
struct srv6_sid_ctx ctx = {};
@@ -922,7 +937,7 @@ extern void static_zebra_request_srv6_sid(struct static_srv6_sid *sid)
struct vrf *vrf;
struct interface *ifp;
- if (!sid)
+ if (!sid || !static_zebra_sid_locator_block_check(sid))
return;
/* convert `srv6_endpoint_behavior_codepoint` to `seg6local_action_t` */
@@ -992,12 +1007,17 @@ extern void static_zebra_request_srv6_sid(struct static_srv6_sid *sid)
case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID_PSP_USD:
case SRV6_ENDPOINT_BEHAVIOR_OPAQUE:
case SRV6_ENDPOINT_BEHAVIOR_RESERVED:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_NEXT_CSID:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED_NEXT_CSID:
zlog_warn("unsupported behavior: %u", sid->behavior);
return;
}
/* Request SRv6 SID from SID Manager */
- ret = srv6_manager_get_sid(zclient, &ctx, &sid->addr.prefix, sid->locator->name, NULL);
+ ret = srv6_manager_get_sid(static_zclient, &ctx, &sid->addr.prefix, sid->locator->name,
+ NULL);
if (ret < 0)
zlog_warn("%s: error getting SRv6 SID!", __func__);
}
@@ -1079,12 +1099,16 @@ extern void static_zebra_release_srv6_sid(struct static_srv6_sid *sid)
case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID_PSP_USD:
case SRV6_ENDPOINT_BEHAVIOR_OPAQUE:
case SRV6_ENDPOINT_BEHAVIOR_RESERVED:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_NEXT_CSID:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED_NEXT_CSID:
zlog_warn("unsupported behavior: %u", sid->behavior);
return;
}
/* remove the SRv6 SID from the zebra RIB */
- ret = srv6_manager_release_sid(zclient, &ctx);
+ ret = srv6_manager_release_sid(static_zclient, &ctx);
if (ret == ZCLIENT_SEND_FAILURE)
flog_err(EC_LIB_ZAPI_SOCKET, "zclient_send_get_srv6_sid() delete failed: %s",
safe_strerror(errno));
@@ -1105,7 +1129,7 @@ int static_zebra_srv6_manager_get_locator(const char *name)
* Send the Get Locator request to the SRv6 Manager and return the
* result
*/
- return srv6_manager_get_locator(zclient, name);
+ return srv6_manager_get_locator(static_zclient, name);
}
static void request_srv6_sids(struct static_srv6_locator *locator)
@@ -1360,16 +1384,16 @@ void static_zebra_init(void)
hook_register_prio(if_down, 0, static_ifp_down);
hook_register_prio(if_unreal, 0, static_ifp_destroy);
- zclient = zclient_new(master, &zclient_options_default, static_handlers,
- array_size(static_handlers));
+ static_zclient = zclient_new(master, &zclient_options_default, static_handlers,
+ array_size(static_handlers));
- zclient_init(zclient, ZEBRA_ROUTE_STATIC, 0, &static_privs);
- zclient->zebra_capabilities = static_zebra_capabilities;
- zclient->zebra_connected = zebra_connected;
- zclient->nexthop_update = static_zebra_nexthop_update;
+ zclient_init(static_zclient, ZEBRA_ROUTE_STATIC, 0, &static_privs);
+ static_zclient->zebra_capabilities = static_zebra_capabilities;
+ static_zclient->zebra_connected = zebra_connected;
+ static_zclient->nexthop_update = static_zebra_nexthop_update;
static_nht_hash_init(static_nht_hash);
- static_bfd_initialize(zclient, master);
+ static_bfd_initialize(static_zclient, master);
}
/* static_zebra_stop used by tests/lib/test_grpc.cpp */
@@ -1378,23 +1402,23 @@ void static_zebra_stop(void)
static_nht_hash_clear();
static_nht_hash_fini(static_nht_hash);
- if (!zclient)
+ if (!static_zclient)
return;
- zclient_stop(zclient);
- zclient_free(zclient);
- zclient = NULL;
+ zclient_stop(static_zclient);
+ zclient_free(static_zclient);
+ static_zclient = NULL;
}
void static_zebra_vrf_register(struct vrf *vrf)
{
if (vrf->vrf_id == VRF_DEFAULT)
return;
- zclient_send_reg_requests(zclient, vrf->vrf_id);
+ zclient_send_reg_requests(static_zclient, vrf->vrf_id);
}
void static_zebra_vrf_unregister(struct vrf *vrf)
{
if (vrf->vrf_id == VRF_DEFAULT)
return;
- zclient_send_dereg_requests(zclient, vrf->vrf_id);
+ zclient_send_dereg_requests(static_zclient, vrf->vrf_id);
}