Update BRCM KNET modules to support new psample definitions from sflow… (#11709)
* Update BRCM KNET module to support new psample definitions from sflow dropmon feature * Update BRCM KNET module to support new psample definitions from sflow dropmon feature * Advance saibcm-modules-dnx
This commit is contained in:
parent
6f9f765f1e
commit
055b7d5fad
@ -1 +1 @@
|
|||||||
Subproject commit 8771baa40be8392c2cf662648fc166929efa4b64
|
Subproject commit 65bce4ea8315a7cd0875b3ea2f5c35423f32f868
|
@ -45,17 +45,14 @@ function create_devices()
|
|||||||
function load_kernel_modules()
|
function load_kernel_modules()
|
||||||
{
|
{
|
||||||
if [[ $is_ltsw_chip -eq 1 ]]; then
|
if [[ $is_ltsw_chip -eq 1 ]]; then
|
||||||
insmod /lib/modules/$(uname -r)/extra/psample.ko
|
modprobe psample
|
||||||
modprobe linux_ngbde
|
modprobe linux_ngbde
|
||||||
modprobe linux_ngknet
|
modprobe linux_ngknet
|
||||||
modprobe linux_ngknetcb
|
modprobe linux_ngknetcb
|
||||||
else
|
else
|
||||||
modprobe linux-kernel-bde dmasize=$dmasize maxpayload=128 debug=4 dma_debug=1 usemsi=$usemsi
|
modprobe linux-kernel-bde dmasize=$dmasize maxpayload=128 debug=4 dma_debug=1 usemsi=$usemsi
|
||||||
modprobe linux-user-bde
|
modprobe linux-user-bde
|
||||||
|
modprobe psample
|
||||||
# Using insmod with absolute path for psample to make sure bcm psample is loaded.
|
|
||||||
# There is a different psample.ko module getting created at net/psample/psample.ko
|
|
||||||
insmod /lib/modules/$(uname -r)/extra/psample.ko
|
|
||||||
|
|
||||||
modprobe linux-bcm-knet use_rx_skb=1 rx_buffer_size=9238 debug=0x5020 default_mtu=9100
|
modprobe linux-bcm-knet use_rx_skb=1 rx_buffer_size=9238 debug=0x5020 default_mtu=9100
|
||||||
modprobe linux-knet-cb
|
modprobe linux-knet-cb
|
||||||
@ -69,9 +66,9 @@ function remove_kernel_modules()
|
|||||||
rmmod linux_ngknetcb
|
rmmod linux_ngknetcb
|
||||||
rmmod linux_ngknet
|
rmmod linux_ngknet
|
||||||
rmmod linux_ngbde
|
rmmod linux_ngbde
|
||||||
rmmod psample.ko
|
rmmod psample
|
||||||
else
|
else
|
||||||
rmmod psample.ko
|
rmmod psample
|
||||||
rmmod linux-knet-cb
|
rmmod linux-knet-cb
|
||||||
rmmod linux-bcm-knet
|
rmmod linux-bcm-knet
|
||||||
rmmod linux-user-bde
|
rmmod linux-user-bde
|
||||||
|
@ -44,12 +44,7 @@ export CROSS_COMPILE
|
|||||||
|
|
||||||
override SDK := $(CURDIR)
|
override SDK := $(CURDIR)
|
||||||
|
|
||||||
ifeq ($(BUILD_PSAMPLE),1)
|
kmod: bde knet knetcb
|
||||||
PSAMPLE=psample
|
|
||||||
PSAMPLE_SYMVERS=$(SDK)/linux/psample/Module.symvers
|
|
||||||
endif
|
|
||||||
|
|
||||||
kmod: bde knet knetcb $(PSAMPLE)
|
|
||||||
|
|
||||||
bde:
|
bde:
|
||||||
$(MAKE) -C $(SDK)/linux/bde SDK=$(SDK) \
|
$(MAKE) -C $(SDK)/linux/bde SDK=$(SDK) \
|
||||||
@ -62,20 +57,12 @@ knet: bde
|
|||||||
$(TARGET)
|
$(TARGET)
|
||||||
ln -sf $(SDK)/linux/knet/*.ko
|
ln -sf $(SDK)/linux/knet/*.ko
|
||||||
|
|
||||||
knetcb: knet $(PSAMPLE)
|
knetcb: knet
|
||||||
$(MAKE) -C $(SDK)/linux/knetcb SDK=$(SDK) \
|
$(MAKE) -C $(SDK)/linux/knetcb SDK=$(SDK) \
|
||||||
KBUILD_EXTRA_SYMBOLS=$(SDK)/linux/knet/Module.symvers \
|
KBUILD_EXTRA_SYMBOLS=$(SDK)/linux/knet/Module.symvers \
|
||||||
KBUILD_EXTRA_SYMBOLS+=$(PSAMPLE_SYMVERS) \
|
|
||||||
$(TARGET)
|
$(TARGET)
|
||||||
ln -sf $(SDK)/linux/knetcb/*.ko
|
ln -sf $(SDK)/linux/knetcb/*.ko
|
||||||
|
|
||||||
ifeq ($(BUILD_PSAMPLE),1)
|
|
||||||
$(PSAMPLE):
|
|
||||||
$(MAKE) -C $(SDK)/linux/psample SDK=$(SDK) \
|
|
||||||
$(TARGET)
|
|
||||||
ln -sf $(SDK)/linux/psample/*.ko
|
|
||||||
endif
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(MAKE) kmod TARGET=clean
|
$(MAKE) kmod TARGET=clean
|
||||||
rm -f *.ko
|
rm -f *.ko
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
#ifndef __NET_PSAMPLE_H
|
|
||||||
#define __NET_PSAMPLE_H
|
|
||||||
|
|
||||||
#include <lkm/lkm.h>
|
|
||||||
#include <uapi/linux/psample.h>
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/list.h>
|
|
||||||
|
|
||||||
struct psample_group {
|
|
||||||
struct list_head list;
|
|
||||||
struct net *net;
|
|
||||||
u32 group_num;
|
|
||||||
u32 refcount;
|
|
||||||
u32 seq;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern struct psample_group *psample_group_get(struct net *net, u32 group_num);
|
|
||||||
extern void psample_group_put(struct psample_group *group);
|
|
||||||
|
|
||||||
extern void psample_sample_packet(struct psample_group *group, struct sk_buff *skb,
|
|
||||||
u32 trunc_size, int in_ifindex, int out_ifindex,
|
|
||||||
u32 sample_rate);
|
|
||||||
|
|
||||||
#endif /* __NET_PSAMPLE_H */
|
|
@ -1,35 +0,0 @@
|
|||||||
#ifndef __UAPI_PSAMPLE_H
|
|
||||||
#define __UAPI_PSAMPLE_H
|
|
||||||
|
|
||||||
enum {
|
|
||||||
/* sampled packet metadata */
|
|
||||||
PSAMPLE_ATTR_IIFINDEX,
|
|
||||||
PSAMPLE_ATTR_OIFINDEX,
|
|
||||||
PSAMPLE_ATTR_ORIGSIZE,
|
|
||||||
PSAMPLE_ATTR_SAMPLE_GROUP,
|
|
||||||
PSAMPLE_ATTR_GROUP_SEQ,
|
|
||||||
PSAMPLE_ATTR_SAMPLE_RATE,
|
|
||||||
PSAMPLE_ATTR_DATA,
|
|
||||||
|
|
||||||
/* commands attributes */
|
|
||||||
PSAMPLE_ATTR_GROUP_REFCOUNT,
|
|
||||||
|
|
||||||
__PSAMPLE_ATTR_MAX
|
|
||||||
};
|
|
||||||
|
|
||||||
enum psample_command {
|
|
||||||
PSAMPLE_CMD_SAMPLE,
|
|
||||||
PSAMPLE_CMD_GET_GROUP,
|
|
||||||
PSAMPLE_CMD_NEW_GROUP,
|
|
||||||
PSAMPLE_CMD_DEL_GROUP,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Can be overridden at runtime by module option */
|
|
||||||
#define PSAMPLE_ATTR_MAX (__PSAMPLE_ATTR_MAX - 1)
|
|
||||||
|
|
||||||
#define PSAMPLE_NL_MCGRP_CONFIG_NAME "config"
|
|
||||||
#define PSAMPLE_NL_MCGRP_SAMPLE_NAME "packets"
|
|
||||||
#define PSAMPLE_GENL_NAME "psample"
|
|
||||||
#define PSAMPLE_GENL_VERSION 1
|
|
||||||
|
|
||||||
#endif
|
|
@ -251,6 +251,7 @@ psample_task(struct work_struct *work)
|
|||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
struct list_head *list_ptr, *list_next;
|
struct list_head *list_ptr, *list_next;
|
||||||
psample_pkt_t *pkt;
|
psample_pkt_t *pkt;
|
||||||
|
struct psample_metadata md = {0};
|
||||||
|
|
||||||
spin_lock_irqsave(&psample_work->lock, flags);
|
spin_lock_irqsave(&psample_work->lock, flags);
|
||||||
list_for_each_safe(list_ptr, list_next, &psample_work->pkt_list) {
|
list_for_each_safe(list_ptr, list_next, &psample_work->pkt_list) {
|
||||||
@ -267,12 +268,13 @@ psample_task(struct work_struct *work)
|
|||||||
pkt->meta.trunc_size, pkt->meta.src_ifindex,
|
pkt->meta.trunc_size, pkt->meta.src_ifindex,
|
||||||
pkt->meta.dst_ifindex, pkt->meta.sample_rate);
|
pkt->meta.dst_ifindex, pkt->meta.sample_rate);
|
||||||
|
|
||||||
|
md.trunc_size = pkt->meta.trunc_size;
|
||||||
|
md.in_ifindex = pkt->meta.src_ifindex;
|
||||||
|
md.out_ifindex = pkt->meta.dst_ifindex;
|
||||||
psample_sample_packet(pkt->group,
|
psample_sample_packet(pkt->group,
|
||||||
pkt->skb,
|
pkt->skb,
|
||||||
pkt->meta.trunc_size,
|
pkt->meta.sample_rate,
|
||||||
pkt->meta.src_ifindex,
|
&md);
|
||||||
pkt->meta.dst_ifindex,
|
|
||||||
pkt->meta.sample_rate);
|
|
||||||
g_psample_stats.pkts_f_psample_mod++;
|
g_psample_stats.pkts_f_psample_mod++;
|
||||||
|
|
||||||
dev_kfree_skb_any(pkt->skb);
|
dev_kfree_skb_any(pkt->skb);
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
# -*- Kbuild -*-
|
|
||||||
#
|
|
||||||
# Linux psample module.
|
|
||||||
#
|
|
||||||
# $Copyright: (c) 2020 Broadcom.
|
|
||||||
# Broadcom Proprietary and Confidential. All rights reserved.$
|
|
||||||
#
|
|
||||||
|
|
||||||
obj-m := linux_psample.o
|
|
||||||
|
|
||||||
ccflags-y := $(LKM_CFLAGS) \
|
|
||||||
-I$(SDK)/shr/include \
|
|
||||||
-I$(SDK)/bcmdrd/include \
|
|
||||||
-I$(SDK)/linux/include \
|
|
||||||
-I$(SDK)/linux/knet/include \
|
|
||||||
-I$(SDK)/linux/knet
|
|
||||||
|
|
||||||
linux_psample-y := psample.o
|
|
@ -1,21 +0,0 @@
|
|||||||
# -*- Makefile -*-
|
|
||||||
#
|
|
||||||
# Linux psample module.
|
|
||||||
#
|
|
||||||
# $Copyright: (c) 2020 Broadcom.
|
|
||||||
# Broadcom Proprietary and Confidential. All rights reserved.$
|
|
||||||
#
|
|
||||||
|
|
||||||
include Kbuild
|
|
||||||
|
|
||||||
ifeq ($(KERNELRELEASE),)
|
|
||||||
|
|
||||||
MOD_NAME = linux_psample
|
|
||||||
|
|
||||||
include $(SDK)/make/lkm.mk
|
|
||||||
|
|
||||||
endif
|
|
||||||
|
|
||||||
.PHONY: distclean
|
|
||||||
|
|
||||||
distclean:
|
|
@ -1,302 +0,0 @@
|
|||||||
/*
|
|
||||||
* net/psample/psample.c - Netlink channel for packet sampling
|
|
||||||
* Copyright (c) 2017 Yotam Gigi <yotamg@mellanox.com>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <lkm/lkm.h>
|
|
||||||
#include <linux/types.h>
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/skbuff.h>
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <net/net_namespace.h>
|
|
||||||
#include <net/sock.h>
|
|
||||||
#include <net/netlink.h>
|
|
||||||
#include <net/genetlink.h>
|
|
||||||
#include <net/psample.h>
|
|
||||||
#include <linux/spinlock.h>
|
|
||||||
|
|
||||||
#define PSAMPLE_MAX_PACKET_SIZE 0xffff
|
|
||||||
|
|
||||||
static LIST_HEAD(psample_groups_list);
|
|
||||||
static DEFINE_SPINLOCK(psample_groups_lock);
|
|
||||||
|
|
||||||
/* multicast groups */
|
|
||||||
enum psample_nl_multicast_groups {
|
|
||||||
PSAMPLE_NL_MCGRP_CONFIG,
|
|
||||||
PSAMPLE_NL_MCGRP_SAMPLE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct genl_multicast_group psample_nl_mcgrps[] = {
|
|
||||||
[PSAMPLE_NL_MCGRP_CONFIG] = { .name = PSAMPLE_NL_MCGRP_CONFIG_NAME },
|
|
||||||
[PSAMPLE_NL_MCGRP_SAMPLE] = { .name = PSAMPLE_NL_MCGRP_SAMPLE_NAME },
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct genl_family psample_nl_family;
|
|
||||||
|
|
||||||
static int psample_group_nl_fill(struct sk_buff *msg,
|
|
||||||
struct psample_group *group,
|
|
||||||
enum psample_command cmd, u32 portid, u32 seq,
|
|
||||||
int flags)
|
|
||||||
{
|
|
||||||
void *hdr;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
hdr = genlmsg_put(msg, portid, seq, &psample_nl_family, flags, cmd);
|
|
||||||
if (!hdr)
|
|
||||||
return -EMSGSIZE;
|
|
||||||
|
|
||||||
ret = nla_put_u32(msg, PSAMPLE_ATTR_SAMPLE_GROUP, group->group_num);
|
|
||||||
if (ret < 0)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
ret = nla_put_u32(msg, PSAMPLE_ATTR_GROUP_REFCOUNT, group->refcount);
|
|
||||||
if (ret < 0)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
ret = nla_put_u32(msg, PSAMPLE_ATTR_GROUP_SEQ, group->seq);
|
|
||||||
if (ret < 0)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
genlmsg_end(msg, hdr);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
error:
|
|
||||||
genlmsg_cancel(msg, hdr);
|
|
||||||
return -EMSGSIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int psample_nl_cmd_get_group_dumpit(struct sk_buff *msg,
|
|
||||||
struct netlink_callback *cb)
|
|
||||||
{
|
|
||||||
struct psample_group *group;
|
|
||||||
int start = cb->args[0];
|
|
||||||
int idx = 0;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
spin_lock(&psample_groups_lock);
|
|
||||||
list_for_each_entry(group, &psample_groups_list, list) {
|
|
||||||
if (!net_eq(group->net, sock_net(msg->sk)))
|
|
||||||
continue;
|
|
||||||
if (idx < start) {
|
|
||||||
idx++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
err = psample_group_nl_fill(msg, group, PSAMPLE_CMD_NEW_GROUP,
|
|
||||||
NETLINK_CB(cb->skb).portid,
|
|
||||||
cb->nlh->nlmsg_seq, NLM_F_MULTI);
|
|
||||||
if (err)
|
|
||||||
break;
|
|
||||||
idx++;
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_unlock(&psample_groups_lock);
|
|
||||||
cb->args[0] = idx;
|
|
||||||
return msg->len;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct genl_ops psample_nl_ops[] = {
|
|
||||||
{
|
|
||||||
.cmd = PSAMPLE_CMD_GET_GROUP,
|
|
||||||
.dumpit = psample_nl_cmd_get_group_dumpit,
|
|
||||||
/* can be retrieved by unprivileged users */
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct genl_family psample_nl_family = {
|
|
||||||
.name = PSAMPLE_GENL_NAME,
|
|
||||||
.version = PSAMPLE_GENL_VERSION,
|
|
||||||
.maxattr = PSAMPLE_ATTR_MAX,
|
|
||||||
.netnsok = true,
|
|
||||||
.module = THIS_MODULE,
|
|
||||||
.mcgrps = psample_nl_mcgrps,
|
|
||||||
.ops = psample_nl_ops,
|
|
||||||
.n_ops = ARRAY_SIZE(psample_nl_ops),
|
|
||||||
.n_mcgrps = ARRAY_SIZE(psample_nl_mcgrps),
|
|
||||||
};
|
|
||||||
|
|
||||||
static void psample_group_notify(struct psample_group *group,
|
|
||||||
enum psample_command cmd)
|
|
||||||
{
|
|
||||||
struct sk_buff *msg;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
|
|
||||||
if (!msg)
|
|
||||||
return;
|
|
||||||
|
|
||||||
err = psample_group_nl_fill(msg, group, cmd, 0, 0, NLM_F_MULTI);
|
|
||||||
if (!err)
|
|
||||||
genlmsg_multicast_netns(&psample_nl_family, group->net, msg, 0,
|
|
||||||
PSAMPLE_NL_MCGRP_CONFIG, GFP_ATOMIC);
|
|
||||||
else
|
|
||||||
nlmsg_free(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct psample_group *psample_group_create(struct net *net,
|
|
||||||
u32 group_num)
|
|
||||||
{
|
|
||||||
struct psample_group *group;
|
|
||||||
|
|
||||||
group = kzalloc(sizeof(*group), GFP_ATOMIC);
|
|
||||||
if (!group)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
group->net = net;
|
|
||||||
group->group_num = group_num;
|
|
||||||
list_add_tail(&group->list, &psample_groups_list);
|
|
||||||
|
|
||||||
psample_group_notify(group, PSAMPLE_CMD_NEW_GROUP);
|
|
||||||
return group;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void psample_group_destroy(struct psample_group *group)
|
|
||||||
{
|
|
||||||
psample_group_notify(group, PSAMPLE_CMD_DEL_GROUP);
|
|
||||||
list_del(&group->list);
|
|
||||||
kfree(group);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct psample_group *
|
|
||||||
psample_group_lookup(struct net *net, u32 group_num)
|
|
||||||
{
|
|
||||||
struct psample_group *group;
|
|
||||||
|
|
||||||
list_for_each_entry(group, &psample_groups_list, list)
|
|
||||||
if ((group->group_num == group_num) && (group->net == net))
|
|
||||||
return group;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct psample_group *psample_group_get(struct net *net, u32 group_num)
|
|
||||||
{
|
|
||||||
struct psample_group *group;
|
|
||||||
|
|
||||||
spin_lock(&psample_groups_lock);
|
|
||||||
|
|
||||||
group = psample_group_lookup(net, group_num);
|
|
||||||
if (!group) {
|
|
||||||
group = psample_group_create(net, group_num);
|
|
||||||
if (!group)
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
group->refcount++;
|
|
||||||
|
|
||||||
out:
|
|
||||||
spin_unlock(&psample_groups_lock);
|
|
||||||
return group;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(psample_group_get);
|
|
||||||
|
|
||||||
void psample_group_put(struct psample_group *group)
|
|
||||||
{
|
|
||||||
spin_lock(&psample_groups_lock);
|
|
||||||
|
|
||||||
if (--group->refcount == 0)
|
|
||||||
psample_group_destroy(group);
|
|
||||||
|
|
||||||
spin_unlock(&psample_groups_lock);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(psample_group_put);
|
|
||||||
|
|
||||||
void psample_sample_packet(struct psample_group *group, struct sk_buff *skb,
|
|
||||||
u32 trunc_size, int in_ifindex, int out_ifindex,
|
|
||||||
u32 sample_rate)
|
|
||||||
{
|
|
||||||
struct sk_buff *nl_skb;
|
|
||||||
int data_len;
|
|
||||||
int meta_len;
|
|
||||||
void *data;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
meta_len = (in_ifindex ? nla_total_size(sizeof(u16)) : 0) +
|
|
||||||
(out_ifindex ? nla_total_size(sizeof(u16)) : 0) +
|
|
||||||
nla_total_size(sizeof(u32)) + /* sample_rate */
|
|
||||||
nla_total_size(sizeof(u32)) + /* orig_size */
|
|
||||||
nla_total_size(sizeof(u32)) + /* group_num */
|
|
||||||
nla_total_size(sizeof(u32)); /* seq */
|
|
||||||
|
|
||||||
data_len = min(skb->len, trunc_size);
|
|
||||||
if (meta_len + nla_total_size(data_len) > PSAMPLE_MAX_PACKET_SIZE)
|
|
||||||
data_len = PSAMPLE_MAX_PACKET_SIZE - meta_len - NLA_HDRLEN
|
|
||||||
- NLA_ALIGNTO;
|
|
||||||
|
|
||||||
nl_skb = genlmsg_new(meta_len + nla_total_size(data_len), GFP_ATOMIC);
|
|
||||||
if (unlikely(!nl_skb))
|
|
||||||
return;
|
|
||||||
|
|
||||||
data = genlmsg_put(nl_skb, 0, 0, &psample_nl_family, 0,
|
|
||||||
PSAMPLE_CMD_SAMPLE);
|
|
||||||
if (unlikely(!data))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (in_ifindex) {
|
|
||||||
ret = nla_put_u16(nl_skb, PSAMPLE_ATTR_IIFINDEX, in_ifindex);
|
|
||||||
if (unlikely(ret < 0))
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (out_ifindex) {
|
|
||||||
ret = nla_put_u16(nl_skb, PSAMPLE_ATTR_OIFINDEX, out_ifindex);
|
|
||||||
if (unlikely(ret < 0))
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_SAMPLE_RATE, sample_rate);
|
|
||||||
if (unlikely(ret < 0))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_ORIGSIZE, skb->len);
|
|
||||||
if (unlikely(ret < 0))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_SAMPLE_GROUP, group->group_num);
|
|
||||||
if (unlikely(ret < 0))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_GROUP_SEQ, group->seq++);
|
|
||||||
if (unlikely(ret < 0))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (data_len) {
|
|
||||||
int nla_len = nla_total_size(data_len);
|
|
||||||
struct nlattr *nla;
|
|
||||||
|
|
||||||
nla = (struct nlattr *)skb_put(nl_skb, nla_len);
|
|
||||||
nla->nla_type = PSAMPLE_ATTR_DATA;
|
|
||||||
nla->nla_len = nla_attr_size(data_len);
|
|
||||||
|
|
||||||
if (skb_copy_bits(skb, 0, nla_data(nla), data_len))
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
genlmsg_end(nl_skb, data);
|
|
||||||
genlmsg_multicast_netns(&psample_nl_family, group->net, nl_skb, 0,
|
|
||||||
PSAMPLE_NL_MCGRP_SAMPLE, GFP_ATOMIC);
|
|
||||||
|
|
||||||
return;
|
|
||||||
error:
|
|
||||||
pr_err_ratelimited("Could not create psample log message\n");
|
|
||||||
nlmsg_free(nl_skb);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(psample_sample_packet);
|
|
||||||
|
|
||||||
static int __init psample_module_init(void)
|
|
||||||
{
|
|
||||||
return genl_register_family(&psample_nl_family);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __exit psample_module_exit(void)
|
|
||||||
{
|
|
||||||
genl_unregister_family(&psample_nl_family);
|
|
||||||
}
|
|
||||||
|
|
||||||
module_init(psample_module_init);
|
|
||||||
module_exit(psample_module_exit);
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Yotam Gigi <yotamg@mellanox.com>");
|
|
||||||
MODULE_DESCRIPTION("netlink channel for packet sampling");
|
|
||||||
MODULE_LICENSE("GPL v2");
|
|
@ -1,24 +0,0 @@
|
|||||||
#ifndef __NET_PSAMPLE_H
|
|
||||||
#define __NET_PSAMPLE_H
|
|
||||||
|
|
||||||
#include <gmodule.h>
|
|
||||||
#include <uapi/linux/psample.h>
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/list.h>
|
|
||||||
|
|
||||||
struct psample_group {
|
|
||||||
struct list_head list;
|
|
||||||
struct net *net;
|
|
||||||
u32 group_num;
|
|
||||||
u32 refcount;
|
|
||||||
u32 seq;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern struct psample_group *psample_group_get(struct net *net, u32 group_num);
|
|
||||||
extern void psample_group_put(struct psample_group *group);
|
|
||||||
|
|
||||||
extern void psample_sample_packet(struct psample_group *group, struct sk_buff *skb,
|
|
||||||
u32 trunc_size, int in_ifindex, int out_ifindex,
|
|
||||||
u32 sample_rate);
|
|
||||||
|
|
||||||
#endif /* __NET_PSAMPLE_H */
|
|
@ -1,35 +0,0 @@
|
|||||||
#ifndef __UAPI_PSAMPLE_H
|
|
||||||
#define __UAPI_PSAMPLE_H
|
|
||||||
|
|
||||||
enum {
|
|
||||||
/* sampled packet metadata */
|
|
||||||
PSAMPLE_ATTR_IIFINDEX,
|
|
||||||
PSAMPLE_ATTR_OIFINDEX,
|
|
||||||
PSAMPLE_ATTR_ORIGSIZE,
|
|
||||||
PSAMPLE_ATTR_SAMPLE_GROUP,
|
|
||||||
PSAMPLE_ATTR_GROUP_SEQ,
|
|
||||||
PSAMPLE_ATTR_SAMPLE_RATE,
|
|
||||||
PSAMPLE_ATTR_DATA,
|
|
||||||
|
|
||||||
/* commands attributes */
|
|
||||||
PSAMPLE_ATTR_GROUP_REFCOUNT,
|
|
||||||
|
|
||||||
__PSAMPLE_ATTR_MAX
|
|
||||||
};
|
|
||||||
|
|
||||||
enum psample_command {
|
|
||||||
PSAMPLE_CMD_SAMPLE,
|
|
||||||
PSAMPLE_CMD_GET_GROUP,
|
|
||||||
PSAMPLE_CMD_NEW_GROUP,
|
|
||||||
PSAMPLE_CMD_DEL_GROUP,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Can be overridden at runtime by module option */
|
|
||||||
#define PSAMPLE_ATTR_MAX (__PSAMPLE_ATTR_MAX - 1)
|
|
||||||
|
|
||||||
#define PSAMPLE_NL_MCGRP_CONFIG_NAME "config"
|
|
||||||
#define PSAMPLE_NL_MCGRP_SAMPLE_NAME "packets"
|
|
||||||
#define PSAMPLE_GENL_NAME "psample"
|
|
||||||
#define PSAMPLE_GENL_VERSION 1
|
|
||||||
|
|
||||||
#endif
|
|
@ -48,9 +48,6 @@ build: $(MODULE) $(KMODULE)
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
KBUILD_EXTRA_SYMBOLS := ${BLDDIR}/../bcm-knet/kernel_module/Module.symvers
|
KBUILD_EXTRA_SYMBOLS := ${BLDDIR}/../bcm-knet/kernel_module/Module.symvers
|
||||||
ifeq ($(BUILD_PSAMPLE),1)
|
|
||||||
KBUILD_EXTRA_SYMBOLS += ${BLDDIR}/../psample/kernel_module/Module.symvers
|
|
||||||
endif
|
|
||||||
|
|
||||||
# BCM Network Device
|
# BCM Network Device
|
||||||
|
|
||||||
@ -61,9 +58,6 @@ $(KMODULE): $(MODULE)
|
|||||||
rm -fr $(BLDDIR)/$(KERNEL_MODULE_DIR)
|
rm -fr $(BLDDIR)/$(KERNEL_MODULE_DIR)
|
||||||
mkdir $(BLDDIR)/$(KERNEL_MODULE_DIR)
|
mkdir $(BLDDIR)/$(KERNEL_MODULE_DIR)
|
||||||
cp ${SDK}/make/Makefile.linux-kmodule $(BLDDIR)/$(KERNEL_MODULE_DIR)/Makefile
|
cp ${SDK}/make/Makefile.linux-kmodule $(BLDDIR)/$(KERNEL_MODULE_DIR)/Makefile
|
||||||
ifeq ($(BUILD_PSAMPLE),1)
|
|
||||||
sed -i 's/0x......../0x00000000/' ${BLDDIR}/../psample/kernel_module/Module.symvers
|
|
||||||
endif
|
|
||||||
cat ${KBUILD_EXTRA_SYMBOLS} > $(BLDDIR)/$(KERNEL_MODULE_DIR)/Module.symvers
|
cat ${KBUILD_EXTRA_SYMBOLS} > $(BLDDIR)/$(KERNEL_MODULE_DIR)/Module.symvers
|
||||||
MOD_NAME=$(THIS_MOD_NAME) KBUILD_EXTRA_SYMBOLS="${KBUILD_EXTRA_SYMBOLS}" $(MAKE) -C $(BLDDIR)/$(KERNEL_MODULE_DIR) $(THIS_MOD_NAME).ko
|
MOD_NAME=$(THIS_MOD_NAME) KBUILD_EXTRA_SYMBOLS="${KBUILD_EXTRA_SYMBOLS}" $(MAKE) -C $(BLDDIR)/$(KERNEL_MODULE_DIR) $(THIS_MOD_NAME).ko
|
||||||
endif
|
endif
|
||||||
|
@ -394,6 +394,7 @@ psample_task(struct work_struct *work)
|
|||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
struct list_head *list_ptr, *list_next;
|
struct list_head *list_ptr, *list_next;
|
||||||
psample_pkt_t *pkt;
|
psample_pkt_t *pkt;
|
||||||
|
struct psample_metadata md = {0};
|
||||||
|
|
||||||
spin_lock_irqsave(&psample_work->lock, flags);
|
spin_lock_irqsave(&psample_work->lock, flags);
|
||||||
list_for_each_safe(list_ptr, list_next, &psample_work->pkt_list) {
|
list_for_each_safe(list_ptr, list_next, &psample_work->pkt_list) {
|
||||||
@ -410,12 +411,13 @@ psample_task(struct work_struct *work)
|
|||||||
pkt->meta.trunc_size, pkt->meta.src_ifindex,
|
pkt->meta.trunc_size, pkt->meta.src_ifindex,
|
||||||
pkt->meta.dst_ifindex, pkt->meta.sample_rate);
|
pkt->meta.dst_ifindex, pkt->meta.sample_rate);
|
||||||
|
|
||||||
|
md.trunc_size = pkt->meta.trunc_size;
|
||||||
|
md.in_ifindex = pkt->meta.src_ifindex;
|
||||||
|
md.out_ifindex = pkt->meta.dst_ifindex;
|
||||||
psample_sample_packet(pkt->group,
|
psample_sample_packet(pkt->group,
|
||||||
pkt->skb,
|
pkt->skb,
|
||||||
pkt->meta.trunc_size,
|
pkt->meta.sample_rate,
|
||||||
pkt->meta.src_ifindex,
|
&md);
|
||||||
pkt->meta.dst_ifindex,
|
|
||||||
pkt->meta.sample_rate);
|
|
||||||
g_psample_stats.pkts_f_psample_mod++;
|
g_psample_stats.pkts_f_psample_mod++;
|
||||||
|
|
||||||
dev_kfree_skb_any(pkt->skb);
|
dev_kfree_skb_any(pkt->skb);
|
||||||
|
@ -1,64 +0,0 @@
|
|||||||
#
|
|
||||||
# Copyright 2017 Broadcom
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License, version 2, as
|
|
||||||
# published by the Free Software Foundation (the "GPL").
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
# General Public License version 2 (GPLv2) for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# version 2 (GPLv2) along with this source code.
|
|
||||||
#
|
|
||||||
# -*- Makefile -*-
|
|
||||||
# $Id: Makefile,v 1.3 Broadcom SDK $
|
|
||||||
# $Copyright: (c) 2005 Broadcom Corp.
|
|
||||||
# All Rights Reserved.$
|
|
||||||
#
|
|
||||||
LOCALDIR = systems/linux/kernel/modules/psample
|
|
||||||
|
|
||||||
include ${SDK}/make/Make.config
|
|
||||||
|
|
||||||
LIBS = $(LIBDIR)/libkern.a
|
|
||||||
|
|
||||||
ifeq ($(kernel_version),2_4)
|
|
||||||
MODULE = $(LIBDIR)/psample.o
|
|
||||||
else
|
|
||||||
KERNEL_MODULE_DIR = kernel_module
|
|
||||||
|
|
||||||
THIS_MOD_NAME := psample
|
|
||||||
MODULE = $(LIBDIR)/$(THIS_MOD_NAME).o
|
|
||||||
KMODULE = $(LIBDIR)/$(THIS_MOD_NAME).ko
|
|
||||||
|
|
||||||
build: $(MODULE) $(KMODULE)
|
|
||||||
endif
|
|
||||||
|
|
||||||
KBUILD_EXTRA_SYMBOLS := ${BLDDIR}/../bcm-knet/kernel_module/Module.symvers
|
|
||||||
|
|
||||||
# BCM Network Device
|
|
||||||
|
|
||||||
$(MODULE): $(BLDDIR)/.tree $(BOBJS) $(LIBS)
|
|
||||||
$(LD) $(MODULE_LDFLAGS) -r -d $(BOBJS) $(LIBS) -o $@
|
|
||||||
ifneq ($(kernel_version),2_4)
|
|
||||||
$(KMODULE): $(MODULE)
|
|
||||||
rm -fr $(BLDDIR)/$(KERNEL_MODULE_DIR)
|
|
||||||
mkdir $(BLDDIR)/$(KERNEL_MODULE_DIR)
|
|
||||||
cp ${SDK}/make/Makefile.linux-kmodule $(BLDDIR)/$(KERNEL_MODULE_DIR)/Makefile
|
|
||||||
cat ${KBUILD_EXTRA_SYMBOLS} > $(BLDDIR)/$(KERNEL_MODULE_DIR)/Module.symvers
|
|
||||||
MOD_NAME=$(THIS_MOD_NAME) KBUILD_EXTRA_SYMBOLS="${KBUILD_EXTRA_SYMBOLS}" $(MAKE) -C $(BLDDIR)/$(KERNEL_MODULE_DIR) $(THIS_MOD_NAME).ko
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Make.depend is before clean:: so that Make.depend's clean:: runs first.
|
|
||||||
|
|
||||||
include ${SDK}/make/Make.depend
|
|
||||||
|
|
||||||
clean::
|
|
||||||
$(RM) $(BLDDIR)/version.c $(BLDDIR)/version.o
|
|
||||||
$(RM) $(BOBJS) $(MODULE)
|
|
||||||
|
|
||||||
ifneq ($(kernel_version),2_4)
|
|
||||||
.PHONY: build
|
|
||||||
endif
|
|
@ -1,304 +0,0 @@
|
|||||||
/*
|
|
||||||
* net/psample/psample.c - Netlink channel for packet sampling
|
|
||||||
* Copyright (c) 2017 Yotam Gigi <yotamg@mellanox.com>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <gmodule.h>
|
|
||||||
#include <linux/types.h>
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/skbuff.h>
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <net/net_namespace.h>
|
|
||||||
#include <net/sock.h>
|
|
||||||
#include <net/netlink.h>
|
|
||||||
#include <net/genetlink.h>
|
|
||||||
#include <net/psample.h>
|
|
||||||
#include <linux/spinlock.h>
|
|
||||||
|
|
||||||
#define PSAMPLE_MAX_PACKET_SIZE 0xffff
|
|
||||||
|
|
||||||
static LIST_HEAD(psample_groups_list);
|
|
||||||
static DEFINE_SPINLOCK(psample_groups_lock);
|
|
||||||
|
|
||||||
/* multicast groups */
|
|
||||||
enum psample_nl_multicast_groups {
|
|
||||||
PSAMPLE_NL_MCGRP_CONFIG,
|
|
||||||
PSAMPLE_NL_MCGRP_SAMPLE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct genl_multicast_group psample_nl_mcgrps[] = {
|
|
||||||
[PSAMPLE_NL_MCGRP_CONFIG] = { .name = PSAMPLE_NL_MCGRP_CONFIG_NAME },
|
|
||||||
[PSAMPLE_NL_MCGRP_SAMPLE] = { .name = PSAMPLE_NL_MCGRP_SAMPLE_NAME },
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct genl_family psample_nl_family;
|
|
||||||
|
|
||||||
static int psample_group_nl_fill(struct sk_buff *msg,
|
|
||||||
struct psample_group *group,
|
|
||||||
enum psample_command cmd, u32 portid, u32 seq,
|
|
||||||
int flags)
|
|
||||||
{
|
|
||||||
void *hdr;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
hdr = genlmsg_put(msg, portid, seq, &psample_nl_family, flags, cmd);
|
|
||||||
if (!hdr)
|
|
||||||
return -EMSGSIZE;
|
|
||||||
|
|
||||||
ret = nla_put_u32(msg, PSAMPLE_ATTR_SAMPLE_GROUP, group->group_num);
|
|
||||||
if (ret < 0)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
ret = nla_put_u32(msg, PSAMPLE_ATTR_GROUP_REFCOUNT, group->refcount);
|
|
||||||
if (ret < 0)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
ret = nla_put_u32(msg, PSAMPLE_ATTR_GROUP_SEQ, group->seq);
|
|
||||||
if (ret < 0)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
genlmsg_end(msg, hdr);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
error:
|
|
||||||
genlmsg_cancel(msg, hdr);
|
|
||||||
return -EMSGSIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int psample_nl_cmd_get_group_dumpit(struct sk_buff *msg,
|
|
||||||
struct netlink_callback *cb)
|
|
||||||
{
|
|
||||||
struct psample_group *group;
|
|
||||||
int start = cb->args[0];
|
|
||||||
int idx = 0;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
spin_lock(&psample_groups_lock);
|
|
||||||
list_for_each_entry(group, &psample_groups_list, list) {
|
|
||||||
if (!net_eq(group->net, sock_net(msg->sk)))
|
|
||||||
continue;
|
|
||||||
if (idx < start) {
|
|
||||||
idx++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
err = psample_group_nl_fill(msg, group, PSAMPLE_CMD_NEW_GROUP,
|
|
||||||
NETLINK_CB(cb->skb).portid,
|
|
||||||
cb->nlh->nlmsg_seq, NLM_F_MULTI);
|
|
||||||
if (err)
|
|
||||||
break;
|
|
||||||
idx++;
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_unlock(&psample_groups_lock);
|
|
||||||
cb->args[0] = idx;
|
|
||||||
return msg->len;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct genl_ops psample_nl_ops[] = {
|
|
||||||
{
|
|
||||||
.cmd = PSAMPLE_CMD_GET_GROUP,
|
|
||||||
.dumpit = psample_nl_cmd_get_group_dumpit,
|
|
||||||
/* can be retrieved by unprivileged users */
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct genl_family psample_nl_family = {
|
|
||||||
.name = PSAMPLE_GENL_NAME,
|
|
||||||
.version = PSAMPLE_GENL_VERSION,
|
|
||||||
.maxattr = PSAMPLE_ATTR_MAX,
|
|
||||||
.netnsok = true,
|
|
||||||
.module = THIS_MODULE,
|
|
||||||
.mcgrps = psample_nl_mcgrps,
|
|
||||||
.ops = psample_nl_ops,
|
|
||||||
.n_ops = ARRAY_SIZE(psample_nl_ops),
|
|
||||||
.n_mcgrps = ARRAY_SIZE(psample_nl_mcgrps),
|
|
||||||
};
|
|
||||||
|
|
||||||
static void psample_group_notify(struct psample_group *group,
|
|
||||||
enum psample_command cmd)
|
|
||||||
{
|
|
||||||
struct sk_buff *msg;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
|
|
||||||
if (!msg)
|
|
||||||
return;
|
|
||||||
|
|
||||||
err = psample_group_nl_fill(msg, group, cmd, 0, 0, NLM_F_MULTI);
|
|
||||||
if (!err)
|
|
||||||
genlmsg_multicast_netns(&psample_nl_family, group->net, msg, 0,
|
|
||||||
PSAMPLE_NL_MCGRP_CONFIG, GFP_ATOMIC);
|
|
||||||
else
|
|
||||||
nlmsg_free(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct psample_group *psample_group_create(struct net *net,
|
|
||||||
u32 group_num)
|
|
||||||
{
|
|
||||||
struct psample_group *group;
|
|
||||||
|
|
||||||
group = kzalloc(sizeof(*group), GFP_ATOMIC);
|
|
||||||
if (!group)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
group->net = net;
|
|
||||||
group->group_num = group_num;
|
|
||||||
list_add_tail(&group->list, &psample_groups_list);
|
|
||||||
|
|
||||||
psample_group_notify(group, PSAMPLE_CMD_NEW_GROUP);
|
|
||||||
return group;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void psample_group_destroy(struct psample_group *group)
|
|
||||||
{
|
|
||||||
psample_group_notify(group, PSAMPLE_CMD_DEL_GROUP);
|
|
||||||
list_del(&group->list);
|
|
||||||
kfree(group);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct psample_group *
|
|
||||||
psample_group_lookup(struct net *net, u32 group_num)
|
|
||||||
{
|
|
||||||
struct psample_group *group;
|
|
||||||
|
|
||||||
list_for_each_entry(group, &psample_groups_list, list)
|
|
||||||
if ((group->group_num == group_num) && (group->net == net))
|
|
||||||
return group;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct psample_group *psample_group_get(struct net *net, u32 group_num)
|
|
||||||
{
|
|
||||||
struct psample_group *group;
|
|
||||||
|
|
||||||
spin_lock(&psample_groups_lock);
|
|
||||||
|
|
||||||
group = psample_group_lookup(net, group_num);
|
|
||||||
if (!group) {
|
|
||||||
group = psample_group_create(net, group_num);
|
|
||||||
if (!group)
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
group->refcount++;
|
|
||||||
|
|
||||||
out:
|
|
||||||
spin_unlock(&psample_groups_lock);
|
|
||||||
return group;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(psample_group_get);
|
|
||||||
|
|
||||||
void psample_group_put(struct psample_group *group)
|
|
||||||
{
|
|
||||||
spin_lock(&psample_groups_lock);
|
|
||||||
|
|
||||||
if (--group->refcount == 0)
|
|
||||||
psample_group_destroy(group);
|
|
||||||
|
|
||||||
spin_unlock(&psample_groups_lock);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(psample_group_put);
|
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_PSAMPLE) /* FIXUP:- Remove after GTS kernel is recompiled with change in CONFIG_PSAMPLE flag */
|
|
||||||
void psample_sample_packet(struct psample_group *group, struct sk_buff *skb,
|
|
||||||
u32 trunc_size, int in_ifindex, int out_ifindex,
|
|
||||||
u32 sample_rate)
|
|
||||||
{
|
|
||||||
struct sk_buff *nl_skb;
|
|
||||||
int data_len;
|
|
||||||
int meta_len;
|
|
||||||
void *data;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
meta_len = (in_ifindex ? nla_total_size(sizeof(u16)) : 0) +
|
|
||||||
(out_ifindex ? nla_total_size(sizeof(u16)) : 0) +
|
|
||||||
nla_total_size(sizeof(u32)) + /* sample_rate */
|
|
||||||
nla_total_size(sizeof(u32)) + /* orig_size */
|
|
||||||
nla_total_size(sizeof(u32)) + /* group_num */
|
|
||||||
nla_total_size(sizeof(u32)); /* seq */
|
|
||||||
|
|
||||||
data_len = min(skb->len, trunc_size);
|
|
||||||
if (meta_len + nla_total_size(data_len) > PSAMPLE_MAX_PACKET_SIZE)
|
|
||||||
data_len = PSAMPLE_MAX_PACKET_SIZE - meta_len - NLA_HDRLEN
|
|
||||||
- NLA_ALIGNTO;
|
|
||||||
|
|
||||||
nl_skb = genlmsg_new(meta_len + nla_total_size(data_len), GFP_ATOMIC);
|
|
||||||
if (unlikely(!nl_skb))
|
|
||||||
return;
|
|
||||||
|
|
||||||
data = genlmsg_put(nl_skb, 0, 0, &psample_nl_family, 0,
|
|
||||||
PSAMPLE_CMD_SAMPLE);
|
|
||||||
if (unlikely(!data))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (in_ifindex) {
|
|
||||||
ret = nla_put_u16(nl_skb, PSAMPLE_ATTR_IIFINDEX, in_ifindex);
|
|
||||||
if (unlikely(ret < 0))
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (out_ifindex) {
|
|
||||||
ret = nla_put_u16(nl_skb, PSAMPLE_ATTR_OIFINDEX, out_ifindex);
|
|
||||||
if (unlikely(ret < 0))
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_SAMPLE_RATE, sample_rate);
|
|
||||||
if (unlikely(ret < 0))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_ORIGSIZE, skb->len);
|
|
||||||
if (unlikely(ret < 0))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_SAMPLE_GROUP, group->group_num);
|
|
||||||
if (unlikely(ret < 0))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_GROUP_SEQ, group->seq++);
|
|
||||||
if (unlikely(ret < 0))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (data_len) {
|
|
||||||
int nla_len = nla_total_size(data_len);
|
|
||||||
struct nlattr *nla;
|
|
||||||
|
|
||||||
nla = (struct nlattr *)skb_put(nl_skb, nla_len);
|
|
||||||
nla->nla_type = PSAMPLE_ATTR_DATA;
|
|
||||||
nla->nla_len = nla_attr_size(data_len);
|
|
||||||
|
|
||||||
if (skb_copy_bits(skb, 0, nla_data(nla), data_len))
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
genlmsg_end(nl_skb, data);
|
|
||||||
genlmsg_multicast_netns(&psample_nl_family, group->net, nl_skb, 0,
|
|
||||||
PSAMPLE_NL_MCGRP_SAMPLE, GFP_ATOMIC);
|
|
||||||
|
|
||||||
return;
|
|
||||||
error:
|
|
||||||
pr_err_ratelimited("Could not create psample log message\n");
|
|
||||||
nlmsg_free(nl_skb);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(psample_sample_packet);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int __init psample_module_init(void)
|
|
||||||
{
|
|
||||||
return genl_register_family(&psample_nl_family);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __exit psample_module_exit(void)
|
|
||||||
{
|
|
||||||
genl_unregister_family(&psample_nl_family);
|
|
||||||
}
|
|
||||||
|
|
||||||
module_init(psample_module_init);
|
|
||||||
module_exit(psample_module_exit);
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Yotam Gigi <yotamg@mellanox.com>");
|
|
||||||
MODULE_DESCRIPTION("netlink channel for packet sampling");
|
|
||||||
MODULE_LICENSE("GPL v2");
|
|
@ -106,9 +106,6 @@ KNET_CB := $(DEST_DIR)/$(KNET_CB_LOCAL)
|
|||||||
BCM_KNET_LOCAL :=linux-bcm-knet.$(KOBJ)
|
BCM_KNET_LOCAL :=linux-bcm-knet.$(KOBJ)
|
||||||
BCM_KNET=$(DEST_DIR)/$(BCM_KNET_LOCAL)
|
BCM_KNET=$(DEST_DIR)/$(BCM_KNET_LOCAL)
|
||||||
|
|
||||||
PSAMPLE_LOCAL := psample.$(KOBJ)
|
|
||||||
PSAMPLE := $(DEST_DIR)/$(PSAMPLE_LOCAL)
|
|
||||||
|
|
||||||
ifeq (,$(findstring DELIVER,$(MAKECMDGOALS)))
|
ifeq (,$(findstring DELIVER,$(MAKECMDGOALS)))
|
||||||
.DEFAULT_GOAL := all
|
.DEFAULT_GOAL := all
|
||||||
all_targets := kernel_modules $(KERNEL_BDE) $(USER_BDE)
|
all_targets := kernel_modules $(KERNEL_BDE) $(USER_BDE)
|
||||||
@ -145,7 +142,6 @@ endif
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ifdef BUILD_PSAMPLE
|
ifdef BUILD_PSAMPLE
|
||||||
all_targets += $(PSAMPLE)
|
|
||||||
ADD_TO_CFLAGS += -DPSAMPLE_SUPPORT
|
ADD_TO_CFLAGS += -DPSAMPLE_SUPPORT
|
||||||
endif
|
endif
|
||||||
ADD_TO_CFLAGS += -I$(SDK)/systems/linux/kernel/modules/include
|
ADD_TO_CFLAGS += -I$(SDK)/systems/linux/kernel/modules/include
|
||||||
@ -178,10 +174,6 @@ kernel_modules:
|
|||||||
ifeq ($(BUILD_KNET),1)
|
ifeq ($(BUILD_KNET),1)
|
||||||
$(MAKE) -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \
|
$(MAKE) -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \
|
||||||
subdirs="shared bcm-knet" override-target=linux-$(platform) CFLAGS="$(CFLAGS)"
|
subdirs="shared bcm-knet" override-target=linux-$(platform) CFLAGS="$(CFLAGS)"
|
||||||
ifdef BUILD_PSAMPLE
|
|
||||||
$(MAKE) -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \
|
|
||||||
subdirs="psample" override-target=linux-$(platform) CFLAGS="$(CFLAGS)"
|
|
||||||
endif
|
|
||||||
ifdef BUILD_KNET_CB
|
ifdef BUILD_KNET_CB
|
||||||
$(MAKE) -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \
|
$(MAKE) -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \
|
||||||
subdirs="knet-cb" override-target=linux-$(platform) CFLAGS="$(CFLAGS)"
|
subdirs="knet-cb" override-target=linux-$(platform) CFLAGS="$(CFLAGS)"
|
||||||
@ -201,11 +193,6 @@ $(BCM_KNET): $(KERN_BLDROOT)/linux-bcm-knet.$(KOBJ)
|
|||||||
$(KNET_CB): $(KERN_BLDROOT)/linux-knet-cb.$(KOBJ)
|
$(KNET_CB): $(KERN_BLDROOT)/linux-knet-cb.$(KOBJ)
|
||||||
$(OBJCOPY) --strip-debug $< $@
|
$(OBJCOPY) --strip-debug $< $@
|
||||||
|
|
||||||
$(PSAMPLE): $(KERN_BLDROOT)/psample.$(KOBJ)
|
|
||||||
$(OBJCOPY) --strip-debug $< $@
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ifeq ($(NO_LOCAL_TARGETS),)
|
ifeq ($(NO_LOCAL_TARGETS),)
|
||||||
$(foreach targ,$(LOCAL_TARGETS),$(eval $(call LOCAL_TARGET_DEF,$(targ))))
|
$(foreach targ,$(LOCAL_TARGETS),$(eval $(call LOCAL_TARGET_DEF,$(targ))))
|
||||||
endif
|
endif
|
||||||
@ -214,7 +201,7 @@ clean::
|
|||||||
$(MAKE) -C $(SDK)/systems/bde/linux/kernel $@
|
$(MAKE) -C $(SDK)/systems/bde/linux/kernel $@
|
||||||
$(MAKE) -C $(SDK)/systems/bde/linux/user/kernel $@
|
$(MAKE) -C $(SDK)/systems/bde/linux/user/kernel $@
|
||||||
$(MAKE) -C $(SDK)/systems/linux/kernel/modules \
|
$(MAKE) -C $(SDK)/systems/linux/kernel/modules \
|
||||||
subdirs="shared bcm-knet knet-cb psample" \
|
subdirs="shared bcm-knet knet-cb" \
|
||||||
override-target=linux-$(platform) $@
|
override-target=linux-$(platform) $@
|
||||||
$(RM) $(KERNEL_BDE) $(USER_BDE)
|
$(RM) $(KERNEL_BDE) $(USER_BDE)
|
||||||
$(RM) $(BCM_KNET) $(KNET_CB) $(PSAMPLE)
|
$(RM) $(BCM_KNET) $(KNET_CB) $(PSAMPLE)
|
||||||
@ -222,7 +209,6 @@ clean::
|
|||||||
$(RM) $(KERN_BLDROOT)/linux-user-bde.$(KOBJ)
|
$(RM) $(KERN_BLDROOT)/linux-user-bde.$(KOBJ)
|
||||||
$(RM) $(KERN_BLDROOT)/linux-bcm-knet.$(KOBJ)
|
$(RM) $(KERN_BLDROOT)/linux-bcm-knet.$(KOBJ)
|
||||||
$(RM) $(KERN_BLDROOT)/linux-knet-cb.$(KOBJ)
|
$(RM) $(KERN_BLDROOT)/linux-knet-cb.$(KOBJ)
|
||||||
$(RM) $(KERN_BLDROOT)/psample.$(KOBJ)
|
|
||||||
$(RM) $(LOCAL_TARGETS)
|
$(RM) $(LOCAL_TARGETS)
|
||||||
|
|
||||||
distclean:: clean
|
distclean:: clean
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit b9083b1a271e63757bef4fcd914ed524bd3c35c9
|
Subproject commit fdd9bac78cfc2bbe932833b38c2191b1d382ed07
|
Loading…
Reference in New Issue
Block a user