From: Philippe Guibert Date: Fri, 8 Dec 2017 18:06:34 +0000 (+0100) Subject: zebra: socket operations stick to namespace if necessary X-Git-Tag: frr-5.0-dev~209^2~37 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=fe533c564e1901ee6b767708345abb52a56056af;p=matthieu%2Ffrr.git zebra: socket operations stick to namespace if necessary Upon following calls: interface poll, address poll, route poll, and ICMPv6 handling, each new Namespace is being parsed. For that, the socket operations need to switch from one NS to one other, to get the necessary information. As of now, there is a crash when dumping interfaces, through show running-config. Signed-off-by: Philippe Guibert --- diff --git a/lib/ns.c b/lib/ns.c index fcac28cf7e..170290a9e9 100644 --- a/lib/ns.c +++ b/lib/ns.c @@ -565,9 +565,9 @@ void ns_terminate(void) int ns_socket(int domain, int type, int protocol, ns_id_t ns_id) { struct ns *ns = ns_lookup(ns_id); - int ret = -1; + int ret; - if (!ns_is_enabled(ns)) { + if (!ns || !ns_is_enabled(ns)) { errno = ENOSYS; return -1; } diff --git a/lib/vrf.c b/lib/vrf.c index 56c8bdbabe..81ff6d56fd 100644 --- a/lib/vrf.c +++ b/lib/vrf.c @@ -97,7 +97,8 @@ struct vrf *vrf_get(vrf_id_t vrf_id, const char *name) int new = 0; if (debug_vrf) - zlog_debug("VRF_GET: %s(%u)", name, vrf_id); + zlog_debug("VRF_GET: %s(%u)", + name == NULL ? "(NULL)" : name, vrf_id); /* Nothing to see, move along here */ if (!name && vrf_id == VRF_UNKNOWN) diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index ef30c7830f..6897bd4ee2 100644 --- a/zebra/if_netlink.c +++ b/zebra/if_netlink.c @@ -792,8 +792,12 @@ static int netlink_address(int cmd, int family, struct interface *ifp, char buf[NL_PKT_BUF_SIZE]; } req; - struct zebra_ns *zns = zebra_ns_lookup(NS_DEFAULT); + struct zebra_ns *zns; + if (vrf_is_backend_netns()) + zns = zebra_ns_lookup((ns_id_t)ifp->vrf_id); + else + zns = zebra_ns_lookup(NS_DEFAULT); p = ifc->address; memset(&req, 0, sizeof req - NL_PKT_BUF_SIZE); @@ -1020,6 +1024,7 @@ int netlink_link_change(struct sockaddr_nl *snl, struct nlmsghdr *h, zns = zebra_ns_lookup(ns_id); ifi = NLMSG_DATA(h); + /* assume if not default zns, then new VRF */ if (!(h->nlmsg_type == RTM_NEWLINK || h->nlmsg_type == RTM_DELLINK)) { /* If this is not link add/delete message so print warning. */ zlog_warn("netlink_link_change: wrong kernel message %d", @@ -1107,7 +1112,8 @@ int netlink_link_change(struct sockaddr_nl *snl, struct nlmsghdr *h, } else zif_slave_type = ZEBRA_IF_SLAVE_OTHER; } - + if (vrf_is_backend_netns()) + vrf_id = (vrf_id_t)ns_id; if (ifp == NULL || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) { /* Add interface notification from kernel */ diff --git a/zebra/interface.c b/zebra/interface.c index 07570e64bf..6ee1db6a4c 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -512,8 +512,13 @@ static void if_addr_wakeup(struct interface *ifp) void if_add_update(struct interface *ifp) { struct zebra_if *if_data; + struct zebra_ns *zns; - if_link_per_ns(zebra_ns_lookup(NS_DEFAULT), ifp); + if (vrf_is_backend_netns()) + zns = zebra_ns_lookup((ns_id_t)ifp->vrf_id); + else + zns = zebra_ns_lookup(NS_DEFAULT); + if_link_per_ns(zns, ifp); if_data = ifp->info; assert(if_data); diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c index 1be2cbcaf5..0b3b6eed45 100644 --- a/zebra/kernel_netlink.c +++ b/zebra/kernel_netlink.c @@ -188,7 +188,7 @@ static int netlink_socket(struct nlsock *nl, unsigned long groups, return -1; } - sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); + sock = ns_socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE, ns_id); if (sock < 0) { zlog_err("Can't open %s socket: %s", nl->name, safe_strerror(errno)); diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c index 4d888d8069..3b28a9b242 100644 --- a/zebra/kernel_socket.c +++ b/zebra/kernel_socket.c @@ -1384,7 +1384,8 @@ static void routing_socket(struct zebra_ns *zns) if (zserv_privs.change(ZPRIVS_RAISE)) zlog_err("routing_socket: Can't raise privileges"); - routing_sock = socket(AF_ROUTE, SOCK_RAW, 0); + routing_sock = ns_socket(AF_ROUTE, SOCK_RAW, + 0, (ns_id_t)zns->ns->ns_id); if (routing_sock < 0) { if (zserv_privs.change(ZPRIVS_LOWER)) diff --git a/zebra/rtadv.c b/zebra/rtadv.c index 32418eb82f..860e8710d6 100644 --- a/zebra/rtadv.c +++ b/zebra/rtadv.c @@ -34,6 +34,7 @@ #include "command.h" #include "privs.h" #include "vrf.h" +#include "ns.h" #include "zebra/interface.h" #include "zebra/rtadv.h" @@ -621,7 +622,7 @@ static int rtadv_read(struct thread *thread) return 0; } -static int rtadv_make_socket(void) +static int rtadv_make_socket(ns_id_t ns_id) { int sock; int ret = 0; @@ -631,7 +632,7 @@ static int rtadv_make_socket(void) zlog_err("rtadv_make_socket: could not raise privs, %s", safe_strerror(errno)); - sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); + sock = ns_socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6, ns_id); if (zserv_privs.change(ZPRIVS_LOWER)) zlog_err("rtadv_make_socket: could not lower privs, %s", @@ -1686,7 +1687,7 @@ static void rtadv_event(struct zebra_ns *zns, enum rtadv_event event, int val) void rtadv_init(struct zebra_ns *zns) { - zns->rtadv.sock = rtadv_make_socket(); + zns->rtadv.sock = rtadv_make_socket(zns->ns_id); } void rtadv_terminate(struct zebra_ns *zns)