diff options
31 files changed, 147 insertions, 120 deletions
diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c index 074059c146..11917c6c4a 100644 --- a/bgpd/bgp_main.c +++ b/bgpd/bgp_main.c @@ -57,15 +57,17 @@ /* bgpd options, we use GNU getopt library. */ static const struct option longopts[] = { - {"bgp_port", required_argument, NULL, 'p'}, - {"listenon", required_argument, NULL, 'l'}, - {"no_kernel", no_argument, NULL, 'n'}, - {"skip_runas", no_argument, NULL, 'S'}, - {"ecmp", required_argument, NULL, 'e'}, - {"int_num", required_argument, NULL, 'I'}, - {"no_zebra", no_argument, NULL, 'Z'}, - {"socket_size", required_argument, NULL, 's'}, - {0}}; + { "bgp_port", required_argument, NULL, 'p' }, + { "listenon", required_argument, NULL, 'l' }, + { "no_kernel", no_argument, NULL, 'n' }, + { "skip_runas", no_argument, NULL, 'S' }, + { "ecmp", required_argument, NULL, 'e' }, + { "int_num", required_argument, NULL, 'I' }, + { "no_zebra", no_argument, NULL, 'Z' }, + { "socket_size", required_argument, NULL, 's' }, + { "v6-with-v4-nexthops", no_argument, NULL, 'v' }, + { 0 } +}; /* signal definitions */ void sighup(void); @@ -387,16 +389,16 @@ int main(int argc, char **argv) addresses->cmp = (int (*)(void *, void *))strcmp; frr_preinit(&bgpd_di, argc, argv); - frr_opt_add( - "p:l:SnZe:I:s:" DEPRECATED_OPTIONS, longopts, - " -p, --bgp_port Set BGP listen port number (0 means do not listen).\n" - " -l, --listenon Listen on specified address (implies -n)\n" - " -n, --no_kernel Do not install route to kernel.\n" - " -Z, --no_zebra Do not communicate with Zebra.\n" - " -S, --skip_runas Skip capabilities checks, and changing user and group IDs.\n" - " -e, --ecmp Specify ECMP to use.\n" - " -I, --int_num Set instance number (label-manager)\n" - " -s, --socket_size Set BGP peer socket send buffer size\n"); + frr_opt_add("p:l:SnZe:I:s:" DEPRECATED_OPTIONS, longopts, + " -p, --bgp_port Set BGP listen port number (0 means do not listen).\n" + " -l, --listenon Listen on specified address (implies -n)\n" + " -n, --no_kernel Do not install route to kernel.\n" + " -Z, --no_zebra Do not communicate with Zebra.\n" + " -S, --skip_runas Skip capabilities checks, and changing user and group IDs.\n" + " -e, --ecmp Specify ECMP to use.\n" + " -I, --int_num Set instance number (label-manager)\n" + " -s, --socket_size Set BGP peer socket send buffer size\n" + " , --v6-with-v4-nexthop Allow BGP to form v6 neighbors using v4 nexthops\n"); /* Command line argument treatment. */ while (1) { @@ -458,6 +460,9 @@ int main(int argc, char **argv) case 's': buffer_size = atoi(optarg); break; + case 'v': + bm->v6_with_v4_nexthops = true; + break; default: frr_help_exit(1); } diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 7c2c6f616b..cc9b2c7bb4 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -1787,11 +1787,14 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size) || peer->afc_nego[AFI_IP6][SAFI_MULTICAST] || peer->afc_nego[AFI_IP6][SAFI_MPLS_VPN] || peer->afc_nego[AFI_IP6][SAFI_ENCAP]) { - if (IN6_IS_ADDR_UNSPECIFIED(&peer->nexthop.v6_global)) { -#if defined(HAVE_CUMULUS) - zlog_warn("%s: No local IPv6 address, BGP routing may not work", - peer->host); -#endif + if (IN6_IS_ADDR_UNSPECIFIED(&peer->nexthop.v6_global) && + !bm->v6_with_v4_nexthops) { + flog_err(EC_BGP_SND_FAIL, +"%s: No local IPv6 address, and zebra does not support V6 routing with v4 nexthops, BGP routing for V6 will not work", + peer->host); + bgp_notify_send(peer, BGP_NOTIFY_CEASE, + BGP_NOTIFY_SUBCODE_UNSPECIFIC); + return BGP_Stop; } } peer->rtt = sockopt_tcp_rtt(peer->fd); diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index becd99167f..8ff6b63e05 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -3455,6 +3455,11 @@ static bool bgp_zebra_label_manager_connect(void) return true; } +static void bgp_zebra_capabilities(struct zclient_capabilities *cap) +{ + bm->v6_with_v4_nexthops = cap->v6_with_v4_nexthop; +} + void bgp_zebra_init(struct event_loop *master, unsigned short instance) { struct zclient_options options = zclient_options_default; @@ -3470,6 +3475,7 @@ void bgp_zebra_init(struct event_loop *master, unsigned short instance) array_size(bgp_handlers)); zclient_init(zclient, ZEBRA_ROUTE_BGP, 0, &bgpd_privs); zclient->zebra_connected = bgp_zebra_connected; + zclient->zebra_capabilities = bgp_zebra_capabilities; zclient->instance = instance; /* Initialize special zclient for synchronous message exchanges. */ diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 5e467bb873..67ee8aa138 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -168,6 +168,8 @@ struct bgp_master { struct event *t_bgp_sync_label_manager; struct event *t_bgp_start_label_manager; + bool v6_with_v4_nexthops; + QOBJ_FIELDS; }; DECLARE_QOBJ_TYPE(bgp_master); diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst index ad8f913355..09173ab2f5 100644 --- a/doc/user/bgp.rst +++ b/doc/user/bgp.rst @@ -86,6 +86,15 @@ be specified (:ref:`common-invocation-options`). be done to see if this is helping or not at the scale you are running at. +.. option:: --v6-with-v4-nexthops + + Allow BGP to peer in the V6 afi, when the interface only has v4 addresses. + This allows bgp to install the v6 routes with a v6 nexthop that has the + v4 address encoded in the nexthop. Zebra's equivalent option currently + overrides the bgp setting. This setting is only really usable when + the operator has turned off communication to zebra and is running bgpd + as a complete standalone process. + LABEL MANAGER ------------- diff --git a/doc/user/zebra.rst b/doc/user/zebra.rst index d7e768b710..32de3e908f 100644 --- a/doc/user/zebra.rst +++ b/doc/user/zebra.rst @@ -87,6 +87,13 @@ Besides the common invocation options (:ref:`common-invocation-options`), the Allow zebra to modify the default receive buffer size to SIZE in bytes. Under \*BSD only the -s option is available. +.. option:: --v6-with-v4-nexthops + + Signal to zebra that v6 routes with v4 nexthops are accepted + by the underlying dataplane. This will be communicated to + the upper level daemons that can install v6 routes with v4 + nexthops. + .. _interface-commands: Configuration Addresses behaviour diff --git a/lib/command.c b/lib/command.c index 8025ab534f..affb551b45 100644 --- a/lib/command.c +++ b/lib/command.c @@ -903,8 +903,7 @@ enum node_type node_parent(enum node_type node) } /* Execute command by argument vline vector. */ -static int cmd_execute_command_real(vector vline, enum cmd_filter_type filter, - struct vty *vty, +static int cmd_execute_command_real(vector vline, struct vty *vty, const struct cmd_element **cmd, unsigned int up_level) { @@ -1041,8 +1040,7 @@ int cmd_execute_command(vector vline, struct vty *vty, vector_set_index(shifted_vline, index - 1, vector_lookup(vline, index)); - ret = cmd_execute_command_real(shifted_vline, FILTER_RELAXED, - vty, cmd, 0); + ret = cmd_execute_command_real(shifted_vline, vty, cmd, 0); vector_free(shifted_vline); vty->node = onode; @@ -1051,7 +1049,7 @@ int cmd_execute_command(vector vline, struct vty *vty, } saved_ret = ret = - cmd_execute_command_real(vline, FILTER_RELAXED, vty, cmd, 0); + cmd_execute_command_real(vline, vty, cmd, 0); if (vtysh) return saved_ret; @@ -1069,8 +1067,7 @@ int cmd_execute_command(vector vline, struct vty *vty, if (vty->xpath_index > 0 && !cnode->no_xpath) vty->xpath_index--; - ret = cmd_execute_command_real(vline, FILTER_RELAXED, - vty, cmd, 0); + ret = cmd_execute_command_real(vline, vty, cmd, 0); if (ret == CMD_SUCCESS || ret == CMD_WARNING || ret == CMD_ERR_AMBIGUOUS || ret == CMD_ERR_INCOMPLETE || ret == CMD_NOT_MY_INSTANCE @@ -1102,7 +1099,7 @@ int cmd_execute_command(vector vline, struct vty *vty, int cmd_execute_command_strict(vector vline, struct vty *vty, const struct cmd_element **cmd) { - return cmd_execute_command_real(vline, FILTER_STRICT, vty, cmd, 0); + return cmd_execute_command_real(vline, vty, cmd, 0); } /* @@ -1274,8 +1271,7 @@ int command_config_read_one_line(struct vty *vty, && ret != CMD_ERR_AMBIGUOUS && ret != CMD_ERR_INCOMPLETE && ret != CMD_NOT_MY_INSTANCE && ret != CMD_WARNING_CONFIG_FAILED && ret != CMD_NO_LEVEL_UP) - ret = cmd_execute_command_real(vline, FILTER_STRICT, vty, cmd, - ++up_level); + ret = cmd_execute_command_real(vline, vty, cmd, ++up_level); if (ret == CMD_NO_LEVEL_UP) ret = CMD_ERR_NO_MATCH; diff --git a/lib/command_match.h b/lib/command_match.h index db2a8535e0..3e7a549e1d 100644 --- a/lib/command_match.h +++ b/lib/command_match.h @@ -17,11 +17,6 @@ extern "C" { #endif -/* These definitions exist in command.c in the current engine but should be - * relocated here in the new engine - */ -enum cmd_filter_type { FILTER_RELAXED, FILTER_STRICT }; - /* matcher result value */ enum matcher_rv { MATCHER_NO_MATCH, diff --git a/lib/zclient.c b/lib/zclient.c index c36bcc6e2e..294a78feb0 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -3876,6 +3876,7 @@ static int zclient_capability_decode(ZAPI_CALLBACK_ARGS) cap.mpls_enabled = !!mpls_enabled; STREAM_GETL(s, cap.ecmp); STREAM_GETC(s, cap.role); + STREAM_GETC(s, cap.v6_with_v4_nexthop); if (zclient->zebra_capabilities) (*zclient->zebra_capabilities)(&cap); diff --git a/lib/zclient.h b/lib/zclient.h index 316dd4cd68..42c5a5fdac 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -274,6 +274,7 @@ struct zclient_capabilities { uint32_t ecmp; bool mpls_enabled; enum mlag_role role; + bool v6_with_v4_nexthop; }; /* Graceful Restart Capabilities message */ diff --git a/tests/topotests/babel_topo1/r3/babeld.conf b/tests/topotests/babel_topo1/r3/babeld.conf index bfda3622dd..e10e5aaacc 100644 --- a/tests/topotests/babel_topo1/r3/babeld.conf +++ b/tests/topotests/babel_topo1/r3/babeld.conf @@ -14,4 +14,3 @@ router babel network r3-eth1 redistribute ipv4 connected redistribute ipv4 static - redistirbute ipv6 connected diff --git a/tests/topotests/bfd_ospf_topo1/rt1/ospfd.conf b/tests/topotests/bfd_ospf_topo1/rt1/ospfd.conf index ce36494604..72238ccd40 100644 --- a/tests/topotests/bfd_ospf_topo1/rt1/ospfd.conf +++ b/tests/topotests/bfd_ospf_topo1/rt1/ospfd.conf @@ -27,6 +27,5 @@ interface eth-rt3 ! router ospf ospf router-id 1.1.1.1 - passive interface lo router-info area 0.0.0.0 ! diff --git a/tests/topotests/bfd_ospf_topo1/rt2/ospfd.conf b/tests/topotests/bfd_ospf_topo1/rt2/ospfd.conf index a8ca564e4e..c5f4262a8f 100644 --- a/tests/topotests/bfd_ospf_topo1/rt2/ospfd.conf +++ b/tests/topotests/bfd_ospf_topo1/rt2/ospfd.conf @@ -25,6 +25,5 @@ interface eth-rt5 ! router ospf ospf router-id 2.2.2.2 - passive interface lo router-info area 0.0.0.0 ! diff --git a/tests/topotests/bfd_ospf_topo1/rt3/ospfd.conf b/tests/topotests/bfd_ospf_topo1/rt3/ospfd.conf index 0404994c09..e487bdd7c0 100644 --- a/tests/topotests/bfd_ospf_topo1/rt3/ospfd.conf +++ b/tests/topotests/bfd_ospf_topo1/rt3/ospfd.conf @@ -25,6 +25,5 @@ interface eth-rt4 ! router ospf ospf router-id 3.3.3.3 - passive interface lo router-info area 0.0.0.0 ! diff --git a/tests/topotests/bfd_ospf_topo1/rt4/ospfd.conf b/tests/topotests/bfd_ospf_topo1/rt4/ospfd.conf index 6b8ab3704f..560904e75d 100644 --- a/tests/topotests/bfd_ospf_topo1/rt4/ospfd.conf +++ b/tests/topotests/bfd_ospf_topo1/rt4/ospfd.conf @@ -24,6 +24,5 @@ interface eth-rt5 ! router ospf ospf router-id 4.4.4.4 - passive interface lo router-info area 0.0.0.0 ! diff --git a/tests/topotests/bfd_ospf_topo1/rt5/ospfd.conf b/tests/topotests/bfd_ospf_topo1/rt5/ospfd.conf index 043432ec3d..77f5445286 100644 --- a/tests/topotests/bfd_ospf_topo1/rt5/ospfd.conf +++ b/tests/topotests/bfd_ospf_topo1/rt5/ospfd.conf @@ -24,6 +24,5 @@ interface eth-rt4 ! router ospf ospf router-id 5.5.5.5 - passive interface lo router-info area 0.0.0.0 ! diff --git a/tests/topotests/bgp_addpath_best_selected/r2/bgpd.conf b/tests/topotests/bgp_addpath_best_selected/r2/bgpd.conf index 0c13824323..cdef611286 100644 --- a/tests/topotests/bgp_addpath_best_selected/r2/bgpd.conf +++ b/tests/topotests/bgp_addpath_best_selected/r2/bgpd.conf @@ -2,7 +2,6 @@ router bgp 65002 timers bgp 3 10 no bgp ebgp-requires-policy neighbor 192.168.1.1 remote-as external - neighbor 192.168.1.1 remote-as external neighbor 192.168.7.7 remote-as external neighbor 192.168.7.7 timers connect 5 neighbor 192.168.2.3 remote-as external diff --git a/tests/topotests/bgp_addpath_best_selected/test_bgp_addpath_best_selected.py b/tests/topotests/bgp_addpath_best_selected/test_bgp_addpath_best_selected.py index dfd538f1c6..2a610c901e 100644 --- a/tests/topotests/bgp_addpath_best_selected/test_bgp_addpath_best_selected.py +++ b/tests/topotests/bgp_addpath_best_selected/test_bgp_addpath_best_selected.py @@ -75,6 +75,42 @@ def test_bgp_addpath_best_selected(): r2 = tgen.gears["r2"] + def _bgp_converge(): + output = json.loads(r2.vtysh_cmd("show bgp ipv4 unicast 172.16.16.254/32 json")) + expected = { + "paths": [ + { + "aspath": { + "string": "65006", + }, + "weight": 6, + }, + { + "aspath": { + "string": "65005", + }, + "weight": 5, + }, + { + "aspath": { + "string": "65004", + }, + "weight": 4, + }, + { + "aspath": { + "string": "65003", + }, + "weight": 3, + }, + ] + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial(_bgp_converge) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "Can't converge initially" + def check_bgp_advertised_routes_to_r1(): output = json.loads( r2.vtysh_cmd( @@ -104,7 +140,7 @@ def test_bgp_addpath_best_selected(): return topotest.json_cmp(output, expected) test_func = functools.partial(check_bgp_advertised_routes_to_r1) - success, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) assert ( result is None ), "Received more/less Add-Path best paths, but should be only 1+1 (real best path)" @@ -143,7 +179,7 @@ def test_bgp_addpath_best_selected(): return topotest.json_cmp(output, expected) test_func = functools.partial(check_bgp_advertised_routes_to_r7) - success, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) assert ( result is None ), "Received more/less Add-Path best paths, but should be only 2+1 (real best path)" diff --git a/tests/topotests/bgp_update_delay/r2/zebra.conf b/tests/topotests/bgp_update_delay/r2/zebra.conf index 420f00d974..1fcedaaf72 100644 --- a/tests/topotests/bgp_update_delay/r2/zebra.conf +++ b/tests/topotests/bgp_update_delay/r2/zebra.conf @@ -12,9 +12,5 @@ interface r2-eth3 ip address 192.168.252.1/30 vrf vrf1 ! -auto vrf1 -iface vrf1 - vrf-table auto -! ip forwarding ! diff --git a/tests/topotests/bgp_vpnv4_noretain/r1/isisd.conf b/tests/topotests/bgp_vpnv4_noretain/r1/isisd.conf deleted file mode 100644 index 233a6473b3..0000000000 --- a/tests/topotests/bgp_vpnv4_noretain/r1/isisd.conf +++ /dev/null @@ -1,14 +0,0 @@ -interface r1-eth0 - ip router isis 1 - isis circuit-type level-1 -! -interface lo - ip router isis 1 - isis passive -! -router isis 1 - is-type level-1 - net 49.0002.0000.1994.00 - segment-routing on - segment-routing prefix 192.0.2.1/32 index 11 -! diff --git a/tests/topotests/bgp_vpnv4_noretain/r2/isisd.conf b/tests/topotests/bgp_vpnv4_noretain/r2/isisd.conf deleted file mode 100644 index 547d10f2bc..0000000000 --- a/tests/topotests/bgp_vpnv4_noretain/r2/isisd.conf +++ /dev/null @@ -1,14 +0,0 @@ -interface r2-eth0 - ip router isis 1 - isis circuit-type level-1 -! -interface lo - ip router isis 1 - isis passive -! -router isis 1 - is-type level-1 - net 49.0002.0000.1995.00 - segment-routing on - segment-routing prefix 192.0.2.2/32 index 22 -! diff --git a/tests/topotests/bgp_vpnv4_noretain/test_bgp_vpnv4_noretain.py b/tests/topotests/bgp_vpnv4_noretain/test_bgp_vpnv4_noretain.py index f665040f7f..f2865fec9e 100644 --- a/tests/topotests/bgp_vpnv4_noretain/test_bgp_vpnv4_noretain.py +++ b/tests/topotests/bgp_vpnv4_noretain/test_bgp_vpnv4_noretain.py @@ -120,9 +120,6 @@ def setup_module(mod): router.load_config( TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname)) ) - router.load_config( - TopoRouter.RD_ISIS, os.path.join(CWD, "{}/bgpd.conf".format(rname)) - ) # Initialize all routers. tgen.start_router() diff --git a/tests/topotests/config_timing/r1/zebra.conf b/tests/topotests/config_timing/r1/zebra.conf index 46fd965034..b4dc338b8d 100644 --- a/tests/topotests/config_timing/r1/zebra.conf +++ b/tests/topotests/config_timing/r1/zebra.conf @@ -4,10 +4,8 @@ ip prefix-list ANY permit 0.0.0.0/0 le 32 ipv6 prefix-list ANY seq 10 permit any route-map RM-NONE4 deny 10 -exit-route-map route-map RM-NONE6 deny 10 -exit-route-map interface r1-eth0 ip address 100.0.0.1/24 diff --git a/tests/topotests/cspf_topo1/r1/sharpd.conf b/tests/topotests/cspf_topo1/r1/sharpd.conf index 272eac944e..465034f150 100644 --- a/tests/topotests/cspf_topo1/r1/sharpd.conf +++ b/tests/topotests/cspf_topo1/r1/sharpd.conf @@ -1,3 +1,2 @@ ! -import-te ! diff --git a/tests/topotests/isis_snmp/r1/ldpd.conf b/tests/topotests/isis_snmp/r1/ldpd.conf index 5b1cbfebc9..64f51fce27 100644 --- a/tests/topotests/isis_snmp/r1/ldpd.conf +++ b/tests/topotests/isis_snmp/r1/ldpd.conf @@ -5,7 +5,6 @@ log file ldpd.log ! debug mpls ldp event ! debug mpls ldp errors ! debug mpls ldp sync -agentx ! mpls ldp router-id 1.1.1.1 diff --git a/tests/topotests/ospf6_gr_topo1/rt1/ospf6d.conf b/tests/topotests/ospf6_gr_topo1/rt1/ospf6d.conf index 8a9b4eb124..aa9438b78e 100644 --- a/tests/topotests/ospf6_gr_topo1/rt1/ospf6d.conf +++ b/tests/topotests/ospf6_gr_topo1/rt1/ospf6d.conf @@ -1,4 +1,3 @@ -:assword 1 hostname rt1 log file ospf6d.log log commands diff --git a/zebra/main.c b/zebra/main.c index bd4623be55..aeb9739c13 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -71,22 +71,25 @@ uint32_t rcvbufsize = 128 * 1024; #define OPTION_V6_RR_SEMANTICS 2000 #define OPTION_ASIC_OFFLOAD 2001 +#define OPTION_V6_WITH_V4_NEXTHOP 2002 /* Command line options. */ const struct option longopts[] = { - {"batch", no_argument, NULL, 'b'}, - {"allow_delete", no_argument, NULL, 'a'}, - {"socket", required_argument, NULL, 'z'}, - {"ecmp", required_argument, NULL, 'e'}, - {"retain", no_argument, NULL, 'r'}, - {"graceful_restart", required_argument, NULL, 'K'}, - {"asic-offload", optional_argument, NULL, OPTION_ASIC_OFFLOAD}, + { "batch", no_argument, NULL, 'b' }, + { "allow_delete", no_argument, NULL, 'a' }, + { "socket", required_argument, NULL, 'z' }, + { "ecmp", required_argument, NULL, 'e' }, + { "retain", no_argument, NULL, 'r' }, + { "graceful_restart", required_argument, NULL, 'K' }, + { "asic-offload", optional_argument, NULL, OPTION_ASIC_OFFLOAD }, + { "v6-with-v4-nexthops", no_argument, NULL, OPTION_V6_WITH_V4_NEXTHOP }, #ifdef HAVE_NETLINK - {"vrfwnetns", no_argument, NULL, 'n'}, - {"nl-bufsize", required_argument, NULL, 's'}, - {"v6-rr-semantics", no_argument, NULL, OPTION_V6_RR_SEMANTICS}, + { "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, @@ -287,6 +290,7 @@ int main(int argc, char **argv) struct sockaddr_storage dummy; socklen_t dummylen; bool asic_offload = false; + bool v6_with_v4_nexthop = false; bool notify_on_ack = true; graceful_restart = 0; @@ -294,26 +298,26 @@ int main(int argc, char **argv) frr_preinit(&zebra_di, argc, argv); - frr_opt_add( - "baz:e:rK:s:" + frr_opt_add("baz:e:rK:s:" #ifdef HAVE_NETLINK - "n" + "n" #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" - " -r, --retain When program terminates, retain added route by zebra.\n" - " -K, --graceful_restart Graceful restart at the kernel level, timer in seconds for expiration\n" - " -A, --asic-offload FRR is interacting with an asic underneath the linux kernel\n" + , + 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" + " -r, --retain When program terminates, retain added route by zebra.\n" + " -K, --graceful_restart Graceful restart at the kernel level, timer in seconds for expiration\n" + " -A, --asic-offload FRR is interacting with an asic underneath the linux kernel\n" + " --v6-with-v4-nexthops Underlying dataplane supports v6 routes with v4 nexthops" #ifdef HAVE_NETLINK - " -s, --nl-bufsize Set netlink receive buffer size\n" - " -n, --vrfwnetns Use NetNS as VRF backend\n" - " --v6-rr-semantics Use v6 RR semantics\n" + " -s, --nl-bufsize Set netlink receive buffer size\n" + " -n, --vrfwnetns Use NetNS as VRF backend\n" + " --v6-rr-semantics Use v6 RR semantics\n" #else - " -s, Set kernel socket receive buffer size\n" + " -s, Set kernel socket receive buffer size\n" #endif /* HAVE_NETLINK */ ); @@ -383,6 +387,9 @@ int main(int argc, char **argv) notify_on_ack = true; asic_offload = true; break; + case OPTION_V6_WITH_V4_NEXTHOP: + v6_with_v4_nexthop = true; + break; #endif /* HAVE_NETLINK */ default: frr_help_exit(1); @@ -392,7 +399,7 @@ int main(int argc, char **argv) zrouter.master = frr_init(); /* Zebra related initialize. */ - zebra_router_init(asic_offload, notify_on_ack); + zebra_router_init(asic_offload, notify_on_ack, v6_with_v4_nexthop); zserv_init(); rib_init(); zebra_if_init(); diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index 2fc696c4e1..e9c243217a 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -2319,7 +2319,7 @@ static void zsend_capabilities(struct zserv *client, struct zebra_vrf *zvrf) stream_putc(s, mpls_enabled); stream_putl(s, zrouter.multipath_num); stream_putc(s, zebra_mlag_get_role()); - + stream_putc(s, zrouter.v6_with_v4_nexthop); stream_putw_at(s, 0, stream_get_endp(s)); zserv_send_message(client, s); } diff --git a/zebra/zebra_router.c b/zebra/zebra_router.c index 1b3e31ee42..4caaf8a9e2 100644 --- a/zebra/zebra_router.c +++ b/zebra/zebra_router.c @@ -255,7 +255,8 @@ bool zebra_router_notify_on_ack(void) return !zrouter.asic_offloaded || zrouter.notify_on_ack; } -void zebra_router_init(bool asic_offload, bool notify_on_ack) +void zebra_router_init(bool asic_offload, bool notify_on_ack, + bool v6_with_v4_nexthop) { zrouter.sequence_num = 0; @@ -310,7 +311,7 @@ void zebra_router_init(bool asic_offload, bool notify_on_ack) zrouter.asic_offloaded = asic_offload; zrouter.notify_on_ack = notify_on_ack; - + zrouter.v6_with_v4_nexthop = v6_with_v4_nexthop; /* * If you start using asic_notification_nexthop_control * come talk to the FRR community about what you are doing diff --git a/zebra/zebra_router.h b/zebra/zebra_router.h index a7f0f135f9..bd86cfb495 100644 --- a/zebra/zebra_router.h +++ b/zebra/zebra_router.h @@ -207,6 +207,7 @@ struct zebra_router { */ bool asic_offloaded; bool notify_on_ack; + bool v6_with_v4_nexthop; /* * If the asic is notifying us about successful nexthop @@ -237,7 +238,8 @@ struct zebra_router { extern struct zebra_router zrouter; extern uint32_t rcvbufsize; -extern void zebra_router_init(bool asic_offload, bool notify_on_ack); +extern void zebra_router_init(bool asic_offload, bool notify_on_ack, + bool v6_with_v4_nexthop); extern void zebra_router_cleanup(void); extern void zebra_router_terminate(void); diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 291c2eb7e0..1a123ba5c2 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -4033,6 +4033,9 @@ DEFUN (show_zebra, ttable_add_row(table, "VRF|Not Available"); #endif + ttable_add_row(table, "v6 with v4 nexthop|%s", + zrouter.v6_with_v4_nexthop ? "Used" : "Unavaliable"); + ttable_add_row(table, "ASIC offload|%s", zrouter.asic_offloaded ? "Used" : "Unavailable"); |
