From 4e996e98ecca5bc92ef133ca243fcd621d7d235a Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Fri, 3 Nov 2023 16:35:45 +0000 Subject: [PATCH 1/3] zebra: Add v6_rr_semantics status to `show zebra` The v6_rr_semantics variable was being set but never reported and had to be inferred from watching netlink messages to the kernel. Let's add a bit of code to `show zebra` so that we can know how it is being used. Signed-off-by: Donald Sharp --- zebra/zebra_vty.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index d36c2f81c7..e7a59b4700 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -4047,7 +4047,8 @@ DEFUN (show_zebra, ttable_add_row(table, "MPLS|%s", mpls_enabled ? "On" : "Off"); ttable_add_row(table, "EVPN|%s", is_evpn_enabled() ? "On" : "Off"); ttable_add_row(table, "Kernel socket buffer size|%d", rcvbufsize); - + ttable_add_row(table, "v6 Route Replace Semantics|%s", + v6_rr_semantics ? "Replace" : "Delete than Add"); #ifdef GNU_LINUX if (!vrf_is_backend_netns()) From 7fe9333dd7e963dd6c96e1dac1dbbc4271ad693f Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Fri, 3 Nov 2023 16:58:42 +0000 Subject: [PATCH 2/3] zebra: Move v6_rr_semantics to be part of zrouter structure Move global variable v6_rr_semantics from a global data structure into the zrouter data structure. Signed-off-by: Donald Sharp --- zebra/main.c | 4 +--- zebra/rib.h | 2 -- zebra/rt_netlink.c | 5 ++--- zebra/zebra_router.h | 2 ++ zebra/zebra_vty.c | 2 +- 5 files changed, 6 insertions(+), 9 deletions(-) diff --git a/zebra/main.c b/zebra/main.c index 1e833ce7f1..158d1b8c4c 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -59,8 +59,6 @@ int retain_mode = 0; int graceful_restart; -bool v6_rr_semantics = false; - /* Receive buffer size for kernel control sockets */ #define RCVBUFSIZE_MIN 4194304 #ifdef HAVE_NETLINK @@ -385,7 +383,7 @@ int main(int argc, char **argv) vrf_configure_backend(VRF_BACKEND_NETNS); break; case OPTION_V6_RR_SEMANTICS: - v6_rr_semantics = true; + zrouter.v6_rr_semantics = true; break; case OPTION_ASIC_OFFLOAD: if (!strcmp(optarg, "notify_on_offload")) diff --git a/zebra/rib.h b/zebra/rib.h index e70b5c1423..665f286f67 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -627,8 +627,6 @@ extern void zebra_vty_init(void); extern pid_t pid; -extern bool v6_rr_semantics; - extern uint32_t rt_table_main_id; /* Name of hook calls */ diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index ec35842b0a..3351b03950 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -2209,7 +2209,7 @@ ssize_t netlink_route_multipath_msg_encode(int cmd, struct zebra_dplane_ctx *ctx req->n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST; if (((cmd == RTM_NEWROUTE) && - ((p->family == AF_INET) || v6_rr_semantics)) || + ((p->family == AF_INET) || zrouter.v6_rr_semantics)) || force_rr) req->n.nlmsg_flags |= NLM_F_REPLACE; @@ -3095,8 +3095,7 @@ netlink_put_route_update_msg(struct nl_batch *bth, struct zebra_dplane_ctx *ctx) } else if (dplane_ctx_get_op(ctx) == DPLANE_OP_ROUTE_INSTALL) { cmd = RTM_NEWROUTE; } else if (dplane_ctx_get_op(ctx) == DPLANE_OP_ROUTE_UPDATE) { - - if (p->family == AF_INET || v6_rr_semantics) { + if (p->family == AF_INET || zrouter.v6_rr_semantics) { /* Single 'replace' operation */ /* diff --git a/zebra/zebra_router.h b/zebra/zebra_router.h index b700851df5..a926369ef8 100644 --- a/zebra/zebra_router.h +++ b/zebra/zebra_router.h @@ -209,6 +209,8 @@ struct zebra_router { bool notify_on_ack; bool v6_with_v4_nexthop; + bool v6_rr_semantics; + /* * If the asic is notifying us about successful nexthop * allocation/control. Some developers have made their diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index e7a59b4700..fce358f9ff 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -4048,7 +4048,7 @@ DEFUN (show_zebra, ttable_add_row(table, "EVPN|%s", is_evpn_enabled() ? "On" : "Off"); ttable_add_row(table, "Kernel socket buffer size|%d", rcvbufsize); ttable_add_row(table, "v6 Route Replace Semantics|%s", - v6_rr_semantics ? "Replace" : "Delete than Add"); + zrouter.v6_rr_semantics ? "Replace" : "Delete then Add"); #ifdef GNU_LINUX if (!vrf_is_backend_netns()) From 7e1b56ba98c22bb26cd798b289a214abfb32a8e2 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Mon, 6 Nov 2023 08:56:50 -0500 Subject: [PATCH 3/3] zebra: When using Nexthop groups, use v6 RR semantics The nexthop group route replace operation was made consistent across all versions of the kernel. A v6 route replacement does not need to do a delete than add when using nexthop groups Signed-off-by: Donald Sharp --- zebra/rt_netlink.c | 6 ++++-- zebra/zebra_vty.c | 14 +++++++++++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 3351b03950..58116c6563 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -2209,7 +2209,8 @@ ssize_t netlink_route_multipath_msg_encode(int cmd, struct zebra_dplane_ctx *ctx req->n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST; if (((cmd == RTM_NEWROUTE) && - ((p->family == AF_INET) || zrouter.v6_rr_semantics)) || + ((p->family == AF_INET) || kernel_nexthops_supported() || + zrouter.v6_rr_semantics)) || force_rr) req->n.nlmsg_flags |= NLM_F_REPLACE; @@ -3095,7 +3096,8 @@ netlink_put_route_update_msg(struct nl_batch *bth, struct zebra_dplane_ctx *ctx) } else if (dplane_ctx_get_op(ctx) == DPLANE_OP_ROUTE_INSTALL) { cmd = RTM_NEWROUTE; } else if (dplane_ctx_get_op(ctx) == DPLANE_OP_ROUTE_UPDATE) { - if (p->family == AF_INET || zrouter.v6_rr_semantics) { + if (p->family == AF_INET || kernel_nexthops_supported() || + zrouter.v6_rr_semantics) { /* Single 'replace' operation */ /* diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index fce358f9ff..8c97248737 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -4028,6 +4028,17 @@ static int config_write_protocol(struct vty *vty) return 1; } +static inline bool zebra_vty_v6_rr_semantics_used(void) +{ + if (zebra_nhg_kernel_nexthops_enabled()) + return true; + + if (zrouter.v6_rr_semantics) + return true; + + return false; +} + DEFUN (show_zebra, show_zebra_cmd, "show zebra", @@ -4048,7 +4059,8 @@ DEFUN (show_zebra, ttable_add_row(table, "EVPN|%s", is_evpn_enabled() ? "On" : "Off"); ttable_add_row(table, "Kernel socket buffer size|%d", rcvbufsize); ttable_add_row(table, "v6 Route Replace Semantics|%s", - zrouter.v6_rr_semantics ? "Replace" : "Delete then Add"); + zebra_vty_v6_rr_semantics_used() ? "Replace" + : "Delete then Add"); #ifdef GNU_LINUX if (!vrf_is_backend_netns())