^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * net/psample/psample.c - Netlink channel for packet sampling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 2017 Yotam Gigi <yotamg@mellanox.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <net/net_namespace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <net/sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <net/netlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <net/genetlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <net/psample.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <net/ip_tunnels.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <net/dst_metadata.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define PSAMPLE_MAX_PACKET_SIZE 0xffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) static LIST_HEAD(psample_groups_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) static DEFINE_SPINLOCK(psample_groups_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) /* multicast groups */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) enum psample_nl_multicast_groups {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) PSAMPLE_NL_MCGRP_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) PSAMPLE_NL_MCGRP_SAMPLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) static const struct genl_multicast_group psample_nl_mcgrps[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) [PSAMPLE_NL_MCGRP_CONFIG] = { .name = PSAMPLE_NL_MCGRP_CONFIG_NAME },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) [PSAMPLE_NL_MCGRP_SAMPLE] = { .name = PSAMPLE_NL_MCGRP_SAMPLE_NAME },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static struct genl_family psample_nl_family __ro_after_init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) static int psample_group_nl_fill(struct sk_buff *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct psample_group *group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) enum psample_command cmd, u32 portid, u32 seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) hdr = genlmsg_put(msg, portid, seq, &psample_nl_family, flags, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) ret = nla_put_u32(msg, PSAMPLE_ATTR_SAMPLE_GROUP, group->group_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) ret = nla_put_u32(msg, PSAMPLE_ATTR_GROUP_REFCOUNT, group->refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) ret = nla_put_u32(msg, PSAMPLE_ATTR_GROUP_SEQ, group->seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) genlmsg_cancel(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static int psample_nl_cmd_get_group_dumpit(struct sk_buff *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct psample_group *group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) int start = cb->args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) int idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) spin_lock_bh(&psample_groups_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) list_for_each_entry(group, &psample_groups_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) if (!net_eq(group->net, sock_net(msg->sk)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if (idx < start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) err = psample_group_nl_fill(msg, group, PSAMPLE_CMD_NEW_GROUP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) NETLINK_CB(cb->skb).portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) cb->nlh->nlmsg_seq, NLM_F_MULTI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) spin_unlock_bh(&psample_groups_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) cb->args[0] = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) return msg->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) static const struct genl_small_ops psample_nl_ops[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) .cmd = PSAMPLE_CMD_GET_GROUP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) .dumpit = psample_nl_cmd_get_group_dumpit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /* can be retrieved by unprivileged users */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static struct genl_family psample_nl_family __ro_after_init = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) .name = PSAMPLE_GENL_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) .version = PSAMPLE_GENL_VERSION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) .maxattr = PSAMPLE_ATTR_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) .netnsok = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) .module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) .mcgrps = psample_nl_mcgrps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) .small_ops = psample_nl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) .n_small_ops = ARRAY_SIZE(psample_nl_ops),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) .n_mcgrps = ARRAY_SIZE(psample_nl_mcgrps),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static void psample_group_notify(struct psample_group *group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) enum psample_command cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) err = psample_group_nl_fill(msg, group, cmd, 0, 0, NLM_F_MULTI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) genlmsg_multicast_netns(&psample_nl_family, group->net, msg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) PSAMPLE_NL_MCGRP_CONFIG, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) static struct psample_group *psample_group_create(struct net *net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) u32 group_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct psample_group *group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) group = kzalloc(sizeof(*group), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (!group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) group->net = net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) group->group_num = group_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) list_add_tail(&group->list, &psample_groups_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) psample_group_notify(group, PSAMPLE_CMD_NEW_GROUP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) static void psample_group_destroy(struct psample_group *group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) psample_group_notify(group, PSAMPLE_CMD_DEL_GROUP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) list_del(&group->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) kfree_rcu(group, rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static struct psample_group *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) psample_group_lookup(struct net *net, u32 group_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) struct psample_group *group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) list_for_each_entry(group, &psample_groups_list, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if ((group->group_num == group_num) && (group->net == net))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) struct psample_group *psample_group_get(struct net *net, u32 group_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) struct psample_group *group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) spin_lock_bh(&psample_groups_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) group = psample_group_lookup(net, group_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (!group) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) group = psample_group_create(net, group_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (!group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) group->refcount++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) spin_unlock_bh(&psample_groups_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) return group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) EXPORT_SYMBOL_GPL(psample_group_get);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) void psample_group_take(struct psample_group *group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) spin_lock_bh(&psample_groups_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) group->refcount++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) spin_unlock_bh(&psample_groups_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) EXPORT_SYMBOL_GPL(psample_group_take);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) void psample_group_put(struct psample_group *group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) spin_lock_bh(&psample_groups_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) if (--group->refcount == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) psample_group_destroy(group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) spin_unlock_bh(&psample_groups_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) EXPORT_SYMBOL_GPL(psample_group_put);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) #ifdef CONFIG_INET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) static int __psample_ip_tun_to_nlattr(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) struct ip_tunnel_info *tun_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) unsigned short tun_proto = ip_tunnel_info_af(tun_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) const void *tun_opts = ip_tunnel_info_opts(tun_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) const struct ip_tunnel_key *tun_key = &tun_info->key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) int tun_opts_len = tun_info->options_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (tun_key->tun_flags & TUNNEL_KEY &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) nla_put_be64(skb, PSAMPLE_TUNNEL_KEY_ATTR_ID, tun_key->tun_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) PSAMPLE_TUNNEL_KEY_ATTR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (tun_info->mode & IP_TUNNEL_INFO_BRIDGE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) nla_put_flag(skb, PSAMPLE_TUNNEL_KEY_ATTR_IPV4_INFO_BRIDGE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) switch (tun_proto) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) case AF_INET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if (tun_key->u.ipv4.src &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) nla_put_in_addr(skb, PSAMPLE_TUNNEL_KEY_ATTR_IPV4_SRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) tun_key->u.ipv4.src))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (tun_key->u.ipv4.dst &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) nla_put_in_addr(skb, PSAMPLE_TUNNEL_KEY_ATTR_IPV4_DST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) tun_key->u.ipv4.dst))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) case AF_INET6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if (!ipv6_addr_any(&tun_key->u.ipv6.src) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) nla_put_in6_addr(skb, PSAMPLE_TUNNEL_KEY_ATTR_IPV6_SRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) &tun_key->u.ipv6.src))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) if (!ipv6_addr_any(&tun_key->u.ipv6.dst) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) nla_put_in6_addr(skb, PSAMPLE_TUNNEL_KEY_ATTR_IPV6_DST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) &tun_key->u.ipv6.dst))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (tun_key->tos &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) nla_put_u8(skb, PSAMPLE_TUNNEL_KEY_ATTR_TOS, tun_key->tos))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (nla_put_u8(skb, PSAMPLE_TUNNEL_KEY_ATTR_TTL, tun_key->ttl))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if ((tun_key->tun_flags & TUNNEL_DONT_FRAGMENT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) nla_put_flag(skb, PSAMPLE_TUNNEL_KEY_ATTR_DONT_FRAGMENT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) if ((tun_key->tun_flags & TUNNEL_CSUM) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) nla_put_flag(skb, PSAMPLE_TUNNEL_KEY_ATTR_CSUM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (tun_key->tp_src &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) nla_put_be16(skb, PSAMPLE_TUNNEL_KEY_ATTR_TP_SRC, tun_key->tp_src))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) if (tun_key->tp_dst &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) nla_put_be16(skb, PSAMPLE_TUNNEL_KEY_ATTR_TP_DST, tun_key->tp_dst))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if ((tun_key->tun_flags & TUNNEL_OAM) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) nla_put_flag(skb, PSAMPLE_TUNNEL_KEY_ATTR_OAM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (tun_opts_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (tun_key->tun_flags & TUNNEL_GENEVE_OPT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) nla_put(skb, PSAMPLE_TUNNEL_KEY_ATTR_GENEVE_OPTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) tun_opts_len, tun_opts))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) else if (tun_key->tun_flags & TUNNEL_ERSPAN_OPT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) nla_put(skb, PSAMPLE_TUNNEL_KEY_ATTR_ERSPAN_OPTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) tun_opts_len, tun_opts))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) static int psample_ip_tun_to_nlattr(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) struct ip_tunnel_info *tun_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) struct nlattr *nla;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) nla = nla_nest_start_noflag(skb, PSAMPLE_ATTR_TUNNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (!nla)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) err = __psample_ip_tun_to_nlattr(skb, tun_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) nla_nest_cancel(skb, nla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) nla_nest_end(skb, nla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) static int psample_tunnel_meta_len(struct ip_tunnel_info *tun_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) unsigned short tun_proto = ip_tunnel_info_af(tun_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) const struct ip_tunnel_key *tun_key = &tun_info->key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) int tun_opts_len = tun_info->options_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) int sum = nla_total_size(0); /* PSAMPLE_ATTR_TUNNEL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (tun_key->tun_flags & TUNNEL_KEY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) sum += nla_total_size_64bit(sizeof(u64));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) if (tun_info->mode & IP_TUNNEL_INFO_BRIDGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) sum += nla_total_size(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) switch (tun_proto) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) case AF_INET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (tun_key->u.ipv4.src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) sum += nla_total_size(sizeof(u32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (tun_key->u.ipv4.dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) sum += nla_total_size(sizeof(u32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) case AF_INET6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) if (!ipv6_addr_any(&tun_key->u.ipv6.src))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) sum += nla_total_size(sizeof(struct in6_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (!ipv6_addr_any(&tun_key->u.ipv6.dst))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) sum += nla_total_size(sizeof(struct in6_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if (tun_key->tos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) sum += nla_total_size(sizeof(u8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) sum += nla_total_size(sizeof(u8)); /* TTL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (tun_key->tun_flags & TUNNEL_DONT_FRAGMENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) sum += nla_total_size(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (tun_key->tun_flags & TUNNEL_CSUM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) sum += nla_total_size(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (tun_key->tp_src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) sum += nla_total_size(sizeof(u16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (tun_key->tp_dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) sum += nla_total_size(sizeof(u16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) if (tun_key->tun_flags & TUNNEL_OAM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) sum += nla_total_size(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (tun_opts_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) if (tun_key->tun_flags & TUNNEL_GENEVE_OPT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) sum += nla_total_size(tun_opts_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) else if (tun_key->tun_flags & TUNNEL_ERSPAN_OPT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) sum += nla_total_size(tun_opts_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) return sum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) void psample_sample_packet(struct psample_group *group, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) u32 trunc_size, int in_ifindex, int out_ifindex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) u32 sample_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) #ifdef CONFIG_INET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) struct ip_tunnel_info *tun_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) struct sk_buff *nl_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) int data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) int meta_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) void *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) meta_len = (in_ifindex ? nla_total_size(sizeof(u16)) : 0) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) (out_ifindex ? nla_total_size(sizeof(u16)) : 0) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) nla_total_size(sizeof(u32)) + /* sample_rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) nla_total_size(sizeof(u32)) + /* orig_size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) nla_total_size(sizeof(u32)) + /* group_num */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) nla_total_size(sizeof(u32)); /* seq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) #ifdef CONFIG_INET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) tun_info = skb_tunnel_info(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (tun_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) meta_len += psample_tunnel_meta_len(tun_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) data_len = min(skb->len, trunc_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) if (meta_len + nla_total_size(data_len) > PSAMPLE_MAX_PACKET_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) data_len = PSAMPLE_MAX_PACKET_SIZE - meta_len - NLA_HDRLEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) - NLA_ALIGNTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) nl_skb = genlmsg_new(meta_len + nla_total_size(data_len), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if (unlikely(!nl_skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) data = genlmsg_put(nl_skb, 0, 0, &psample_nl_family, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) PSAMPLE_CMD_SAMPLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (unlikely(!data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) if (in_ifindex) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) ret = nla_put_u16(nl_skb, PSAMPLE_ATTR_IIFINDEX, in_ifindex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) if (unlikely(ret < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) if (out_ifindex) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) ret = nla_put_u16(nl_skb, PSAMPLE_ATTR_OIFINDEX, out_ifindex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) if (unlikely(ret < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_SAMPLE_RATE, sample_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if (unlikely(ret < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_ORIGSIZE, skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) if (unlikely(ret < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_SAMPLE_GROUP, group->group_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (unlikely(ret < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_GROUP_SEQ, group->seq++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) if (unlikely(ret < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (data_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) int nla_len = nla_total_size(data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) struct nlattr *nla;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) nla = skb_put(nl_skb, nla_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) nla->nla_type = PSAMPLE_ATTR_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) nla->nla_len = nla_attr_size(data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (skb_copy_bits(skb, 0, nla_data(nla), data_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) #ifdef CONFIG_INET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if (tun_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) ret = psample_ip_tun_to_nlattr(nl_skb, tun_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) if (unlikely(ret < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) genlmsg_end(nl_skb, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) genlmsg_multicast_netns(&psample_nl_family, group->net, nl_skb, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) PSAMPLE_NL_MCGRP_SAMPLE, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) pr_err_ratelimited("Could not create psample log message\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) nlmsg_free(nl_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) EXPORT_SYMBOL_GPL(psample_sample_packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) static int __init psample_module_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) return genl_register_family(&psample_nl_family);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) static void __exit psample_module_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) genl_unregister_family(&psample_nl_family);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) module_init(psample_module_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) module_exit(psample_module_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) MODULE_AUTHOR("Yotam Gigi <yotam.gi@gmail.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) MODULE_DESCRIPTION("netlink channel for packet sampling");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) MODULE_LICENSE("GPL v2");