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()
|
||||
{
|
||||
if [[ $is_ltsw_chip -eq 1 ]]; then
|
||||
insmod /lib/modules/$(uname -r)/extra/psample.ko
|
||||
modprobe psample
|
||||
modprobe linux_ngbde
|
||||
modprobe linux_ngknet
|
||||
modprobe linux_ngknetcb
|
||||
else
|
||||
modprobe linux-kernel-bde dmasize=$dmasize maxpayload=128 debug=4 dma_debug=1 usemsi=$usemsi
|
||||
modprobe linux-user-bde
|
||||
|
||||
# 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 psample
|
||||
|
||||
modprobe linux-bcm-knet use_rx_skb=1 rx_buffer_size=9238 debug=0x5020 default_mtu=9100
|
||||
modprobe linux-knet-cb
|
||||
@ -69,9 +66,9 @@ function remove_kernel_modules()
|
||||
rmmod linux_ngknetcb
|
||||
rmmod linux_ngknet
|
||||
rmmod linux_ngbde
|
||||
rmmod psample.ko
|
||||
rmmod psample
|
||||
else
|
||||
rmmod psample.ko
|
||||
rmmod psample
|
||||
rmmod linux-knet-cb
|
||||
rmmod linux-bcm-knet
|
||||
rmmod linux-user-bde
|
||||
|
@ -44,12 +44,7 @@ export CROSS_COMPILE
|
||||
|
||||
override SDK := $(CURDIR)
|
||||
|
||||
ifeq ($(BUILD_PSAMPLE),1)
|
||||
PSAMPLE=psample
|
||||
PSAMPLE_SYMVERS=$(SDK)/linux/psample/Module.symvers
|
||||
endif
|
||||
|
||||
kmod: bde knet knetcb $(PSAMPLE)
|
||||
kmod: bde knet knetcb
|
||||
|
||||
bde:
|
||||
$(MAKE) -C $(SDK)/linux/bde SDK=$(SDK) \
|
||||
@ -62,20 +57,12 @@ knet: bde
|
||||
$(TARGET)
|
||||
ln -sf $(SDK)/linux/knet/*.ko
|
||||
|
||||
knetcb: knet $(PSAMPLE)
|
||||
knetcb: knet
|
||||
$(MAKE) -C $(SDK)/linux/knetcb SDK=$(SDK) \
|
||||
KBUILD_EXTRA_SYMBOLS=$(SDK)/linux/knet/Module.symvers \
|
||||
KBUILD_EXTRA_SYMBOLS+=$(PSAMPLE_SYMVERS) \
|
||||
$(TARGET)
|
||||
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:
|
||||
$(MAKE) kmod TARGET=clean
|
||||
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;
|
||||
struct list_head *list_ptr, *list_next;
|
||||
psample_pkt_t *pkt;
|
||||
struct psample_metadata md = {0};
|
||||
|
||||
spin_lock_irqsave(&psample_work->lock, flags);
|
||||
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.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,
|
||||
pkt->skb,
|
||||
pkt->meta.trunc_size,
|
||||
pkt->meta.src_ifindex,
|
||||
pkt->meta.dst_ifindex,
|
||||
pkt->meta.sample_rate);
|
||||
pkt->meta.sample_rate,
|
||||
&md);
|
||||
g_psample_stats.pkts_f_psample_mod++;
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
@ -61,9 +58,6 @@ $(KMODULE): $(MODULE)
|
||||
rm -fr $(BLDDIR)/$(KERNEL_MODULE_DIR)
|
||||
mkdir $(BLDDIR)/$(KERNEL_MODULE_DIR)
|
||||
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
|
||||
MOD_NAME=$(THIS_MOD_NAME) KBUILD_EXTRA_SYMBOLS="${KBUILD_EXTRA_SYMBOLS}" $(MAKE) -C $(BLDDIR)/$(KERNEL_MODULE_DIR) $(THIS_MOD_NAME).ko
|
||||
endif
|
||||
|
@ -394,6 +394,7 @@ psample_task(struct work_struct *work)
|
||||
unsigned long flags;
|
||||
struct list_head *list_ptr, *list_next;
|
||||
psample_pkt_t *pkt;
|
||||
struct psample_metadata md = {0};
|
||||
|
||||
spin_lock_irqsave(&psample_work->lock, flags);
|
||||
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.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,
|
||||
pkt->skb,
|
||||
pkt->meta.trunc_size,
|
||||
pkt->meta.src_ifindex,
|
||||
pkt->meta.dst_ifindex,
|
||||
pkt->meta.sample_rate);
|
||||
pkt->meta.sample_rate,
|
||||
&md);
|
||||
g_psample_stats.pkts_f_psample_mod++;
|
||||
|
||||
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=$(DEST_DIR)/$(BCM_KNET_LOCAL)
|
||||
|
||||
PSAMPLE_LOCAL := psample.$(KOBJ)
|
||||
PSAMPLE := $(DEST_DIR)/$(PSAMPLE_LOCAL)
|
||||
|
||||
ifeq (,$(findstring DELIVER,$(MAKECMDGOALS)))
|
||||
.DEFAULT_GOAL := all
|
||||
all_targets := kernel_modules $(KERNEL_BDE) $(USER_BDE)
|
||||
@ -145,7 +142,6 @@ endif
|
||||
endif
|
||||
|
||||
ifdef BUILD_PSAMPLE
|
||||
all_targets += $(PSAMPLE)
|
||||
ADD_TO_CFLAGS += -DPSAMPLE_SUPPORT
|
||||
endif
|
||||
ADD_TO_CFLAGS += -I$(SDK)/systems/linux/kernel/modules/include
|
||||
@ -178,10 +174,6 @@ kernel_modules:
|
||||
ifeq ($(BUILD_KNET),1)
|
||||
$(MAKE) -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \
|
||||
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
|
||||
$(MAKE) -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \
|
||||
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)
|
||||
$(OBJCOPY) --strip-debug $< $@
|
||||
|
||||
$(PSAMPLE): $(KERN_BLDROOT)/psample.$(KOBJ)
|
||||
$(OBJCOPY) --strip-debug $< $@
|
||||
|
||||
|
||||
|
||||
ifeq ($(NO_LOCAL_TARGETS),)
|
||||
$(foreach targ,$(LOCAL_TARGETS),$(eval $(call LOCAL_TARGET_DEF,$(targ))))
|
||||
endif
|
||||
@ -214,7 +201,7 @@ clean::
|
||||
$(MAKE) -C $(SDK)/systems/bde/linux/kernel $@
|
||||
$(MAKE) -C $(SDK)/systems/bde/linux/user/kernel $@
|
||||
$(MAKE) -C $(SDK)/systems/linux/kernel/modules \
|
||||
subdirs="shared bcm-knet knet-cb psample" \
|
||||
subdirs="shared bcm-knet knet-cb" \
|
||||
override-target=linux-$(platform) $@
|
||||
$(RM) $(KERNEL_BDE) $(USER_BDE)
|
||||
$(RM) $(BCM_KNET) $(KNET_CB) $(PSAMPLE)
|
||||
@ -222,7 +209,6 @@ clean::
|
||||
$(RM) $(KERN_BLDROOT)/linux-user-bde.$(KOBJ)
|
||||
$(RM) $(KERN_BLDROOT)/linux-bcm-knet.$(KOBJ)
|
||||
$(RM) $(KERN_BLDROOT)/linux-knet-cb.$(KOBJ)
|
||||
$(RM) $(KERN_BLDROOT)/psample.$(KOBJ)
|
||||
$(RM) $(LOCAL_TARGETS)
|
||||
|
||||
distclean:: clean
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit b9083b1a271e63757bef4fcd914ed524bd3c35c9
|
||||
Subproject commit fdd9bac78cfc2bbe932833b38c2191b1d382ed07
|
Loading…
Reference in New Issue
Block a user