frr/zebra/main.c

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

548 lines
13 KiB
C
Raw Normal View History

// SPDX-License-Identifier: GPL-2.0-or-later
/* zebra daemon main routine.
2002-12-13 21:15:29 +01:00
* Copyright (C) 1997, 98 Kunihiro Ishiguro
*/
#include <zebra.h>
#ifdef GNU_LINUX
#include <linux/rtnetlink.h>
#endif
#include <lib/version.h>
2002-12-13 21:15:29 +01:00
#include "getopt.h"
#include "command.h"
#include "frrevent.h"
2002-12-13 21:15:29 +01:00
#include "filter.h"
#include "memory.h"
#include "prefix.h"
#include "log.h"
[zebra] Routemap support on received routes, with 'set src' command (linux) 2007-05-01 David L Stevens <dlstevens@us.ibm.com> * (general) These changes collectively add route-map and prefix-list support to zebra and fix a bug in "show route-map" (with no argument). * doc/main.texi: added route-map, prefix-list, ip protocol and set src documentation * lib/command.h: added PROTOCOL_NODE type * lib/log.c: (proto_name2num) new function, protocol name to number translation. * lib/routemap.c: (vty_show_route_map) fixed "show route-map" without route-map name * lib/routemap.h: added RMAP_ZEBRA type * lib/zebra.h: added proto_name2num() prototype * vtysh/extract.pl.in: added VTYSH_ZEBRA flag for route-map and plist * vtysh/Makefile.am: added zebra_routemap.c * vtysh/vtysh.h: added VTYSH_ZEBRA flag to VTYSH_RMAP * zebra/connected.c: (connected_up_ipv4) added src preference argument to rib_add_ipv4() * zebra/kernel_socket.c: (rtm_read) ditto * zebra/main.c: added prefix list initialization * zebra/Makefile.am: added zebra_routemap.c source file * zebra/rib.h: added generic address union "g_addr" and use in existing places that had an explicit union. Added "src" to struct nexthop. Added preferred src arg to nexthop_ipv4_add and rib_add_ipv4. * zebra/rt_netlink.c: (netlink_routing_table) set preferred source on netlink messages. (netlink_route_change) ditto (netlink_route_multipath) ditto. * zebra/rtread_getmsg.c: (handle_route_entry) added (NULL) src to rib_add_ipv4() call. * zebra/rtread_proc.c: (proc_route_read) ditto * zebra/zebra_rib.c: (nexthop_ipv4_add) add src argument. (nexthop_ipv4_ifindex_add) ditto (rib_add_ipv4) ditto (nexthop_active_check) Add route-map processing. * zebra/zebra_routemap.c: new file for zebra route-map commands. * zebra/zebra_vty.c: (ip_protocol_cmd) Apply route-map to protocol (vty_show_ip_route_detail) added "src" printing (vty_show_ip_route) ditto (show_ip_protocol_cmd) new command, list routemaps. (config_write_protocol) write out routemap protocl config. (zebra_vty_init) Install the new routemap protocol commands. * zebra/zserv.c: (zread_ipv4_add) added (NULL) src arg (zebra_init) init zebra route-maps. * zebra/zserv.h: add zebra_route_map_init
2007-05-02 18:05:35 +02:00
#include "plist.h"
#include "privs.h"
#include "sigevent.h"
lib, zebra: move "struct vrf" to be a lib module Previously "struct vrf" is defined locally in zebra. Now it is moved to be a lib module. This is the first step to support multi-VRF in quagga. The implementation is splitted into small patches for the purpose of easy review. * lib: "struct vrf" with basic members is defined in vrf.c. The member "void *info" is for user data. Some basic functions are defined in vrf.c for adding/deleting/ looking up a VRF, scanning the VRF table and initializing the VRF module. The type "vrf_id_t" is defined specificly for VRF ID. * zebra: The previous "struct vrf" is re-defined as "struct zebra_vrf"; and previous "vrf" variables are renamed to "zvrf". The previous "struct vrf" related functions are removed from zbera_rib.c. New functions are defined to maintain the new "struct zebra_vrf". The names vrf_xxx are reserved for the functions in VRF module. So: - the previous vrf_table() are renamed to zebra_vrf_table(); - the previous vrf_static_table() are renamed to zebra_vrf_static_table(). The main logic is not changed. BTW: Add a statement to zebra_snmp.c telling that the SNMP is running only for the MIBs in the default VRF. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Vincent JARDIN <vincent.jardin@6wind.com> Signed-off-by: David Lamparter <equinox@opensourcerouting.org> Conflicts: lib/Makefile.am zebra/zebra_rib.c zebra/zebra_vty.c Conflicts: lib/Makefile.am lib/memtypes.c zebra/rib.h zebra/zebra_rib.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zebra_vty.c
2015-05-22 11:39:56 +02:00
#include "vrf.h"
#include "libfrr.h"
#include "affinitymap.h"
#include "routemap.h"
#include "routing_nb.h"
#include "mgmt_be_client.h"
#include "libagentx.h"
2002-12-13 21:15:29 +01:00
#include "zebra/zebra_router.h"
#include "zebra/zebra_errors.h"
2002-12-13 21:15:29 +01:00
#include "zebra/rib.h"
#include "zebra/zserv.h"
#include "zebra/debug.h"
2004-10-03 20:18:34 +02:00
#include "zebra/router-id.h"
#include "zebra/irdp.h"
#include "zebra/rtadv.h"
#include "zebra/zebra_ptm.h"
#include "zebra/zebra_ns.h"
#include "zebra/redistribute.h"
#include "zebra/zebra_mpls.h"
#include "zebra/label_manager.h"
#include "zebra/zebra_netns_notify.h"
#include "zebra/zebra_rnh.h"
#include "zebra/zebra_pbr.h"
#include "zebra/zebra_vxlan.h"
#include "zebra/zebra_routemap.h"
#include "zebra/zebra_nb.h"
#include "zebra/zebra_opaque.h"
#include "zebra/zebra_srte.h"
#include "zebra/zebra_srv6.h"
#include "zebra/zebra_srv6_vty.h"
#define ZEBRA_PTM_SUPPORT
2002-12-13 21:15:29 +01:00
char *zserv_path;
2002-12-13 21:15:29 +01:00
/* process id. */
pid_t zebra_pid;
2002-12-13 21:15:29 +01:00
/* Pacify zclient.o in libfrr, which expects this variable. */
struct event_loop *master;
struct mgmt_be_client *mgmt_be_client;
2002-12-13 21:15:29 +01:00
/* Route retain mode flag. */
int retain_mode = 0;
/* Receive buffer size for kernel control sockets */
#define RCVBUFSIZE_MIN 4194304
#ifdef HAVE_NETLINK
uint32_t rcvbufsize = RCVBUFSIZE_MIN;
#else
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
2002-12-13 21:15:29 +01:00
/* 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' },
{ "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 },
#endif /* HAVE_NETLINK */
{ "routing-table", optional_argument, NULL, 'R' },
{ 0 }
};
2002-12-13 21:15:29 +01:00
zebra_capabilities_t _caps_p[] = {ZCAP_NET_ADMIN, ZCAP_SYS_ADMIN,
ZCAP_NET_RAW,
#ifdef HAVE_DPDK
ZCAP_IPC_LOCK, ZCAP_READ_SEARCH,
ZCAP_SYS_RAWIO
#endif
};
/* zebra privileges to run with */
struct zebra_privs_t zserv_privs = {
#if defined(FRR_USER) && defined(FRR_GROUP)
.user = FRR_USER,
.group = FRR_GROUP,
#endif
#ifdef VTY_GROUP
.vty_group = VTY_GROUP,
#endif
.caps_p = _caps_p,
.cap_num_p = array_size(_caps_p),
.cap_num_i = 0};
2002-12-13 21:15:29 +01:00
/* SIGHUP handler. */
static void sighup(void)
2002-12-13 21:15:29 +01:00
{
zlog_info("SIGHUP received");
/* Reload of config file. */
;
}
/* SIGINT handler. */
static void sigint(void)
2002-12-13 21:15:29 +01:00
{
struct vrf *vrf;
struct zebra_vrf *zvrf;
struct zserv *client;
static bool sigint_done;
if (sigint_done)
return;
sigint_done = true;
2004-12-03 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * bgp_main.c: (sigint) Use zlog_notice for termination message. (main) Use zlog_notice for startup announcement. * isis_main.c: (sigint,sigterm) Use zlog_notice for termination message. (terminate) This function should be static, not global. (main) Use zlog_notice for startup announcement, and remove ifdef ZEBRA_VERSION. * version.h.in: Remove declaration for pid_output_lock, this function is now static, not global. * pid_output.c: (pid_output_lock) This function should be static, not global. And remove "old umask" error message, since it was really an unimportant debug message, not an error. (pid_output) Need to declare static function pid_output_lock. * ospf6_main.c: (sigint,sigterm) Use zlog_notice for termination message. (main) Remove commented-out call to pid_output_lock (which should never be called other than from inside pid_output). And use zlog_notice to print the startup message, which now includes the vty port. * ospf_main.c: (sigint) Use zlog_notice for termination message. (main) Issue a startup announcement using zlog_notice. * rip_main.c: (sigint) Use zlog_notice for termination message. (main) Add a startup announcement using zlog_notice. * ripng_main.c: (sighup) Remove spurious terminating message. (sigint) Use zlog_notice for termination message. (main) Issue a startup announcement using zlog_notice. * main.c: (sigint) Use zlog_notice for termination message. (main) Add a startup announcement using zlog_notice.
2004-12-03 17:36:46 +01:00
zlog_notice("Terminating on signal");
2002-12-13 21:15:29 +01:00
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);
/* send RA lifetime of 0 before stopping. rfc4861/6.2.5 */
rtadv_stop_ra_all();
frr_early_fini();
2002-12-13 21:15:29 +01:00
/* Stop the opaque module pthread */
zebra_opaque_stop();
zebra_dplane_pre_finish();
/* Clean up GR related info. */
zebra_gr_stale_client_cleanup();
/* Clean up zapi clients and server module */
frr_each_safe (zserv_client_list, &zrouter.client_list, client)
zserv_close_client(client);
zserv_close();
/* Once all the zclients are cleaned up, clean up the opaque module */
zebra_opaque_finish();
zebra_ptm_finish();
if (retain_mode) {
zebra_nhg_mark_keep();
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
zvrf = vrf->info;
if (zvrf)
SET_FLAG(zvrf->flags, ZEBRA_VRF_RETAIN);
}
}
if (zrouter.lsp_process_q)
work_queue_free_and_null(&zrouter.lsp_process_q);
access_list_reset();
prefix_list_reset();
/*
* zebra_routemap_finish will
* 1 set rmap upd timer to 0 so that rmap update wont be scheduled again
* 2 Put off the rmap update thread
* 3 route_map_finish
*/
zebra_routemap_finish();
zebra: Cleanup ctx leak on shutdown and turn off event two things: On shutdown cleanup any events associated with the update walker. Also do not allow new events to be created. Fixes this mem-leak: ./msdp_topo1.test_msdp_topo1/r2.zebra.asan.1117790:Direct leak of 8 byte(s) in 1 object(s) allocated from: ./msdp_topo1.test_msdp_topo1/r2.zebra.asan.1117790- #0 0x7f0dd0b08037 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154 ./msdp_topo1.test_msdp_topo1/r2.zebra.asan.1117790- #1 0x7f0dd06c19f9 in qcalloc lib/memory.c:105 ./msdp_topo1.test_msdp_topo1/r2.zebra.asan.1117790- #2 0x55b42fb605bc in rib_update_ctx_init zebra/zebra_rib.c:4383 ./msdp_topo1.test_msdp_topo1/r2.zebra.asan.1117790- #3 0x55b42fb6088f in rib_update zebra/zebra_rib.c:4421 ./msdp_topo1.test_msdp_topo1/r2.zebra.asan.1117790- #4 0x55b42fa00344 in netlink_link_change zebra/if_netlink.c:2221 ./msdp_topo1.test_msdp_topo1/r2.zebra.asan.1117790- #5 0x55b42fa24622 in netlink_information_fetch zebra/kernel_netlink.c:399 ./msdp_topo1.test_msdp_topo1/r2.zebra.asan.1117790- #6 0x55b42fa28c02 in netlink_parse_info zebra/kernel_netlink.c:1183 ./msdp_topo1.test_msdp_topo1/r2.zebra.asan.1117790- #7 0x55b42fa24951 in kernel_read zebra/kernel_netlink.c:493 ./msdp_topo1.test_msdp_topo1/r2.zebra.asan.1117790- #8 0x7f0dd0797f0c in event_call lib/event.c:1995 ./msdp_topo1.test_msdp_topo1/r2.zebra.asan.1117790- #9 0x7f0dd0684fd9 in frr_run lib/libfrr.c:1185 ./msdp_topo1.test_msdp_topo1/r2.zebra.asan.1117790- #10 0x55b42fa30caa in main zebra/main.c:465 ./msdp_topo1.test_msdp_topo1/r2.zebra.asan.1117790- #11 0x7f0dd01b5d09 in __libc_start_main ../csu/libc-start.c:308 ./msdp_topo1.test_msdp_topo1/r2.zebra.asan.1117790- ./msdp_topo1.test_msdp_topo1/r2.zebra.asan.1117790-SUMMARY: AddressSanitizer: 8 byte(s) leaked in 1 allocation(s). Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2023-03-31 15:08:23 +02:00
rib_update_finish();
/*
* 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
* with the 'finalize' function.
*/
zebra_dplane_finish();
}
/*
* Final shutdown step for the zebra main thread. This is run after all
* async update processing has completed.
*/
void zebra_finalize(struct event *dummy)
{
zlog_info("Zebra final shutdown");
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();
/* Final shutdown of ns resources */
zebra: fix heap-use-after free on ns shutdown The following ASAN issue has been observed: > ERROR: AddressSanitizer: heap-use-after-free on address 0x6160000acba4 at pc 0x55910c5694d0 bp 0x7ffe3a8ac850 sp 0x7ffe3a8ac840 > READ of size 4 at 0x6160000acba4 thread T0 > #0 0x55910c5694cf in ctx_info_from_zns zebra/zebra_dplane.c:3315 > #1 0x55910c569696 in dplane_ctx_ns_init zebra/zebra_dplane.c:3331 > #2 0x55910c56bf61 in dplane_ctx_nexthop_init zebra/zebra_dplane.c:3680 > #3 0x55910c5711ca in dplane_nexthop_update_internal zebra/zebra_dplane.c:4490 > #4 0x55910c571c5c in dplane_nexthop_delete zebra/zebra_dplane.c:4717 > #5 0x55910c61e90e in zebra_nhg_uninstall_kernel zebra/zebra_nhg.c:3413 > #6 0x55910c615d8a in zebra_nhg_decrement_ref zebra/zebra_nhg.c:1919 > #7 0x55910c6404db in route_entry_update_nhe zebra/zebra_rib.c:454 > #8 0x55910c64c904 in rib_re_nhg_free zebra/zebra_rib.c:2822 > #9 0x55910c655be2 in rib_unlink zebra/zebra_rib.c:4212 > #10 0x55910c6430f9 in zebra_rtable_node_cleanup zebra/zebra_rib.c:968 > #11 0x7f26f275b8a9 in route_node_free lib/table.c:75 > #12 0x7f26f275bae4 in route_table_free lib/table.c:111 > #13 0x7f26f275b749 in route_table_finish lib/table.c:46 > #14 0x55910c65db17 in zebra_router_free_table zebra/zebra_router.c:191 > #15 0x55910c65dfb5 in zebra_router_terminate zebra/zebra_router.c:244 > #16 0x55910c4f40db in zebra_finalize zebra/main.c:249 > #17 0x7f26f2777108 in event_call lib/event.c:2011 > #18 0x7f26f264180e in frr_run lib/libfrr.c:1212 > #19 0x55910c4f49cb in main zebra/main.c:531 > #20 0x7f26f2029d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58 > #21 0x7f26f2029e3f in __libc_start_main_impl ../csu/libc-start.c:392 > #22 0x55910c4b0114 in _start (/usr/lib/frr/zebra+0x1ae114) It happens with FRR using the kernel. During shutdown, the namespace identifier is attempted to be obtained by zebra, in an attempt to prepare zebra dataplane nexthop messages. Fix this by accessing the ns structure. Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
2024-10-07 15:11:43 +02:00
ns_walk_func(zebra_ns_kernel_shutdown, NULL, NULL);
zebra_rib_terminate();
zebra_router_terminate();
zebra_mpls_terminate();
zebra_pw_terminate();
zebra_srv6_terminate();
label_manager_terminate();
affinity_map_terminate();
zebra: fix heap-use-after free on ns shutdown The following ASAN issue has been observed: > ERROR: AddressSanitizer: heap-use-after-free on address 0x6160000acba4 at pc 0x55910c5694d0 bp 0x7ffe3a8ac850 sp 0x7ffe3a8ac840 > READ of size 4 at 0x6160000acba4 thread T0 > #0 0x55910c5694cf in ctx_info_from_zns zebra/zebra_dplane.c:3315 > #1 0x55910c569696 in dplane_ctx_ns_init zebra/zebra_dplane.c:3331 > #2 0x55910c56bf61 in dplane_ctx_nexthop_init zebra/zebra_dplane.c:3680 > #3 0x55910c5711ca in dplane_nexthop_update_internal zebra/zebra_dplane.c:4490 > #4 0x55910c571c5c in dplane_nexthop_delete zebra/zebra_dplane.c:4717 > #5 0x55910c61e90e in zebra_nhg_uninstall_kernel zebra/zebra_nhg.c:3413 > #6 0x55910c615d8a in zebra_nhg_decrement_ref zebra/zebra_nhg.c:1919 > #7 0x55910c6404db in route_entry_update_nhe zebra/zebra_rib.c:454 > #8 0x55910c64c904 in rib_re_nhg_free zebra/zebra_rib.c:2822 > #9 0x55910c655be2 in rib_unlink zebra/zebra_rib.c:4212 > #10 0x55910c6430f9 in zebra_rtable_node_cleanup zebra/zebra_rib.c:968 > #11 0x7f26f275b8a9 in route_node_free lib/table.c:75 > #12 0x7f26f275bae4 in route_table_free lib/table.c:111 > #13 0x7f26f275b749 in route_table_finish lib/table.c:46 > #14 0x55910c65db17 in zebra_router_free_table zebra/zebra_router.c:191 > #15 0x55910c65dfb5 in zebra_router_terminate zebra/zebra_router.c:244 > #16 0x55910c4f40db in zebra_finalize zebra/main.c:249 > #17 0x7f26f2777108 in event_call lib/event.c:2011 > #18 0x7f26f264180e in frr_run lib/libfrr.c:1212 > #19 0x55910c4f49cb in main zebra/main.c:531 > #20 0x7f26f2029d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58 > #21 0x7f26f2029e3f in __libc_start_main_impl ../csu/libc-start.c:392 > #22 0x55910c4b0114 in _start (/usr/lib/frr/zebra+0x1ae114) It happens with FRR using the kernel. During shutdown, the namespace identifier is attempted to be obtained by zebra, in an attempt to prepare zebra dataplane nexthop messages. Fix this by accessing the ns structure. Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
2024-10-07 15:11:43 +02:00
ns_walk_func(zebra_ns_final_shutdown, NULL, NULL);
ns_terminate();
zserv_client_list_fini(&zrouter.client_list);
zserv_stale_client_list_fini(&zrouter.stale_client_list);
frr_fini();
2002-12-13 21:15:29 +01:00
exit(0);
}
/* SIGUSR1 handler. */
static void sigusr1(void)
2002-12-13 21:15:29 +01:00
{
zlog_rotate();
2002-12-13 21:15:29 +01:00
}
struct frr_signal_t zebra_signals[] = {
2002-12-13 21:15:29 +01:00
{
.signal = SIGHUP,
.handler = &sighup,
},
{
.signal = SIGUSR1,
.handler = &sigusr1,
},
{
.signal = SIGINT,
2004-03-17 21:39:18 +01:00
.handler = &sigint,
},
{
.signal = SIGTERM,
.handler = &sigint,
},
};
lib, zebra: move "struct vrf" to be a lib module Previously "struct vrf" is defined locally in zebra. Now it is moved to be a lib module. This is the first step to support multi-VRF in quagga. The implementation is splitted into small patches for the purpose of easy review. * lib: "struct vrf" with basic members is defined in vrf.c. The member "void *info" is for user data. Some basic functions are defined in vrf.c for adding/deleting/ looking up a VRF, scanning the VRF table and initializing the VRF module. The type "vrf_id_t" is defined specificly for VRF ID. * zebra: The previous "struct vrf" is re-defined as "struct zebra_vrf"; and previous "vrf" variables are renamed to "zvrf". The previous "struct vrf" related functions are removed from zbera_rib.c. New functions are defined to maintain the new "struct zebra_vrf". The names vrf_xxx are reserved for the functions in VRF module. So: - the previous vrf_table() are renamed to zebra_vrf_table(); - the previous vrf_static_table() are renamed to zebra_vrf_static_table(). The main logic is not changed. BTW: Add a statement to zebra_snmp.c telling that the SNMP is running only for the MIBs in the default VRF. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Vincent JARDIN <vincent.jardin@6wind.com> Signed-off-by: David Lamparter <equinox@opensourcerouting.org> Conflicts: lib/Makefile.am zebra/zebra_rib.c zebra/zebra_vty.c Conflicts: lib/Makefile.am lib/memtypes.c zebra/rib.h zebra/zebra_rib.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zebra_vty.c
2015-05-22 11:39:56 +02:00
/* clang-format off */
static const struct frr_yang_module_info *const zebra_yang_modules[] = {
&frr_backend_info,
&frr_filter_info,
&frr_interface_info,
&frr_route_map_info,
&frr_zebra_info,
&frr_vrf_info,
&frr_routing_info,
&frr_affinity_map_info,
&frr_zebra_route_map_info,
};
/* clang-format on */
/* 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.",
.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 */
void zebra_main_router_started(void)
{
/*
* Clean up zebra-originated routes. The requests will be sent to OS
* immediately, so originating PID in notifications from kernel
* will be equal to the current getpid(). To know about such routes,
* we have to have route_read() called before.
* If FRR is gracefully restarting, we either wait for clients
* (e.g., BGP) to signal GR is complete else we wait for specified
* duration.
*/
zrouter.startup_time = monotime(NULL);
zrouter.rib_sweep_time = 0;
zrouter.graceful_restart = zebra_di.graceful_restart;
if (!zrouter.graceful_restart)
event_add_timer(zrouter.master, rib_sweep_route, NULL, 0, NULL);
else {
int gr_cleanup_time;
gr_cleanup_time = zebra_di.gr_cleanup_time ? zebra_di.gr_cleanup_time
: ZEBRA_GR_DEFAULT_RIB_SWEEP_TIME;
event_add_timer(zrouter.master, rib_sweep_route, NULL, gr_cleanup_time,
&zrouter.t_rib_sweep);
}
zserv_start(zserv_path);
}
2002-12-13 21:15:29 +01:00
/* Main startup routine. */
int main(int argc, char **argv)
{
// int batch_mode = 0;
struct sockaddr_storage dummy;
socklen_t dummylen;
bool asic_offload = false;
bool v6_with_v4_nexthop = false;
bool notify_on_ack = true;
zserv_path = NULL;
if_notify_oper_changes = true;
vrf_notify_oper_changes = true;
frr_preinit(&zebra_di, argc, argv);
2002-12-13 21:15:29 +01:00
frr_opt_add("baz:e:rK:s:R:"
#ifdef HAVE_NETLINK
"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"
" -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\n"
#ifdef HAVE_NETLINK
" -s, --nl-bufsize Set netlink receive buffer size\n"
" -n, --vrfwnetns Use NetNS as VRF backend (deprecated, use -w)\n"
" --v6-rr-semantics Use v6 RR semantics\n"
#else
" -s, Set kernel socket receive buffer size\n"
#endif /* HAVE_NETLINK */
" -R, --routing-table Set kernel routing table\n");
while (1) {
int opt = frr_getopt(argc, argv, NULL);
2002-12-13 21:15:29 +01:00
if (opt == EOF)
break;
switch (opt) {
2002-12-13 21:15:29 +01:00
case 0:
break;
case 'b':
// batch_mode = 1;
2002-12-13 21:15:29 +01:00
break;
case 'a':
zrouter.allow_delete = true;
break;
case 'e': {
unsigned long int parsed_multipath =
strtoul(optarg, NULL, 10);
if (parsed_multipath == 0
|| parsed_multipath > MULTIPATH_NUM
|| parsed_multipath > UINT32_MAX) {
flog_err(
EC_ZEBRA_BAD_MULTIPATH_NUM,
"Multipath Number specified must be less than %u and greater than 0",
MULTIPATH_NUM);
return 1;
}
zrouter.multipath_num = parsed_multipath;
break;
}
case 'z':
zserv_path = optarg;
if (!frr_zclient_addr(&dummy, &dummylen, optarg)) {
fprintf(stderr,
"Invalid zserv socket path: %s\n",
optarg);
exit(1);
}
break;
2002-12-13 21:15:29 +01:00
case 'r':
retain_mode = 1;
break;
case 's':
rcvbufsize = atoi(optarg);
if (rcvbufsize < RCVBUFSIZE_MIN)
fprintf(stderr,
"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':
fprintf(stderr,
"The -n option is deprecated, please use global -w option instead.\n");
vrf_configure_backend(VRF_BACKEND_NETNS);
break;
case OPTION_V6_RR_SEMANTICS:
zrouter.v6_rr_semantics = true;
break;
case OPTION_ASIC_OFFLOAD:
if (!strcmp(optarg, "notify_on_offload"))
notify_on_ack = false;
if (!strcmp(optarg, "notify_on_ack"))
notify_on_ack = true;
asic_offload = true;
break;
case OPTION_V6_WITH_V4_NEXTHOP:
v6_with_v4_nexthop = true;
break;
#endif /* HAVE_NETLINK */
2002-12-13 21:15:29 +01:00
default:
frr_help_exit(1);
}
2002-12-13 21:15:29 +01:00
}
zrouter.master = frr_init();
2002-12-13 21:15:29 +01:00
/* Zebra related initialize. */
libagentx_init();
zebra_router_init(asic_offload, notify_on_ack, v6_with_v4_nexthop);
zserv_init();
zebra_rib_init();
2002-12-13 21:15:29 +01:00
zebra_if_init();
zebra_debug_init();
/* Open Zebra API server socket */
zserv_open(zserv_path);
/*
* Initialize NS( and implicitly the VRF module), and make kernel
* routing socket. */
*: rework renaming the default VRF Currently, it is possible to rename the default VRF either by passing `-o` option to zebra or by creating a file in `/var/run/netns` and binding it to `/proc/self/ns/net`. In both cases, only zebra knows about the rename and other daemons learn about it only after they connect to zebra. This is a problem, because daemons may read their config before they connect to zebra. To handle this rename after the config is read, we have some special code in every single daemon, which is not very bad but not desirable in my opinion. But things are getting worse when we need to handle this in northbound layer as we have to manually rewrite the config nodes. This approach is already hacky, but still works as every daemon handles its own NB structures. But it is completely incompatible with the central management daemon architecture we are aiming for, as mgmtd doesn't even have a connection with zebra to learn from it. And it shouldn't have it, because operational state changes should never affect configuration. To solve the problem and simplify the code, I propose to expand the `-o` option to all daemons. By using the startup option, we let daemons know about the rename before they read their configs so we don't need any special code to deal with it. There's an easy way to pass the option to all daemons by using `frr_global_options` variable. Unfortunately, the second way of renaming by creating a file in `/var/run/netns` is incompatible with the new mgmtd architecture. Theoretically, we could force daemons to read their configs only after they connect to zebra, but it means adding even more code to handle a very specific use-case. And anyway this won't work for mgmtd as it doesn't have a connection with zebra. So I had to remove this option. Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
2021-12-03 23:22:55 +01:00
zebra_ns_init();
router_id_cmd_init();
zebra_vty_init();
mgmt_be_client = mgmt_be_client_create("zebra", NULL, 0,
zrouter.master);
access_list_init_new(true);
[zebra] Routemap support on received routes, with 'set src' command (linux) 2007-05-01 David L Stevens <dlstevens@us.ibm.com> * (general) These changes collectively add route-map and prefix-list support to zebra and fix a bug in "show route-map" (with no argument). * doc/main.texi: added route-map, prefix-list, ip protocol and set src documentation * lib/command.h: added PROTOCOL_NODE type * lib/log.c: (proto_name2num) new function, protocol name to number translation. * lib/routemap.c: (vty_show_route_map) fixed "show route-map" without route-map name * lib/routemap.h: added RMAP_ZEBRA type * lib/zebra.h: added proto_name2num() prototype * vtysh/extract.pl.in: added VTYSH_ZEBRA flag for route-map and plist * vtysh/Makefile.am: added zebra_routemap.c * vtysh/vtysh.h: added VTYSH_ZEBRA flag to VTYSH_RMAP * zebra/connected.c: (connected_up_ipv4) added src preference argument to rib_add_ipv4() * zebra/kernel_socket.c: (rtm_read) ditto * zebra/main.c: added prefix list initialization * zebra/Makefile.am: added zebra_routemap.c source file * zebra/rib.h: added generic address union "g_addr" and use in existing places that had an explicit union. Added "src" to struct nexthop. Added preferred src arg to nexthop_ipv4_add and rib_add_ipv4. * zebra/rt_netlink.c: (netlink_routing_table) set preferred source on netlink messages. (netlink_route_change) ditto (netlink_route_multipath) ditto. * zebra/rtread_getmsg.c: (handle_route_entry) added (NULL) src to rib_add_ipv4() call. * zebra/rtread_proc.c: (proc_route_read) ditto * zebra/zebra_rib.c: (nexthop_ipv4_add) add src argument. (nexthop_ipv4_ifindex_add) ditto (rib_add_ipv4) ditto (nexthop_active_check) Add route-map processing. * zebra/zebra_routemap.c: new file for zebra route-map commands. * zebra/zebra_vty.c: (ip_protocol_cmd) Apply route-map to protocol (vty_show_ip_route_detail) added "src" printing (vty_show_ip_route) ditto (show_ip_protocol_cmd) new command, list routemaps. (config_write_protocol) write out routemap protocl config. (zebra_vty_init) Install the new routemap protocol commands. * zebra/zserv.c: (zread_ipv4_add) added (NULL) src arg (zebra_init) init zebra route-maps. * zebra/zserv.h: add zebra_route_map_init
2007-05-02 18:05:35 +02:00
prefix_list_init();
rtadv_init();
rtadv_cmd_init();
/* PTM socket */
#ifdef ZEBRA_PTM_SUPPORT
zebra_ptm_init();
#endif
2002-12-13 21:15:29 +01:00
zebra_mpls_init();
zebra_mpls_vty_init();
zebra_pw_vty_init();
zebra_pbr_init();
zebra_opaque_init();
zebra_srte_init();
zebra_srv6_init();
zebra_srv6_vty_init();
/* For debug purpose. */
/* SET_FLAG (zebra_debug_event, ZEBRA_DEBUG_EVENT); */
2002-12-13 21:15:29 +01:00
/* Process the configuration file. Among other configuration
* directives we can meet those installing static routes. Such
* requests will not be executed immediately, but queued in
* zebra->ribq structure until we enter the main execution loop.
* The notifications from kernel will show originating PID equal
* to that after daemon() completes (if ever called).
*/
frr_config_fork();
2002-12-13 21:15:29 +01:00
/*
* After we have successfully acquired the pidfile, we can be sure
* about being the only copy of zebra process, which is submitting
* changes to the FIB.
*/
2002-12-13 21:15:29 +01:00
/* Needed for BSD routing socket. */
zebra_pid = getpid();
2002-12-13 21:15:29 +01:00
/* Start dataplane system */
zebra_dplane_start();
/* Start the ted module, before zserv */
zebra_opaque_start();
/* Init label manager */
label_manager_init();
/* RNH init */
zebra_rnh_init();
/* Config handler Init */
zebra_evpn_init();
/* Error init */
zebra_error_init();
frr_run(zrouter.master);
2002-12-13 21:15:29 +01:00
/* Not reached... */
return 0;
2002-12-13 21:15:29 +01:00
}