[net-next,2/3] ioam6: multicast event
Commit Message
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
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
@@ -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 */
@@ -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,
};