Use a flag to request notifications form all network namespaces and
include the namespace id from which notification came from in the
callback.

Signed-off-by: Adrian Moreno <[email protected]>
---
 lib/if-notifier.c              |  5 +++--
 lib/netlink-notifier.c         | 22 +++++++++++++++-------
 lib/netlink-notifier.h         | 10 ++++++----
 lib/netnsid.h                  |  1 +
 lib/route-table.c              | 17 +++++++++++------
 lib/route-table.h              |  2 +-
 lib/rtnetlink.c                |  6 ++++--
 lib/rtnetlink.h                |  2 +-
 tests/system-route.at          | 12 ++++++------
 tests/test-lib-route-table.c   | 20 +++++++++++++++-----
 tests/test-netlink-conntrack.c |  7 ++++---
 11 files changed, 67 insertions(+), 37 deletions(-)

diff --git a/lib/if-notifier.c b/lib/if-notifier.c
index f2d7157b9..9b450fa22 100644
--- a/lib/if-notifier.c
+++ b/lib/if-notifier.c
@@ -16,6 +16,7 @@
 
 #include <config.h>
 #include "if-notifier.h"
+#include "netnsid.h"
 #include "rtnetlink.h"
 #include "util.h"
 
@@ -26,11 +27,11 @@ struct if_notifier {
 };
 
 static void
