Skip to content

Commit

Permalink
zebra: default ns->info should be default zebra_ns
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
sworleys committed Nov 15, 2019
1 parent 1e5fe0e commit 257b245
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 3 deletions.
6 changes: 6 additions & 0 deletions zebra/zebra_errors.c
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,12 @@ static struct log_ref ferr_zebra_err[] = {
.description = "Zebra attempted to look up a interface for a particular vrf_id and interface index, but didn't find anything.",
.suggestion = "If you entered a command to trigger this error, make sure you entered the arguments correctly. Check your config file for any potential errors. If these look correct, seek help.",
},
{
.code = EC_ZEBRA_NS_NO_DEFAULT,
.title = "Zebra NameSpace failed to find Default",
.description = "Zebra NameSpace subsystem failed to find a Default namespace during initialization.",
.suggestion = "Open an Issue with all relevant log files and restart FRR",
},
/* Warnings */
{
.code = EC_ZEBRAING_LM_PROTO_MISMATCH,
Expand Down
1 change: 1 addition & 0 deletions zebra/zebra_errors.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ enum zebra_log_refs {
EC_ZEBRA_NHG_SYNC,
EC_ZEBRA_NHG_FIB_UPDATE,
EC_ZEBRA_IF_LOOKUP_FAILED,
EC_ZEBRA_NS_NO_DEFAULT,
/* warnings */
EC_ZEBRA_NS_NOTIFY_READ,
EC_ZEBRAING_LM_PROTO_MISMATCH,
Expand Down
17 changes: 14 additions & 3 deletions zebra/zebra_ns.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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();
Expand Down

0 comments on commit 257b245

Please sign in to comment.