From 6b093863ecca602d40ef5a22f07b3cfc432671f5 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Fri, 18 May 2018 15:41:46 -0400 Subject: [PATCH] zebra: Allow runtime determination of v6 RR semantics The linux kernel is getting the same Route Replace semantics for v6 that v4 uses. Allow the end-user to know if their kernel has this ability and if so to specify it so zebra can take advantage of this. Why not do auto-detection? Because you would have to write code in zebra to add a route then add the same route again with different nexthops to see if which semantics it is using. It sure is easier to just add a cli that allows the user to do it. Signed-off-by: Donald Sharp --- zebra/main.c | 51 +++++++++++++++++++++++++++------------------- zebra/rib.h | 1 + zebra/rt_netlink.c | 2 +- 3 files changed, 32 insertions(+), 22 deletions(-) diff --git a/zebra/main.c b/zebra/main.c index 9a495c894..da9fe9512 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -75,24 +75,29 @@ int allow_delete = 0; /* Don't delete kernel route. */ int keep_kernel_mode = 0; +bool v6_rr_semantics = false; + #ifdef HAVE_NETLINK /* Receive buffer size for netlink socket */ uint32_t nl_rcvbufsize = 4194304; #endif /* HAVE_NETLINK */ +#define OPTION_V6_RR_SEMANTICS 2000 /* Command line options. */ -struct option longopts[] = {{"batch", no_argument, NULL, 'b'}, - {"allow_delete", no_argument, NULL, 'a'}, - {"keep_kernel", no_argument, NULL, 'k'}, - {"socket", required_argument, NULL, 'z'}, - {"ecmp", required_argument, NULL, 'e'}, - {"label_socket", no_argument, NULL, 'l'}, - {"retain", no_argument, NULL, 'r'}, +struct option longopts[] = { + {"batch", no_argument, NULL, 'b'}, + {"allow_delete", no_argument, NULL, 'a'}, + {"keep_kernel", no_argument, NULL, 'k'}, + {"socket", required_argument, NULL, 'z'}, + {"ecmp", required_argument, NULL, 'e'}, + {"label_socket", no_argument, NULL, 'l'}, + {"retain", no_argument, NULL, 'r'}, #ifdef HAVE_NETLINK - {"vrfwnetns", no_argument, NULL, 'n'}, - {"nl-bufsize", required_argument, NULL, 's'}, + {"vrfwnetns", no_argument, NULL, 'n'}, + {"nl-bufsize", required_argument, NULL, 's'}, + {"v6-rr-semantics", no_argument, NULL, OPTION_V6_RR_SEMANTICS}, #endif /* HAVE_NETLINK */ - {0}}; + {0}}; zebra_capabilities_t _caps_p[] = { ZCAP_NET_ADMIN, ZCAP_SYS_ADMIN, ZCAP_NET_RAW, @@ -224,21 +229,22 @@ int main(int argc, char **argv) #endif , longopts, - " -b, --batch Runs in batch mode\n" - " -a, --allow_delete Allow other processes to delete zebra routes\n" - " -z, --socket Set path of zebra socket\n" - " -e, --ecmp Specify ECMP to use.\n" - " -l, --label_socket Socket to external label manager\n" - " -k, --keep_kernel Don't delete old routes which installed by zebra.\n" - " -r, --retain When program terminates, retain added route by zebra.\n" + " -b, --batch Runs in batch mode\n" + " -a, --allow_delete Allow other processes to delete zebra routes\n" + " -z, --socket Set path of zebra socket\n" + " -e, --ecmp Specify ECMP to use.\n" + " -l, --label_socket Socket to external label manager\n" + " -k, --keep_kernel Don't delete old routes which installed by zebra.\n" + " -r, --retain When program terminates, retain added route by zebra.\n" #ifdef HAVE_NETLINK - " -n, --vrfwnetns Set VRF with NetNS\n" - " -s, --nl-bufsize Set netlink receive buffer size\n" + " -n, --vrfwnetns Set VRF with NetNS\n" + " -s, --nl-bufsize Set netlink receive buffer size\n" + " --v6-rr-semantics Use v6 RR semantics\n" #endif /* HAVE_NETLINK */ #if defined(HANDLE_ZAPI_FUZZING) - " -c Bypass normal startup use this file for tetsting of zapi" + " -c Bypass normal startup use this file for tetsting of zapi" #endif - ); + ); while (1) { int opt = frr_getopt(argc, argv, NULL); @@ -292,6 +298,9 @@ int main(int argc, char **argv) logicalrouter_configure_backend( LOGICALROUTER_BACKEND_OFF); break; + case OPTION_V6_RR_SEMANTICS: + v6_rr_semantics = true; + break; #endif /* HAVE_NETLINK */ #if defined(HANDLE_ZAPI_FUZZING) case 'c': diff --git a/zebra/rib.h b/zebra/rib.h index 7b9e6d56a..209f085ed 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -456,4 +456,5 @@ extern void static_config_install_delayed_routes(struct zebra_vrf *zvrf); extern pid_t pid; +extern bool v6_rr_semantics; #endif /*_ZEBRA_RIB_H */ diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 2fd7bee05..8ab70c8d4 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -1696,7 +1696,7 @@ void kernel_route_rib(struct route_node *rn, struct prefix *p, assert(old || new); if (new) { - if (p->family == AF_INET) + if (p->family == AF_INET || v6_rr_semantics) ret = netlink_route_multipath(RTM_NEWROUTE, p, src_p, new, (old) ? 1 : 0); else { -- 2.39.2