summaryrefslogtreecommitdiff
path: root/staticd
diff options
context:
space:
mode:
Diffstat (limited to 'staticd')
-rw-r--r--staticd/static_nb.c21
-rw-r--r--staticd/static_nb.h16
-rw-r--r--staticd/static_nb_config.c107
-rw-r--r--staticd/static_routes.c5
-rw-r--r--staticd/static_vty.c70
-rw-r--r--staticd/static_zebra.c98
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);
/*