Use a flag to request notifications form all network namespaces and include the namespace id from which notification came from in the parsing callback.
Signed-off-by: Adrian Moreno <[email protected]> --- lib/if-notifier.c | 3 ++- lib/netlink-notifier.c | 14 +++++++++++--- lib/netlink-notifier.h | 6 ++++-- lib/netnsid.h | 1 + lib/route-table.c | 12 ++++++------ lib/route-table.h | 2 +- lib/rtnetlink.c | 14 +++++++++++--- lib/rtnetlink.h | 5 +++-- tests/test-lib-route-table.c | 9 ++++++++- tests/test-netlink-conntrack.c | 9 +++++++-- 10 files changed, 54 insertions(+), 21 deletions(-) diff --git a/lib/if-notifier.c b/lib/if-notifier.c index f2d7157b9..5b3ba8b69 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" @@ -30,7 +31,7 @@ if_notifier_cb(const struct rtnetlink_change *change, void *aux) { struct if_notifier *notifier; - if (change && change->irrelevant) { + if (change && (change->irrelevant || change->nsid != NETNSID_LOCAL)) { return; } diff --git a/lib/netlink-notifier.c b/lib/netlink-notifier.c index ea4742a90..6ecb4392b 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,13 +188,14 @@ 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); + int group = nln->parse(&buf, nsid, nln->change); if (group != 0) { nln_report(nln, nln->change, group); diff --git a/lib/netlink-notifier.h b/lib/netlink-notifier.h index dd0c183de..8b6c32048 100644 --- a/lib/netlink-notifier.h +++ b/lib/netlink-notifier.h @@ -37,11 +37,13 @@ typedef void nln_notify_func(const void *change, void *aux); /* Function called to parse incoming nln notifications. The 'buf' message * should be parsed into 'change' as specified in nln_create(). + * 'nsid` is the network namespace id from which the netlink event came from. * Returns the multicast_group the change belongs to, or 0 for a parse error. */ -typedef int nln_parse_func(struct ofpbuf *buf, void *change); +typedef int nln_parse_func(struct ofpbuf *buf, int nsid, 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); 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 2a13a5cc7..5cb6f7842 100644 --- a/lib/route-table.c +++ b/lib/route-table.c @@ -33,6 +33,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" @@ -84,7 +85,7 @@ static struct nln_notifier *name_notifier = NULL; static bool route_table_valid = false; static bool rules_valid = false; -static int route_nln_parse(struct ofpbuf *, void *change); +static int route_nln_parse(struct ofpbuf *, int nsid, void *change); static void rule_handle_msg(const struct route_table_msg *); static int rule_parse(struct ofpbuf *, void *change); @@ -137,7 +138,7 @@ route_table_init(void) ovs_assert(!rule6_notifier); ovs_router_init(); - nln = nln_create(NETLINK_ROUTE, route_nln_parse, &nln_rtmsg_change); + nln = nln_create(NETLINK_ROUTE, false, route_nln_parse, &nln_rtmsg_change); route_notifier = nln_notifier_create(nln, RTNLGRP_IPV4_ROUTE, @@ -295,7 +296,7 @@ rule_handle_msg(const struct route_table_msg *change) } static int -route_nln_parse(struct ofpbuf *buf, void *change_) +route_nln_parse(struct ofpbuf *buf, int nsid OVS_UNUSED, void *change_) { const struct nlmsghdr *nlmsg = buf->data; @@ -795,10 +796,9 @@ name_table_init(void) static void -name_table_change(const struct rtnetlink_change *change, - void *aux OVS_UNUSED) +name_table_change(const struct rtnetlink_change *change, void *aux OVS_UNUSED) { - if (change && change->irrelevant) { + if (change && (change->nsid != NETNSID_LOCAL || change->irrelevant)) { return; } diff --git a/lib/route-table.h b/lib/route-table.h index b49fbb14e..e4edcb307 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..6b63afa06 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" @@ -89,6 +90,7 @@ rtnetlink_parse(struct ofpbuf *buf, struct rtnetlink_change *change) bool parsed = false; change->irrelevant = false; + change->nsid = NETNSID_UNSET; if (rtnetlink_type_is_rtnlgrp_link(nlmsg->nlmsg_type)) { /* Policy for RTNLGRP_LINK messages. @@ -190,9 +192,14 @@ rtnetlink_parse(struct ofpbuf *buf, struct rtnetlink_change *change) /* Return RTNLGRP_LINK on success, 0 on parse error. */ static int -rtnetlink_parse_cb(struct ofpbuf *buf, void *change) +rtnetlink_parse_cb(struct ofpbuf *buf, int nsid, void *change) { - return rtnetlink_parse(buf, change) ? RTNLGRP_LINK : 0; + bool ret = rtnetlink_parse(buf, change); + if (ret) { + ((struct rtnetlink_change *) change)->nsid = nsid; + return RTNLGRP_LINK; + } + return 0; } /* Registers 'cb' to be called with auxiliary data 'aux' with network device @@ -210,7 +217,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); diff --git a/lib/rtnetlink.h b/lib/rtnetlink.h index cf3f600f0..9b2397b4e 100644 --- a/lib/rtnetlink.h +++ b/lib/rtnetlink.h @@ -39,6 +39,8 @@ struct rtnetlink_change { /* Common attributes. */ int if_index; /* Index of network device. */ const char *ifname; /* Name of network device. */ + int nsid; /* Network namespace id of the from which + the event comes from. */ /* Network device link status. */ int master_ifindex; /* Ifindex of datapath master (0 if none). */ @@ -63,8 +65,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 *aux); +void rtnetlink_notify_func(const struct rtnetlink_change *change, void *aux); bool rtnetlink_type_is_rtnlgrp_link(uint16_t type); bool rtnetlink_type_is_rtnlgrp_addr(uint16_t type); diff --git a/tests/test-lib-route-table.c b/tests/test-lib-route-table.c index f99f056c8..c5126426b 100644 --- a/tests/test-lib-route-table.c +++ b/tests/test-lib-route-table.c @@ -129,6 +129,13 @@ test_lib_route_table_change(struct route_table_msg *change, route_data_destroy(&change->rd); } +static int +test_lib_route_table_parse(struct ofpbuf *buf, int nsid OVS_UNUSED, + void *change) +{ + return route_table_parse(buf, change); +} + static void test_lib_route_table_monitor(int argc, char *argv[]) { @@ -143,7 +150,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, test_lib_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..a8bcadc4d 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" @@ -32,10 +33,14 @@ struct test_change { }; static int -event_parse(struct ofpbuf *buf, void *change_) +event_parse(struct ofpbuf *buf, int nsid, void *change_) { struct test_change *change = change_; + if (nsid != NETNSID_LOCAL) { + return 0; + } + if (nl_ct_parse_entry(buf, &change->entry, &change->type)) { switch (change->type) { case NL_CT_EVENT_NEW: @@ -80,7 +85,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.53.0 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
