summaryrefslogtreecommitdiff
path: root/zebra/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/main.c')
-rw-r--r--zebra/main.c132
1 files changed, 92 insertions, 40 deletions
diff --git a/zebra/main.c b/zebra/main.c
index 81a3066445..d83f1d0491 100644
--- a/zebra/main.c
+++ b/zebra/main.c
@@ -5,6 +5,10 @@
#include <zebra.h>
+#ifdef GNU_LINUX
+#include <linux/rtnetlink.h>
+#endif
+
#include <lib/version.h>
#include "getopt.h"
#include "command.h"
@@ -21,6 +25,7 @@
#include "affinitymap.h"
#include "routemap.h"
#include "routing_nb.h"
+#include "mgmt_be_client.h"
#include "zebra/zebra_router.h"
#include "zebra/zebra_errors.h"
@@ -54,13 +59,13 @@ pid_t pid;
/* Pacify zclient.o in libfrr, which expects this variable. */
struct event_loop *master;
+struct mgmt_be_client *mgmt_be_client;
+
/* Route retain mode flag. */
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
@@ -69,24 +74,30 @@ uint32_t rcvbufsize = RCVBUFSIZE_MIN;
uint32_t rcvbufsize = 128 * 1024;
#endif
+uint32_t rt_table_main_id = RT_TABLE_MAIN;
+
#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}};
+ {"routing-table", optional_argument, NULL, 'R'},
+ { 0 }
+};
zebra_capabilities_t _caps_p[] = {ZCAP_NET_ADMIN, ZCAP_SYS_ADMIN,
ZCAP_NET_RAW,
@@ -134,6 +145,10 @@ static void sigint(void)
zlog_notice("Terminating on signal");
+ nb_oper_cancel_all_walks();
+ mgmt_be_client_destroy(mgmt_be_client);
+ mgmt_be_client = NULL;
+
atomic_store_explicit(&zrouter.in_shutdown, true,
memory_order_relaxed);
@@ -188,6 +203,13 @@ static void sigint(void)
rib_update_finish();
list_delete(&zrouter.client_list);
+ list_delete(&zrouter.stale_client_list);
+
+ /*
+ * Besides other clean-ups zebra's vrf_disable() also enqueues installed
+ * routes for removal from the kernel, unless ZEBRA_VRF_RETAIN is set.
+ */
+ vrf_iterate(vrf_disable);
/* Indicate that all new dplane work has been enqueued. When that
* work is complete, the dataplane will enqueue an event
@@ -206,17 +228,31 @@ void zebra_finalize(struct event *dummy)
vrf_terminate();
+ /*
+ * Stop dplane thread and finish any cleanup
+ * This is before the zebra_ns_early_shutdown call
+ * because sockets that the dplane depends on are closed
+ * in those functions
+ */
+ zebra_dplane_shutdown();
+
ns_walk_func(zebra_ns_early_shutdown, NULL, NULL);
zebra_ns_notify_close();
- /* Stop dplane thread and finish any cleanup */
- zebra_dplane_shutdown();
-
/* Final shutdown of ns resources */
ns_walk_func(zebra_ns_final_shutdown, NULL, NULL);
+ zebra_rib_terminate();
zebra_router_terminate();
+ zebra_mpls_terminate();
+
+ zebra_pw_terminate();
+
+ zebra_srv6_terminate();
+
+ label_manager_terminate();
+
ns_terminate();
frr_fini();
exit(0);
@@ -260,19 +296,23 @@ static const struct frr_yang_module_info *const zebra_yang_modules[] = {
};
/* clang-format on */
-FRR_DAEMON_INFO(
- zebra, ZEBRA, .vty_port = ZEBRA_VTY_PORT, .flags = FRR_NO_ZCLIENT,
-
+/* clang-format off */
+FRR_DAEMON_INFO(zebra, ZEBRA,
+ .vty_port = ZEBRA_VTY_PORT,
.proghelp =
"Daemon which manages kernel routing table management and\nredistribution between different routing protocols.",
- .signals = zebra_signals, .n_signals = array_size(zebra_signals),
+ .flags = FRR_NO_ZCLIENT,
+
+ .signals = zebra_signals,
+ .n_signals = array_size(zebra_signals),
.privs = &zserv_privs,
.yang_modules = zebra_yang_modules,
.n_yang_modules = array_size(zebra_yang_modules),
);
+/* clang-format on */
/* Main startup routine. */
int main(int argc, char **argv)
@@ -282,6 +322,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;
@@ -289,27 +330,28 @@ 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:R:"
#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 */
+ " -R, --routing-table Set kernel routing table\n"
);
while (1) {
@@ -364,12 +406,15 @@ int main(int argc, char **argv)
"Rcvbufsize is smaller than recommended value: %d\n",
RCVBUFSIZE_MIN);
break;
+ case 'R':
+ rt_table_main_id = atoi(optarg);
+ break;
#ifdef HAVE_NETLINK
case 'n':
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"))
@@ -378,6 +423,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);
@@ -387,9 +435,9 @@ 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_rib_init();
zebra_if_init();
zebra_debug_init();
@@ -399,8 +447,12 @@ int main(int argc, char **argv)
zebra_ns_init();
router_id_cmd_init();
zebra_vty_init();
- access_list_init();
+ mgmt_be_client = mgmt_be_client_create("zebra", NULL, 0,
+ zrouter.master);
+ access_list_init_new(true);
prefix_list_init();
+
+ rtadv_init();
rtadv_cmd_init();
/* PTM socket */
#ifdef ZEBRA_PTM_SUPPORT