mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 13:11:40 +00:00
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. Reviewed-by: David Ahern <dsahern@kernel.org> Signed-off-by: Justin Iurman <justin.iurman@uliege.be> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
5fa918a335
commit
67c8e4bb4f
@ -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,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,
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user