2024-02-23 14:43:54

by Justin Iurman

[permalink] [raw]
Subject: [PATCH net-next v4 0/3] ioam6: netlink multicast event

v4:
- rebase on top of net merge
v3:
- patchset was mistakenly superseded due to same cover title used for
iproute2-next equivalent patch -> resend (renamed)
v2:
- fix warnings

Add generic netlink multicast event support to ioam6 as another solution
to share IOAM data with user space. The other one being via IPv6 raw
sockets combined with ancillary data. This patchset focuses on the IOAM
Pre-allocated Trace (the only Option-Type currently supported), and so
on IOAM "trace" events. See an example of a consumer here [1].

[1] https://github.com/Advanced-Observability/ioam-agent-python/blob/netlink_event/ioam-agent.py

Justin Iurman (3):
uapi: ioam6: API for netlink multicast events
net: ioam6: multicast event
net: exthdrs: ioam6: send trace event

include/net/ioam6.h | 4 +++
include/uapi/linux/ioam6_genl.h | 20 +++++++++++
net/ipv6/exthdrs.c | 6 ++++
net/ipv6/ioam6.c | 64 +++++++++++++++++++++++++++++++++
4 files changed, 94 insertions(+)


base-commit: a818bd12538c1408c7480de31573cdb3c3c0926f
--
2.34.1



2024-02-23 14:44:11

by Justin Iurman

[permalink] [raw]
Subject: [PATCH net-next v4 2/3] net: ioam6: multicast event

Add a multicast group to the ioam6 generic netlink family and provide
ioam6_event() to send an ioam6 event to the multicast group.

Signed-off-by: Justin Iurman <[email protected]>
---
include/net/ioam6.h | 4 +++
net/ipv6/ioam6.c | 64 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 68 insertions(+)

diff --git a/include/net/ioam6.h b/include/net/ioam6.h
index 781d2d8b2f29..2cbbee6e806a 100644
--- a/include/net/ioam6.h
+++ b/include/net/ioam6.h
@@ -12,6 +12,7 @@
#include <linux/net.h>
#include <linux/ipv6.h>
#include <linux/ioam6.h>
+#include <linux/ioam6_genl.h>
#include <linux/rhashtable-types.h>

struct ioam6_namespace {
@@ -65,4 +66,7 @@ void ioam6_exit(void);
int ioam6_iptunnel_init(void);
void ioam6_iptunnel_exit(void);

+void ioam6_event(enum ioam6_event_type type, struct net *net, gfp_t gfp,
+ void *opt, unsigned int opt_len);
+
#endif /* _NET_IOAM6_H */
diff --git a/net/ipv6/ioam6.c b/net/ipv6/ioam6.c
index 571f0e4d9cf3..5fa923f06632 100644
--- a/net/ipv6/ioam6.c
+++ b/net/ipv6/ioam6.c
@@ -612,6 +612,68 @@ static const struct genl_ops ioam6_genl_ops[] = {
},
};

+#define IOAM6_GENL_EV_GRP_OFFSET 0
+
+static const struct genl_multicast_group ioam6_mcgrps[] = {
+ [IOAM6_GENL_EV_GRP_OFFSET] = { .name = IOAM6_GENL_EV_GRP_NAME,
+ .flags = GENL_MCAST_CAP_NET_ADMIN },
+};
+
+static int ioam6_event_put_trace(struct sk_buff *skb,
+ struct ioam6_trace_hdr *trace,
+ unsigned int len)
+{
+ if (nla_put_u16(skb, IOAM6_EVENT_ATTR_TRACE_NAMESPACE,
+ be16_to_cpu(trace->namespace_id)) ||
+ nla_put_u8(skb, IOAM6_EVENT_ATTR_TRACE_NODELEN, trace->nodelen) ||
+ nla_put_u32(skb, IOAM6_EVENT_ATTR_TRACE_TYPE,
+ be32_to_cpu(trace->type_be32)) ||
+ nla_put(skb, IOAM6_EVENT_ATTR_TRACE_DATA,
+ len - sizeof(struct ioam6_trace_hdr) - trace->remlen * 4,
+ trace->data + trace->remlen * 4))
+ return 1;
+
+ return 0;
+}
+
+void ioam6_event(enum ioam6_event_type type, struct net *net, gfp_t gfp,
+ void *opt, unsigned int opt_len)
+{
+ struct nlmsghdr *nlh;
+ struct sk_buff *skb;
+
+ if (!genl_has_listeners(&ioam6_genl_family, net,
+ IOAM6_GENL_EV_GRP_OFFSET))
+ return;
+
+ skb = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
+ if (!skb)
+ return;
+
+ nlh = genlmsg_put(skb, 0, 0, &ioam6_genl_family, 0, type);
+ if (!nlh)
+ goto nla_put_failure;
+
+ switch (type) {
+ case IOAM6_EVENT_UNSPEC:
+ WARN_ON_ONCE(1);
+ break;
+ case IOAM6_EVENT_TRACE:
+ if (ioam6_event_put_trace(skb, (struct ioam6_trace_hdr *)opt,
+ opt_len))
+ goto nla_put_failure;
+ break;
+ }
+
+ genlmsg_end(skb, nlh);
+ genlmsg_multicast_netns(&ioam6_genl_family, net, skb, 0,
+ IOAM6_GENL_EV_GRP_OFFSET, gfp);
+ return;
+
+nla_put_failure:
+ nlmsg_free(skb);
+}
+
static struct genl_family ioam6_genl_family __ro_after_init = {
.name = IOAM6_GENL_NAME,
.version = IOAM6_GENL_VERSION,
@@ -620,6 +682,8 @@ static struct genl_family ioam6_genl_family __ro_after_init = {
.ops = ioam6_genl_ops,
.n_ops = ARRAY_SIZE(ioam6_genl_ops),
.resv_start_op = IOAM6_CMD_NS_SET_SCHEMA + 1,
+ .mcgrps = ioam6_mcgrps,
+ .n_mcgrps = ARRAY_SIZE(ioam6_mcgrps),
.module = THIS_MODULE,
};

--
2.34.1


2024-02-23 16:50:50

by David Ahern

[permalink] [raw]
Subject: Re: [PATCH net-next v4 0/3] ioam6: netlink multicast event

On 2/23/24 7:41 AM, Justin Iurman wrote:
> v4:
> - rebase on top of net merge
> v3:
> - patchset was mistakenly superseded due to same cover title used for
> iproute2-next equivalent patch -> resend (renamed)
> v2:
> - fix warnings
>
> Add generic netlink multicast event support to ioam6 as another solution
> to share IOAM data with user space. The other one being via IPv6 raw
> sockets combined with ancillary data. This patchset focuses on the IOAM
> Pre-allocated Trace (the only Option-Type currently supported), and so
> on IOAM "trace" events. See an example of a consumer here [1].
>
> [1] https://github.com/Advanced-Observability/ioam-agent-python/blob/netlink_event/ioam-agent.py
>
> Justin Iurman (3):
> uapi: ioam6: API for netlink multicast events
> net: ioam6: multicast event
> net: exthdrs: ioam6: send trace event
>
> include/net/ioam6.h | 4 +++
> include/uapi/linux/ioam6_genl.h | 20 +++++++++++
> net/ipv6/exthdrs.c | 6 ++++
> net/ipv6/ioam6.c | 64 +++++++++++++++++++++++++++++++++
> 4 files changed, 94 insertions(+)
>
>
> base-commit: a818bd12538c1408c7480de31573cdb3c3c0926f

For the set:
Reviewed-by: David Ahern <[email protected]>