[net-next,2/3] ioam6: multicast event

Message ID 20240220194444.36127-3-justin.iurman@uliege.be
State New
Headers
Series multicast event support for ioam6 |

Commit Message

Justin Iurman Feb. 20, 2024, 7:44 p.m. UTC
  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 <justin.iurman@uliege.be>
---
 include/net/ioam6.h |  4 +++
 net/ipv6/ioam6.c    | 61 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+)
  

Comments

kernel test robot Feb. 21, 2024, 2:18 p.m. UTC | #1
Hi Justin,

kernel test robot noticed the following build warnings:

[auto build test WARNING on a6e0cb150c514efba4aaba4069927de43d80bb59]

url:    https://github.com/intel-lab-lkp/linux/commits/Justin-Iurman/uapi-ioam6-API-for-netlink-multicast-events/20240221-034623
base:   a6e0cb150c514efba4aaba4069927de43d80bb59
patch link:    https://lore.kernel.org/r/20240220194444.36127-3-justin.iurman%40uliege.be
patch subject: [PATCH net-next 2/3] ioam6: multicast event
config: parisc-defconfig (https://download.01.org/0day-ci/archive/20240221/202402212253.mfysd5E1-lkp@intel.com/config)
compiler: hppa-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240221/202402212253.mfysd5E1-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202402212253.mfysd5E1-lkp@intel.com/

All warnings (new ones prefixed by >>):

   net/ipv6/ioam6.c: In function 'ioam6_event':
>> net/ipv6/ioam6.c:657:9: warning: enumeration value 'IOAM6_EVENT_UNSPEC' not handled in switch [-Wswitch]
     657 |         switch (type) {
         |         ^~~~~~


vim +/IOAM6_EVENT_UNSPEC +657 net/ipv6/ioam6.c

   638	
   639	void ioam6_event(enum ioam6_event_type type, struct net *net, gfp_t gfp,
   640			 void *opt, unsigned int opt_len)
   641	{
   642		struct nlmsghdr *nlh;
   643		struct sk_buff *skb;
   644	
   645		if (!genl_has_listeners(&ioam6_genl_family, net,
   646					IOAM6_GENL_EV_GRP_OFFSET))
   647			return;
   648	
   649		skb = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
   650		if (!skb)
   651			return;
   652	
   653		nlh = genlmsg_put(skb, 0, 0, &ioam6_genl_family, 0, type);
   654		if (!nlh)
   655			goto nla_put_failure;
   656	
 > 657		switch (type) {
   658		case IOAM6_EVENT_TRACE:
   659			if (ioam6_event_put_trace(skb, (struct ioam6_trace_hdr *)opt,
   660						  opt_len))
   661				goto nla_put_failure;
   662			break;
   663		}
   664	
   665		genlmsg_end(skb, nlh);
   666		genlmsg_multicast_netns(&ioam6_genl_family, net, skb, 0,
   667					IOAM6_GENL_EV_GRP_OFFSET, gfp);
   668		return;
   669	
   670	nla_put_failure:
   671		nlmsg_free(skb);
   672	}
   673
  

Patch

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..d06a406658f6 100644
--- a/net/ipv6/ioam6.c
+++ b/net/ipv6/ioam6.c
@@ -612,6 +612,65 @@  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 trace_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,
+		    trace_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_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 +679,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,
 };