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:
Michael Li 2022-08-16 11:46:03 -07:00 committed by GitHub
parent 6f9f765f1e
commit 055b7d5fad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 22 additions and 881 deletions

@ -1 +1 @@
Subproject commit 8771baa40be8392c2cf662648fc166929efa4b64
Subproject commit 65bce4ea8315a7cd0875b3ea2f5c35423f32f868

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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:

View File

@ -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");

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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->skb,
pkt->meta.sample_rate,
&md);
g_psample_stats.pkts_f_psample_mod++;
dev_kfree_skb_any(pkt->skb);

View File

@ -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

View File

@ -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");

View File

@ -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