summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--isisd/isis_zebra.c16
-rw-r--r--lib/srv6.h12
-rw-r--r--staticd/static_vty.c12
-rw-r--r--staticd/static_zebra.c16
-rw-r--r--tests/topotests/lib/common_config.py12
-rwxr-xr-xtools/frr-reload.py22
-rw-r--r--zebra/fpm_listener.c68
7 files changed, 152 insertions, 6 deletions
diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c
index cb729501cc..9d483c9368 100644
--- a/isisd/isis_zebra.c
+++ b/isisd/isis_zebra.c
@@ -1007,6 +1007,10 @@ void isis_zebra_srv6_sid_install(struct isis_area *area,
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:
default:
zlog_err(
"ISIS-SRv6 (%s): unsupported SRv6 endpoint behavior %u",
@@ -1072,6 +1076,10 @@ void isis_zebra_srv6_sid_uninstall(struct isis_area *area,
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:
default:
zlog_err(
"ISIS-SRv6 (%s): unsupported SRv6 endpoint behavior %u",
@@ -1145,6 +1153,10 @@ void isis_zebra_srv6_adj_sid_install(struct srv6_adjacency *sra)
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:
default:
zlog_err(
"ISIS-SRv6 (%s): unsupported SRv6 endpoint behavior %u",
@@ -1199,6 +1211,10 @@ void isis_zebra_srv6_adj_sid_uninstall(struct srv6_adjacency *sra)
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:
default:
zlog_err(
"ISIS-SRv6 (%s): unsupported SRv6 endpoint behavior %u",
diff --git a/lib/srv6.h b/lib/srv6.h
index 467f02a3c9..bd80253b55 100644
--- a/lib/srv6.h
+++ b/lib/srv6.h
@@ -179,9 +179,11 @@ enum srv6_endpoint_behavior_codepoint {
SRV6_ENDPOINT_BEHAVIOR_END_PSP = 0x0002,
SRV6_ENDPOINT_BEHAVIOR_END_X = 0x0005,
SRV6_ENDPOINT_BEHAVIOR_END_X_PSP = 0x0006,
+ SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS = 0x000E,
SRV6_ENDPOINT_BEHAVIOR_END_DT6 = 0x0012,
SRV6_ENDPOINT_BEHAVIOR_END_DT4 = 0x0013,
SRV6_ENDPOINT_BEHAVIOR_END_DT46 = 0x0014,
+ SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED = 0x001B,
SRV6_ENDPOINT_BEHAVIOR_END_PSP_USD = 0x001D,
SRV6_ENDPOINT_BEHAVIOR_END_X_PSP_USD = 0x0021,
SRV6_ENDPOINT_BEHAVIOR_END_NEXT_CSID = 0x002B,
@@ -193,6 +195,8 @@ enum srv6_endpoint_behavior_codepoint {
SRV6_ENDPOINT_BEHAVIOR_END_DT6_USID = 0x003E,
SRV6_ENDPOINT_BEHAVIOR_END_DT4_USID = 0x003F,
SRV6_ENDPOINT_BEHAVIOR_END_DT46_USID = 0x0040,
+ SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_NEXT_CSID = 0x005D,
+ SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED_NEXT_CSID = 0x005E,
SRV6_ENDPOINT_BEHAVIOR_OPAQUE = 0xFFFF,
};
@@ -215,6 +219,8 @@ srv6_endpoint_behavior_codepoint2str(enum srv6_endpoint_behavior_codepoint behav
return "End.X";
case SRV6_ENDPOINT_BEHAVIOR_END_X_PSP:
return "End.X PSP";
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS:
+ return "End.B6.Encaps";
case SRV6_ENDPOINT_BEHAVIOR_END_X_PSP_USD:
return "End.X PSP/USD";
case SRV6_ENDPOINT_BEHAVIOR_END_DT6:
@@ -223,6 +229,8 @@ srv6_endpoint_behavior_codepoint2str(enum srv6_endpoint_behavior_codepoint behav
return "End.DT4";
case SRV6_ENDPOINT_BEHAVIOR_END_DT46:
return "End.DT46";
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED:
+ return "End.B6.Encaps.Red";
case SRV6_ENDPOINT_BEHAVIOR_END_NEXT_CSID:
return "uN";
case SRV6_ENDPOINT_BEHAVIOR_END_NEXT_CSID_PSP:
@@ -241,6 +249,10 @@ srv6_endpoint_behavior_codepoint2str(enum srv6_endpoint_behavior_codepoint behav
return "uDT4";
case SRV6_ENDPOINT_BEHAVIOR_END_DT46_USID:
return "uDT46";
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_NEXT_CSID:
+ return "uB6.Encaps";
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED_NEXT_CSID:
+ return "uB6.Encaps.Red";
case SRV6_ENDPOINT_BEHAVIOR_OPAQUE:
return "Opaque";
}
diff --git a/staticd/static_vty.c b/staticd/static_vty.c
index ffa90d5352..6fc4f067d9 100644
--- a/staticd/static_vty.c
+++ b/staticd/static_vty.c
@@ -1752,6 +1752,9 @@ static void srv6_sid_cli_show(struct vty *vty, const struct lyd_node *sid, bool
case SRV6_ENDPOINT_BEHAVIOR_END_X_PSP:
vty_out(vty, " behavior End.X PSP");
break;
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS:
+ vty_out(vty, " behavior End.B6.Encaps");
+ break;
case SRV6_ENDPOINT_BEHAVIOR_END_X_PSP_USD:
vty_out(vty, " behavior End.X PSP/USD");
break;
@@ -1764,6 +1767,9 @@ static void srv6_sid_cli_show(struct vty *vty, const struct lyd_node *sid, bool
case SRV6_ENDPOINT_BEHAVIOR_END_DT46:
vty_out(vty, " behavior End.DT46");
break;
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED:
+ vty_out(vty, " behavior End.B6.Encaps.Red");
+ break;
case SRV6_ENDPOINT_BEHAVIOR_END_NEXT_CSID:
vty_out(vty, " behavior uN");
break;
@@ -1791,6 +1797,12 @@ static void srv6_sid_cli_show(struct vty *vty, const struct lyd_node *sid, bool
case SRV6_ENDPOINT_BEHAVIOR_END_DT46_USID:
vty_out(vty, " behavior uDT46");
break;
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_NEXT_CSID:
+ vty_out(vty, " behavior uB6.Encaps");
+ break;
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED_NEXT_CSID:
+ vty_out(vty, " behavior uB6.Encaps.Red");
+ break;
case SRV6_ENDPOINT_BEHAVIOR_RESERVED:
case SRV6_ENDPOINT_BEHAVIOR_OPAQUE:
vty_out(vty, " behavior unknown");
diff --git a/staticd/static_zebra.c b/staticd/static_zebra.c
index 714f4b89ea..f02fe1e95c 100644
--- a/staticd/static_zebra.c
+++ b/staticd/static_zebra.c
@@ -730,6 +730,10 @@ 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);
@@ -853,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;
}
@@ -999,6 +1007,10 @@ 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;
}
@@ -1087,6 +1099,10 @@ 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;
}
diff --git a/tests/topotests/lib/common_config.py b/tests/topotests/lib/common_config.py
index f34c48b890..54142e8526 100644
--- a/tests/topotests/lib/common_config.py
+++ b/tests/topotests/lib/common_config.py
@@ -196,7 +196,7 @@ def get_seq_id(obj_type, router, obj_name):
return seq_id
-def set_seq_id(obj_type, router, id, obj_name):
+def set_seq_id(obj_type, router, sequence_id, obj_name):
"""
Saves sequence number if not auto-generated and given by user
Parameters
@@ -209,7 +209,7 @@ def set_seq_id(obj_type, router, id, obj_name):
obj_data = router_data.setdefault(obj_name, {})
seq_id = obj_data.setdefault("seq_id", 0)
- seq_id = int(seq_id) + int(id)
+ seq_id = int(seq_id) + int(sequence_id)
obj_data["seq_id"] = seq_id
@@ -2539,10 +2539,10 @@ def create_route_maps(tgen, input_dict, build=False):
)
return False
if large_comm_list:
- id = large_comm_list.setdefault("id", None)
+ comm_id = large_comm_list.setdefault("id", None)
del_comm = large_comm_list.setdefault("delete", None)
- if id:
- cmd = "set large-comm-list {}".format(id)
+ if comm_id:
+ cmd = "set large-comm-list {}".format(comm_id)
if del_comm:
cmd = "{} delete".format(cmd)
@@ -4608,7 +4608,7 @@ class HostApplicationHelper(object):
self.init()
return self
- def __exit__(self, type, value, traceback):
+ def __exit__(self, exit_type, exit_value, exit_traceback):
self.cleanup()
def __str__(self):
diff --git a/tools/frr-reload.py b/tools/frr-reload.py
index f2389f27a5..95a00c2b6a 100755
--- a/tools/frr-reload.py
+++ b/tools/frr-reload.py
@@ -1698,6 +1698,7 @@ def ignore_unconfigurable_lines(lines_to_add, lines_to_del):
those commands from lines_to_del.
"""
lines_to_del_to_del = []
+ lines_to_del_to_add = []
for ctx_keys, line in lines_to_del:
# The integrated-vtysh-config one is technically "no"able but if we did
@@ -1719,10 +1720,31 @@ def ignore_unconfigurable_lines(lines_to_add, lines_to_del):
):
log.info(f'"{ctx_keys[-1]}" cannot be removed')
lines_to_del_to_del.append((ctx_keys, line))
+ # Handle segment-routing srv6 locators and formats commands
+ # - Ignore "no formats" and "no locators" command
+ # - replace "no prefix" under locator XYZ as "no locator XYZ"
+ elif (
+ len(ctx_keys) > 2
+ and ctx_keys[0].startswith("segment-routing")
+ and ctx_keys[1].startswith("srv6")
+ and ctx_keys[2] in {"locators", "formats"}
+ ):
+ is_top_level = len(ctx_keys) == 3 and not line
+ if ctx_keys[2] == "formats" and is_top_level:
+ lines_to_del_to_del.append((ctx_keys, line))
+ elif ctx_keys[2] == "locators":
+ if is_top_level:
+ lines_to_del_to_del.append((ctx_keys, line))
+ elif len(ctx_keys) == 4 and line and line.startswith("prefix "):
+ lines_to_del_to_del.append((ctx_keys, line))
+ lines_to_del_to_add.append((ctx_keys[:-1] + (ctx_keys[-1],), None))
for ctx_keys, line in lines_to_del_to_del:
lines_to_del.remove((ctx_keys, line))
+ for ctx_keys, line in lines_to_del_to_add:
+ lines_to_del.append((ctx_keys, line))
+
return (lines_to_add, lines_to_del)
diff --git a/zebra/fpm_listener.c b/zebra/fpm_listener.c
index 70dcaf91a1..7ae9601ef4 100644
--- a/zebra/fpm_listener.c
+++ b/zebra/fpm_listener.c
@@ -33,10 +33,12 @@
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <linux/if_link.h>
+#include <linux/nexthop.h>
#include "rt_netlink.h"
#include "fpm/fpm.h"
#include "lib/libfrr.h"
+#include "zebra/kernel_netlink.h"
XREF_SETUP();
@@ -573,6 +575,67 @@ static int parse_route_msg(struct netlink_msg_ctx *ctx)
}
/*
+ * parse_nexthop_msg
+ */
+static int parse_nexthop_msg(struct nlmsghdr *hdr)
+{
+ struct nhmsg *nhmsg;
+ struct rtattr *tb[NHA_MAX + 1] = {};
+ int len;
+ uint32_t nhgid = 0;
+ uint8_t nhg_count = 0;
+ const char *err_msg = NULL;
+ char protocol_str[32] = "Unknown";
+
+ nhmsg = NLMSG_DATA(hdr);
+ len = hdr->nlmsg_len - NLMSG_LENGTH(sizeof(*nhmsg));
+ if (len < 0) {
+ fprintf(stderr, "Bad nexthop message length\n");
+ return 0;
+ }
+
+ if (!parse_rtattrs_(RTM_NHA(nhmsg), len, tb, ARRAY_SIZE(tb), &err_msg)) {
+ fprintf(stderr, "Error parsing nexthop attributes: %s\n", err_msg);
+ return 0;
+ }
+
+ /* Get protocol string */
+ snprintf(protocol_str, sizeof(protocol_str), "%s(%u)",
+ netlink_prot_to_s(nhmsg->nh_protocol), nhmsg->nh_protocol);
+
+ /* Get Nexthop Group ID */
+ if (tb[NHA_ID])
+ nhgid = *(uint32_t *)RTA_DATA(tb[NHA_ID]);
+
+ /* Count nexthops in the group */
+ if (tb[NHA_GROUP]) {
+ struct nexthop_grp *nhg = (struct nexthop_grp *)RTA_DATA(tb[NHA_GROUP]);
+ size_t count = (RTA_PAYLOAD(tb[NHA_GROUP]) / sizeof(*nhg));
+
+ if (count > 0 && (count * sizeof(*nhg)) == RTA_PAYLOAD(tb[NHA_GROUP]))
+ nhg_count = count;
+ } else if (tb[NHA_OIF] || tb[NHA_GATEWAY]) {
+ /* Single nexthop case */
+ nhg_count = 1;
+ }
+
+ /* Print blackhole status if applicable */
+ if (tb[NHA_BLACKHOLE]) {
+ fprintf(glob->output_file,
+ "[%s] %s Nexthop Group ID: %u, Protocol: %s, Type: BLACKHOLE, Family: %u\n",
+ get_timestamp(), hdr->nlmsg_type == RTM_NEWNEXTHOP ? "New" : "Del", nhgid,
+ protocol_str, nhmsg->nh_family);
+ } else {
+ fprintf(glob->output_file,
+ "[%s] %s Nexthop Group ID: %u, Protocol: %s, Contains %u nexthops, Family: %u, Scope: %u\n",
+ get_timestamp(), hdr->nlmsg_type == RTM_NEWNEXTHOP ? "New" : "Del", nhgid,
+ protocol_str, nhg_count, nhmsg->nh_family, nhmsg->nh_scope);
+ }
+
+ return 1;
+}
+
+/*
* addr_to_s
*/
static const char *
@@ -742,6 +805,11 @@ static void parse_netlink_msg(char *buf, size_t buf_len, fpm_msg_hdr_t *fpm)
}
break;
+ case RTM_NEWNEXTHOP:
+ case RTM_DELNEXTHOP:
+ parse_nexthop_msg(hdr);
+ break;
+
default:
fprintf(glob->output_file, "[%s] Ignoring netlink message - Type: %s(%d)\n",
get_timestamp(), netlink_msg_type_to_s(hdr->nlmsg_type),