diff options
| -rw-r--r-- | isisd/isis_zebra.c | 16 | ||||
| -rw-r--r-- | lib/srv6.h | 12 | ||||
| -rw-r--r-- | staticd/static_vty.c | 12 | ||||
| -rw-r--r-- | staticd/static_zebra.c | 16 | ||||
| -rw-r--r-- | tests/topotests/lib/common_config.py | 12 | ||||
| -rwxr-xr-x | tools/frr-reload.py | 22 | ||||
| -rw-r--r-- | zebra/fpm_listener.c | 68 |
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), |
