diff options
Diffstat (limited to 'staticd')
| -rw-r--r-- | staticd/static_nb.c | 21 | ||||
| -rw-r--r-- | staticd/static_nb.h | 16 | ||||
| -rw-r--r-- | staticd/static_nb_config.c | 107 | ||||
| -rw-r--r-- | staticd/static_routes.c | 5 | ||||
| -rw-r--r-- | staticd/static_vty.c | 70 | ||||
| -rw-r--r-- | staticd/static_zebra.c | 98 |
6 files changed, 311 insertions, 6 deletions
diff --git a/staticd/static_nb.c b/staticd/static_nb.c index ef363bfe7e..60dc3dc788 100644 --- a/staticd/static_nb.c +++ b/staticd/static_nb.c @@ -157,6 +157,27 @@ const struct frr_yang_module_info frr_staticd_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/segment-routing/srv6/static-sids/sid/paths", + .cbs = { + .create = routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_paths_create, + .destroy = routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_paths_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/segment-routing/srv6/static-sids/sid/paths/interface", + .cbs = { + .modify = routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_paths_interface_modify, + .destroy = routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_paths_interface_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/segment-routing/srv6/static-sids/sid/paths/next-hop", + .cbs = { + .modify = routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_paths_next_hop_modify, + .destroy = routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_paths_next_hop_destroy, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/segment-routing/srv6/static-sids/sid/locator-name", .cbs = { .modify = routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_locator_name_modify, diff --git a/staticd/static_nb.h b/staticd/static_nb.h index aa11f34021..282c9dcf11 100644 --- a/staticd/static_nb.h +++ b/staticd/static_nb.h @@ -96,6 +96,18 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_segment_routi struct nb_cb_modify_args *args); int routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_vrf_name_destroy( struct nb_cb_destroy_args *args); +int routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_paths_create( + struct nb_cb_create_args *args); +int routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_paths_destroy( + struct nb_cb_destroy_args *args); +int routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_paths_interface_modify( + struct nb_cb_modify_args *args); +int routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_paths_interface_destroy( + struct nb_cb_destroy_args *args); +int routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_paths_next_hop_modify( + struct nb_cb_modify_args *args); +int routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_paths_next_hop_destroy( + struct nb_cb_destroy_args *args); int routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_locator_name_modify( struct nb_cb_modify_args *args); int routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_locator_name_destroy( @@ -183,6 +195,10 @@ int routing_control_plane_protocols_name_validate( #define FRR_STATIC_SRV6_SID_LOCATOR_NAME_XPATH "/locator-name" +#define FRR_STATIC_SRV6_SID_INTERFACE_XPATH "/paths[path-index=%u]/interface" + +#define FRR_STATIC_SRV6_SID_NEXTHOP_XPATH "/paths[path-index=%u]/next-hop" + #ifdef __cplusplus } #endif diff --git a/staticd/static_nb_config.c b/staticd/static_nb_config.c index e2ab1f2ffe..71df15fa61 100644 --- a/staticd/static_nb_config.c +++ b/staticd/static_nb_config.c @@ -1231,6 +1231,113 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_segment_routi /* * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/segment-routing/srv6/locators/locator/static-sids/sid/paths + */ +int routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_paths_create( + struct nb_cb_create_args *args) +{ + /* Actual setting is done in apply_finish */ + return NB_OK; +} + +int routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_paths_destroy( + struct nb_cb_destroy_args *args) +{ + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/segment-routing/srv6/locators/locator/static-sids/sid/paths/interface + */ +int routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_paths_interface_modify( + struct nb_cb_modify_args *args) +{ + struct static_srv6_sid *sid; + const char *ifname; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + sid = nb_running_get_entry(args->dnode, NULL, true); + + /* Release and uninstall existing SID, if any, before requesting the new one */ + if (CHECK_FLAG(sid->flags, STATIC_FLAG_SRV6_SID_VALID)) { + static_zebra_release_srv6_sid(sid); + UNSET_FLAG(sid->flags, STATIC_FLAG_SRV6_SID_VALID); + } + + if (CHECK_FLAG(sid->flags, STATIC_FLAG_SRV6_SID_SENT_TO_ZEBRA)) { + static_zebra_srv6_sid_uninstall(sid); + UNSET_FLAG(sid->flags, STATIC_FLAG_SRV6_SID_SENT_TO_ZEBRA); + } + + ifname = yang_dnode_get_string(args->dnode, "../interface"); + snprintf(sid->attributes.ifname, sizeof(sid->attributes.ifname), "%s", ifname); + + return NB_OK; +} + +int routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_paths_interface_destroy( + struct nb_cb_destroy_args *args) +{ + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/segment-routing/srv6/locators/locator/static-sids/sid/paths/next-hop + */ +int routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_paths_next_hop_modify( + struct nb_cb_modify_args *args) +{ + struct static_srv6_sid *sid; + struct ipaddr nexthop; + + switch (args->event) { + case NB_EV_VALIDATE: + zlog_info("validating nexthop %pI6", &nexthop.ipaddr_v6); + yang_dnode_get_ip(&nexthop, args->dnode, "../next-hop"); + if (!IS_IPADDR_V6(&nexthop)) { + snprintf(args->errmsg, args->errmsg_len, + "%% Nexthop must be an IPv6 address"); + return NB_ERR_VALIDATION; + } + break; + case NB_EV_ABORT: + case NB_EV_PREPARE: + break; + case NB_EV_APPLY: + sid = nb_running_get_entry(args->dnode, NULL, true); + + /* Release and uninstall existing SID, if any, before requesting the new one */ + if (CHECK_FLAG(sid->flags, STATIC_FLAG_SRV6_SID_VALID)) { + static_zebra_release_srv6_sid(sid); + UNSET_FLAG(sid->flags, STATIC_FLAG_SRV6_SID_VALID); + } + + if (CHECK_FLAG(sid->flags, STATIC_FLAG_SRV6_SID_SENT_TO_ZEBRA)) { + static_zebra_srv6_sid_uninstall(sid); + UNSET_FLAG(sid->flags, STATIC_FLAG_SRV6_SID_SENT_TO_ZEBRA); + } + + yang_dnode_get_ip(&nexthop, args->dnode, "../next-hop"); + sid->attributes.nh6 = nexthop.ipaddr_v6; + + break; + } + + return NB_OK; +} + +int routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_paths_next_hop_destroy( + struct nb_cb_destroy_args *args) +{ + return NB_OK; +} + +/* + * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/segment-routing/srv6/locators/locator/static-sids/sid/vrf-name */ int routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_locator_name_modify( diff --git a/staticd/static_routes.c b/staticd/static_routes.c index cbe1c3c8c0..82eabd8d56 100644 --- a/staticd/static_routes.c +++ b/staticd/static_routes.c @@ -53,6 +53,11 @@ void zebra_stable_node_cleanup(struct route_table *table, /* Install static path into rib. */ void static_install_path(struct static_path *pn) { + struct static_nexthop *nh; + + frr_each (static_nexthop_list, &pn->nexthop_list, nh) + static_zebra_nht_register(nh, true); + if (static_nexthop_list_count(&pn->nexthop_list)) static_zebra_route_add(pn, true); } diff --git a/staticd/static_vty.c b/staticd/static_vty.c index 895846a1c7..6e9087363d 100644 --- a/staticd/static_vty.c +++ b/staticd/static_vty.c @@ -1199,13 +1199,18 @@ DEFUN_NOSH (static_srv6_sids, static_srv6_sids_cmd, } DEFPY_YANG(srv6_sid, srv6_sid_cmd, - "sid X:X::X:X/M locator NAME$locator_name behavior <uN | uDT6 vrf VIEWVRFNAME | uDT4 vrf VIEWVRFNAME | uDT46 vrf VIEWVRFNAME>", + "sid X:X::X:X/M locator NAME$locator_name behavior <uN | uA interface INTERFACE$interface [nexthop X:X::X:X$nh6] | uDT6 vrf VIEWVRFNAME | uDT4 vrf VIEWVRFNAME | uDT46 vrf VIEWVRFNAME>", "Configure SRv6 SID\n" "Specify SRv6 SID\n" "Locator name\n" "Specify Locator name\n" "Specify SRv6 SID behavior\n" "Apply the code to a uN SID\n" + "Behavior uA\n" + "Configure the interface\n" + "Interface name\n" + "Configure the nexthop\n" + "IPv6 address of the nexthop\n" "Apply the code to an uDT6 SID\n" "Configure VRF name\n" "Specify VRF name\n" @@ -1223,7 +1228,10 @@ DEFPY_YANG(srv6_sid, srv6_sid_cmd, char xpath_sid[XPATH_MAXLEN]; char xpath_behavior[XPATH_MAXLEN]; char xpath_vrf_name[XPATH_MAXLEN]; + char xpath_ifname[XPATH_MAXLEN]; + char xpath_nexthop[XPATH_MAXLEN]; char xpath_locator_name[XPATH_MAXLEN]; + char ab_xpath[XPATH_MAXLEN]; if (argv_find(argv, argc, "uN", &idx)) { behavior = SRV6_ENDPOINT_BEHAVIOR_END_NEXT_CSID; @@ -1236,6 +1244,8 @@ DEFPY_YANG(srv6_sid, srv6_sid_cmd, } else if (argv_find(argv, argc, "uDT46", &idx)) { behavior = SRV6_ENDPOINT_BEHAVIOR_END_DT46_USID; vrf_name = argv[idx + 2]->arg; + } else if (argv_find(argv, argc, "uA", &idx)) { + behavior = SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID; } snprintf(xpath_srv6, sizeof(xpath_srv6), FRR_STATIC_SRV6_INFO_KEY_XPATH, @@ -1259,6 +1269,22 @@ DEFPY_YANG(srv6_sid, srv6_sid_cmd, nb_cli_enqueue_change(vty, xpath_vrf_name, NB_OP_MODIFY, vrf_name); } + if (interface) { + snprintf(ab_xpath, sizeof(ab_xpath), FRR_STATIC_SRV6_SID_INTERFACE_XPATH, 0); + strlcpy(xpath_ifname, xpath_sid, sizeof(xpath_ifname)); + strlcat(xpath_ifname, ab_xpath, sizeof(xpath_ifname)); + + nb_cli_enqueue_change(vty, xpath_ifname, NB_OP_MODIFY, interface); + } + + if (nh6_str) { + snprintf(ab_xpath, sizeof(ab_xpath), FRR_STATIC_SRV6_SID_NEXTHOP_XPATH, 0); + strlcpy(xpath_nexthop, xpath_sid, sizeof(xpath_nexthop)); + strlcat(xpath_nexthop, ab_xpath, sizeof(xpath_nexthop)); + + nb_cli_enqueue_change(vty, xpath_nexthop, NB_OP_MODIFY, nh6_str); + } + strlcpy(xpath_locator_name, xpath_sid, sizeof(xpath_locator_name)); strlcat(xpath_locator_name, FRR_STATIC_SRV6_SID_LOCATOR_NAME_XPATH, sizeof(xpath_locator_name)); @@ -1269,7 +1295,7 @@ DEFPY_YANG(srv6_sid, srv6_sid_cmd, } DEFPY_YANG(no_srv6_sid, no_srv6_sid_cmd, - "no sid X:X::X:X/M [locator NAME$locator_name] [behavior <uN | uDT6 vrf VIEWVRFNAME | uDT4 vrf VIEWVRFNAME | uDT46 vrf VIEWVRFNAME>]", + "no sid X:X::X:X/M [locator NAME$locator_name] [behavior <uN | uA interface INTERFACE$interface [nexthop X:X::X:X$nh6] | uDT6 vrf VIEWVRFNAME | uDT4 vrf VIEWVRFNAME | uDT46 vrf VIEWVRFNAME>]", NO_STR "Configure SRv6 SID\n" "Specify SRv6 SID\n" @@ -1277,6 +1303,11 @@ DEFPY_YANG(no_srv6_sid, no_srv6_sid_cmd, "Specify Locator name\n" "Specify SRv6 SID behavior\n" "Apply the code to a uN SID\n" + "Behavior uA\n" + "Configure the interface\n" + "Interface name\n" + "Configure the nexthop\n" + "IPv6 address of the nexthop\n" "Apply the code to an uDT6 SID\n" "Configure VRF name\n" "Specify VRF name\n" @@ -1685,6 +1716,7 @@ static void srv6_sid_cli_show(struct vty *vty, const struct lyd_node *sid, bool { enum srv6_endpoint_behavior_codepoint srv6_behavior; struct prefix_ipv6 sid_value; + struct ipaddr nexthop; yang_dnode_get_ipv6p(&sid_value, sid, "sid"); @@ -1696,9 +1728,21 @@ static void srv6_sid_cli_show(struct vty *vty, const struct lyd_node *sid, bool case SRV6_ENDPOINT_BEHAVIOR_END: vty_out(vty, " behavior End"); break; + case SRV6_ENDPOINT_BEHAVIOR_END_PSP: + vty_out(vty, " behavior End PSP"); + break; + case SRV6_ENDPOINT_BEHAVIOR_END_PSP_USD: + vty_out(vty, " behavior End PSP/USD"); + break; case SRV6_ENDPOINT_BEHAVIOR_END_X: vty_out(vty, " behavior End.X"); break; + case SRV6_ENDPOINT_BEHAVIOR_END_X_PSP: + vty_out(vty, " behavior End.X PSP"); + break; + case SRV6_ENDPOINT_BEHAVIOR_END_X_PSP_USD: + vty_out(vty, " behavior End.X PSP/USD"); + break; case SRV6_ENDPOINT_BEHAVIOR_END_DT6: vty_out(vty, " behavior End.DT6"); break; @@ -1711,9 +1755,21 @@ static void srv6_sid_cli_show(struct vty *vty, const struct lyd_node *sid, bool case SRV6_ENDPOINT_BEHAVIOR_END_NEXT_CSID: vty_out(vty, " behavior uN"); break; + case SRV6_ENDPOINT_BEHAVIOR_END_NEXT_CSID_PSP: + vty_out(vty, " behavior uN PSP"); + break; + case SRV6_ENDPOINT_BEHAVIOR_END_NEXT_CSID_PSP_USD: + vty_out(vty, " behavior uN PSP/USD"); + break; case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID: vty_out(vty, " behavior uA"); break; + case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID_PSP: + vty_out(vty, " behavior uA PSP"); + break; + case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID_PSP_USD: + vty_out(vty, " behavior uA PSP/USD"); + break; case SRV6_ENDPOINT_BEHAVIOR_END_DT6_USID: vty_out(vty, " behavior uDT6"); break; @@ -1732,6 +1788,16 @@ static void srv6_sid_cli_show(struct vty *vty, const struct lyd_node *sid, bool if (yang_dnode_exists(sid, "vrf-name")) vty_out(vty, " vrf %s", yang_dnode_get_string(sid, "vrf-name")); + if (yang_dnode_exists(sid, "paths[path-index=0]/interface")) { + vty_out(vty, " interface %s", + yang_dnode_get_string(sid, "paths[path-index=0]/interface")); + + if (yang_dnode_exists(sid, "paths[path-index=0]/next-hop")) { + yang_dnode_get_ip(&nexthop, sid, "paths[path-index=0]/next-hop"); + vty_out(vty, " nexthop %pI6", &nexthop.ipaddr_v6); + } + } + vty_out(vty, "\n"); } diff --git a/staticd/static_zebra.c b/staticd/static_zebra.c index 9a794d4d02..a6521cccc6 100644 --- a/staticd/static_zebra.c +++ b/staticd/static_zebra.c @@ -323,6 +323,10 @@ void static_zebra_nht_register(struct static_nexthop *nh, bool reg) if (!static_zebra_nht_get_prefix(nh, &lookup.nh)) return; + + if (nh->nh_vrf_id == VRF_UNKNOWN) + return; + lookup.nh_vrf_id = nh->nh_vrf_id; lookup.safi = si->safi; @@ -631,9 +635,20 @@ void static_zebra_srv6_sid_install(struct static_srv6_sid *sid) } switch (sid->behavior) { + case SRV6_ENDPOINT_BEHAVIOR_END_PSP: + action = ZEBRA_SEG6_LOCAL_ACTION_END; + SET_SRV6_FLV_OP(ctx.flv.flv_ops, ZEBRA_SEG6_LOCAL_FLV_OP_PSP); + break; case SRV6_ENDPOINT_BEHAVIOR_END: action = ZEBRA_SEG6_LOCAL_ACTION_END; break; + case SRV6_ENDPOINT_BEHAVIOR_END_NEXT_CSID_PSP: + action = ZEBRA_SEG6_LOCAL_ACTION_END; + SET_SRV6_FLV_OP(ctx.flv.flv_ops, ZEBRA_SEG6_LOCAL_FLV_OP_NEXT_CSID); + SET_SRV6_FLV_OP(ctx.flv.flv_ops, ZEBRA_SEG6_LOCAL_FLV_OP_PSP); + ctx.flv.lcblock_len = sid->locator->block_bits_length; + ctx.flv.lcnode_func_len = sid->locator->node_bits_length; + break; case SRV6_ENDPOINT_BEHAVIOR_END_NEXT_CSID: action = ZEBRA_SEG6_LOCAL_ACTION_END; SET_SRV6_FLV_OP(ctx.flv.flv_ops, ZEBRA_SEG6_LOCAL_FLV_OP_NEXT_CSID); @@ -691,8 +706,26 @@ void static_zebra_srv6_sid_install(struct static_srv6_sid *sid) return; } break; - case SRV6_ENDPOINT_BEHAVIOR_END_X: case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID: + action = ZEBRA_SEG6_LOCAL_ACTION_END_X; + ctx.nh6 = sid->attributes.nh6; + ifp = if_lookup_by_name(sid->attributes.ifname, VRF_DEFAULT); + if (!ifp) { + zlog_warn("Failed to install SID %pFX: failed to get interface %s", + &sid->addr, sid->attributes.ifname); + return; + } + SET_SRV6_FLV_OP(ctx.flv.flv_ops, ZEBRA_SEG6_LOCAL_FLV_OP_NEXT_CSID); + ctx.flv.lcblock_len = sid->locator->block_bits_length; + ctx.flv.lcnode_func_len = sid->locator->node_bits_length; + break; + case SRV6_ENDPOINT_BEHAVIOR_END_PSP_USD: + case SRV6_ENDPOINT_BEHAVIOR_END_NEXT_CSID_PSP_USD: + case SRV6_ENDPOINT_BEHAVIOR_END_X: + case SRV6_ENDPOINT_BEHAVIOR_END_X_PSP: + 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_OPAQUE: case SRV6_ENDPOINT_BEHAVIOR_RESERVED: zlog_warn("unsupported behavior: %u", sid->behavior); @@ -764,7 +797,9 @@ void static_zebra_srv6_sid_uninstall(struct static_srv6_sid *sid) switch (sid->behavior) { case SRV6_ENDPOINT_BEHAVIOR_END: + case SRV6_ENDPOINT_BEHAVIOR_END_PSP: case SRV6_ENDPOINT_BEHAVIOR_END_NEXT_CSID: + case SRV6_ENDPOINT_BEHAVIOR_END_NEXT_CSID_PSP: break; case SRV6_ENDPOINT_BEHAVIOR_END_DT6: case SRV6_ENDPOINT_BEHAVIOR_END_DT6_USID: @@ -811,8 +846,22 @@ void static_zebra_srv6_sid_uninstall(struct static_srv6_sid *sid) return; } break; - case SRV6_ENDPOINT_BEHAVIOR_END_X: case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID: + ctx.nh6 = sid->attributes.nh6; + ifp = if_lookup_by_name(sid->attributes.ifname, VRF_DEFAULT); + if (!ifp) { + zlog_warn("Failed to install SID %pFX: failed to get interface %s", + &sid->addr, sid->attributes.ifname); + return; + } + break; + case SRV6_ENDPOINT_BEHAVIOR_END_PSP_USD: + case SRV6_ENDPOINT_BEHAVIOR_END_NEXT_CSID_PSP_USD: + case SRV6_ENDPOINT_BEHAVIOR_END_X: + case SRV6_ENDPOINT_BEHAVIOR_END_X_PSP: + 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_OPAQUE: case SRV6_ENDPOINT_BEHAVIOR_RESERVED: zlog_warn("unsupported behavior: %u", sid->behavior); @@ -865,6 +914,7 @@ extern void static_zebra_request_srv6_sid(struct static_srv6_sid *sid) struct srv6_sid_ctx ctx = {}; int ret = 0; struct vrf *vrf; + struct interface *ifp; if (!sid) return; @@ -872,7 +922,9 @@ extern void static_zebra_request_srv6_sid(struct static_srv6_sid *sid) /* convert `srv6_endpoint_behavior_codepoint` to `seg6local_action_t` */ switch (sid->behavior) { case SRV6_ENDPOINT_BEHAVIOR_END: + case SRV6_ENDPOINT_BEHAVIOR_END_PSP: case SRV6_ENDPOINT_BEHAVIOR_END_NEXT_CSID: + case SRV6_ENDPOINT_BEHAVIOR_END_NEXT_CSID_PSP: ctx.behavior = ZEBRA_SEG6_LOCAL_ACTION_END; break; case SRV6_ENDPOINT_BEHAVIOR_END_DT6: @@ -914,8 +966,24 @@ extern void static_zebra_request_srv6_sid(struct static_srv6_sid *sid) } break; - case SRV6_ENDPOINT_BEHAVIOR_END_X: case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID: + ctx.behavior = ZEBRA_SEG6_LOCAL_ACTION_END_X; + ctx.nh6 = sid->attributes.nh6; + ifp = if_lookup_by_name(sid->attributes.ifname, VRF_DEFAULT); + if (!ifp) { + zlog_warn("Failed to request SRv6 SID %pFX: interface %s does not exist", + &sid->addr, sid->attributes.ifname); + return; + } + ctx.ifindex = ifp->ifindex; + break; + case SRV6_ENDPOINT_BEHAVIOR_END_PSP_USD: + case SRV6_ENDPOINT_BEHAVIOR_END_NEXT_CSID_PSP_USD: + case SRV6_ENDPOINT_BEHAVIOR_END_X: + case SRV6_ENDPOINT_BEHAVIOR_END_X_PSP: + 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_OPAQUE: case SRV6_ENDPOINT_BEHAVIOR_RESERVED: zlog_warn("unsupported behavior: %u", sid->behavior); @@ -933,6 +1001,7 @@ extern void static_zebra_release_srv6_sid(struct static_srv6_sid *sid) struct srv6_sid_ctx ctx = {}; struct vrf *vrf; int ret = 0; + struct interface *ifp; if (!sid || !CHECK_FLAG(sid->flags, STATIC_FLAG_SRV6_SID_VALID)) return; @@ -940,7 +1009,9 @@ extern void static_zebra_release_srv6_sid(struct static_srv6_sid *sid) /* convert `srv6_endpoint_behavior_codepoint` to `seg6local_action_t` */ switch (sid->behavior) { case SRV6_ENDPOINT_BEHAVIOR_END: + case SRV6_ENDPOINT_BEHAVIOR_END_PSP: case SRV6_ENDPOINT_BEHAVIOR_END_NEXT_CSID: + case SRV6_ENDPOINT_BEHAVIOR_END_NEXT_CSID_PSP: ctx.behavior = ZEBRA_SEG6_LOCAL_ACTION_END; break; case SRV6_ENDPOINT_BEHAVIOR_END_DT6: @@ -982,8 +1053,24 @@ extern void static_zebra_release_srv6_sid(struct static_srv6_sid *sid) } break; - case SRV6_ENDPOINT_BEHAVIOR_END_X: case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID: + ctx.behavior = ZEBRA_SEG6_LOCAL_ACTION_END_X; + ctx.nh6 = sid->attributes.nh6; + ifp = if_lookup_by_name(sid->attributes.ifname, VRF_DEFAULT); + if (!ifp) { + zlog_warn("Failed to request SRv6 SID %pFX: interface %s does not exist", + &sid->addr, sid->attributes.ifname); + return; + } + ctx.ifindex = ifp->ifindex; + break; + case SRV6_ENDPOINT_BEHAVIOR_END_PSP_USD: + case SRV6_ENDPOINT_BEHAVIOR_END_NEXT_CSID_PSP_USD: + case SRV6_ENDPOINT_BEHAVIOR_END_X: + case SRV6_ENDPOINT_BEHAVIOR_END_X_PSP: + 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_OPAQUE: case SRV6_ENDPOINT_BEHAVIOR_RESERVED: zlog_warn("unsupported behavior: %u", sid->behavior); @@ -1199,6 +1286,9 @@ static int static_zebra_srv6_sid_notify(ZAPI_CALLBACK_ARGS) return 0; } + if (!IPV6_ADDR_SAME(&ctx.nh6, &in6addr_any)) + sid->attributes.nh6 = ctx.nh6; + SET_FLAG(sid->flags, STATIC_FLAG_SRV6_SID_VALID); /* |
