]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra, lib: new API to get absolute netns val from relative netns val
authorPhilippe Guibert <philippe.guibert@6wind.com>
Wed, 2 Oct 2019 11:37:11 +0000 (13:37 +0200)
committerPhilippe Guibert <philippe.guibert@6wind.com>
Mon, 21 Sep 2020 07:17:10 +0000 (09:17 +0200)
when receiving a netlink API for an interface in a namespace, this
interface may come with LINK_NSID value, which means that the interface
has its link in an other namespace. Unfortunately, the link_nsid value
is self to that namespace, and there is a need to know what is its
associated nsid value from the default namespace point of view.
The information collected previously on each namespace, can then be
compared with that value to check if the link belongs to the default
namespace or not.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
lib/netns_linux.c
lib/ns.h
zebra/if_netlink.c

index bb66e8938fa0f035d16284f21276bd12d101c8e1..0109b3db6a31d5cab0f2c1f4ae414be0805e151a 100644 (file)
@@ -584,6 +584,26 @@ int ns_socket(int domain, int type, int protocol, ns_id_t ns_id)
        return ret;
 }
 
+/* if relative link_nsid matches default netns,
+ * then return default absolute netns value
+ * otherwise, return NS_UNKNOWN
+ */
+ns_id_t ns_id_get_absolute(ns_id_t ns_id_reference, ns_id_t link_nsid)
+{
+       struct ns *ns;
+
+       ns = ns_lookup(ns_id_reference);
+       if (!ns)
+               return NS_UNKNOWN;
+
+       if (ns->relative_default_ns != link_nsid)
+               return NS_UNKNOWN;
+
+       ns = ns_get_default();
+       assert(ns);
+       return ns->ns_id;
+}
+
 ns_id_t ns_get_default_id(void)
 {
        if (default_ns)
index 188161e11a2b0862a30a79d8e6aa07809c4e6199..0dfd977429a4b1f3b95c77795a2cbb51dec93546 100644 (file)
--- a/lib/ns.h
+++ b/lib/ns.h
@@ -181,6 +181,7 @@ extern struct ns *ns_lookup_name(const char *name);
  */
 extern int ns_enable(struct ns *ns, void (*func)(ns_id_t, void *));
 extern struct ns *ns_get_created(struct ns *ns, char *name, ns_id_t ns_id);
+extern ns_id_t ns_id_get_absolute(ns_id_t ns_id_reference, ns_id_t link_nsid);
 extern void ns_disable(struct ns *ns);
 extern struct ns *ns_get_default(void);
 
index 5cd3e69299ca48f2ae8af0b11cac16281363fd9d..c3eab60148a9ff9dc43ac6fe67bb58a6aa1ab75b 100644 (file)
@@ -798,8 +798,10 @@ static int netlink_interface(struct nlmsghdr *h, ns_id_t ns_id, int startup)
        if (tb[IFLA_LINK])
                link_ifindex = *(ifindex_t *)RTA_DATA(tb[IFLA_LINK]);
 
-       if (tb[IFLA_LINK_NETNSID])
+       if (tb[IFLA_LINK_NETNSID]) {
                link_nsid = *(ns_id_t *)RTA_DATA(tb[IFLA_LINK_NETNSID]);
+               link_nsid = ns_id_get_absolute(ns_id, link_nsid);
+       }
 
        /* Add interface.
         * We add by index first because in some cases such as the master
@@ -1349,9 +1351,10 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
        if (tb[IFLA_LINK])
                link_ifindex = *(ifindex_t *)RTA_DATA(tb[IFLA_LINK]);
 
-       if (tb[IFLA_LINK_NETNSID])
+       if (tb[IFLA_LINK_NETNSID]) {
                link_nsid = *(ns_id_t *)RTA_DATA(tb[IFLA_LINK_NETNSID]);
-
+               link_nsid = ns_id_get_absolute(ns_id, link_nsid);
+       }
        if (tb[IFLA_IFALIAS]) {
                desc = (char *)RTA_DATA(tb[IFLA_IFALIAS]);
        }