summaryrefslogtreecommitdiffstats
path: root/zebra/zebra_ns.c
diff options
context:
space:
mode:
authorStephen Worley <sworley@cumulusnetworks.com>2019-11-14 19:43:11 +0100
committerStephen Worley <sworley@cumulusnetworks.com>2019-11-15 18:33:35 +0100
commit257b245cd13e3d836093e8fb5c704d90ef978660 (patch)
treeae4c481cfbe64e2e6f90d6a236ac8b5bcf487bfb /zebra/zebra_ns.c
parentMerge pull request #5303 from taspelund/special_interface_error (diff)
downloadfrr-257b245cd13e3d836093e8fb5c704d90ef978660.tar.xz
frr-257b245cd13e3d836093e8fb5c704d90ef978660.zip
zebra: default ns->info should be default zebra_ns
We were not connecting the default zebra_ns to the default ns->info at namespace initialization in zebra. Thus, when we tried to use the `ns_walk_func()` it would ignore the default zebra_ns since there is no pointer to it from the ns struct. Fix this by connecting them in `zebra_ns_init()` and, if the default ns is not found, exit with failure since this is not recoverable. This was found during a crash where we fail to cancel the kernel_read thread at termination (via the `ns_walk_func()`) and then we get a netlink notification trying to use the zns struct that has already been freed. ``` (gdb) bt \#0 0x00007fc1134dc7bb in raise () from /lib/x86_64-linux-gnu/libc.so.6 \#1 0x00007fc1134c7535 in abort () from /lib/x86_64-linux-gnu/libc.so.6 \#2 0x00007fc113996f8f in core_handler (signo=11, siginfo=0x7ffe5429d070, context=<optimized out>) at lib/sigevent.c:254 \#3 <signal handler called> \#4 0x0000561880e15449 in if_lookup_by_index_per_ns (ns=0x0, ifindex=174) at zebra/interface.c:269 \#5 0x0000561880e1642c in if_up (ifp=ifp@entry=0x561883076c50) at zebra/interface.c:1043 \#6 0x0000561880e10723 in netlink_link_change (h=0x7ffe5429d8f0, ns_id=<optimized out>, startup=<optimized out>) at zebra/if_netlink.c:1384 \#7 0x0000561880e17e68 in netlink_parse_info (filter=filter@entry=0x561880e17680 <netlink_information_fetch>, nl=nl@entry=0x561882497238, zns=zns@entry=0x7ffe542a5940, count=count@entry=5, startup=startup@entry=0) at zebra/kernel_netlink.c:932 \#8 0x0000561880e186a5 in kernel_read (thread=<optimized out>) at zebra/kernel_netlink.c:406 \#9 0x00007fc1139a4416 in thread_call (thread=thread@entry=0x7ffe542a5b70) at lib/thread.c:1599 \#10 0x00007fc113974ef8 in frr_run (master=0x5618823c9510) at lib/libfrr.c:1024 \#11 0x0000561880e0b916 in main (argc=8, argv=0x7ffe542a5f78) at zebra/main.c:483 ``` Signed-off-by: Stephen Worley <sworley@cumulusnetworks.com>
Diffstat (limited to 'zebra/zebra_ns.c')
-rw-r--r--zebra/zebra_ns.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/zebra/zebra_ns.c b/zebra/zebra_ns.c
index 37f53bf91..4d971cc24 100644
--- a/zebra/zebra_ns.c
+++ b/zebra/zebra_ns.c
@@ -37,6 +37,7 @@
#include "zebra_pbr.h"
#include "rib.h"
#include "table_manager.h"
+#include "zebra_errors.h"
extern struct zebra_privs_t zserv_privs;
@@ -64,6 +65,9 @@ static int zebra_ns_new(struct ns *ns)
{
struct zebra_ns *zns;
+ if (!ns)
+ return -1;
+
if (IS_ZEBRA_DEBUG_EVENT)
zlog_info("ZNS %s with id %u (created)", ns->name, ns->ns_id);
@@ -175,19 +179,26 @@ int zebra_ns_final_shutdown(struct ns *ns)
int zebra_ns_init(const char *optional_default_name)
{
+ struct ns *default_ns;
ns_id_t ns_id;
ns_id_t ns_id_external;
- dzns = zebra_ns_alloc();
-
frr_with_privs(&zserv_privs) {
ns_id = zebra_ns_id_get_default();
}
ns_id_external = ns_map_nsid_with_external(ns_id, true);
ns_init_management(ns_id_external, ns_id);
+ default_ns = ns_lookup(ns_get_default_id());
+ if (!default_ns) {
+ flog_err(EC_ZEBRA_NS_NO_DEFAULT,
+ "%s: failed to find default ns", __func__);
+ exit(EXIT_FAILURE); /* This is non-recoverable */
+ }
+
/* Do any needed per-NS data structure allocation. */
- dzns->if_table = route_table_init();
+ zebra_ns_new(default_ns);
+ dzns = default_ns->info;
/* Register zebra VRF callbacks, create and activate default VRF. */
zebra_vrf_init();