diff options
Diffstat (limited to 'staticd/static_zebra.c')
| -rw-r--r-- | staticd/static_zebra.c | 120 |
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); } |