-if_notifier_cb(const struct rtnetlink_change *change, void *aux)
+if_notifier_cb(const struct rtnetlink_change *change, int nsid, void *aux)
 {
     struct if_notifier *notifier;
 
-    if (change && change->irrelevant) {
+    if (change && (change->irrelevant || nsid != NETNSID_LOCAL)) {
         return;
     }
 
diff --git a/lib/netlink-notifier.c b/lib/netlink-notifier.c
index ea4742a90..0d24a45da 100644
--- a/lib/netlink-notifier.c
+++ b/lib/netlink-notifier.c
@@ -25,6 +25,7 @@
 #include "coverage.h"
 #include "netlink.h"
 #include "netlink-socket.h"
+#include "netnsid.h"
 #include "openvswitch/ofpbuf.h"
 #include "openvswitch/vlog.h"
 
@@ -41,6 +42,7 @@ struct nln {
     int protocol;                /* Protocol passed to nl_sock_create(). */
     nln_parse_func *parse;       /* Message parsing function. */
     void *change;                /* Change passed to parse. */
+    bool all_netns;              /* Whether to listen on all namespaces. */
 };
 
 struct nln_notifier {
@@ -55,10 +57,11 @@ struct nln_notifier {
 /* Creates an nln handle which may be used to manage change notifications.  The
  * created handle will listen for netlink messages on 'multicast_group' using
  * netlink protocol 'protocol' (e.g. NETLINK_ROUTE, NETLINK_GENERIC, ...).
+ * If 'all_netns', it will listen for events on all network namespaces.
  * Incoming messages will be parsed with 'parse' which will be passed 'change'
  * as an argument. */
 struct nln *
-nln_create(int protocol, nln_parse_func *parse, void *change)
+nln_create(int protocol, bool all_netns, nln_parse_func *parse, void *change)
 {
     struct nln *nln;
 
@@ -68,6 +71,7 @@ nln_create(int protocol, nln_parse_func *parse, void *change)
     nln->parse = parse;
     nln->change = change;
     nln->has_run = false;
+    nln->all_netns = all_netns;
 
     ovs_list_init(&nln->all_notifiers);
     return nln;
@@ -112,6 +116,9 @@ nln_notifier_create(struct nln *nln, int multicast_group, 
nln_notify_func *cb,
                       ovs_strerror(error));
             return NULL;
         }
+        if (nln->all_netns) {
+            nl_sock_listen_all_nsid(sock, true);
+        }
         nln->notify_sock = sock;
     } else {
         /* Catch up on notification work so that the new notifier won't
@@ -181,19 +188,20 @@ nln_run(struct nln *nln)
     nln->has_run = true;
     for (;;) {
         uint64_t buf_stub[4096 / 8];
+        int nsid = NETNSID_UNSET;
         struct ofpbuf buf;
         int error;
 
         ofpbuf_use_stub(&buf, buf_stub, sizeof buf_stub);
-        error = nl_sock_recv(nln->notify_sock, &buf, NULL, false);
+        error = nl_sock_recv(nln->notify_sock, &buf, &nsid, false);
         if (!error) {
             int group = nln->parse(&buf, nln->change);
 
             if (group != 0) {
-                nln_report(nln, nln->change, group);
+                nln_report(nln, nln->change, group, nsid);
             } else {
                 VLOG_WARN_RL(&rl, "unexpected netlink message contents");
-                nln_report(nln, NULL, 0);
+                nln_report(nln, NULL, 0, nsid);
             }
             ofpbuf_uninit(&buf);
         } else if (error == EAGAIN) {
@@ -203,7 +211,7 @@ nln_run(struct nln *nln)
                 nl_sock_drain(nln->notify_sock);
                 /* The socket buffer might be full, there could be too many
                  * notifications, so it makes sense to call nln_report() */
-                nln_report(nln, NULL, 0);
+                nln_report(nln, NULL, 0, NETNSID_UNSET);
                 VLOG_WARN_RL(&rl, "netlink receive buffer overflowed");
             } else {
                 VLOG_WARN_RL(&rl, "error reading netlink socket: %s",
@@ -225,7 +233,7 @@ nln_wait(struct nln *nln)
 }
 
 void OVS_NO_SANITIZE_FUNCTION
-nln_report(const struct nln *nln, void *change, int group)
+nln_report(const struct nln *nln, void *change, int group, int nsid)
 {
     struct nln_notifier *notifier;
 
@@ -235,7 +243,7 @@ nln_report(const struct nln *nln, void *change, int group)
 
     LIST_FOR_EACH (notifier, node, &nln->all_notifiers) {
         if (!change || group == notifier->multicast_group) {
-            notifier->cb(change, notifier->aux);
+            notifier->cb(change, nsid, notifier->aux);
         }
     }
 }
diff --git a/lib/netlink-notifier.h b/lib/netlink-notifier.h
index dd0c183de..60c002615 100644
--- a/lib/netlink-notifier.h
+++ b/lib/netlink-notifier.h
@@ -32,8 +32,9 @@ struct ofpbuf;
  * specific change filled out by an nln_parse_func.  It may be null if the
  * buffer of change information overflowed, in which case the function must
  * assume that everything may have changed. 'aux' is as specified in
- * nln_notifier_register(). */
-typedef void nln_notify_func(const void *change, void *aux);
+ * nln_notifier_register().  'nsid` is the network namespace id from which the
+ * netlink event came from. */
+typedef void nln_notify_func(const void *change, int nsid, void *aux);
 
 /* Function called to parse incoming nln notifications.  The 'buf' message
  * should be parsed into 'change' as specified in nln_create().
@@ -41,12 +42,13 @@ typedef void nln_notify_func(const void *change, void *aux);
  */
 typedef int nln_parse_func(struct ofpbuf *buf, void *change);
 
-struct nln *nln_create(int protocol, nln_parse_func *, void *change);
+struct nln *nln_create(int protocol, bool all_netns, nln_parse_func *,
+                       void *change);
 void nln_destroy(struct nln *);
 struct nln_notifier *nln_notifier_create(struct nln *, int multicast_group,
                                          nln_notify_func *, void *aux);
 void nln_notifier_destroy(struct nln_notifier *);
 void nln_run(struct nln *);
 void nln_wait(struct nln *);
-void nln_report(const struct nln *nln, void *change, int group);
+void nln_report(const struct nln *nln, void *change, int group, int nsid);
 #endif /* netlink-notifier.h */
diff --git a/lib/netnsid.h b/lib/netnsid.h
index 1d5ab83c5..47f55ee6c 100644
--- a/lib/netnsid.h
+++ b/lib/netnsid.h
@@ -18,6 +18,7 @@
 #define NETNSID_H 1
 
 #include <stdbool.h>
+#include "util.h"
 
 #ifdef HAVE_LINUX_NET_NAMESPACE_H
 #include <linux/net_namespace.h>
diff --git a/lib/route-table.c b/lib/route-table.c
index ca87ff7db..3127d9f85 100644
--- a/lib/route-table.c
+++ b/lib/route-table.c
@@ -32,6 +32,7 @@
 #include "netlink.h"
 #include "netlink-notifier.h"
 #include "netlink-socket.h"
+#include "netnsid.h"
 #include "openvswitch/list.h"
 #include "openvswitch/ofpbuf.h"
 #include "ovs-router.h"
@@ -74,11 +75,12 @@ static bool route_table_valid = false;
 
 static void route_table_reset(void);
 static void route_table_handle_msg(const struct route_table_msg *, void *aux);
-static void route_table_change(struct route_table_msg *, void *aux);
+static void route_table_change(struct route_table_msg *, int nsid, void *aux);
 static void route_map_clear(void);
 
 static void name_table_init(void);
-static void name_table_change(const struct rtnetlink_change *, void *);
+static void name_table_change(const struct rtnetlink_change *, int nsid,
+                              void *);
 
 static void
 route_data_destroy_nexthops__(struct route_data *rd)
@@ -116,7 +118,8 @@ route_table_init(void)
     ovs_assert(!route6_notifier);
 
     ovs_router_init();
-    nln = nln_create(NETLINK_ROUTE, route_table_parse, &nln_rtmsg_change);
+    nln = nln_create(NETLINK_ROUTE, false, route_table_parse,
+                     &nln_rtmsg_change);
 
     route_notifier =
         nln_notifier_create(nln, RTNLGRP_IPV4_ROUTE,
@@ -538,10 +541,12 @@ is_standard_table_id(uint32_t table_id)
 }
 
 static void
-route_table_change(struct route_table_msg *change, void *aux OVS_UNUSED)
+route_table_change(struct route_table_msg *change, int nsid,
+                   void *aux OVS_UNUSED)
 {
     if (!change
         || (change->relevant
+            && nsid == NETNSID_LOCAL
             && is_standard_table_id(change->rd.rta_table_id))) {
         route_table_valid = false;
     }
@@ -599,10 +604,10 @@ name_table_init(void)
 
 
 static void
-name_table_change(const struct rtnetlink_change *change,
+name_table_change(const struct rtnetlink_change *change, int nsid,
                   void *aux OVS_UNUSED)
 {
-    if (change && change->irrelevant) {
+    if (change && (nsid != NETNSID_LOCAL || change->irrelevant)) {
         return;
     }
 
diff --git a/lib/route-table.h b/lib/route-table.h
index b805e84dd..1d0e4e3e5 100644
--- a/lib/route-table.h
+++ b/lib/route-table.h
@@ -79,7 +79,7 @@
  *     static struct route_table_msg nln_change;
  *     static struct nln *nln = NULL;
  *
- *     nln = nln_create(NETLINK_ROUTE, route_table_parse, NULL);
+ *     nln = nln_create(NETLINK_ROUTE, false, nln_route_table_parse, NULL);
  *
  *     route6_notifier =
  *        nln_notifier_create(nln, RTNLGRP_IPV6_ROUTE,
diff --git a/lib/rtnetlink.c b/lib/rtnetlink.c
index 37078d00e..82613cfd5 100644
--- a/lib/rtnetlink.c
+++ b/lib/rtnetlink.c
@@ -24,6 +24,7 @@
 
 #include "netlink.h"
 #include "netlink-notifier.h"
+#include "netnsid.h"
 #include "openvswitch/ofpbuf.h"
 #include "packets.h"
 
@@ -210,7 +211,8 @@ struct nln_notifier *
 rtnetlink_notifier_create(rtnetlink_notify_func *cb, void *aux)
 {
     if (!nln) {
-        nln = nln_create(NETLINK_ROUTE, rtnetlink_parse_cb, &rtn_change);
+        nln = nln_create(NETLINK_ROUTE, false, rtnetlink_parse_cb,
+                         &rtn_change);
     }
 
     return nln_notifier_create(nln, RTNLGRP_LINK, (nln_notify_func *) cb, aux);
@@ -249,6 +251,6 @@ void
 rtnetlink_report_link(void)
 {
     if (nln) {
-        nln_report(nln, NULL, RTNLGRP_LINK);
+        nln_report(nln, NULL, RTNLGRP_LINK, NETNSID_UNSET);
     }
 }
diff --git a/lib/rtnetlink.h b/lib/rtnetlink.h
index cf3f600f0..7ca068488 100644
--- a/lib/rtnetlink.h
+++ b/lib/rtnetlink.h
@@ -63,7 +63,7 @@ struct rtnetlink_change {
  * have changed.  'aux' is as specified in the call to
  * rtnetlink_notifier_register().  */
 typedef
-void rtnetlink_notify_func(const struct rtnetlink_change *change,
+void rtnetlink_notify_func(const struct rtnetlink_change *change, int nsid,
                            void *aux);
 
 bool rtnetlink_type_is_rtnlgrp_link(uint16_t type);
diff --git a/tests/system-route.at b/tests/system-route.at
index 66bfd0e8e..5366965fe 100644
--- a/tests/system-route.at
+++ b/tests/system-route.at
@@ -128,7 +128,7 @@ Cached: 10.0.0.17/32 dev p1-route SRC 10.0.0.17 local
 Cached: 10.0.0.18/32 dev p1-route SRC 10.0.0.17
 ])
 AT_CHECK([ovstest test-lib-route-table-dump | \
-          awk '/rta_table_id:.*42/{print$1" "$15" "$16}' | sort], [0], [dnl
+          awk '/rta_table_id:.*42/{print$1" "$17" "$18}' | sort], [0], [dnl
 10.0.0.19/32 rta_table_id: 42
 10.0.0.20/32 rta_table_id: 1042
 ])
@@ -299,7 +299,7 @@ on_exit 'ip link del p1-route'
 dnl Add ip address.
 AT_CHECK([ip addr add 10.0.0.17/24 dev p1-route], [0], [stdout])
 AT_CHECK([ovstest test-lib-route-table-dump | \
-          awk '/^10.0.0.17/{print$1" "$6" "$7}'], [0], [dnl
+          awk '/^10.0.0.17/{print$1" "$8" "$9}'], [0], [dnl
 10.0.0.17/32 rtm_protocol: RTPROT_KERNEL
 ])
 
@@ -307,11 +307,11 @@ dnl Add route.
 AT_CHECK([ip route add 192.168.10.12/32 dev p1-route via 10.0.0.18], [0],
          [stdout])
 AT_CHECK([ovstest test-lib-route-table-dump | \
-          awk '/^192.168.10.12/{print$1" "$17" "$18}'], [0], [dnl
+          awk '/^192.168.10.12/{print$1" "$19" "$20}'], [0], [dnl
 192.168.10.12/32 rta_priority: 0
 ])
 AT_CHECK([ovstest test-lib-route-table-dump | \
-          awk '/^192.168.10.12/{print$1" "$6" "$7}'], [0], [dnl
+          awk '/^192.168.10.12/{print$1" "$8" "$9}'], [0], [dnl
 192.168.10.12/32 rtm_protocol: RTPROT_BOOT
 ])
 
@@ -323,11 +323,11 @@ dnl Add route with priority.
 AT_CHECK([ip route add 192.168.10.12/32 dev p1-route via 10.0.0.18 metric 42],
          [0], [stdout])
 AT_CHECK([ovstest test-lib-route-table-dump | \
-          awk '/^192.168.10.12/{print$1" "$17" "$18}'], [0], [dnl
+          awk '/^192.168.10.12/{print$1" "$19" "$20}'], [0], [dnl
 192.168.10.12/32 rta_priority: 42
 ])
 AT_CHECK([ovstest test-lib-route-table-dump | \
-          awk '/^192.168.10.12/{print$1" "$6" "$7}'], [0], [dnl
+          awk '/^192.168.10.12/{print$1" "$8" "$9}'], [0], [dnl
 192.168.10.12/32 rtm_protocol: RTPROT_BOOT
 ])
 
diff --git a/tests/test-lib-route-table.c b/tests/test-lib-route-table.c
index 4ba17826e..e42068dfc 100644
--- a/tests/test-lib-route-table.c
+++ b/tests/test-lib-route-table.c
@@ -23,6 +23,7 @@
 #include <stdlib.h>
 
 #include "netlink-notifier.h"
+#include "netnsid.h"
 #include "ovstest.h"
 #include "packets.h"
 #include "route-table.h"
@@ -72,6 +73,7 @@ rt_table_name(uint32_t id)
 
 static void
 test_lib_route_table_handle_msg(const struct route_table_msg *change,
+                                int nsid,
                                 void *data OVS_UNUSED)
 {
     struct ds nexthop_addr = DS_EMPTY_INITIALIZER;
@@ -83,10 +85,10 @@ test_lib_route_table_handle_msg(const struct 
route_table_msg *change,
     ipv6_format_mapped(&change->rd.rta_prefsrc, &rta_prefsrc);
     ipv6_format_mapped(&change->rd.rta_dst, &rta_dst);
 
-    printf("%s/%u relevant: %d nlmsg_type: %d rtm_protocol: %s (%u) "
+    printf("%s/%u nsid %d relevant: %d nlmsg_type: %d rtm_protocol: %s (%u) "
            "rtn_local: %d rta_prefsrc: %s rta_mark: %"PRIu32" "
            "rta_table_id: %s rta_priority: %"PRIu32"\n",
-           ds_cstr(&rta_dst), rd->rtm_dst_len, change->relevant,
+           ds_cstr(&rta_dst), rd->rtm_dst_len, nsid, change->relevant,
            change->nlmsg_type, rt_prot_name(rd->rtm_protocol),
            rd->rtm_protocol, rd->rtn_local, ds_cstr(&rta_prefsrc),
            rd->rta_mark, rt_table_name(rd->rta_table_id), rd->rta_priority);
@@ -108,19 +110,27 @@ test_lib_route_table_handle_msg(const struct 
route_table_msg *change,
     ds_destroy(&rta_dst);
 }
 
+static void
+__test_lib_route_table_dump(const struct route_table_msg *change,
+                          void *data OVS_UNUSED) {
+
+    test_lib_route_table_handle_msg(change, NETNSID_LOCAL, NULL);
+}
+
 static void
 test_lib_route_table_dump(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
 {
     route_table_dump_one_table(RT_TABLE_UNSPEC,
-                               test_lib_route_table_handle_msg,
+                               __test_lib_route_table_dump,
                                NULL);
 }
 
 static void
 test_lib_route_table_change(struct route_table_msg *change,
+                            int nsid,
                             void *aux OVS_UNUSED)
 {
-    test_lib_route_table_handle_msg(change, NULL);
+    test_lib_route_table_handle_msg(change, nsid, NULL);
     route_data_destroy(&change->rd);
 }
 
@@ -138,7 +148,7 @@ test_lib_route_table_monitor(int argc, char *argv[])
         exit(EXIT_FAILURE);
     }
 
-    nln = nln_create(NETLINK_ROUTE, route_table_parse, &rtmsg);
+    nln = nln_create(NETLINK_ROUTE, false, route_table_parse, &rtmsg);
 
     route_notifier =
         nln_notifier_create(nln, RTNLGRP_IPV4_ROUTE,
diff --git a/tests/test-netlink-conntrack.c b/tests/test-netlink-conntrack.c
index 2a62615b2..61a4d697d 100644
--- a/tests/test-netlink-conntrack.c
+++ b/tests/test-netlink-conntrack.c
@@ -22,6 +22,7 @@
 #include "ct-dpif.h"
 #include "netlink-conntrack.h"
 #include "netlink-notifier.h"
+#include "netnsid.h"
 #include "ovstest.h"
 #include "openvswitch/poll-loop.h"
 
@@ -50,11 +51,11 @@ event_parse(struct ofpbuf *buf, void *change_)
 }
 
 static void
-event_print(const void *change_, void *aux OVS_UNUSED)
+event_print(const void *change_, int nsid, void *aux OVS_UNUSED)
 {
     const struct test_change *change = change_;
 
-    if (change) {
+    if (change && nsid == NETNSID_LOCAL) {
         struct ds ds = DS_EMPTY_INITIALIZER;
 
         nl_ct_format_event_entry(&change->entry, change->type, &ds, true,
@@ -80,7 +81,7 @@ test_nl_ct_monitor(struct ovs_cmdl_context *ctx OVS_UNUSED)
 
     unsigned i;
 
-    nln = nln_create(NETLINK_NETFILTER, event_parse, &change);
+    nln = nln_create(NETLINK_NETFILTER, false, event_parse, &change);
 
     for (i = 0; i < ARRAY_SIZE(groups); i++) {
         notifiers[i] = nln_notifier_create(nln, groups[i], event_print, NULL);
-- 
2.52.0

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to