On 6/8/26 10:54 AM, Adrian Moreno via dev wrote:
> 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)) {
Need to use the netnsid_is_local() function, espacially since now
it is not only NETNSID_LOCAL. Same applies to all other places
that check for the id being local. In general, the constants should
not be used directly outside of the netnsid module.
> 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;
Shouldn't we initialize this to local with netnsid_set_local() ?
Otherwise, if not provided in the nelink message, the message will
be rejected by the handlers.
>
> 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);
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev