package: add qca-nss support for k6.x

Before I can get to work a feed repository that work i have included
qca-nss source needed on this commit

Source author: SqTER-PL <r.napierala@asta-net.pl>
This commit is contained in:
Lucas Asvio
2025-02-22 13:19:41 +01:00
parent 53e175d098
commit e38c766dc7
83 changed files with 51893 additions and 0 deletions

View File

@@ -0,0 +1,49 @@
#
# Copyright (C) 2008-2012 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=nss-ifb
PKG_RELEASE:=1
include $(INCLUDE_DIR)/package.mk
define KernelPackage/nss-ifb
SECTION:=kernel
CATEGORY:=Kernel modules
SUBMENU:=Network Devices
TITLE:=NSS IFB Interface
DEPENDS:=+kmod-qca-nss-drv
FILES:=$(PKG_BUILD_DIR)/nss-ifb.ko
KCONFIG:=
endef
define KernelPackage/nss-ifb/description
Kernel module to register a NSS aware IFB interface.
endef
EXTRA_KCONFIG:= \
CONFIG_NET_CLS=y
EXTRA_CFLAGS:= \
-I$(STAGING_DIR)/usr/include/qca-nss-drv
MAKE_OPTS:= \
$(KERNEL_MAKE_FLAGS) \
M="$(PKG_BUILD_DIR)" \
EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \
$(EXTRA_KCONFIG)
define Build/Compile
$(MAKE) -C "$(LINUX_DIR)" \
$(MAKE_OPTS) \
modules
endef
$(eval $(call KernelPackage,nss-ifb))

View File

@@ -0,0 +1,45 @@
NSS Physical Interface Ingress Driver
=====================================
This driver redirect NSS physical interface (namely GMACs) ingress traffic to itself
and sends it back to the Linux network stack (as the source GMACs packets) as it's
egress traffic.
This allows the NSS QDISC drivers to manage the egress traffic of this driver's
NSS virtual interface.
This driver will create a single network interface named 'nssifb'. The default
source interface is defined as 'eth0'. It can be changed using the following module
parameter path:
/sys/module/nss-ifb/parameter/nss_src_dev
To change the source NSS physical interface to 'eth1', use the following command:
printf eth1 > /sys/module/nss-ifb/parameter/nss_src_dev
You need to change the source interface first before bringing up the 'nssifb'
interface. Changing it after the interface is up will have no effect. You need
to bring down the interface and bring it back up to have the changes take effect.
CPU load imposed on the Krait CPUs appears negligible with this driver intercepting
the physical interface's ingress traffic. Full line speed of the GMAC interface
could still be achieved.
The commands below shows an example to shape ingress traffic to 500 Mbps and egress
to 200 Mbps for the 'eth0' interface.
# Load the module if it's not loaded
modprobe nss-ifb
# Bring up the nssifb interface to active ingress redirect
ip link set up nssifb
# Shape ingress traffic to 500 Mbit with chained NSSFQ_CODEL
tc qdisc add dev nssifb root handle 1: nsstbl rate 500Mbit burst 1Mb
tc qdisc add dev nssifb parent 1: handle 10: nssfq_codel limit 10240 flows 1024 quantum 1514 target 5ms interval 100ms set_default
# Shape egress traffic to 200 Mbit with chained NSSFQ_CODEL
tc qdisc add dev eth0 root handle 1: nsstbl rate 200Mbit burst 1Mb
tc qdisc add dev eth0 parent 1: handle 10: nssfq_codel limit 10240 flows 1024 quantum 1514 target 5ms interval 100ms set_default

View File

@@ -0,0 +1,3 @@
obj-m += nss-ifb.o
nss-ifb-objs := nss_ifb.o

View File

@@ -0,0 +1,304 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* This driver is adapted from the Linux /drivers/net/ifb.c file.
*
* Redirect QCA NSS physical interface ingress traffic to this driver's
* virtual interface. This will allow ingress traffic shaping using the
* QCA NSS shaper.
*/
#include <nss_api_if.h>
#define TX_Q_LIMIT 32
struct nss_ifb_dev_private {
struct nss_virt_if_handle *nssctx;
struct net_device *nss_src_dev;
uint32_t nss_src_if_num;
char nss_src_dev_name[32];
};
char nss_dev_name_array[32] = "eth0";
char *nss_dev_name = nss_dev_name_array;
module_param(nss_dev_name, charp, 0644);
MODULE_PARM_DESC(nss_dev_name, "NSS physical interface source device name");
/*
* Virtual interface egress packet callback.
*
* We send it back to the Linux network stack.
*/
static void nss_ifb_data_cb(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi)
{
struct nss_ifb_dev_private *dp = netdev_priv(netdev);
skb->protocol = eth_type_trans(skb, dp->nss_src_dev);
skb->ip_summed = CHECKSUM_UNNECESSARY;
napi_gro_receive(napi, skb);
}
/*
* Virtual interface ingress packet callback.
*
* We just send it back to the NSS firmware to let the shaper work on it.
*/
static void nss_ifb_xmit_cb(struct net_device *netdev, struct sk_buff *skb)
{
struct nss_ifb_dev_private *dp = netdev_priv(netdev);
int ret;
ret = nss_virt_if_tx_buf(dp->nssctx, skb);
if (unlikely(ret)) {
pr_warn("Failed [%d] to send skb [len: %d, protocol: 0x%X] to NSS!\n",
ret, skb->len, ntohs(skb->protocol));
}
}
static void nss_ifb_stats64(struct net_device *dev,
struct rtnl_link_stats64 *stats)
{
}
static int nss_ifb_dev_init(struct net_device *dev)
{
struct nss_ifb_dev_private *dp = netdev_priv(dev);
dp->nssctx = nss_virt_if_create_sync_nexthop(dev, NSS_ETH_RX_INTERFACE, NSS_ETH_RX_INTERFACE);
if (!dp->nssctx) {
dp->nssctx = NULL;
pr_warn("Could not create a NSS virtual interface for dev [%s]\n",
dev->name);
return -ENODEV;
}
pr_info("Created a NSS virtual interface for dev [%s]\n", dev->name);
nss_virt_if_register(dp->nssctx, nss_ifb_data_cb, dev);
pr_info("NSS IFB data callback registered\n");
nss_virt_if_xmit_callback_register(dp->nssctx, nss_ifb_xmit_cb);
pr_info("NSS IFB transmit callback registered\n");
return 0;
}
static void nss_ifb_dev_uninit(struct net_device *dev)
{
struct nss_ifb_dev_private *dp = netdev_priv(dev);
int ret;
nss_virt_if_xmit_callback_unregister(dp->nssctx);
pr_info("NSS IFB transmit callback unregistered\n");
ret = nss_virt_if_destroy_sync(dp->nssctx);
if (ret == NSS_TX_SUCCESS) {
pr_info("NSS virtual interface destroyed for dev [%s]\n", dev->name);
}
else {
pr_warn("Unable to destroy NSS virtual interface for dev [%s], error[%d]\n",
dev->name, ret);
}
dp->nssctx = NULL;
}
static netdev_tx_t nss_ifb_xmit(struct sk_buff *skb, struct net_device *dev)
{
return NETDEV_TX_OK;
}
static int nss_ifb_close(struct net_device *dev)
{
struct nss_ifb_dev_private *dp = netdev_priv(dev);
struct nss_ctx_instance *nss_ctx;
struct net_device *src_dev;
uint32_t src_if_num;
int ret;
nss_ctx = dp->nssctx->nss_ctx;
src_dev = dp->nss_src_dev;
src_if_num = dp->nss_src_if_num;
ret = nss_phys_if_set_nexthop(nss_ctx, src_if_num, NSS_ETH_RX_INTERFACE);
if (ret != NSS_TX_SUCCESS) {
pr_warn("%p: Failed to reset next hop for net device [%s].\n",
nss_ctx, src_dev->name);
}
else {
pr_info("%p: Reset nexthop successful for net device [%s].\n",
nss_ctx, src_dev->name);
}
dev_put(src_dev);
dp->nss_src_dev = NULL;
dp->nss_src_if_num = -1;
return 0;
}
static int nss_ifb_open(struct net_device *dev)
{
struct nss_ifb_dev_private *dp = netdev_priv(dev);
struct net_device *src_dev;
uint32_t src_if_num;
uint32_t nh_if_num;
nss_tx_status_t nss_tx_status;
struct nss_ctx_instance *nss_ctx;
nss_ctx = dp->nssctx->nss_ctx;
nh_if_num = dp->nssctx->if_num_n2h;
strcpy(dp->nss_src_dev_name, nss_dev_name);
src_dev = dev_get_by_name(&init_net, dp->nss_src_dev_name);
if (!src_dev) {
pr_warn("%p: Cannot find the net device [%s]\n",
nss_ctx, dp->nss_src_dev_name);
return -ENODEV;
}
pr_info("%p: Found net device [%s]\n", nss_ctx, dp->nss_src_dev_name);
src_if_num = nss_cmn_get_interface_number_by_dev(src_dev);
if (src_if_num < 0) {
pr_warn("%p: Invalid interface number:%d\n", nss_ctx, src_if_num);
dev_put(src_dev);
return -ENODEV;
}
pr_info("%p: Net device [%s] has NSS intf_num [%d]\n",
nss_ctx, dp->nss_src_dev_name, src_if_num);
nss_tx_status = nss_phys_if_set_nexthop(nss_ctx, src_if_num, nh_if_num);
if (nss_tx_status != NSS_TX_SUCCESS) {
pr_warn("%p: Sending message failed, cannot change nexthop for [%s]\n",
nss_ctx, dp->nss_src_dev_name);
}
else {
pr_info("Nexthop successfully set for [%s] to [%s]\n",
dp->nss_src_dev_name, dev->name);
}
dp->nss_src_dev = src_dev;
dp->nss_src_if_num = src_if_num;
return 0;
}
static const struct net_device_ops nss_ifb_netdev_ops = {
.ndo_open = nss_ifb_open,
.ndo_stop = nss_ifb_close,
.ndo_get_stats64 = nss_ifb_stats64,
.ndo_start_xmit = nss_ifb_xmit,
.ndo_validate_addr = eth_validate_addr,
.ndo_init = nss_ifb_dev_init,
.ndo_uninit = nss_ifb_dev_uninit,
};
#define IFB_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | NETIF_F_FRAGLIST | \
NETIF_F_TSO_ECN | NETIF_F_TSO | NETIF_F_TSO6 | \
NETIF_F_GSO_ENCAP_ALL | \
NETIF_F_HIGHDMA | NETIF_F_HW_VLAN_CTAG_TX | \
NETIF_F_HW_VLAN_STAG_TX)
static void nss_ifb_dev_free(struct net_device *dev)
{
}
static void nss_ifb_setup(struct net_device *dev)
{
/* Initialize the device structure. */
dev->netdev_ops = &nss_ifb_netdev_ops;
/* Fill in device structure with ethernet-generic values. */
ether_setup(dev);
dev->tx_queue_len = TX_Q_LIMIT;
dev->features |= IFB_FEATURES;
dev->hw_features |= dev->features;
dev->hw_enc_features |= dev->features;
dev->vlan_features |= IFB_FEATURES & ~(NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_STAG_TX);
dev->flags |= IFF_NOARP;
dev->flags &= ~IFF_MULTICAST;
dev->priv_flags &= ~IFF_TX_SKB_SHARING;
netif_keep_dst(dev);
eth_hw_addr_random(dev);
dev->needs_free_netdev = true;
dev->priv_destructor = nss_ifb_dev_free;
dev->min_mtu = 0;
dev->max_mtu = 0;
}
static int nss_ifb_validate(struct nlattr *tb[], struct nlattr *data[],
struct netlink_ext_ack *extack)
{
if (tb[IFLA_ADDRESS]) {
if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
return -EINVAL;
if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
return -EADDRNOTAVAIL;
}
return 0;
}
static struct rtnl_link_ops nss_ifb_link_ops __read_mostly = {
.kind = "nss_ifb",
.priv_size = sizeof(struct nss_ifb_dev_private),
.setup = nss_ifb_setup,
.validate = nss_ifb_validate,
};
static int __init nss_ifb_init_module(void)
{
struct net_device *dev;
int err;
down_write(&pernet_ops_rwsem);
rtnl_lock();
err = __rtnl_link_register(&nss_ifb_link_ops);
if (err < 0)
goto out;
dev = alloc_netdev(sizeof(struct nss_ifb_dev_private), "nssifb",
NET_NAME_UNKNOWN, nss_ifb_setup);
if (dev) {
dev->rtnl_link_ops = &nss_ifb_link_ops;
err = register_netdevice(dev);
}
else {
err = -ENOMEM;
}
if (err)
__rtnl_link_unregister(&nss_ifb_link_ops);
out:
rtnl_unlock();
up_write(&pernet_ops_rwsem);
if (!err)
pr_info("NSS IFB module loaded.\n");
else
pr_warn("Failed to load NSS IFB module.\n");
return err;
}
static void __exit nss_ifb_cleanup_module(void)
{
rtnl_link_unregister(&nss_ifb_link_ops);
pr_info("NSS IFB module unloaded.\n");
}
module_init(nss_ifb_init_module);
module_exit(nss_ifb_cleanup_module);
MODULE_LICENSE("GPL");
MODULE_ALIAS_RTNL_LINK("nss_ifb");

View File

@@ -0,0 +1,46 @@
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=libnl-nss
PKG_RELEASE:=1
PKG_BUILD_DEPENDS:=libnl
include $(INCLUDE_DIR)/package.mk
define Package/libnl-nss
SECTION:=Libs
CATEGORY:=Libraries
TITLE:=Framework to communicate between userspace applications and the kernel.
DEPENDS:=+libpthread +libnl +@NSS_DRV_CRYPTO_ENABLE +kmod-qca-nss-drv-netlink
endef
define Package/libnl-nss/description
A framework in the userspace that establishes communication between userspace applications and the kernel.
endef
TOOL_CFLAGS:= -I$(STAGING_DIR)/usr/include/qca-nss-clients \
-I$(STAGING_DIR)/usr/include/qca-nss-drv \
-I$(STAGING_DIR)/usr/include/libnl3
TOOL_LDFLAGS:= -L$(STAGING_DIR)/lib
define Build/Compile
$(MAKE) -C $(PKG_BUILD_DIR) \
CC="$(TARGET_CC)" \
AR="$(TARGET_AR) " \
CFLAGS="$(TOOL_CFLAGS)" \
LD_LIBRARY_PATH="$(TOOL_LDFLAGS)"
endef
define Build/InstallDev
$(INSTALL_DIR) $(STAGING_DIR)/usr/include/libnl-nss
$(CP) $(PKG_BUILD_DIR)/obj/libnl-nss.so $(STAGING_DIR)/usr/lib
$(CP) $(PKG_BUILD_DIR)/include/* $(STAGING_DIR)/usr/include/libnl-nss
endef
define Package/libnl-nss/install
$(INSTALL_DIR) $(1)/lib
$(INSTALL_DATA) $(PKG_BUILD_DIR)/obj/libnl-nss.so $(1)/lib
endef
$(eval $(call BuildPackage,libnl-nss))

View File

@@ -0,0 +1,35 @@
MKDIR = @mkdir -p $(@D)
SRCPATH = ./
OBJPATH = obj
BINARY = $(OBJPATH)/libnl-nss.so
SOURCES = $(wildcard $(SRCPATH)/*.c)
OBJECTS = $(SOURCES:$(SRCPATH)/%.c=$(OBJPATH)/%.o)
HEADERS = $(wildcard $(SRCPATH)/*.h)
INCLUDE += -I./include
LDFLAGS = -lnl-3 -lnl-genl-3
EXTRA_CFLAGS = -Wall -Werror -fPIC -Wl,-z,relro -Wl,-z,now
EXTRA_LDFLAGS = -pie -Wl,-z,relro -Wl,-z,now
all: release
release: $(BINARY)
$(OBJPATH)/%.o: $(SRCPATH)/%.c $(HEADERS)
$(MKDIR)
@echo [CC] $@
@$(CC) -c $(CFLAGS) $(INCLUDE) $(EXTRA_CFLAGS) -o $@ $<
$(BINARY): $(OBJECTS)
@echo $(BINARY)
@echo [LD] $@
@$(CC) -shared -o $@ $^ $(LDFLAGS) $(LDLIBS)
clean:
@echo [Clean]
@rm -f $(OBJECTS)
@rm -f $(BINARY)
@rm -rf $(OBJPATH)
.PHONY: clean

View File

@@ -0,0 +1,71 @@
/*
**************************************************************************
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**************************************************************************
*/
#ifndef __NSS_NLBASE_H__
#define __NSS_NLBASE_H__
/*
* TODO: Remove inter-dependencies between the header files.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <assert.h>
#include <fcntl.h>
#include <getopt.h>
#include <limits.h>
#include <linux/socket.h>
#include <net/if.h>
#include <pthread.h>
#include <stdbool.h>
#include <stdint.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <linux/if_ether.h>
/* Generic Netlink header */
#include <netlink/genl/ctrl.h>
#include <netlink/genl/family.h>
#include <netlink/genl/genl.h>
#if !defined (likely) || !defined (unlikely)
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#endif
/* NSS headers */
#include <nss_arch.h>
#include <nss_def.h>
#include <nss_cmn.h>
#include <nss_ipv4.h>
#include <nss_ipv6.h>
#include <nss_nlcmn_if.h>
#include <nss_dtls_cmn.h>
#include <nss_dtlsmgr.h>
#include <nss_nl_if.h>
#include <nss_nlsock_api.h>
#include <nss_nldtls_if.h>
#include <nss_nldtls_api.h>
#include <nss_nlist_api.h>
#include <nss_nlipv4_if.h>
#include <nss_nlipv4_api.h>
#include <nss_nlipv6_if.h>
#include <nss_nlipv6_api.h>
#include <nss_nlmcast_api.h>
#endif /* __NSS_NLBASE_H__ */

View File

@@ -0,0 +1,119 @@
/*
**************************************************************************
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**************************************************************************
*/
#ifndef __NSS_NLDTLS_API_H__
#define __NSS_NLDTLS_API_H__
/** @addtogroup chapter_nldtls
This chapter describes Data Transport Layer Security (DTLS) APIs in the user space.
These APIs are wrapper functions for DTLS family specific operations.
*/
/** @addtogroup nss_nldtls_datatypes @{ */
/**
* Response callback for DTLS.
*
* @param[in] user_ctx User context (provided at socket open).
* @param[in] rule DTLS rule.
* @param[in] resp_ctx User data per callback.
*
* @return
* None.
*/
typedef void (*nss_nldtls_resp_t)(void *user_ctx, struct nss_nldtls_rule *rule, void *resp_ctx);
/**
* Event callback for DTLS.
*
* @param[in] user_ctx User context (provided at socket open).
* @param[in] rule DTLS rule.
*
* @return
* None.
*/
typedef void (*nss_nldtls_event_t)(void *user_ctx, struct nss_nldtls_rule *rule);
/**
* NSS NL DTLS response.
*/
struct nss_nldtls_resp {
void *data; /**< Response context. */
nss_nldtls_resp_t cb; /**< Response callback. */
};
/**
* NSS NL DTLS context.
*/
struct nss_nldtls_ctx {
struct nss_nlsock_ctx sock; /**< NSS socket context. */
nss_nldtls_event_t event; /**< NSS event callback function. */
};
/** @} *//* end_addtogroup nss_nldtls_datatypes */
/** @addtogroup nss_nldtls_functions @{ */
/**
* Opens NSS NL DTLS socket.
*
* @param[in] ctx NSS NL socket context allocated by the caller.
* @param[in] user_ctx User context stored per socket.
* @param[in] event_cb Event callback handler.
*
* @return
* Status of the open call.
*/
int nss_nldtls_sock_open(struct nss_nldtls_ctx *ctx, void *user_ctx, nss_nldtls_event_t event_cb);
/**
* Closes NSS NL DTLS socket.
*
* @param[in] ctx NSS NL context.
*
* @return
* None.
*/
void nss_nldtls_sock_close(struct nss_nldtls_ctx *ctx);
/**
* Send a DTLS rule synchronously to NSS NL NETLINK.
*
* @param[in] ctx NSS DTLS NL context.
* @param[in] rule DTLS rule.
* @param[in] cb Response callback handler.
* @param[in] data Data received from sender.
*
* @return
* Send status:
* - 0 -- Success.
* - Negative version error (-ve) -- Failure.
*/
int nss_nldtls_sock_send(struct nss_nldtls_ctx *ctx, struct nss_nldtls_rule *rule, nss_nldtls_resp_t cb, void *data);
/**
* Initializes create rule message.
*
* @param[in] rule DTLS rule.
* @param[in] type Type of command.
*
* @return
* None.
*/
void nss_nldtls_init_rule(struct nss_nldtls_rule *rule, enum nss_nldtls_cmd_type type);
/** @} *//* end_addtogroup nss_nldtls_functions */
#endif /* __NSS_NLDTLS_API_H__ */

View File

@@ -0,0 +1,253 @@
/*
**************************************************************************
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**************************************************************************
*/
#ifndef __NSS_NLIPV4_API_H__
#define __NSS_NLIPV4_API_H__
#define NSS_IPV4_RULE_CREATE_IDENTIFIER_VALID 0x1000 /**< Identifier is valid. */
/** @addtogroup chapter_nlipv4
This chapter describes IPv4 APIs in the user space.
These APIs are wrapper functions for IPv4 family specific operations.
*/
/** @addtogroup nss_nlipv4_datatypes @{ */
/**
* Response callback for IPv4.
*
* @param[in] user_ctx User context (provided at socket open).
* @param[in] rule IPv4 rule.
* @param[in] resp_ctx User data per callback.
*
* @return
* None.
*/
typedef void (*nss_nlipv4_resp_t)(void *user_ctx, struct nss_nlipv4_rule *rule, void *resp_ctx);
/**
* Event callback for IPv4.
*
* @param[in] user_ctx User context (provided at socket open).
* @param[in] rule IPv4 rule.
*
* @return
* None.
*/
typedef void (*nss_nlipv4_event_t)(void *user_ctx, struct nss_nlipv4_rule *rule);
/**
* NSS NL IPv4 response.
*/
struct nss_nlipv4_resp {
void *data; /**< Response context. */
nss_nlipv4_resp_t cb; /**< Response callback. */
};
/**
* NSS NL IPv4 context.
*/
struct nss_nlipv4_ctx {
struct nss_nlsock_ctx sock; /**< NSS socket context. */
nss_nlipv4_event_t event; /**< NSS event callback function. */
};
/** @} *//* end_addtogroup nss_nlipv4_datatypes */
/** @addtogroup nss_nlipv4_functions @{ */
/**
* Opens NSS NL IPv4 socket.
*
* @param[in] ctx NSS NL socket context allocated by the caller.
* @param[in] user_ctx User context stored per socket.
* @param[in] event_cb Event callback handler.
*
* @return
* Status of the open call.
*/
int nss_nlipv4_sock_open(struct nss_nlipv4_ctx *ctx, void *user_ctx, nss_nlipv4_event_t event_cb);
/**
* Closes NSS NL IPv4 socket.
*
* @param[in] ctx NSS NL context.
*
* @return
* None.
*/
void nss_nlipv4_sock_close(struct nss_nlipv4_ctx *ctx);
/**
* Sends an IPv4 rule synchronously to NSS NETLINK.
*
* @param[in] ctx NSS NL IPv4 context.
* @param[in] rule IPv4 rule.
* @param[in] cb Response callback handler.
* @param[in] data Response data per callback.
*
* @return
* Send status:
* - 0 -- Success.
* - Negative version error (-ve) -- Failure.
*/
int nss_nlipv4_sock_send(struct nss_nlipv4_ctx *ctx, struct nss_nlipv4_rule *rule, nss_nlipv4_resp_t cb, void *data);
/**
* Initializes IPv4 rule message.
*
* @param[in] rule IPv4 rule.
* @param[in] type Command type.
*
* @return
* None.
*/
void nss_nlipv4_init_rule(struct nss_nlipv4_rule *rule, enum nss_ipv4_message_types type);
/**
* Initializes connection rule for create message.
*
* @param[in] create Creates message.
*
* @return
* None.
*/
static inline void nss_nlipv4_init_conn_rule(struct nss_ipv4_rule_create_msg *create)
{
create->valid_flags |= NSS_IPV4_RULE_CREATE_CONN_VALID;
}
/**
* Enables route flow.
*
* @param[in] create Creates message.
*
* @return
* None.
*/
static inline void nss_nlipv4_init_route_flow_rule(struct nss_ipv4_rule_create_msg *create)
{
create->rule_flags |= NSS_IPV4_RULE_CREATE_FLAG_ROUTED;
}
/**
* Enables bridge flow.
*
* @param[in] create Creates message.
*
* @return
* None.
*/
static inline void nss_nlipv4_init_bridge_flow_rule(struct nss_ipv4_rule_create_msg *create)
{
create->rule_flags |= NSS_IPV4_RULE_CREATE_FLAG_BRIDGE_FLOW;
}
/**
* Initializes TCP protocol rule for create message.
*
* @param[in] create Creates message.
*
* @return
* None.
*/
static inline void nss_nlipv4_init_tcp_rule(struct nss_ipv4_rule_create_msg *create)
{
create->valid_flags |= NSS_IPV4_RULE_CREATE_TCP_VALID;
}
/**
* Initializes PPPoE rule for create message.
*
* @param[in] create Creates message.
*
* @return
* None.
*/
static inline void nss_nlipv4_init_pppoe_rule(struct nss_ipv4_rule_create_msg *create)
{
create->valid_flags |= NSS_IPV4_RULE_CREATE_PPPOE_VALID;
}
/**
* Initializes QoS rule for create message.
*
* @param[in] create Creates message.
*
* @return
* None.
*/
static inline void nss_nlipv4_init_qos_rule(struct nss_ipv4_rule_create_msg *create)
{
create->valid_flags |= NSS_IPV4_RULE_CREATE_QOS_VALID;
}
/**
* Initializes DSCP rule for create message.
*
* @param[in] create Creates message.
*
* @return
* None.
*/
static inline void nss_nlipv4_init_dscp_rule(struct nss_ipv4_rule_create_msg *create)
{
create->valid_flags |= NSS_IPV4_RULE_CREATE_DSCP_MARKING_VALID;
}
/**
* Initializes VLAN rule for create message.
*
* @param[in] create Creates message.
*
* @return
* None.
*/
static inline void nss_nlipv4_init_vlan_rule(struct nss_ipv4_rule_create_msg *create)
{
struct nss_ipv4_vlan_rule *primary;
struct nss_ipv4_vlan_rule *secondary;
primary = &create->vlan_primary_rule;
secondary = &create->vlan_secondary_rule;
create->valid_flags |= NSS_IPV4_RULE_CREATE_VLAN_VALID;
/*
* set the tags to default values
*/
primary->ingress_vlan_tag = NSS_NLIPV4_VLAN_ID_NOT_CONFIGURED;
primary->egress_vlan_tag = NSS_NLIPV4_VLAN_ID_NOT_CONFIGURED;
secondary->ingress_vlan_tag = NSS_NLIPV4_VLAN_ID_NOT_CONFIGURED;
secondary->egress_vlan_tag = NSS_NLIPV4_VLAN_ID_NOT_CONFIGURED;
}
/**
* Initializes Identifier rule for create message.
*
* @param[in] create Creates message.
*
* @return
* None.
*/
static inline void nss_nlipv4_init_identifier_rule(struct nss_ipv4_rule_create_msg *create)
{
create->valid_flags |= NSS_IPV4_RULE_CREATE_IDENTIFIER_VALID;
}
/** @} *//* end_addtogroup nss_nlipv4_functions */
#endif /* __NSS_NLIPV4_API_H__ */

View File

@@ -0,0 +1,253 @@
/*
**************************************************************************
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**************************************************************************
*/
#ifndef __NSS_NLIPV6_API_H__
#define __NSS_NLIPV6_API_H__
#define NSS_IPV6_RULE_CREATE_IDENTIFIER_VALID 0x1000 /**< Identifier is valid. */
/** @addtogroup chapter_nlipv6
This chapter describes IPv6 APIs in the user space.
These APIs are wrapper functions for IPv6 family specific operations.
*/
/** @addtogroup nss_nlipv6_datatypes @{ */
/**
* Response callback for IPv6.
*
* @param[in] user_ctx User context (provided at socket open).
* @param[in] rule IPv6 rule.
* @param[in] resp_ctx user data per callback.
*
* @return
* None.
*/
typedef void (*nss_nlipv6_resp_t)(void *user_ctx, struct nss_nlipv6_rule *rule, void *resp_ctx);
/**
* Event callback for IPv6.
*
* @param[in] user_ctx User context (provided at socket open).
* @param[in] rule IPv6 Rule.
*
* @return
* None.
*/
typedef void (*nss_nlipv6_event_t)(void *user_ctx, struct nss_nlipv6_rule *rule);
/**
* NSS NL IPv6 response.
*/
struct nss_nlipv6_resp {
void *data; /**< Response context. */
nss_nlipv6_resp_t cb; /**< Response callback. */
};
/**
* NSS NL IPv6 context.
*/
struct nss_nlipv6_ctx {
struct nss_nlsock_ctx sock; /**< NSS socket context. */
nss_nlipv6_event_t event; /**< NSS event callback function. */
};
/** @} *//* end_addtogroup nss_nlipv6_datatypes */
/** @addtogroup nss_nlipv6_functions @{ */
/**
* Opens NSS NL IPv6 socket.
*
* @param[in] ctx NSS NL socket context allocated by the caller.
* @param[in] user_ctx User context stored per socket.
* @param[in] event_cb Event callback handler.
*
* @return
* Status of the open call.
*/
int nss_nlipv6_sock_open(struct nss_nlipv6_ctx *ctx, void *user_ctx, nss_nlipv6_event_t event_cb);
/**
* Closes NSS NL IPv6 socket.
*
* @param[in] ctx NSS NL context.
*
* @return
* None.
*/
void nss_nlipv6_sock_close(struct nss_nlipv6_ctx *ctx);
/**
* Sends an IPv6 rule synchronously to NSS NETLINK.
*
* @param[in] ctx NSS IPv6 NL context.
* @param[in] rule IPv6 rule.
* @param[in] cb Response callback handler.
* @param[in] data Response data per callback.
*
* @return
* Send status:
* - 0 -- Success.
* - Negative version error (-ve) -- Failure.
*/
int nss_nlipv6_sock_send(struct nss_nlipv6_ctx *ctx, struct nss_nlipv6_rule *rule, nss_nlipv6_resp_t cb, void *data);
/**
* Initializes rule message.
*
* @param[in] rule IPv6 rule.
* @param[in] type Command type.
*
* @return
* None.
*/
void nss_nlipv6_init_rule(struct nss_nlipv6_rule *rule, enum nss_ipv6_message_types type);
/**
* Initializes connection rule for create message.
*
* @param[in] create Creates message.
*
* @return
* None.
*/
static inline void nss_nlipv6_init_conn_rule(struct nss_ipv6_rule_create_msg *create)
{
create->valid_flags |= NSS_IPV6_RULE_CREATE_CONN_VALID;
}
/**
* Enables route flow.
*
* @param[in] create Creates message.
*
* @return
* None.
*/
static inline void nss_nlipv6_init_route_flow_rule(struct nss_ipv6_rule_create_msg *create)
{
create->rule_flags |= NSS_IPV6_RULE_CREATE_FLAG_ROUTED;
}
/**
* Enables bridge flow.
*
* @param[in] create create message.
*
* @return
* None.
*/
static inline void nss_nlipv6_init_bridge_flow_rule(struct nss_ipv6_rule_create_msg *create)
{
create->rule_flags |= NSS_IPV6_RULE_CREATE_FLAG_BRIDGE_FLOW;
}
/**
* Initializes TCP protocol rule for create message.
*
* @param[in] create Creates message.
*
* @return
* None.
*/
static inline void nss_nlipv6_init_tcp_rule(struct nss_ipv6_rule_create_msg *create)
{
create->valid_flags |= NSS_IPV6_RULE_CREATE_TCP_VALID;
}
/**
* Initializes PPPoE rule for create message.
*
* @param[in] create Creates message.
*
* @return
* None.
*/
static inline void nss_nlipv6_init_pppoe_rule(struct nss_ipv6_rule_create_msg *create)
{
create->valid_flags |= NSS_IPV6_RULE_CREATE_PPPOE_VALID;
}
/**
* Initializes QoS rule for create message.
*
* @param[in] create Creates message.
*
* @return
* None.
*/
static inline void nss_nlipv6_init_qos_rule(struct nss_ipv6_rule_create_msg *create)
{
create->valid_flags |= NSS_IPV6_RULE_CREATE_QOS_VALID;
}
/**
* Initializes DSCP rule for create message.
*
* @param[in] create Creates message.
*
* @return
* None.
*/
static inline void nss_nlipv6_init_dscp_rule(struct nss_ipv6_rule_create_msg *create)
{
create->valid_flags |= NSS_IPV6_RULE_CREATE_DSCP_MARKING_VALID;
}
/**
* Initializes VLAN rule for create message.
*
* @param[in] create Creates message.
*
* @return
* None.
*/
static inline void nss_nlipv6_init_vlan_rule(struct nss_ipv6_rule_create_msg *create)
{
struct nss_ipv6_vlan_rule *primary;
struct nss_ipv6_vlan_rule *secondary;
primary = &create->vlan_primary_rule;
secondary = &create->vlan_secondary_rule;
create->valid_flags |= NSS_IPV6_RULE_CREATE_VLAN_VALID;
/*
* set the tags to default values
*/
primary->ingress_vlan_tag = NSS_NLIPV6_VLAN_ID_NOT_CONFIGURED;
primary->egress_vlan_tag = NSS_NLIPV6_VLAN_ID_NOT_CONFIGURED;
secondary->ingress_vlan_tag = NSS_NLIPV6_VLAN_ID_NOT_CONFIGURED;
secondary->egress_vlan_tag = NSS_NLIPV6_VLAN_ID_NOT_CONFIGURED;
}
/**
* Initializes Identifier rule for create message.
*
* @param[in] create Creates message.
*
* @return
* None.
*/
static inline void nss_nlipv6_init_identifier_rule(struct nss_ipv6_rule_create_msg *create)
{
create->valid_flags |= NSS_IPV6_RULE_CREATE_IDENTIFIER_VALID;
}
/** @} *//* end_addtogroup nss_nlipv6_functions */
#endif /* __NSS_NLIPV6_API_H__ */

View File

@@ -0,0 +1,220 @@
/*
**************************************************************************
* Copyright (c) 2019,2021 The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**************************************************************************
*/
#ifndef __NSS_NLIST_H__
#define __NSS_NLIST_H__
/** @addtogroup chapter_nlist
This chapter describes Netlink list APIs in the user space.
*/
/** @ingroup nss_nlist_datatypes
* List node
*/
struct nss_nlist {
struct nss_nlist *next; /**< Next node. */
struct nss_nlist *prev; /**< Previous node. */
};
/** @addtogroup nss_nlist_functions @{ */
/**
* Initializes the list node.
*
* @param[in] node List node.
*
* @return
* None.
*/
static inline void nss_nlist_init(struct nss_nlist *node)
{
node->next = node->prev = node;
}
/**
* Gets the previous node.
*
* @param[in] node Previous node.
*
* @return
* Previous node or head node.
*/
static inline struct nss_nlist *nss_nlist_prev(struct nss_nlist *node)
{
return node->prev;
}
/**
* Gets the next node.
*
* @param[in] node Next node.
*
* @return
* Next node or head node.
*/
static inline struct nss_nlist *nss_nlist_next(struct nss_nlist *node)
{
return node->next;
}
/**
* Initializes the head node.
*
* @param[in] head Head of list.
*
* @return
* None.
*/
static inline void nss_nlist_init_head(struct nss_nlist *head)
{
nss_nlist_init(head);
}
/**
* Returns first node in the list.
*
* @param[in] head List head.
*
* @return
* First node.
*/
static inline struct nss_nlist *nss_nlist_first(struct nss_nlist *head)
{
return nss_nlist_next(head);
}
/**
* Returns last node in the list.
*
* @param[in] head List head.
*
* @return
* Last node.
*/
static inline struct nss_nlist *nss_nlist_last(struct nss_nlist *head)
{
return nss_nlist_prev(head);
}
/**
* Checks if list is empty.
*
* @param[in] head List head.
*
* @return
* TRUE if empty.
*/
static inline bool nss_nlist_isempty(struct nss_nlist *head)
{
struct nss_nlist *first = nss_nlist_first(head);
return first == head;
}
/**
* Checks if corresponding node is the last node.
*
* @param[in] head Head node.
* @param[in] node Node to check.
*
* @return
* TRUE if it is the last node.
*/
static inline bool nss_nlist_islast(struct nss_nlist *head, struct nss_nlist *node)
{
struct nss_nlist *last = nss_nlist_last(head);
return last == node;
}
/**
* Adds node to head of the list.
*
* @param[in] head List head.
* @param[in] node Node to add.
*
* @return
* None.
*/
static inline void nss_nlist_add_head(struct nss_nlist *head, struct nss_nlist *node)
{
struct nss_nlist *first = nss_nlist_first(head);
node->prev = head;
node->next = first;
first->prev = node;
head->next = node;
}
/**
* Adds node to tail of the list.
*
* @param[in] head List head.
* @param[in] node Node to add.
*
* @return
* None.
*/
static inline void nss_nlist_add_tail(struct nss_nlist *head, struct nss_nlist *node)
{
struct nss_nlist *last = nss_nlist_last(head);
node->next = head;
node->prev = last;
last->next = node;
head->prev = node;
}
/**
* Unlinks node from the list.
*
* @param[in] node Node to unlink.
*
* @return
* None.
*/
static inline void nss_nlist_unlink(struct nss_nlist *node)
{
struct nss_nlist *prev = nss_nlist_prev(node);
struct nss_nlist *next = nss_nlist_next(node);
prev->next = next;
next->prev = prev;
nss_nlist_init(node);
}
/** @} *//* end_addtogroup nss_nlist_functions */
/** @ingroup nss_nlist_macros
* Lists node iterator.
*
* @hideinitializer
* @param[in] _tmp Temporary node for assignment.
* @param[in] _head Head node to start.
*
* @return
* None.
*/
#define nss_nlist_iterate(_tmp, _head) \
for ((_tmp) = nss_nlist_first((_head)); \
!nss_nlist_islast((_head), (_tmp)); \
(_tmp) = nss_nlist_next((_tmp))
#endif /* __NSS_NLIST_H__ */

View File

@@ -0,0 +1,102 @@
/*
**************************************************************************
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**************************************************************************
*/
#ifndef __NSS_NLMCAST_API_H__
#define __NSS_NLMCAST_API_H__
/** @addtogroup chapter_nlmcast
This chapter describes multicast APIs in the user space.
These APIs are wrapper functions for multicast specific operations.
*/
/** @addtogroup nss_nlmcast_datatypes @{ */
/**
* Event callback for multicast.
*
* @param[in] cmd Command received in generic Netlink header.
* @param[in] data Data received in Netlink message.
*/
typedef void (*nss_nlmcast_event_t)(int cmd, void *data);
/**
* NSS multicast context.
*/
struct nss_nlmcast_ctx {
struct nss_nlsock_ctx sock; /**< NSS socket context. */
nss_nlmcast_event_t event; /**< NSS event callback function. */
};
/** @} *//* end_addtogroup nss_nlmcast_datatypes */
/** @addtogroup nss_nlmcast_functions @{ */
/**
* Listens to NSS NL multicast event data.
*
* @param[in] ctx Multicast context.
*
* @return
* Listen status.
*/
int nss_nlmcast_sock_listen(struct nss_nlmcast_ctx *ctx);
/**
* Subscribe the multicast group to receive responses.
*
* @param[in] ctx Multicast context.
* @param[in] grp_name NSS NL group name.
*
* @return
* Subscription status.
*/
int nss_nlmcast_sock_join_grp(struct nss_nlmcast_ctx *ctx, char *grp_name);
/**
* Unsubscribe the multicast group to stop receiving responses.
*
* @param[in] ctx Multicast context.
* @param[in] grp_name NSS NL group name.
*
* @return
* Status of the operation.
*/
int nss_nlmcast_sock_leave_grp(struct nss_nlmcast_ctx *ctx, char *grp_name);
/**
* Opens a socket for listening to NSS NL event data.
*
* @param[in] ctx Multicast context.
* @param[in] cb Callback function.
* @param[in] family_name NSS NL family name.
*
* @return
* Status of the operation.
*/
int nss_nlmcast_sock_open(struct nss_nlmcast_ctx *ctx, nss_nlmcast_event_t cb, const char *family_name);
/**
* Closes socket.
*
* @param[in] ctx Multicast context.
*
* @return
* None.
*/
void nss_nlmcast_sock_close(struct nss_nlmcast_ctx *ctx);
/** @} *//* end_addtogroup nss_nlmcast_functions */
#endif /* __NSS_NLMCAST_API_H__ */

View File

@@ -0,0 +1,197 @@
/*
**************************************************************************
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**************************************************************************
*/
#ifndef __NSS_NLSOCK_API_H__
#define __NSS_NLSOCK_API_H__
/** @addtogroup chapter_nlsocket
This chapter describes socket APIs for direct use.
@note1hang
Use these APIs(s) only if there are no available helpers for the specific family.
*/
/**
* @ingroup nss_nlsocket_datatypes
* NSS NL socket context.
*/
struct nss_nlsock_ctx {
/* Public, caller must populate using helpers */
const char *family_name; /**< Family name. */
void *user_ctx; /**< Socket user context. */
/* Private, maintained by the library */
pthread_t thread; /**< Response sync. */
pthread_spinlock_t lock; /**< Context lock. */
int ref_cnt; /**< References to the socket. */
struct nl_sock *nl_sk; /**< Linux NL socket. */
struct nl_cb *nl_cb; /**< NSS NL callback context. */
pid_t pid; /**< Process ID associated with the socket. */
int family_id; /**< Family identifier. */
int grp_id; /**< Group indentifier. */
bool is_avail; /**< Indicates if the socket is available to send or listen. */
};
/** @addtogroup nss_nlsocket_macros @{ */
/**
* Prints error log.
*
* @param[in] arg Argument to be printed
*/
#define nss_nlsock_log_error(arg, ...) printf("NSS_NLERROR(%s[%d]):"arg, __func__, __LINE__, ##__VA_ARGS__)
/**
* Prints arguments
*
* @param[in] arg Argument to be printed
*/
#define nss_nlsock_log_info(arg, ...) printf("NSS_NLINFO(%s[%d]):"arg, __func__, __LINE__, ##__VA_ARGS__)
/** @} *//* end_addtogroup nss_nlsocket_macros */
/** @addtogroup nss_nlsocket_functions @{ */
/**
* Sets family name.
*
* @param[in] sock Socket context.
* @param[in] name Family name.
*
* @return
* None.
*/
static inline void nss_nlsock_set_family(struct nss_nlsock_ctx *sock, const char *name)
{
sock->family_name = name;
}
/**
* Sets user context.
*
* @param[in] sock Socket context.
* @param[in] user User context.
*
* @return
* None.
*/
static inline void nss_nlsock_set_user_ctx(struct nss_nlsock_ctx *sock, void *user)
{
sock->user_ctx = user;
}
/**
* Extracts NSS NL message data.
*
* @param[in] msg NL message.
*
* @return
* Pointer to start of NSS NL message.
*/
static inline void *nss_nlsock_get_data(struct nl_msg *msg)
{
struct genlmsghdr *genl_hdr = nlmsg_data((nlmsg_hdr(msg)));
return genlmsg_data(genl_hdr);
}
/**
* Opens NSS NL family socket.
*
* @param[in] sock Socket context to be allocated by the caller.
* @param[in] cb Callback function for response.
*
* @return
* Status of the operation.
*
* @note The underlying entity should set the sock->family name for the socket to open.
*/
int nss_nlsock_open(struct nss_nlsock_ctx *sock, nl_recvmsg_msg_cb_t cb);
/**
* Closes NSS NL family socket.
*
* @param[in] sock Socket context.
*
* @return
* None.
*/
void nss_nlsock_close(struct nss_nlsock_ctx *sock);
/**
* Sends NSS NL message synchronously.
*
* @param[in] sock Socket context.
* @param[in] cm Common message header.
* @param[in] data Message data.
* @param[in] has_resp Determines if response is needed from kernel.
*
* @detdesc The function blocks until ack/error is received from the kernel
* and also blocks for the message response from the kernel if is_resp is TRUE
* @return
* Status of the send operation.
*/
int nss_nlsock_send(struct nss_nlsock_ctx *sock, struct nss_nlcmn *cm, void *data, bool has_resp);
/**
* Listens to asynchronous events from kernel.
*
* @param[in] sock Socket context.
*
* @return
* Listen status.
*/
int nss_nlsock_listen(struct nss_nlsock_ctx *sock);
/**
* Subscribes to multicast group.
*
* @param[in] sock Socket context.
* @param[in] grp_name NSS NL group name.
*
* @return
* Subscription status.
*/
int nss_nlsock_join_grp(struct nss_nlsock_ctx *sock, char *grp_name);
/**
* Unsubscribes from multicast group.
*
* @param[in] sock Socket context.
* @param[in] grp_name NSS NL group name.
*
* @return
* Status of the operation.
*/
int nss_nlsock_leave_grp(struct nss_nlsock_ctx *sock, char *grp_name);
/**
* Opens a socket for listening to NSS NL event data.
*
* @param[in] sock Socket context.
* @param[in] cb Callback function.
*
* @return
* Status of the operation.
*/
int nss_nlsock_open_mcast(struct nss_nlsock_ctx *sock, nl_recvmsg_msg_cb_t cb);
/** @} *//* end_addtogroup nss_nlsocket_functions */
#endif /* __NSS_NLSOCK_API_H__ */

View File

@@ -0,0 +1,138 @@
/*
**************************************************************************
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**************************************************************************
*/
#include <nss_nlbase.h>
#include <nss_nlsock_api.h>
#include <nss_nldtls_api.h>
/*
* nss_nldtls_sock_cb()
* Callback func for dtls netlink socket
*/
int nss_nldtls_sock_cb(struct nl_msg *msg, void *arg)
{
pid_t pid = getpid();
struct nss_nldtls_rule *rule = nss_nlsock_get_data(msg);
if (!rule) {
nss_nlsock_log_error("%d:failed to get NSS NL dtls header\n", pid);
return NL_SKIP;
}
uint8_t cmd = nss_nlcmn_get_cmd(&rule->cm);
switch (cmd) {
case NSS_NLDTLS_CMD_TYPE_CREATE_TUN:
case NSS_NLDTLS_CMD_TYPE_DESTROY_TUN:
case NSS_NLDTLS_CMD_TYPE_UPDATE_CONFIG:
case NSS_NLDTLS_CMD_TYPE_TX_PKTS:
return NL_OK;
default:
nss_nlsock_log_error("%d:unsupported message cmd type(%d)\n", pid, cmd);
return NL_SKIP;
}
}
/*
* nss_nldtls_sock_open()
* Opens the NSS dtls NL socket for usage
*/
int nss_nldtls_sock_open(struct nss_nldtls_ctx *ctx, void *user_ctx, nss_nldtls_event_t event_cb)
{
pid_t pid = getpid();
int error;
if (!ctx) {
nss_nlsock_log_error("%d: invalid parameters passed\n", pid);
return -EINVAL;
}
memset(ctx, 0, sizeof(*ctx));
nss_nlsock_set_family(&ctx->sock, NSS_NLDTLS_FAMILY);
nss_nlsock_set_user_ctx(&ctx->sock, user_ctx);
/*
* try opening the socket with Linux
*/
error = nss_nlsock_open(&ctx->sock, nss_nldtls_sock_cb);
if (error) {
nss_nlsock_log_error("%d:unable to open NSS dtls socket, error(%d)\n", pid, error);
goto fail;
}
return 0;
fail:
memset(ctx, 0, sizeof(*ctx));
return error;
}
/*
* nss_nldtls_sock_close()
* Close the NSS dtls NL socket
*/
void nss_nldtls_sock_close(struct nss_nldtls_ctx *ctx)
{
nss_nlsock_close(&ctx->sock);
memset(ctx, 0, sizeof(struct nss_nldtls_ctx));
}
/*
* nss_nldtls_sock_send()
* Send the dtls message synchronously through the socket
*/
int nss_nldtls_sock_send(struct nss_nldtls_ctx *ctx, struct nss_nldtls_rule *rule, nss_nldtls_resp_t cb, void *data)
{
int32_t family_id = ctx->sock.family_id;
struct nss_nldtls_resp *resp;
pid_t pid = getpid();
bool has_resp = false;
int error = 0;
if (!rule) {
nss_nlsock_log_error("%d:invalid NSS dtls rule\n", pid);
return -EINVAL;
}
if (cb) {
nss_nlcmn_set_cb_owner(&rule->cm, family_id);
resp = nss_nlcmn_get_cb_data(&rule->cm, family_id);
assert(resp);
resp->data = data;
resp->cb = cb;
has_resp = true;
}
error = nss_nlsock_send(&ctx->sock, &rule->cm, rule, has_resp);
if (error) {
nss_nlsock_log_error("%d:failed to send NSS dtls rule, error(%d)\n", pid, error);
}
return error;
}
/*
* nss_nldtls_init_rule()
* Initialize the dtls rule
*/
void nss_nldtls_init_rule(struct nss_nldtls_rule *rule, enum nss_nldtls_cmd_type type)
{
nss_nldtls_rule_init(rule, type);
}

View File

@@ -0,0 +1,176 @@
/*
**************************************************************************
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**************************************************************************
*/
#include <nss_nlbase.h>
#include <nss_nlsock_api.h>
#include <nss_nlipv4_api.h>
/*
* nss_nlipv4_sock_cb()
* NSS NL IPv4 callback
*/
int nss_nlipv4_sock_cb(struct nl_msg *msg, void *arg)
{
pid_t pid = getpid();
struct nss_nlipv4_ctx *ctx = (struct nss_nlipv4_ctx *)arg;
struct nss_nlsock_ctx *sock = &ctx->sock;
struct nss_nlipv4_rule *rule = nss_nlsock_get_data(msg);
if (!rule) {
nss_nlsock_log_error("%d:failed to get NSS NL IPv4 header\n", pid);
return NL_SKIP;
}
uint8_t cmd = nss_nlcmn_get_cmd(&rule->cm);
switch (cmd) {
case NSS_IPV4_TX_CREATE_RULE_MSG:
case NSS_IPV4_TX_DESTROY_RULE_MSG:
{
void *cb_data = nss_nlcmn_get_cb_data(&rule->cm, sock->family_id);
if (!cb_data) {
return NL_SKIP;
}
/*
* Note: The callback user can modify the CB content so it
* needs to locally save the response data for further use
* after the callback is completed
*/
struct nss_nlipv4_resp resp;
memcpy(&resp, cb_data, sizeof(struct nss_nlipv4_resp));
/*
* clear the ownership of the CB so that callback user can
* use it if needed
*/
nss_nlcmn_clr_cb_owner(&rule->cm);
if (!resp.cb) {
nss_nlsock_log_info("%d:no IPv4 response callback for cmd(%d)\n", pid, cmd);
return NL_SKIP;
}
resp.cb(sock->user_ctx, rule, resp.data);
return NL_OK;
}
case NSS_IPV4_RX_CONN_STATS_SYNC_MSG:
{
nss_nlipv4_event_t event = ctx->event;
assert(event);
event(sock->user_ctx, rule);
return NL_OK;
}
default:
nss_nlsock_log_error("%d:unsupported message cmd type(%d)\n", pid, cmd);
return NL_SKIP;
}
}
/*
* nss_nlipv4_sock_open()
* this opens the NSS IPv4 NL socket for usage
*/
int nss_nlipv4_sock_open(struct nss_nlipv4_ctx *ctx, void *user_ctx, nss_nlipv4_event_t event_cb)
{
pid_t pid = getpid();
int error;
if (!ctx) {
nss_nlsock_log_error("%d: invalid parameters passed\n", pid);
return -EINVAL;
}
memset(ctx, 0, sizeof(*ctx));
nss_nlsock_set_family(&ctx->sock, NSS_NLIPV4_FAMILY);
nss_nlsock_set_user_ctx(&ctx->sock, user_ctx);
/*
* try opening the socket with Linux
*/
error = nss_nlsock_open(&ctx->sock, nss_nlipv4_sock_cb);
if (error) {
nss_nlsock_log_error("%d:unable to open NSS IPv4 socket, error(%d)\n", pid, error);
goto fail;
}
return 0;
fail:
memset(ctx, 0, sizeof(*ctx));
return error;
}
/*
* nss_nlipv4_sock_close()
* close the NSS IPv4 NL socket
*/
void nss_nlipv4_sock_close(struct nss_nlipv4_ctx *ctx)
{
nss_nlsock_close(&ctx->sock);
}
/*
* nss_nlipv4_sock_send()
* register callback and send the IPv4 message synchronously through the socket
*/
int nss_nlipv4_sock_send(struct nss_nlipv4_ctx *ctx, struct nss_nlipv4_rule *rule, nss_nlipv4_resp_t cb, void *data)
{
int32_t family_id = ctx->sock.family_id;
struct nss_nlipv4_resp *resp;
pid_t pid = getpid();
bool has_resp = false;
int error;
if (!rule) {
nss_nlsock_log_error("%d:invalid NSS IPv4 rule\n", pid);
return -ENOMEM;
}
if (cb) {
nss_nlcmn_set_cb_owner(&rule->cm, family_id);
resp = nss_nlcmn_get_cb_data(&rule->cm, family_id);
assert(resp);
resp->data = data;
resp->cb = cb;
has_resp = true;
}
error = nss_nlsock_send(&ctx->sock, &rule->cm, rule, has_resp);
if (error) {
nss_nlsock_log_error("%d:failed to send NSS IPv4 rule, error(%d)\n", pid, error);
return error;
}
return 0;
}
/*
* nss_nlipv4_init_rule()
* init the rule message
*/
void nss_nlipv4_init_rule(struct nss_nlipv4_rule *rule, enum nss_ipv4_message_types type)
{
nss_nlipv4_rule_init(rule, type);
}

View File

@@ -0,0 +1,176 @@
/*
**************************************************************************
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**************************************************************************
*/
#include <nss_nlbase.h>
#include <nss_nlsock_api.h>
#include <nss_nlipv6_api.h>
/*
* nss_nlipv6_sock_cb()
* NSS NL IPv6 callback
*/
int nss_nlipv6_sock_cb(struct nl_msg *msg, void *arg)
{
pid_t pid = getpid();
struct nss_nlipv6_ctx *ctx = (struct nss_nlipv6_ctx *)arg;
struct nss_nlsock_ctx *sock = &ctx->sock;
struct nss_nlipv6_rule *rule = nss_nlsock_get_data(msg);
if (!rule) {
nss_nlsock_log_error("%d:failed to get NSS NL IPv6 header\n", pid);
return NL_SKIP;
}
uint8_t cmd = nss_nlcmn_get_cmd(&rule->cm);
switch (cmd) {
case NSS_IPV6_TX_CREATE_RULE_MSG:
case NSS_IPV6_TX_DESTROY_RULE_MSG:
{
void *cb_data = nss_nlcmn_get_cb_data(&rule->cm, sock->family_id);
if (!cb_data) {
return NL_SKIP;
}
/*
* Note: The callback user can modify the CB content so it
* needs to locally save the response data for further use
* after the callback is completed
*/
struct nss_nlipv6_resp resp;
memcpy(&resp, cb_data, sizeof(struct nss_nlipv6_resp));
/*
* clear the ownership of the CB so that callback user can
* use it if needed
*/
nss_nlcmn_clr_cb_owner(&rule->cm);
if (!resp.cb) {
nss_nlsock_log_info("%d:no IPv6 response callback for cmd(%d)\n", pid, cmd);
return NL_SKIP;
}
resp.cb(sock->user_ctx, rule, resp.data);
return NL_OK;
}
case NSS_IPV6_RX_CONN_STATS_SYNC_MSG:
{
nss_nlipv6_event_t event = ctx->event;
assert(event);
event(sock->user_ctx, rule);
return NL_OK;
}
default:
nss_nlsock_log_error("%d:unsupported message cmd type(%d)\n", pid, cmd);
return NL_SKIP;
}
}
/*
* nss_nlipv6_sock_open()
* this opens the NSS IPv6 NL socket for usage
*/
int nss_nlipv6_sock_open(struct nss_nlipv6_ctx *ctx, void *user_ctx, nss_nlipv6_event_t event_cb)
{
pid_t pid = getpid();
int error;
if (!ctx) {
nss_nlsock_log_error("%d: invalid parameters passed\n", pid);
return -EINVAL;
}
memset(ctx, 0, sizeof(*ctx));
nss_nlsock_set_family(&ctx->sock, NSS_NLIPV6_FAMILY);
nss_nlsock_set_user_ctx(&ctx->sock, user_ctx);
/*
* try opening the socket with Linux
*/
error = nss_nlsock_open(&ctx->sock, nss_nlipv6_sock_cb);
if (error) {
nss_nlsock_log_error("%d:unable to open NSS IPv6 socket, error(%d)\n", pid, error);
goto fail;
}
return 0;
fail:
memset(ctx, 0, sizeof(*ctx));
return error;
}
/*
* nss_nlipv6_sock_close()
* close the NSS IPv6 NL socket
*/
void nss_nlipv6_sock_close(struct nss_nlipv6_ctx *ctx)
{
nss_nlsock_close(&ctx->sock);
}
/*
* nss_nlipv6_sock_send()
* register callback and send the IPv6 message synchronously through the socket
*/
int nss_nlipv6_sock_send(struct nss_nlipv6_ctx *ctx, struct nss_nlipv6_rule *rule, nss_nlipv6_resp_t cb, void *data)
{
int32_t family_id = ctx->sock.family_id;
struct nss_nlipv6_resp *resp;
pid_t pid = getpid();
bool has_resp = false;
int error;
if (!rule) {
nss_nlsock_log_error("%d:invalid NSS IPv6 rule\n", pid);
return -ENOMEM;
}
if (cb) {
nss_nlcmn_set_cb_owner(&rule->cm, family_id);
resp = nss_nlcmn_get_cb_data(&rule->cm, family_id);
assert(resp);
resp->data = data;
resp->cb = cb;
has_resp = true;
}
error = nss_nlsock_send(&ctx->sock, &rule->cm, rule, has_resp);
if (error) {
nss_nlsock_log_error("%d:failed to send NSS IPv6 rule, error(%d)\n", pid, error);
return error;
}
return 0;
}
/*
* nss_nlipv6_init_rule()
* init the rule message
*/
void nss_nlipv6_init_rule(struct nss_nlipv6_rule *rule, enum nss_ipv6_message_types type)
{
nss_nlipv6_rule_init(rule, type);
}

View File

@@ -0,0 +1,146 @@
/*
**************************************************************************
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**************************************************************************
*/
#include <nss_nlbase.h>
#include <nss_nlsock_api.h>
#include <nss_nlmcast_api.h>
/*
* nss_nlmcast_sock_cb()
* NSS NL mcast callback.
*/
static int nss_nlmcast_sock_cb(struct nl_msg *msg, void *arg)
{
struct nss_nlmcast_ctx *ctx = (struct nss_nlmcast_ctx *)arg;
struct genlmsghdr *genl_hdr = nlmsg_data((nlmsg_hdr(msg)));
uint8_t cmd = genl_hdr->cmd;
void *data = nss_nlsock_get_data(msg);
if (!data) {
nss_nlsock_log_error("%d:failed to get NSS NL msg header\n", getpid());
return NL_SKIP;
}
nss_nlmcast_event_t event = ctx->event;
assert(event);
event(cmd, data);
return NL_OK;
}
/*
* nss_nlmcast_sock_open()
* Open the NL socket for listening to MCAST events from kernel.
*/
int nss_nlmcast_sock_open(struct nss_nlmcast_ctx *ctx, nss_nlmcast_event_t event_cb, const char *family_name)
{
int error;
if (!ctx || !event_cb) {
nss_nlsock_log_error("Invalid parameters passed\n");
return -EINVAL;
}
memset(ctx, 0, sizeof(*ctx));
nss_nlsock_set_family(&ctx->sock, family_name);
/*
* Subscribe to the NSS NL Multicast group.
*/
error = nss_nlsock_open_mcast(&ctx->sock, nss_nlmcast_sock_cb);
if (error) {
nss_nlsock_log_error("Unable to create socket, error(%d)\n", error);
return error;
}
ctx->event = event_cb;
return 0;
}
/*
* nss_nlmcast_sock_close()
* Close the NL socket.
*/
void nss_nlmcast_sock_close(struct nss_nlmcast_ctx *ctx)
{
nss_nlsock_close(&ctx->sock);
}
/*
* nss_nlmcast_sock_join_grp()
* Subscribe for MCAST group from kernel.
*/
int nss_nlmcast_sock_join_grp(struct nss_nlmcast_ctx *ctx, char *grp_name)
{
int error;
if (!ctx || !grp_name) {
nss_nlsock_log_error("Invalid parameters passed\n");
return -EINVAL;
}
error = nss_nlsock_join_grp(&ctx->sock, grp_name);
if (error) {
nss_nlsock_log_error("Unable to subscribe for mcast group, error(%d)\n", error);
return error;
}
return 0;
}
/*
* nss_nlmcast_sock_leave_grp()
* Unsubscribe for MCAST group from kernel.
*/
int nss_nlmcast_sock_leave_grp(struct nss_nlmcast_ctx *ctx, char *grp_name)
{
int error;
if (!ctx || !grp_name) {
nss_nlsock_log_error("Invalid parameters passed\n");
return -EINVAL;
}
error = nss_nlsock_leave_grp(&ctx->sock, grp_name);
if (error) {
nss_nlsock_log_error("Unable to unsubscribe for mcast group, error(%d)\n", error);
return error;
}
return 0;
}
/*
* nss_nlmcast_sock_listen()
* Listen for MCAST events from kernel
*/
int nss_nlmcast_sock_listen(struct nss_nlmcast_ctx *ctx)
{
int error;
if (!ctx) {
nss_nlsock_log_error("Invalid parameters passed\n");
return -EINVAL;
}
error = nss_nlsock_listen(&ctx->sock);
if (error) {
nss_nlsock_log_error("Unable to listen to mcast events, error(%d)\n", error);
return error;
}
return 0;
}

View File

@@ -0,0 +1,498 @@
/*
**************************************************************************
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**************************************************************************
*/
/*
* @file netlink socket handler
*/
#include <nss_nlbase.h>
#include <nss_nlsock_api.h>
/*
* nss_nlsock_deinit()
* de-initialize the socket
*/
static void nss_nlsock_deinit(struct nss_nlsock_ctx *sock)
{
assert(sock);
nl_cb_put(sock->nl_cb);
sock->nl_cb = NULL;
nl_socket_free(sock->nl_sk);
sock->nl_sk = NULL;
}
/*
* nss_nlsock_init()
* initialize the socket and callback
*/
static int nss_nlsock_init(struct nss_nlsock_ctx *sock, nl_recvmsg_msg_cb_t cb)
{
int error;
assert(sock);
/*
* Initialize spinlock
*/
error = pthread_spin_init(&sock->lock, PTHREAD_PROCESS_PRIVATE);
if (error) {
nss_nlsock_log_error("Failed to init spinlock for family(%s), error %d\n", sock->family_name, error);
return error;
}
sock->pid = getpid();
/*
* create callback
*/
sock->nl_cb = nl_cb_alloc(NL_CB_CUSTOM);
if (!sock->nl_cb) {
nss_nlsock_log_error("%d:failed to alloc callback for family(%s)\n",sock->pid, sock->family_name);
goto fail1;
}
/*
* register callback
*/
nl_cb_set(sock->nl_cb, NL_CB_VALID, NL_CB_CUSTOM, cb, sock);
/*
* Create netlink socket
*/
sock->nl_sk = nl_socket_alloc_cb(sock->nl_cb);
if (!sock->nl_sk) {
nss_nlsock_log_error("%d:failed to alloc socket for family(%s)\n", sock->pid, sock->family_name);
goto fail2;
}
sock->ref_cnt = 1;
/*
* is_avail is set to indicate the socket is available for send/listen
*/
sock->is_avail = true;
return 0;
fail2:
nl_cb_put(sock->nl_cb);
sock->nl_cb = NULL;
fail1:
pthread_spin_destroy(&sock->lock);
sock->lock = (pthread_spinlock_t)0;
return -ENOMEM;
}
/*
* nss_nlsock_deref()
* decrement the reference count and free socket resources if '0'
*/
static inline void nss_nlsock_deref(struct nss_nlsock_ctx *sock)
{
assert(sock->ref_cnt > 0);
pthread_spin_lock(&sock->lock);
if (--sock->ref_cnt) {
pthread_spin_unlock(&sock->lock);
return;
}
/*
* When there are no more references on the socket,
* deinitialize the socket and destroy the spin lock
* created during nss_nlsock_init
*/
nss_nlsock_deinit(sock);
pthread_spin_unlock(&sock->lock);
pthread_spin_destroy(&sock->lock);
sock->lock = (pthread_spinlock_t)0;
}
/*
* nss_nlsock_ref()
* Increment the reference count.
*
* if ref_cnt == 0, return false
* if ref_cnt != 0, increment the socket reference count and return true
*/
static inline bool nss_nlsock_ref(struct nss_nlsock_ctx *sock)
{
/*
* if ref count is 0, it means there are no references
* on the socket and so return false. Socket will eventually be
* freed by nss_nlsock_deinit else increment the ref count
*/
pthread_spin_lock(&sock->lock);
if (sock->ref_cnt == 0) {
pthread_spin_unlock(&sock->lock);
return false;
}
sock->ref_cnt++;
pthread_spin_unlock(&sock->lock);
return true;
}
/*
* nss_nlsock_listen_callback()
* listen to responses from the netlink socket
*
* The API keeps listening for the responses on the netlink socket
* until socket close is initiated and there are no more
* responses on the socket
*/
static void *nss_nlsock_listen_callback(void *arg)
{
struct nss_nlsock_ctx *sock = (struct nss_nlsock_ctx *)arg;
assert(sock);
/*
* drain responses on the socket
*/
for (;;) {
/*
* if, socket is freed then break out
*/
if (!nss_nlsock_ref(sock)) {
break;
}
/*
* get or block for pending messages
*/
nl_recvmsgs(sock->nl_sk, sock->nl_cb);
nss_nlsock_deref(sock);
}
return NULL;
}
/*
* nss_nlsock_msg_init()
* Initialize parameters to send message down the socket
*/
static int nss_nlsock_msg_init(struct nss_nlsock_ctx *sock, struct nss_nlcmn *cm, void *data, struct nl_msg *msg)
{
int pid = sock->pid;
void *user_hdr;
uint32_t ver;
uint8_t cmd;
int len;
ver = nss_nlcmn_get_ver(cm);
len = nss_nlcmn_get_len(cm);
cmd = nss_nlcmn_get_cmd(cm);
/*
* create space for user header
*/
user_hdr = genlmsg_put(msg, pid, NL_AUTO_SEQ, sock->family_id, len, 0, cmd, ver);
if (!user_hdr) {
nss_nlsock_log_error("%d:failed to put message header of len(%d)\n", pid, len);
return -ENOMEM;
}
memcpy(user_hdr, data, len);
return 0;
}
/*
* nss_nlsock_leave_grp()
* nl socket unsubscribe for the multicast group
*/
int nss_nlsock_leave_grp(struct nss_nlsock_ctx *sock, char *grp_name)
{
int error;
assert(sock->ref_cnt > 0);
/*
* Resolve the group
*/
sock->grp_id = genl_ctrl_resolve_grp(sock->nl_sk, sock->family_name, grp_name);
if (sock->grp_id < 0) {
nss_nlsock_log_error("failed to resolve group(%s)\n", grp_name);
return -EINVAL;
}
/*
* Unsubscribe for the mcast async events
*/
error = nl_socket_drop_memberships(sock->nl_sk, sock->grp_id, 0);
if (error < 0) {
nss_nlsock_log_error("failed to deregister grp(%s)\n", grp_name);
return error;
}
return 0;
}
/*
* nss_nlsock_join_grp()
* nl socket subscribe for the multicast group
*/
int nss_nlsock_join_grp(struct nss_nlsock_ctx *sock, char *grp_name)
{
int error;
assert(sock->ref_cnt > 0);
/*
* Resolve the group
*/
sock->grp_id = genl_ctrl_resolve_grp(sock->nl_sk, sock->family_name, grp_name);
if (sock->grp_id < 0) {
nss_nlsock_log_error("failed to resolve group(%s)\n", grp_name);
return -EINVAL;
}
/*
* Subscribe for the mcast async events
*/
error = nl_socket_add_memberships(sock->nl_sk, sock->grp_id, 0);
if (error < 0) {
nss_nlsock_log_error("failed to register grp(%s)\n", grp_name);
return error;
}
return 0;
}
/*
* nss_nlsock_open_mcast()
* Open the socket for async events
*/
int nss_nlsock_open_mcast(struct nss_nlsock_ctx *sock, nl_recvmsg_msg_cb_t cb)
{
int error;
assert(sock);
error = nss_nlsock_init(sock, cb);
if (error) {
nss_nlsock_log_error("%d:failed to initialize socket(%s)\n", sock->pid, sock->family_name);
return error;
}
/*
* Disable seq number and auto ack checks for sockets listening for mcast events
*/
nl_socket_disable_seq_check(sock->nl_sk);
nl_socket_disable_auto_ack(sock->nl_sk);
/*
* Connect the socket with the netlink bus
*/
if (genl_connect(sock->nl_sk)) {
nss_nlsock_log_error("%d:failed to connect socket for family(%s)\n", sock->pid, sock->family_name);
error = -EBUSY;
goto free_sock;
}
return 0;
free_sock:
nss_nlsock_deref(sock);
return error;
}
/*
* nss_nlsock_send()
* send a message synchronously through the socket
*/
int nss_nlsock_send(struct nss_nlsock_ctx *sock, struct nss_nlcmn *cm, void *data, bool has_resp)
{
int pid = sock->pid;
struct nl_msg *msg;
int error;
/*
* return -EBUSY if the socket is currently unavailable for sending message
*/
pthread_spin_lock(&sock->lock);
if (!sock->is_avail) {
pthread_spin_unlock(&sock->lock);
return -EBUSY;
}
/*
* To indicate the socket is unavailable until the current thread completes the send/listen.
* This is to prevent other threads from simultaneous send/listen.
*/
sock->is_avail = false;
pthread_spin_unlock(&sock->lock);
/*
* allocate new message buffer
*/
msg = nlmsg_alloc();
if (!msg) {
nss_nlsock_log_error("%d:failed to allocate message buffer\n", pid);
sock->is_avail = true;
return -ENOMEM;
}
/*
* Holds a reference on the socket until msg is sent down to the kernel
*/
if (!nss_nlsock_ref(sock)) {
nss_nlsock_log_error("%d:failed to get NL socket\n", pid);
nlmsg_free(msg);
sock->is_avail = true;
return -EINVAL;
}
/*
* Initialize message parameters
*/
error = nss_nlsock_msg_init(sock, cm, data, msg);
if (error) {
nss_nlsock_log_error("%d:failed to initialize message structure (family:%s, error:%d)\n",
pid, sock->family_name, error);
nss_nlsock_deref(sock);
nlmsg_free(msg);
sock->is_avail = true;
return error;
}
/*
* If has_resp is true and msg is sent to FW, then there will be two
* netlink messages coming from kernel - FW response and ACK
* If msg fails in netlink, then error will be returned from kernel.
* If has_resp is false, then there is only one netlink message
* coming from kernel: either ACK or error
* In case firmware response is sent before nl_recvmsgs is invoked,
* the response will be queued until the listener is available.
*/
error = nl_send_sync(sock->nl_sk, msg);
if (error < 0) {
nss_nlsock_log_error("%d:failed to send (family:%s, error:%d)\n", pid, sock->family_name, error);
nss_nlsock_deref(sock);
sock->is_avail = true;
return error;
}
if (has_resp) {
nl_recvmsgs(sock->nl_sk, sock->nl_cb);
}
nss_nlsock_deref(sock);
sock->is_avail = true;
return 0;
}
/*
* nss_nlsock_listen()
* listen for async events on the socket
*/
int nss_nlsock_listen(struct nss_nlsock_ctx *sock)
{
int error;
assert(sock->ref_cnt > 0);
/*
* return -EBUSY if the socket is currently unavailable for listening
*/
if (!sock->is_avail) {
return -EBUSY;
}
/*
* To indicate the socket is unavailable until the current thread completes the send/listen.
* This is to prevent other threads from simultaneous send/listen.
*/
sock->is_avail = false;
/*
* Create an async thread for clearing the pending resp on the socket asynchronously
*/
error = pthread_create(&sock->thread, NULL, nss_nlsock_listen_callback, sock);
if (error) {
nss_nlsock_log_error("%d:failed to create sync thread for family(%s)\n", sock->pid, sock->family_name);
return error;
}
return 0;
}
/*
* nss_nlsock_close()
* close the allocated socket and all associated memory
*/
void nss_nlsock_close(struct nss_nlsock_ctx *sock)
{
assert(sock);
assert(sock->nl_sk);
assert(sock->ref_cnt > 0);
/*
* put the reference down for the socket
*/
nss_nlsock_deref(sock);
/*
* wait for the async thread to complete
*/
if (sock->thread) {
pthread_join(sock->thread, NULL);
sock->thread = NULL;
}
}
/*
* nss_nlsock_open()
* open a socket for unicast communication with the generic netlink framework
*/
int nss_nlsock_open(struct nss_nlsock_ctx *sock, nl_recvmsg_msg_cb_t cb)
{
int error = 0;
assert(sock);
error = nss_nlsock_init(sock, cb);
if (error) {
nss_nlsock_log_error("%d:failed to initialize socket(%s)\n", sock->pid, sock->family_name);
return error;
}
/*
* Connect the socket with the netlink bus
*/
if (genl_connect(sock->nl_sk)) {
nss_nlsock_log_error("%d:failed to connect socket for family(%s)\n", sock->pid, sock->family_name);
error = -EBUSY;
goto free_sock;
}
/*
* resolve the family
*/
sock->family_id = genl_ctrl_resolve(sock->nl_sk, sock->family_name);
if (sock->family_id <= 0) {
nss_nlsock_log_error("%d:failed to resolve family(%s)\n", sock->pid, sock->family_name);
error = -EINVAL;
goto free_sock;
}
return 0;
free_sock:
nss_nlsock_deref(sock);
return error;
}

View File

@@ -0,0 +1,39 @@
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=nssinfo
PKG_RELEASE:=1
include $(INCLUDE_DIR)/package.mk
define Package/nssinfo
SECTION:=utils
CATEGORY:=Utilities
TITLE:=Userspace utility for fetching stats from NSS
DEPENDS:=+libncurses +libnl-nss
endef
define Package/nssinfo/description
A userspace utility for fetching stats from NSS.
endef
TOOL_CFLAGS:= -I$(STAGING_DIR)/usr/include/qca-nss-clients \
-I$(STAGING_DIR)/usr/include/qca-nss-drv \
-I$(STAGING_DIR)/usr/include/libnl3 \
-I$(STAGING_DIR)/usr/include/libnl-nss
TOOL_LDFLAGS:= -L$(STAGING_DIR)/lib
define Build/Compile
$(MAKE) -C $(PKG_BUILD_DIR) \
CC="$(TARGET_CC)" \
CFLAGS="$(TOOL_CFLAGS)" \
LD_LIBRARY_PATH="$(TOOL_LDFLAGS)"
endef
define Package/nssinfo/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/obj/nssinfo $(1)/usr/sbin/
endef
$(eval $(call BuildPackage,nssinfo))

View File

@@ -0,0 +1,35 @@
MKDIR = mkdir -p $(@D)
SRCPATH = src
OBJPATH = obj
SRCDIR = ./
BINARY = $(OBJPATH)/nssinfo
SOURCES = $(wildcard $(SRCDIR)/src/*.c)
HEADERS = $(wildcard $(SRCDIR)/include/*.h)
OBJECTS = $(SOURCES:$(SRCDIR)/src/%.c=$(OBJPATH)/%.o)
INCLUDE += -I../lib/include
EXTRA_CFLAGS = -Wall -Wno-error=format-truncation -UENABLE_DEBUG
LDFLAGS = -lnl-nss -lncurses
LDLIBS = -L../lib/obj
all: release
release: $(BINARY)
$(OBJPATH)/%.o: $(SRCPATH)/%.c $(HEADERS)
$(MKDIR)
@echo [CC] $@
@$(CC) -c $(CFLAGS) $(EXTRA_CFLAGS) $(INCLUDE) -o $@ $<
$(BINARY): $(OBJECTS)
@echo $(BINARY)
@echo [LD] $@
@$(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS)
clean:
@echo [Clean]
@rm -f $(OBJECTS)
@rm -f $(BINARY)
@rmdir $(OBJPATH)
.PHONY: clean

View File

@@ -0,0 +1,714 @@
/*
**************************************************************************
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**************************************************************************
*/
/*
* @file NSSINFO handler
*/
#include <signal.h>
#include "nssinfo.h"
static pthread_t nssinfo_display_thread; /* Display statistics thread */
static char buf[NSSINFO_STR_LEN]; /* Formatted stats buffer */
bool display_all_stats; /* Display all stats per sub-system */
int invalid_input; /* Identify invalid input */
FILE *output_file; /* Output file pointer */
FILE *flow_file; /* Flow file pointer */
/* Array of pointers to node stats */
struct node *nodes[NSS_MAX_CORES][NSS_MAX_NET_INTERFACES];
/*
* NSS subsystems in alphabetical order for nssinfo tool
* - Make sure the order here is the same as in 'enum nss_nlcmn_subsys'
* defined in qca-nss-clients/netlink/include/nss_nlcmn_if.h.
*/
struct nssinfo_subsystem_info nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_MAX] = {
{.subsystem_name = "dynamic_interface", .init = nssinfo_dynamic_interface_init, .deinit = nssinfo_dynamic_interface_deinit},
{.subsystem_name = "eth_rx", .init = nssinfo_eth_rx_init, .deinit = nssinfo_eth_rx_deinit},
{.subsystem_name = "ipv4", .init = nssinfo_ipv4_init, .deinit = nssinfo_ipv4_deinit},
{.subsystem_name = "ipv6", .init = nssinfo_ipv6_init, .deinit = nssinfo_ipv6_deinit},
{.subsystem_name = "lso_rx", .init = nssinfo_lso_rx_init, .deinit = nssinfo_lso_rx_deinit},
{.subsystem_name = "n2h", .init = nssinfo_n2h_init, .deinit = nssinfo_n2h_deinit},
};
char *nssinfo_summary_fmt = "%-12s %-13s %-13s %-9s %-9s\n";
/*
* nssinfo_print_summary_header()
* Print the summary header.
*/
void nssinfo_print_summary_header(void)
{
nssinfo_stats_print(nssinfo_summary_fmt, "Node", "RX Pkts", "TX Pkts", "Drops", "Exceptions");
nssinfo_stats_print(nssinfo_summary_fmt, "----", "-------", "-------", "-----", "----------");
}
/*
* nssinfo_print_summary()
* Print the summary of the stats:
* - rx pkts
* - tx pkts
* - rx queue drops
* - exceptions
*/
void nssinfo_print_summary(char *node, uint64_t *cmn_node_stats, uint64_t *exception_stats, uint64_t exception_max)
{
int i;
uint64_t drops = 0, exceptions = 0;
char str_rx[NSSINFO_STR_LEN], str_tx[NSSINFO_STR_LEN], str_drop[NSSINFO_STR_LEN], str_ex[NSSINFO_STR_LEN];
assert(cmn_node_stats);
memset(str_rx, 0, sizeof(str_rx));
memset(str_tx, 0, sizeof(str_tx));
memset(str_drop, 0, sizeof(str_drop));
memset(str_ex, 0, sizeof(str_ex));
for (i = NSS_STATS_NODE_RX_QUEUE_0_DROPPED; i < NSS_STATS_NODE_MAX; i++) {
drops += cmn_node_stats[i];
}
if (exception_stats) {
for (i = 0 ; i < exception_max; i++) {
exceptions += exception_stats[i];
}
}
if (cmn_node_stats[NSS_STATS_NODE_RX_PKTS] > 0 || cmn_node_stats[NSS_STATS_NODE_TX_PKTS] > 0 ||
drops > 0 || exceptions > 0 || arguments.verbose) {
char *format_stats = nssinfo_format_stats(cmn_node_stats[NSS_STATS_NODE_RX_PKTS]);
strlcpy(str_rx, format_stats, sizeof(str_rx));
format_stats = nssinfo_format_stats(cmn_node_stats[NSS_STATS_NODE_TX_PKTS]);
strlcpy(str_tx, format_stats, sizeof(str_tx));
format_stats = nssinfo_format_stats(drops);
strlcpy(str_drop, format_stats, sizeof(str_drop));
if (exception_stats) {
format_stats = nssinfo_format_stats(exceptions);
strlcpy(str_ex, format_stats, sizeof(str_ex));
}
nssinfo_stats_print(nssinfo_summary_fmt, node, str_rx, str_tx, str_drop, str_ex);
}
}
/*
* nssinfo_print_all()
* Print detailed statistics.
*/
void nssinfo_print_all(char *node, char *stat_details, struct nssinfo_stats_info *stats_info, uint64_t max, uint64_t *stats_val)
{
int i;
uint16_t maxlen = 0;
char *type;
for (i = 0; i < max; i++){
if (strlen(stats_info[i].stats_name) > maxlen) {
maxlen = strlen(stats_info[i].stats_name);
}
}
/*
* Display stats header, e.g. "#ipv4 Common Stats\n"
*/
if (stat_details != NULL) {
nssinfo_stats_print("#%s\n", stat_details);
}
/* Display each stat, e.g.
* ipv4_rx_byts = 32903179 common
* ipv4_mc_create_invalid_interface = 12 special
* ...
*/
for (i = 0; i < max; i++) {
if (arguments.verbose || stats_val[i] > 0) {
switch (stats_info[i].stats_type) {
case NSS_STATS_TYPE_COMMON:
type = "common";
break;
case NSS_STATS_TYPE_SPECIAL:
type = "special";
break;
case NSS_STATS_TYPE_DROP:
type = "drop";
break;
case NSS_STATS_TYPE_ERROR:
type = "error";
break;
case NSS_STATS_TYPE_EXCEPTION:
type = "exception";
break;
default:
type = "unknown";
break;
}
nssinfo_stats_print("%s_%-*s = %-20llu %-s\n",
node, maxlen, stats_info[i].stats_name, stats_val[i], type);
}
}
nssinfo_stats_print("\n");
return;
}
/*
* nssinfo_parse_stats_strings()
* Parse each line in the debug strings file.
*
* Each line has the following format:
* \t<stats_type> , <stats_name>\n
* for example:
* root@OpenWrt:/sys/kernel/debug/qca-nss-drv/strings# cat n2h
* 0 , rx_pkts
* ...
* 1 , rx_queue[0]_drops
* ...
* 4 , n2h_data_interface_invalid
*/
static void nssinfo_parse_stats_strings(struct nssinfo_stats_info *info, char *line)
{
char *token;
char *rest = NULL;
token = strtok_r(line, " ", &rest);
if (token) {
info->stats_type = atoi(token);
token = strtok_r(NULL, ",", &rest);
}
if (token) {
token = strtok_r(token, " ", &rest);
}
if (token) {
token = strtok_r(token, "\n", &rest);
}
if (token) {
strlcpy(info->stats_name, token, sizeof(info->stats_name));
}
}
/*
* nssinfo_stats_info_init()
* Init 'struct nssinfo_stats_info' from a file in /sys/kernel/debug/qca-nss-drv/strings/.
*/
int nssinfo_stats_info_init(struct nssinfo_stats_info *info, char *strings_file)
{
FILE *fptr;
char line[NSS_STATS_MAX_STR_LENGTH];
fptr = fopen(strings_file, "r");
if (!fptr) {
nssinfo_error("Unable to open\n");
return -1;
}
while (fgets(line, NSS_STATS_MAX_STR_LENGTH, fptr)) {
nssinfo_parse_stats_strings(info, line);
info++;
}
fclose(fptr);
return 0;
}
/*
* nssinfo_node_stats_destroy()
* Release memories used to store the node stats.
*/
void nssinfo_node_stats_destroy(pthread_mutex_t *mutex, uint32_t core_id, uint32_t if_num)
{
struct node *p, *next;
if (mutex) {
pthread_mutex_lock(mutex);
}
p = nodes[core_id][if_num];
nodes[core_id][if_num] = NULL;
if (mutex) {
pthread_mutex_unlock(mutex);
}
while (p) {
next = p->next;
if (p->cmn_node_stats) {
free(p->cmn_node_stats);
}
if (p->node_stats) {
free(p->node_stats);
}
if (p->exception_stats) {
free(p->exception_stats);
}
free(p);
p = next;
}
return;
}
/*
* nssinfo_add_comma()
* Add commas in thousand's place in statistics.
*/
static char* nssinfo_add_comma(uint64_t num)
{
if (num < 1000) {
snprintf(buf, sizeof(buf), "%llu", num);
return buf;
}
nssinfo_add_comma(num/1000);
snprintf(buf + strlen(buf), sizeof(buf[NSSINFO_STR_LEN] + strlen(buf)), ",%03llu", num % 1000);
return buf;
}
/*
* nssinfo_add_suffix()
* Convert number into K thousands M million and B billion suffix.
*/
static char* nssinfo_add_suffix(uint64_t num)
{
if (num < 1000) {
snprintf(buf, sizeof(buf), "%llu", num);
return buf;
}
if (1000 <= num && num < 1000000) {
snprintf(buf , sizeof(buf), "%.2lfK", num / 1000.0);
return buf;
}
if (1000000 <= num && num < 1000000000) {
snprintf(buf , sizeof(buf), "%.2lfM", num / 1000000.0);
return buf;
}
if (1000000000 <= num) {
snprintf(buf , sizeof(buf), "%.2lfB", num / 1000000000.0);
return buf;
}
return buf;
}
/*
* nssinfo_format_stats()
* Format statistics value.
*/
char* nssinfo_format_stats(uint64_t num)
{
memset(buf, 0, sizeof(buf));
if (!arguments.higher_unit) {
return nssinfo_add_comma(num);
}
return nssinfo_add_suffix(num);
}
/*
* nssinfo_stats_display()
* Invoke each sub-system's display function.
*/
static void *nssinfo_stats_display(void *arg)
{
int i, j, core;
char mesg[]="NSS STATS";
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
for (;;) {
nssinfo_stats_print("\t\t\t%s\n", mesg);
/*
* If user does not specify a core id,
* check if the flow file is specified and display stats accordingly.
*/
if (arguments.core < 0) {
/*
* If flow file is not specified (via '-f' option),
* display each node's summary stats in alphabetical order for all the cores.
*/
if (!flow_file) {
for (core = 0 ; core < NSS_MAX_CORES ; core++) {
nssinfo_stats_print("Stats for core %d\n",core);
nssinfo_print_summary_header();
for (i = 0 ; i < NSS_NLCMN_SUBSYS_MAX; i++) {
if (nssinfo_subsystem_array[i].is_inited && i != NSS_NLCMN_SUBSYS_DYNAMIC_INTERFACE) {
nssinfo_subsystem_array[i].display(core, NULL);
}
}
nssinfo_stats_print("\n");
}
goto done;
}
/*
* Flow file is specified (via '-f' option),
* Parse the network graph from flow file and display the node's summary stats
* For example, the network graph would look like
* ipv4-0 eth_rx-0 n2h-1
* Where, node = ipv4 , core = 0
* node = eth_rx , core = 0
* node = n2h , core = 1
*/
char *line = NULL;
char *rest = NULL;
size_t len = 0;
ssize_t read;
char *node = NULL;
int matched = 0;
nssinfo_print_summary_header();
fseek(flow_file, 0, SEEK_SET);
while ((read = getline(&line, &len, flow_file)) != -1) {
node = strtok_r(line, "-", &rest);
while (node != NULL) {
core = atoi(strtok_r(NULL, " ", &rest));
if (core >= NSS_MAX_CORES || core < 0) {
printf("Invalid core id `%d'\n", core);
exit(-1);
}
for (j = 0; j < NSS_NLCMN_SUBSYS_MAX; j++) {
if (nssinfo_subsystem_array[j].is_inited &&
strstr(node, nssinfo_subsystem_array[j].subsystem_name)) {
if (j != NSS_NLCMN_SUBSYS_DYNAMIC_INTERFACE) {
++matched;
nssinfo_subsystem_array[j].display(core, node);
}
}
}
node = strtok_r(NULL, "-", &rest);
}
/* If all NODE names are invalid */
if (matched == invalid_input) {
nssinfo_error("Invalid input\n");
return NULL;
}
}
if (line) {
free(line);
}
goto done;
}
if (!arguments.strings[0]) {
/*
* If a core id is specified (via '-c' option) but NODE is not specified,
* display each node's summary stats in alphabetical order for that core.
*/
nssinfo_stats_print("Stats for core %d\n", arguments.core);
nssinfo_print_summary_header();
for (i = 0 ; i < NSS_NLCMN_SUBSYS_MAX; i++) {
if (nssinfo_subsystem_array[i].is_inited && i != NSS_NLCMN_SUBSYS_DYNAMIC_INTERFACE) {
nssinfo_subsystem_array[i].display(arguments.core, NULL);
}
}
goto done;
}
/*
* If a core id is specified and at least one NODE is specified.
*/
nssinfo_stats_print("Stats for core %d\n", arguments.core);
/*
* If user specifies only one NODE, then display all stats for this NODE.
* For example, if NODE="ipv4", then display:
* - common stats (i.e. enum nss_stats_node)
* - ipv4 special stats (i.e. enum nss_ipv4_stats_types)
* - ipv4 exception stats (i.e. enum nss_ipv4_exception_events)
*/
if (!arguments.strings[1]) {
display_all_stats = true;
} else {
/*
* If user specifies more than one NODEs, then display the summary stats for each node
*/
nssinfo_print_summary_header();
}
/*
* Now, display NODEs in the desired order.
*/
int matched = 0;
for (i = 0; arguments.strings[i]; i++) {
for (j = 0; j < NSS_NLCMN_SUBSYS_MAX; j++) {
if (nssinfo_subsystem_array[j].is_inited &&
strstr(arguments.strings[i], nssinfo_subsystem_array[j].subsystem_name)) {
if (j != NSS_NLCMN_SUBSYS_DYNAMIC_INTERFACE) {
++matched;
nssinfo_subsystem_array[j].display(arguments.core, arguments.strings[i]);
}
}
}
}
/*
* If all NODE names are invalid.
*/
if (matched == invalid_input) {
nssinfo_error("Invalid input\n");
return NULL;
}
done:
/*
* If using ncurses, refresh the screen.
*/
if (!output_file) {
refresh(); /* draw on screen */
clear(); /* clear screen buffer */
move(0, 0); /* move cursor to (line, column)=(0,0) */
}
invalid_input = 0;
sleep(arguments.rate);
}
}
/*
* nssinfo_curses_init()
* Initialize curses library.
*/
static int nssinfo_curses_init()
{
int rows, cols;
if (!initscr()) { /* satrt curses mode */
nssinfo_error("Unable to initialize curses screen\n");
return -EOPNOTSUPP;
}
getmaxyx(stdscr, rows, cols); /* get the size of the screen */
if (rows < CURSES_ROWS_MIN) {
nssinfo_error("Screen must be at least %d rows in height", CURSES_ROWS_MIN);
goto out;
}
if (cols < CURSES_COLS_MIN) {
nssinfo_error("Screen must be at least %d columns width", CURSES_COLS_MIN);
goto out;
}
cbreak(); /* disable line buffering */
noecho(); /* not to echo the input back to the screen */
nonl(); /* disable 'enter' key translation */
keypad(stdscr, TRUE); /* enable keypad keys, such as arrow keys, etc. */
nodelay(stdscr, TRUE); /* cause getch() to be a non-blocking call */
curs_set(0); /* make the cursor invisible */
clear(); /* clear screen buffer */
move(0, 0); /* move cursor to (line, column)=(0,0) */
return 0;
out:
endwin(); /* stop curses mode */
return -1;
}
/*
* nssinfo_termination_handler()
* Terminates all the modules.
*/
static void nssinfo_termination_handler(int signum)
{
pthread_cancel(nssinfo_display_thread);
}
/*
* nssinfo_display_init()
* Handle displaying all the stats.
*/
static int nssinfo_display_init()
{
int error;
if (!output_file) {
if (nssinfo_curses_init() != 0) {
return -1;
}
}
error = pthread_create(&nssinfo_display_thread, NULL, nssinfo_stats_display, NULL);
if (error) {
nssinfo_error("failed to create display thread, error %d\n", error);
if (!output_file) {
endwin();
}
}
return error;
}
/*
* nssinfo_display_wait()
* Wait for the display thread.
*/
static int nssinfo_display_wait()
{
/*
* waiting for the display thread to be terminated.
*/
pthread_join(nssinfo_display_thread, NULL);
if (!output_file) {
refresh();
endwin();
}
return 0;
}
/*
* nssinfo_notify_callback
* Get notified when NL message is received.
*/
static void nssinfo_notify_callback(int cmd, void *data)
{
if (cmd < NSS_NLCMN_SUBSYS_MAX && nssinfo_subsystem_array[cmd].is_inited) {
nssinfo_subsystem_array[cmd].notify(data);
} else {
nssinfo_error("Unknown message type %d\n", cmd);
}
}
/*
*/
static void nssinfo_deinit(struct nss_nlmcast_ctx *ctx)
{
int i, core;
struct node *node;
nssinfo_deinit_t deinit;
/*
* Close NL socket and terminate ctx->sock.thread
*/
nss_nlmcast_sock_close(ctx);
/*
* Release memory used for storing stats
*/
for (core = 0; core < NSS_MAX_CORES; ++core) {
for (i = 0; i < NSS_MAX_NET_INTERFACES; ++i) {
node = nodes[core][i];
if (node) {
assert(node->subsystem_id != NSS_NLCMN_SUBSYS_DYNAMIC_INTERFACE);
nssinfo_subsystem_array[node->subsystem_id].destroy(core, i);
}
}
}
/*
* Release resources used by each subsystem
*/
for (i = 0; i < NSS_NLCMN_SUBSYS_MAX; i++) {
deinit = nssinfo_subsystem_array[i].deinit;
if (deinit) {
deinit(ctx);
}
}
}
/*
* nssinfo_init()
* Initialize all the modules.
*/
int nssinfo_init(void)
{
int error, i;
struct nss_nlmcast_ctx ctx;
nssinfo_init_t init;
memset(&ctx, 0, sizeof(ctx));
/*
* Create NL socket
*/
error = nss_nlmcast_sock_open(&ctx, nssinfo_notify_callback, NULL);
if (error) {
nssinfo_error("Socket creation failed for NSSINFO, error(%d)\n", error);
return error;
}
/*
* Initialize all the subsystems and subscribe for mcast groups.
*/
for (i = 0; i < NSS_NLCMN_SUBSYS_MAX; i++) {
init = nssinfo_subsystem_array[i].init;
if (init) {
error = init(&ctx);
if (error) {
nssinfo_error("%s init failed, error(%d)\n", nssinfo_subsystem_array[i].subsystem_name, error);
}
}
}
/*
* Listen for MCAST events from kernel.
*/
error = nss_nlmcast_sock_listen(&ctx);
if (error < 0) {
nssinfo_error("failed to listen for mcast events from kernel\n");
goto end;
}
/*
* Create a thread which displays the stats continuously.
*/
error = nssinfo_display_init();
if (error) {
goto end;
}
/*
* Install CTRL-C handler
*/
struct sigaction new_action;
new_action.sa_handler = nssinfo_termination_handler;
sigemptyset(&new_action.sa_mask);
new_action.sa_flags = 0;
error = sigaction(SIGINT, &new_action, NULL);
if (error) {
nssinfo_error("failed to install CTRL-C handler\n");
goto end;
}
/*
* main thread is waiting here
*/
nssinfo_display_wait();
end:
nssinfo_deinit(&ctx);
return error;
}

View File

@@ -0,0 +1,233 @@
/*
**************************************************************************
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**************************************************************************
*/
#ifndef __NSSINFO_FAMILY_H
#define __NSSINFO_FAMILY_H
#include "nss_nlbase.h"
#include "ncurses.h"
#include "nssinfo_ipv4.h"
#include "nssinfo_ipv6.h"
#include "nssinfo_ethrx.h"
#include "nssinfo_n2h.h"
#include "nssinfo_dynamic_interface.h"
#include "nssinfo_lso_rx.h"
#include "nss_api_if.h"
#include "nss_dynamic_interface.h"
#include "nss_stats_public.h"
#define NSSINFO_COLOR_RST "\x1b[0m"
#define NSSINFO_COLOR_GRN "\x1b[32m"
#define NSSINFO_COLOR_RED "\x1b[31m"
#define NSSINFO_COLOR_MGT "\x1b[35m"
#ifdef ENABLE_DEBUG
#define nssinfo_info(fmt, arg...) printf(NSSINFO_COLOR_GRN"INF "NSSINFO_COLOR_RST fmt, ## arg)
#define nssinfo_trace(fmt, arg...) printf(NSSINFO_COLOR_MGT"TRC(%s:%d) "NSSINFO_COLOR_RST fmt, __func__, __LINE__, ## arg)
#define nssinfo_options(fmt, arg...) printf(NSSINFO_COLOR_MGT"OPT_%d "NSSINFO_COLOR_RST fmt, ## arg)
#define nssinfo_warn(fmt, arg...) printf(NSSINFO_COLOR_RED"WARN(%s:%d) "NSSINFO_COLOR_RST fmt, __func__, __LINE__, ##arg)
#else
#define nssinfo_info(fmt, arg...)
#define nssinfo_trace(fmt, arg...)
#define nssinfo_options(fmt, arg...)
#define nssinfo_warn(fmt, arg...)
#endif
#define nssinfo_error(fmt, arg...) printf(NSSINFO_COLOR_RED"ERR(%s:%d) "NSSINFO_COLOR_RST fmt, __func__, __LINE__, ## arg)
#define nssinfo_stats_print(fmt, arg...) ({ \
if (output_file) { \
fprintf(output_file, fmt, ## arg); \
} else { \
wprintw(stdscr, fmt, ## arg); \
} \
})
/*
* Minimum terminal size to use curses library
*/
#define CURSES_ROWS_MIN 4
#define CURSES_COLS_MIN 48
/*
* Maximum formatted statistics length
*/
#define NSSINFO_STR_LEN 30
extern bool display_all_stats;
extern FILE *output_file;
extern FILE *flow_file;
extern int invalid_input;
extern struct arguments arguments;
extern char *nssinfo_summary_fmt;
/**
* @brief display method_t function
*
* @param core[IN] NSS core id
*/
typedef void (*nssinfo_stats_display_t)(int core, char *input);
/**
* @brief stats notify method_t function
*
* @param data[IN] data received from Netlink client
*/
typedef void (*nssinfo_stats_notify_t)(void *data);
/**
* @brief init method_t function
*
* @param data[IN] an opague context to be used for initialization
*/
typedef int (*nssinfo_init_t)(void *data);
/**
* @brief deinit method_t function
*
* @param data[IN] an opague context to be used for deinitialization
*/
typedef void (*nssinfo_deinit_t)(void *data);
/**
* @brief destroy method_t function
*
* @param core_id[IN] core id of the node to be destroyed
* @param if_num[IN] interface id of the node to be destroyed
*/
typedef void (*nssinfo_destroy_t)(uint32_t core_id, uint32_t if_num);
/**
* @brief Used by main to communicate with parse_opt
*/
struct arguments {
bool verbose; /*< '-v' >*/
char *output_file; /*< file arg to '--output' >*/
char *flow_file; /*< file arg to '--flowfile' >*/
bool higher_unit; /*< display higher units '-h' >*/
int core; /*< core id >*/
char **strings; /*< non-option arguments: [NODE1 [NODE2 ...]] >*/
int rate; /*< display rate in second >*/
};
/**
* @brief NSSINFO subsystem information
*/
struct nssinfo_subsystem_info {
char *subsystem_name; /**< Subsystem name string */
nssinfo_init_t init; /**< Initialize method_t */
nssinfo_deinit_t deinit; /**< Deinitialize method_t */
nssinfo_stats_display_t display; /**< Display method_t */
nssinfo_stats_notify_t notify; /**< Stats notify method_t */
nssinfo_destroy_t destroy; /**< Stats notify method_t */
bool is_inited; /**< True if the subsystem is initialized */
};
extern struct nssinfo_subsystem_info nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_MAX];
/**
* @brief NSSINFO pnode stats
*/
struct node {
struct node *next; /**< Pointer to next node */
uint64_t id; /**< Dynamic interface number */
int type; /**< see 'enum nss_dynamic_interface_type' */
int subsystem_id; /**< see 'enum nss_nlcmn_subsys' */
void *cmn_node_stats; /**< Common node stats */
void *node_stats; /**< Special stats */
void *exception_stats; /**< Exception stats */
};
extern struct node *nodes[NSS_MAX_CORES][NSS_MAX_NET_INTERFACES];
/**
* @brief Structure definition carrying stats info.
*/
struct nssinfo_stats_info {
char stats_name[NSS_STATS_MAX_STR_LENGTH]; /* stat name */
int stats_type; /* enum that tags stat type */
};
/**
* @brief validates core id and interface number
*
* @param core_id[IN] validates the core d
* @param if_num[IN] validates the interface number
*
* @return true on success or false for failure
*/
static inline bool nssinfo_coreid_ifnum_valid(uint32_t core_id, uint32_t if_num)
{
return (core_id < NSS_MAX_CORES && if_num < NSS_MAX_NET_INTERFACES);
}
/**
* @brief initialize all the modules
*
* @param flow_file[IN] parse it and display output accordingly
*
* @return 0 on success or -ve for failure
*/
int nssinfo_init(void);
/**
* @brief Format statistics value
*
* @param num[IN] statistics value in uint64_t
*
* @return comma separated string
*/
char* nssinfo_format_stats(uint64_t num);
/**
* @brief Init nssinfo_stats_info from kernel debug file.
*
* @param info[IN] pointer to a nssinfo_stats_info array
* @param line[IN] string file in kernel/debug/qca-nss-drv/strings/
*/
int nssinfo_stats_info_init(struct nssinfo_stats_info *info, char *strings_file);
/**
* @brief Free all resources used for node stats.
*
* @param mutex[IN] mutex lock
* @param core_id[IN] core id
* @param if_num[IN] node's interface number
*/
void nssinfo_node_stats_destroy(pthread_mutex_t *mutex, uint32_t core_id, uint32_t if_num);
/**
* @brief Print detailed statistics.
*
* @param node[IN] node for which stats to be printed
* @param stat_details[IN] statistics details to be printed
* @param stats_info[IN] statistics information
* @param max[IN] maximum number of strings
* @param stats_val[IN] statistics values
*/
void nssinfo_print_all(char *node, char *stat_details, struct nssinfo_stats_info *stats_info, uint64_t max, uint64_t *stats_val);
/**
* @brief Print the summary of the statistics.
*
* @param node[IN] node for which stats to be printed
* @param cmn_node_stats[IN] common node stats
* @param exception_stats[IN] exception stats
* @param exception_max[IN] maximum exception type
*/
void nssinfo_print_summary(char *node, uint64_t *cmn_node_stats, uint64_t *exception_stats, uint64_t exception_max);
void nssinfo_print_summary_header(void);
#endif /* __NSSINFO_FAMILY_H*/

View File

@@ -0,0 +1,72 @@
/*
**************************************************************************
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**************************************************************************
*/
/*
* @file NSSINFO dynamic interface handler
*/
#include "nssinfo.h"
#include <nss_nldynamic_interface_if.h>
/*
* nssinfo_dynamic_interface_destroy_notify()
* Dynamic interface notify callback function.
*/
static void nssinfo_dynamic_interface_destroy_notify(void *data)
{
struct nss_dynamic_interface_notification *nss_info = (struct nss_dynamic_interface_notification *)data;
struct node *node = nodes[nss_info->core_id][nss_info->if_num];
if (!node) {
return;
}
nssinfo_subsystem_array[node->subsystem_id].destroy(nss_info->core_id, nss_info->if_num);
}
/*
* nssinfo_dynamic_interface_deinit()
* Deinitialize dynamic_interface module.
*/
void nssinfo_dynamic_interface_deinit(void *data)
{
struct nss_nlmcast_ctx *ctx = (struct nss_nlmcast_ctx *)data;
nss_nlmcast_sock_leave_grp(ctx, NSS_NLDYNAMIC_INTERFACE_MCAST_GRP);
}
/*
* nssinfo_dynamic_interface_init()
* Initialize dynamic interface module.
*/
int nssinfo_dynamic_interface_init(void *data)
{
int error;
struct nss_nlmcast_ctx *ctx = (struct nss_nlmcast_ctx *)data;
/*
* Subscribe for dynamic interface multicast group.
*/
nss_nlsock_set_family(&ctx->sock, NSS_NLDYNAMIC_INTERFACE_FAMILY);
error = nss_nlmcast_sock_join_grp(ctx, NSS_NLDYNAMIC_INTERFACE_MCAST_GRP);
if (error) {
nssinfo_warn("Unable to join dynamic interface multicast group.\n");
return error;
}
nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_DYNAMIC_INTERFACE].notify = nssinfo_dynamic_interface_destroy_notify;
nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_DYNAMIC_INTERFACE].is_inited = true;
return 0;
}

View File

@@ -0,0 +1,28 @@
/*
**************************************************************************
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**************************************************************************
*/
#ifndef __NSSINFO_DYNAMIC_INTERFACE_H
#define __NSSINFO_DYNAMIC_INTERFACE_H
/**
* @brief initialize dynamic interface module.
*
* @return 0 on success or -ve for failure
*/
int nssinfo_dynamic_interface_init(void *data);
void nssinfo_dynamic_interface_deinit(void *data);
#endif /* __NSSINFO_DYNAMIC_INTERFACE_H*/

View File

@@ -0,0 +1,215 @@
/*
**************************************************************************
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**************************************************************************
*/
/*
* @file NSSINFO Ethernet Rx handler
*/
#include "nssinfo.h"
#include <nss_eth_rx.h>
#include <nss_nlethrx_if.h>
static pthread_mutex_t eth_rx_lock;
static struct nssinfo_stats_info nss_eth_rx_cmn_stats_str[NSS_STATS_NODE_MAX];
static struct nssinfo_stats_info nss_eth_rx_stats_str[NSS_ETH_RX_STATS_MAX];
static struct nssinfo_stats_info nss_eth_rx_exception_stats_str[NSS_ETH_RX_EXCEPTION_EVENT_MAX];
/*
* nssinfo_eth_rx_stats_display()
* Ethernet Rx display callback function.
*/
static void nssinfo_eth_rx_stats_display(int core, char *input)
{
struct node *eth_rx_node;
if (input && strncmp(input, nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_ETHRX].subsystem_name, strlen(input))) {
++invalid_input;
nssinfo_trace("Invalid node name: %s\n", input);
return;
}
pthread_mutex_lock(&eth_rx_lock);
eth_rx_node = nodes[core][NSS_ETH_RX_INTERFACE];
if (!eth_rx_node) {
pthread_mutex_unlock(&eth_rx_lock);
return;
}
if (!display_all_stats) {
nssinfo_print_summary("eth_rx", (uint64_t *)eth_rx_node->cmn_node_stats, (uint64_t *)eth_rx_node->exception_stats, NSS_ETH_RX_EXCEPTION_EVENT_MAX);
pthread_mutex_unlock(&eth_rx_lock);
return;
}
nssinfo_print_all("eth_rx", "eth_rx Common Stats", nss_eth_rx_cmn_stats_str, NSS_STATS_NODE_MAX, (uint64_t *)eth_rx_node->cmn_node_stats);
nssinfo_print_all("eth_rx", "eth_rx Special Stats", nss_eth_rx_stats_str, NSS_ETH_RX_STATS_MAX, (uint64_t *)eth_rx_node->node_stats);
nssinfo_print_all("eth_rx", "eth_rx Exception Stats", nss_eth_rx_exception_stats_str, NSS_ETH_RX_EXCEPTION_EVENT_MAX, (uint64_t *)eth_rx_node->exception_stats);
pthread_mutex_unlock(&eth_rx_lock);
}
/*
* nssinfo_eth_rx_stats_notify()
* Ethernet Rx statistics notify callback function.
*/
static void nssinfo_eth_rx_stats_notify(void *data)
{
uint64_t *cmn_node_stats, *node_stats, *exception_stats;
struct nss_eth_rx_stats_notification *nss_stats = (struct nss_eth_rx_stats_notification *)data;
struct node *eth_rx_node;
struct node **eth_rx_ptr;
if (!nssinfo_coreid_ifnum_valid(nss_stats->core_id, NSS_ETH_RX_INTERFACE)) {
return;
}
pthread_mutex_lock(&eth_rx_lock);
eth_rx_ptr = &nodes[nss_stats->core_id][NSS_ETH_RX_INTERFACE];
eth_rx_node = *eth_rx_ptr;
if (eth_rx_node) {
memcpy(eth_rx_node->cmn_node_stats, &nss_stats->cmn_node_stats, sizeof(nss_stats->cmn_node_stats));
memcpy(eth_rx_node->node_stats, &nss_stats->special_stats, sizeof(nss_stats->special_stats));
memcpy(eth_rx_node->exception_stats, &nss_stats->exception_stats, sizeof(nss_stats->exception_stats));
pthread_mutex_unlock(&eth_rx_lock);
return;
}
pthread_mutex_unlock(&eth_rx_lock);
eth_rx_node = (struct node *)calloc(1, sizeof(struct node));
if (!eth_rx_node) {
nssinfo_warn("Failed to allocate memory for eth rx node\n");
return;
}
cmn_node_stats = (uint64_t *)malloc(sizeof(nss_stats->cmn_node_stats));
if (!cmn_node_stats) {
nssinfo_warn("Failed to allocate memory for eth rx common node statistics\n");
goto eth_rx_node_free;
}
node_stats = (uint64_t *)malloc(sizeof(nss_stats->special_stats));
if (!node_stats) {
nssinfo_warn("Failed to allocate memory for eth rx special stats\n");
goto cmn_node_stats_free;
}
exception_stats = (uint64_t *)malloc(sizeof(nss_stats->exception_stats));
if (!exception_stats) {
nssinfo_warn("Failed to allocate memory for eth rx exception stats\n");
goto node_stats_free;
}
memcpy(cmn_node_stats, &nss_stats->cmn_node_stats, sizeof(nss_stats->cmn_node_stats));
memcpy(node_stats, &nss_stats->special_stats, sizeof(nss_stats->special_stats));
memcpy(exception_stats, &nss_stats->exception_stats, sizeof(nss_stats->exception_stats));
eth_rx_node->cmn_node_stats = cmn_node_stats;
eth_rx_node->node_stats = node_stats;
eth_rx_node->exception_stats = exception_stats;
eth_rx_node->subsystem_id = NSS_NLCMN_SUBSYS_ETHRX;
/*
* Notifify is guaranteed to be single threaded via Netlink listen callback
*/
pthread_mutex_lock(&eth_rx_lock);
nodes[nss_stats->core_id][NSS_ETH_RX_INTERFACE] = eth_rx_node;
pthread_mutex_unlock(&eth_rx_lock);
return;
node_stats_free:
free(node_stats);
cmn_node_stats_free:
free(cmn_node_stats);
eth_rx_node_free:
free(eth_rx_node);
return;
}
/*
* nssinfo_eth_rx_destroy()
* Destroy ethernet Rx node.
*/
static void nssinfo_eth_rx_destroy(uint32_t core_id, uint32_t if_num)
{
if (nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_ETHRX].is_inited) {
nssinfo_node_stats_destroy(&eth_rx_lock, core_id, NSS_ETH_RX_INTERFACE);
}
}
/*
* nssinfo_ethrx_deinit()
* Deinitialize ethrx module.
*/
void nssinfo_eth_rx_deinit(void *data)
{
struct nss_nlmcast_ctx *ctx = (struct nss_nlmcast_ctx *)data;
if (nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_ETHRX].is_inited) {
pthread_mutex_destroy(&eth_rx_lock);
nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_ETHRX].is_inited = false;
}
nss_nlmcast_sock_leave_grp(ctx, NSS_NLETHRX_MCAST_GRP);
}
/*
* nssinfo_eth_rx_init()
* Initialize Ethernet Rx module.
*/
int nssinfo_eth_rx_init(void *data)
{
int error;
struct nss_nlmcast_ctx *ctx = (struct nss_nlmcast_ctx *)data;
/*
* Subscribe for Ethernet Rx MCAST group.
*/
nss_nlsock_set_family(&ctx->sock, NSS_NLETHRX_FAMILY);
error = nss_nlmcast_sock_join_grp(ctx, NSS_NLETHRX_MCAST_GRP);
if (error) {
nssinfo_warn("Unable to join Ethernet Rx mcast group.\n");
return error;
}
if (nssinfo_stats_info_init(nss_eth_rx_cmn_stats_str,
"/sys/kernel/debug/qca-nss-drv/strings/common_node_stats") != 0) {
goto fail;
}
if (nssinfo_stats_info_init(nss_eth_rx_stats_str,
"/sys/kernel/debug/qca-nss-drv/strings/eth_rx/special_stats_str") != 0) {
goto fail;
}
if (nssinfo_stats_info_init(nss_eth_rx_exception_stats_str,
"/sys/kernel/debug/qca-nss-drv/strings/eth_rx/exception_stats_str") != 0) {
goto fail;
}
if (pthread_mutex_init(&eth_rx_lock, NULL) != 0) {
nssinfo_warn("Mutex init has failed for Ethernet Rx\n");
goto fail;
}
nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_ETHRX].display = nssinfo_eth_rx_stats_display;
nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_ETHRX].notify = nssinfo_eth_rx_stats_notify;
nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_ETHRX].destroy = nssinfo_eth_rx_destroy;
nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_ETHRX].is_inited = true;
return 0;
fail:
nss_nlmcast_sock_leave_grp(ctx, NSS_NLETHRX_MCAST_GRP);
return -1;
}

View File

@@ -0,0 +1,28 @@
/*
**************************************************************************
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**************************************************************************
*/
#ifndef __NSSINFO_ETHRX_H
#define __NSSINFO_ETHRX_H
/**
* @brief initialize Ethernet Rx module.
*
* @return 0 on success or -ve for failure
*/
int nssinfo_eth_rx_init(void *data);
void nssinfo_eth_rx_deinit(void *data);
#endif /* __NSSINFO_ETHRX_H*/

View File

@@ -0,0 +1,215 @@
/*
**************************************************************************
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**************************************************************************
*/
/*
* @file NSSINFO ipv4 handler
*/
#include "nssinfo.h"
static pthread_mutex_t ipv4_lock;
static struct nssinfo_stats_info nss_stats_str_node[NSS_STATS_NODE_MAX];
static struct nssinfo_stats_info nss_ipv4_stats_str[NSS_IPV4_STATS_MAX];
static struct nssinfo_stats_info nss_ipv4_exception_stats_str[NSS_IPV4_EXCEPTION_EVENT_MAX];
/*
* nssinfo_ipv4_stats_display()
* IPv4 display callback function.
*/
static void nssinfo_ipv4_stats_display(int core, char *input)
{
struct node *ipv4_node;
if (input && strncmp(input, nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_IPV4].subsystem_name, strlen(input)) != 0) {
++invalid_input;
nssinfo_trace("Invalid node name: %s\n", input);
return;
}
pthread_mutex_lock(&ipv4_lock);
ipv4_node = nodes[core][NSS_IPV4_RX_INTERFACE];
if (!ipv4_node) {
pthread_mutex_unlock(&ipv4_lock);
return;
}
if (!display_all_stats) {
nssinfo_print_summary("ipv4", (uint64_t *)ipv4_node->cmn_node_stats, (uint64_t *)ipv4_node->exception_stats, NSS_IPV4_EXCEPTION_EVENT_MAX);
pthread_mutex_unlock(&ipv4_lock);
return;
}
nssinfo_print_all("ipv4", "ipv4 Common Stats", nss_stats_str_node, NSS_STATS_NODE_MAX, (uint64_t *)ipv4_node->cmn_node_stats);
nssinfo_print_all("ipv4", "ipv4 Special Stats", nss_ipv4_stats_str, NSS_IPV4_STATS_MAX, (uint64_t *)ipv4_node->node_stats);
nssinfo_print_all("ipv4", "ipv4 Exception Stats", nss_ipv4_exception_stats_str, NSS_IPV4_EXCEPTION_EVENT_MAX, (uint64_t *)ipv4_node->exception_stats);
pthread_mutex_unlock(&ipv4_lock);
}
/*
* nssinfo_ipv4_stats_notify()
* IPv4 stats notify callback function.
*/
static void nssinfo_ipv4_stats_notify(void *data)
{
uint64_t *cmn_node_stats, *node_stats, *exception_stats;
struct nss_nlipv4_rule *rule = (struct nss_nlipv4_rule *)data;
struct node *ipv4_node;
struct node **ipv4_ptr;
if (!nssinfo_coreid_ifnum_valid(rule->stats.core_id, NSS_IPV4_RX_INTERFACE)) {
return;
}
ipv4_ptr = &nodes[rule->stats.core_id][NSS_IPV4_RX_INTERFACE];
pthread_mutex_lock(&ipv4_lock);
ipv4_node = *ipv4_ptr;
if (ipv4_node) {
memcpy(ipv4_node->cmn_node_stats, &rule->stats.cmn_node_stats, sizeof(rule->stats.cmn_node_stats));
memcpy(ipv4_node->node_stats, &rule->stats.special_stats, sizeof(rule->stats.special_stats));
memcpy(ipv4_node->exception_stats, &rule->stats.exception_stats, sizeof(rule->stats.exception_stats));
pthread_mutex_unlock(&ipv4_lock);
return;
}
pthread_mutex_unlock(&ipv4_lock);
ipv4_node = (struct node *)calloc(1, sizeof(struct node));
if (!ipv4_node) {
nssinfo_warn("Failed to allocate memory for ipv4 node\n");
return;
}
cmn_node_stats = (uint64_t *)malloc(sizeof(rule->stats.cmn_node_stats));
if (!cmn_node_stats) {
nssinfo_warn("Failed to allocate memory for ipv4 common node stats\n");
goto ipv4_node_free;
}
node_stats = (uint64_t *)malloc(sizeof(rule->stats.special_stats));
if (!node_stats) {
nssinfo_warn("Failed to allocate memory for ipv4 special stats\n");
goto cmn_node_stats_free;
}
exception_stats = (uint64_t *)malloc(sizeof(rule->stats.exception_stats));
if (!exception_stats) {
nssinfo_warn("Failed to allocate memory for ipv4 exception stats\n");
goto node_stats_free;
}
memcpy(cmn_node_stats, &rule->stats.cmn_node_stats, sizeof(rule->stats.cmn_node_stats));
memcpy(node_stats, &rule->stats.special_stats, sizeof(rule->stats.special_stats));
memcpy(exception_stats, &rule->stats.exception_stats, sizeof(rule->stats.exception_stats));
ipv4_node->cmn_node_stats = cmn_node_stats;
ipv4_node->node_stats = node_stats;
ipv4_node->exception_stats = exception_stats;
ipv4_node->subsystem_id = NSS_NLCMN_SUBSYS_IPV4;
/*
* Notifify is guaranteed to be single threaded via Netlink listen callback
*/
pthread_mutex_lock(&ipv4_lock);
*ipv4_ptr = ipv4_node;
pthread_mutex_unlock(&ipv4_lock);
return;
node_stats_free:
free(node_stats);
cmn_node_stats_free:
free(cmn_node_stats);
ipv4_node_free:
free(ipv4_node);
}
/*
* nssinfo_ipv4_destroy()
* Destroy IPv4 node.
*/
static void nssinfo_ipv4_destroy(uint32_t core_id, uint32_t if_num)
{
if (nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_IPV4].is_inited) {
nssinfo_node_stats_destroy(&ipv4_lock, core_id, NSS_IPV4_RX_INTERFACE);
}
}
/*
* nssinfo_ipv4_deinit()
* Initialize IPv4 module.
*/
void nssinfo_ipv4_deinit(void *data)
{
struct nss_nlmcast_ctx *ctx = (struct nss_nlmcast_ctx *)data;
if (nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_IPV4].is_inited) {
pthread_mutex_destroy(&ipv4_lock);
nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_IPV4].is_inited = false;
}
nss_nlmcast_sock_leave_grp(ctx, NSS_NLIPV4_MCAST_GRP);
}
/*
* nssinfo_ipv4_init()
* Initialize IPv4 module.
*/
int nssinfo_ipv4_init(void *data)
{
int error;
struct nss_nlmcast_ctx *ctx = (struct nss_nlmcast_ctx *)data;
/*
* Subscribe for IPV4 MCAST group.
*/
nss_nlsock_set_family(&ctx->sock, NSS_NLIPV4_FAMILY);
error = nss_nlmcast_sock_join_grp(ctx, NSS_NLIPV4_MCAST_GRP);
if (error) {
nssinfo_warn("Unable to join IPv4 mcast group\n");
return error;
}
if (nssinfo_stats_info_init(nss_stats_str_node,
"/sys/kernel/debug/qca-nss-drv/strings/common_node_stats") != 0) {
goto fail;
}
if (nssinfo_stats_info_init(nss_ipv4_stats_str,
"/sys/kernel/debug/qca-nss-drv/strings/ipv4/special_stats_str") != 0) {
goto fail;
}
if (nssinfo_stats_info_init(nss_ipv4_exception_stats_str,
"/sys/kernel/debug/qca-nss-drv/strings/ipv4/exception_stats_str") != 0) {
goto fail;
}
if (pthread_mutex_init(&ipv4_lock, NULL) != 0) {
nssinfo_warn("Mutex init has failed for IPV4\n");
goto fail;
}
nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_IPV4].display = nssinfo_ipv4_stats_display;
nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_IPV4].notify = nssinfo_ipv4_stats_notify;
nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_IPV4].destroy = nssinfo_ipv4_destroy;
nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_IPV4].is_inited = true;
return 0;
fail:
nss_nlmcast_sock_leave_grp(ctx, NSS_NLIPV4_MCAST_GRP);
return -1;
}

View File

@@ -0,0 +1,30 @@
/*
**************************************************************************
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**************************************************************************
*/
#ifndef __NSSINFO_IPV4_H
#define __NSSINFO_IPV4_H
#define NSSINFO_IPV4_HDR_VERSION 4
/**
* @brief initialize IPv4 module.
*
* @return 0 on success or -ve for failure
*/
int nssinfo_ipv4_init(void *data);
void nssinfo_ipv4_deinit(void *data);
#endif /* __NSSINFO_IPV4_H*/

View File

@@ -0,0 +1,212 @@
/*
**************************************************************************
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**************************************************************************
*/
/*
* @file NSSINFO ipv6 handler
*/
#include "nssinfo.h"
static pthread_mutex_t ipv6_lock;
static struct nssinfo_stats_info nss_stats_str_node[NSS_STATS_NODE_MAX];
static struct nssinfo_stats_info nss_ipv6_stats_str[NSS_IPV6_STATS_MAX];
static struct nssinfo_stats_info nss_ipv6_exception_stats_str[NSS_IPV6_EXCEPTION_EVENT_MAX];
/*
* nssinfo_ipv6_stats_display()
* IPv6 display callback function.
*/
static void nssinfo_ipv6_stats_display(int core, char *input)
{
struct node *ipv6_node;
if (input && strncmp(input, nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_IPV6].subsystem_name, strlen(input))) {
++invalid_input;
nssinfo_trace("Invalid node name: %s\n", input);
return;
}
pthread_mutex_lock(&ipv6_lock);
ipv6_node = nodes[core][NSS_IPV6_RX_INTERFACE];
if (!ipv6_node) {
pthread_mutex_unlock(&ipv6_lock);
return;
}
if (display_all_stats) {
nssinfo_print_all("ipv6", "ipv6 Common Stats", nss_stats_str_node, NSS_STATS_NODE_MAX, (uint64_t *)ipv6_node->cmn_node_stats);
nssinfo_print_all("ipv6", "ipv6 Special Stats", nss_ipv6_stats_str, NSS_IPV6_STATS_MAX, (uint64_t *)ipv6_node->node_stats);
nssinfo_print_all("ipv6", "ipv6 Exception Stats", nss_ipv6_exception_stats_str, NSS_IPV6_EXCEPTION_EVENT_MAX, (uint64_t *)ipv6_node->exception_stats);
pthread_mutex_unlock(&ipv6_lock);
return;
}
nssinfo_print_summary("ipv6", (uint64_t *)ipv6_node->cmn_node_stats, (uint64_t *)ipv6_node->exception_stats, NSS_IPV6_EXCEPTION_EVENT_MAX);
pthread_mutex_unlock(&ipv6_lock);
}
/*
* nssinfo_ipv6_stats_notify()
* IPv6 stats notify callback function.
*/
static void nssinfo_ipv6_stats_notify(void *data)
{
uint64_t *cmn_node_stats, *node_stats, *exception_stats;
struct nss_nlipv6_rule *rule = (struct nss_nlipv6_rule *)data;
struct node *ipv6_node;
struct node **ipv6_ptr;
if (!nssinfo_coreid_ifnum_valid(rule->stats.core_id, NSS_IPV6_RX_INTERFACE)) {
return;
}
pthread_mutex_lock(&ipv6_lock);
ipv6_ptr = &nodes[rule->stats.core_id][NSS_IPV6_RX_INTERFACE];
ipv6_node = *ipv6_ptr;
if (ipv6_node) {
memcpy(ipv6_node->cmn_node_stats, &rule->stats.cmn_node_stats, sizeof(rule->stats.cmn_node_stats));
memcpy(ipv6_node->node_stats, &rule->stats.special_stats, sizeof(rule->stats.special_stats));
memcpy(ipv6_node->exception_stats, &rule->stats.exception_stats, sizeof(rule->stats.exception_stats));
pthread_mutex_unlock(&ipv6_lock);
return;
}
pthread_mutex_unlock(&ipv6_lock);
ipv6_node = (struct node *)calloc(1, sizeof(struct node));
if (!ipv6_node) {
nssinfo_warn("Failed to allocate memory for ipv6 node\n");
return;
}
cmn_node_stats = (uint64_t *)malloc(sizeof(rule->stats.cmn_node_stats));
if (!cmn_node_stats) {
nssinfo_warn("Failed to allocate memory for ipv6 common node statistics\n");
goto ipv6_node_free;
}
node_stats = (uint64_t *)malloc(sizeof(rule->stats.special_stats));
if (!node_stats) {
nssinfo_warn("Failed to allocate memory for ipv6 special stats\n");
goto cmn_node_stats_free;
}
exception_stats = (uint64_t *)malloc(sizeof(rule->stats.exception_stats));
if (!exception_stats) {
nssinfo_warn("Failed to allocate memory for ipv6 exception stats\n");
goto node_stats_free;
}
memcpy(cmn_node_stats, &rule->stats.cmn_node_stats, sizeof(rule->stats.cmn_node_stats));
memcpy(node_stats, &rule->stats.special_stats, sizeof(rule->stats.special_stats));
memcpy(exception_stats, &rule->stats.exception_stats, sizeof(rule->stats.exception_stats));
ipv6_node->cmn_node_stats = cmn_node_stats;
ipv6_node->node_stats = node_stats;
ipv6_node->exception_stats = exception_stats;
ipv6_node->subsystem_id = NSS_NLCMN_SUBSYS_IPV6;
/*
* Notifify is guaranteed to be single threaded via Netlink listen callback
*/
pthread_mutex_lock(&ipv6_lock);
*ipv6_ptr = ipv6_node;
pthread_mutex_unlock(&ipv6_lock);
return;
node_stats_free:
free(node_stats);
cmn_node_stats_free:
free(cmn_node_stats);
ipv6_node_free:
free(ipv6_node);
}
/*
* nssinfo_ipv6_destroy()
* Destroy IPv6 node.
*/
static void nssinfo_ipv6_destroy(uint32_t core_id, uint32_t if_num)
{
if (nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_IPV6].is_inited) {
nssinfo_node_stats_destroy(&ipv6_lock, core_id, NSS_IPV6_RX_INTERFACE);
}
}
/*
* nssinfo_ipv6_deinit()
* Deinitialize ipv6 module.
*/
void nssinfo_ipv6_deinit(void *data)
{
struct nss_nlmcast_ctx *ctx = (struct nss_nlmcast_ctx *)data;
if (nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_IPV6].is_inited) {
pthread_mutex_destroy(&ipv6_lock);
nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_IPV6].is_inited = false;
}
nss_nlmcast_sock_leave_grp(ctx, NSS_NLIPV6_MCAST_GRP);
}
/*
* nssinfo_ipv6_init()
* Initialize IPv6 module.
*/
int nssinfo_ipv6_init(void *data)
{
int error;
struct nss_nlmcast_ctx *ctx = (struct nss_nlmcast_ctx *)data;
/*
* Subscribe for IPV6 MCAST group.
*/
nss_nlsock_set_family(&ctx->sock, NSS_NLIPV6_FAMILY);
error = nss_nlmcast_sock_join_grp(ctx, NSS_NLIPV6_MCAST_GRP);
if (error) {
nssinfo_warn("Unable to join IPv6 mcast group\n");
return error;
}
if (nssinfo_stats_info_init(nss_stats_str_node,
"/sys/kernel/debug/qca-nss-drv/strings/common_node_stats") != 0) {
goto fail;
}
if (nssinfo_stats_info_init(nss_ipv6_stats_str,
"/sys/kernel/debug/qca-nss-drv/strings/ipv6/special_stats_str") != 0) {
goto fail;
}
if (nssinfo_stats_info_init(nss_ipv6_exception_stats_str,
"/sys/kernel/debug/qca-nss-drv/strings/ipv6/exception_stats_str") != 0) {
goto fail;
}
if (pthread_mutex_init(&ipv6_lock, NULL) != 0) {
nssinfo_warn("Mutex init has failed for IPV6\n");
goto fail;
}
nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_IPV6].display = nssinfo_ipv6_stats_display;
nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_IPV6].notify = nssinfo_ipv6_stats_notify;
nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_IPV6].destroy = nssinfo_ipv6_destroy;
nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_IPV6].is_inited = true;
return 0;
fail:
nss_nlmcast_sock_leave_grp(ctx, NSS_NLIPV6_MCAST_GRP);
return -1;
}

View File

@@ -0,0 +1,30 @@
/*
**************************************************************************
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**************************************************************************
*/
#ifndef __NSSINFO_IPV6_H
#define __NSSINFO_IPV6_H
#define NSSINFO_IPV6_HDR_VERSION 4
/**
* @brief initialize IPv4 module.
*
* @return 0 on success or -ve for failure
*/
int nssinfo_ipv6_init(void *data);
void nssinfo_ipv6_deinit(void *data);
#endif /* __NSSINFO_IPV6_H*/

View File

@@ -0,0 +1,195 @@
/*
**************************************************************************
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**************************************************************************
*/
/*
* @file NSSINFO lso_rx handler
*/
#include "nssinfo.h"
#include <nss_lso_rx.h>
#include <nss_nllso_rx_if.h>
static pthread_mutex_t lso_rx_lock;
static struct nssinfo_stats_info nss_stats_str_node[NSS_STATS_NODE_MAX];
static struct nssinfo_stats_info nss_lso_rx_stats_str[NSS_LSO_RX_STATS_MAX];
/*
* nssinfo_lso_rx_stats_display()
* LSO Rx display callback function.
*/
static void nssinfo_lso_rx_stats_display(int core, char *input)
{
struct node *lso_rx_node;
if (input && strncmp(input, nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_LSO_RX].subsystem_name, strlen(input))) {
++invalid_input;
nssinfo_trace("Invalid node name: %s\n", input);
return;
}
pthread_mutex_lock(&lso_rx_lock);
lso_rx_node = nodes[core][NSS_LSO_RX_INTERFACE];
if (!lso_rx_node) {
pthread_mutex_unlock(&lso_rx_lock);
nssinfo_error("%s is not running on the NPU\n", input);
return;
}
if (display_all_stats) {
nssinfo_print_all("lso_rx", "lso_rx Common Stats", nss_stats_str_node, NSS_STATS_NODE_MAX, (uint64_t *)lso_rx_node->cmn_node_stats);
nssinfo_print_all("lso_rx", "lso_rx Special Stats", nss_lso_rx_stats_str, NSS_LSO_RX_STATS_MAX, (uint64_t *)lso_rx_node->node_stats);
pthread_mutex_unlock(&lso_rx_lock);
return;
}
nssinfo_print_summary("lso_rx", (uint64_t *)lso_rx_node->cmn_node_stats, NULL, 0);
pthread_mutex_unlock(&lso_rx_lock);
}
/*
* nssinfo_lso_rx_stats_notify()
* LSO Rx stats notify callback function.
*/
static void nssinfo_lso_rx_stats_notify(void *data)
{
uint64_t *cmn_node_stats, *node_stats;
struct nss_lso_rx_stats_notification *nss_stats = (struct nss_lso_rx_stats_notification *)data;
struct node *lso_rx_node;
struct node **lso_rx_ptr;
if (!nssinfo_coreid_ifnum_valid(nss_stats->core_id, NSS_LSO_RX_INTERFACE)) {
return;
}
pthread_mutex_lock(&lso_rx_lock);
lso_rx_ptr = &nodes[nss_stats->core_id][NSS_LSO_RX_INTERFACE];
lso_rx_node = *lso_rx_ptr;
if (lso_rx_node) {
memcpy(lso_rx_node->cmn_node_stats, &nss_stats->cmn_node_stats, sizeof(nss_stats->cmn_node_stats));
memcpy(lso_rx_node->node_stats, &nss_stats->node_stats, sizeof(nss_stats->node_stats));
pthread_mutex_unlock(&lso_rx_lock);
return;
}
pthread_mutex_unlock(&lso_rx_lock);
lso_rx_node = (struct node *)calloc(1, sizeof(struct node));
if (!lso_rx_node) {
nssinfo_warn("Failed to allocate memory for lso_rx node\n");
return;
}
cmn_node_stats = (uint64_t *)malloc(sizeof(nss_stats->cmn_node_stats));
if (!cmn_node_stats) {
nssinfo_warn("Failed to allocate memory for lso_rx common node statistics\n");
goto lso_rx_node_free;
}
node_stats = (uint64_t *)malloc(sizeof(nss_stats->node_stats));
if (!node_stats) {
nssinfo_warn("Failed to allocate memory for lso_rx connection stats\n");
goto cmn_node_stats_free;
}
memcpy(cmn_node_stats, &nss_stats->cmn_node_stats, sizeof(nss_stats->cmn_node_stats));
memcpy(node_stats, &nss_stats->node_stats, sizeof(nss_stats->node_stats));
lso_rx_node->cmn_node_stats = cmn_node_stats;
lso_rx_node->node_stats = node_stats;
lso_rx_node->subsystem_id = NSS_NLCMN_SUBSYS_LSO_RX;
/*
* Notify is guaranteed to be single threaded via Netlink listen callback
*/
pthread_mutex_lock(&lso_rx_lock);
*lso_rx_ptr = lso_rx_node;
pthread_mutex_unlock(&lso_rx_lock);
return;
cmn_node_stats_free:
free(cmn_node_stats);
lso_rx_node_free:
free(lso_rx_node);
}
/*
* nssinfo_lso_rx_destroy()
* Destroy LSO Rx node.
*/
static void nssinfo_lso_rx_destroy(uint32_t core_id, uint32_t if_num)
{
if (nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_LSO_RX].is_inited) {
nssinfo_node_stats_destroy(&lso_rx_lock, core_id, NSS_LSO_RX_INTERFACE);
}
}
/*
* nssinfo_lso_rx_deinit()
* Deinitialize lso_rx module.
*/
void nssinfo_lso_rx_deinit(void *data)
{
struct nss_nlmcast_ctx *ctx = (struct nss_nlmcast_ctx *)data;
if (nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_LSO_RX].is_inited) {
pthread_mutex_destroy(&lso_rx_lock);
nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_LSO_RX].is_inited = false;
}
nss_nlmcast_sock_leave_grp(ctx, NSS_NLLSO_RX_MCAST_GRP);
}
/*
* nssinfo_lso_rx_init()
* Initialize LSO Rx module.
*/
int nssinfo_lso_rx_init(void *data)
{
int error;
struct nss_nlmcast_ctx *ctx = (struct nss_nlmcast_ctx *)data;
/*
* Subscribe for LSO Rx multicast group.
*/
nss_nlsock_set_family(&ctx->sock, NSS_NLLSO_RX_FAMILY);
error = nss_nlmcast_sock_join_grp(ctx, NSS_NLLSO_RX_MCAST_GRP);
if (error) {
nssinfo_warn("Unable to join LSO Rx multicast group\n");
return error;
}
if (nssinfo_stats_info_init(nss_stats_str_node,
"/sys/kernel/debug/qca-nss-drv/strings/common_node_stats") != 0) {
goto fail;
}
if (nssinfo_stats_info_init(nss_lso_rx_stats_str,
"/sys/kernel/debug/qca-nss-drv/strings/lso_rx") != 0) {
goto fail;
}
if (pthread_mutex_init(&lso_rx_lock, NULL) != 0) {
nssinfo_warn("Mutex init has failed for LSO Rx\n");
goto fail;
}
nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_LSO_RX].display = nssinfo_lso_rx_stats_display;
nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_LSO_RX].notify = nssinfo_lso_rx_stats_notify;
nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_LSO_RX].destroy = nssinfo_lso_rx_destroy;
nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_LSO_RX].is_inited = true;
return 0;
fail:
nss_nlmcast_sock_leave_grp(ctx, NSS_NLLSO_RX_MCAST_GRP);
return -1;
}

View File

@@ -0,0 +1,28 @@
/*
**************************************************************************
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**************************************************************************
*/
#ifndef __NSSINFO_LSO_RX_H
#define __NSSINFO_LSO_RX_H
/**
* @brief initialize LSO_RX module.
*
* @return 0 on success or -ve for failure
*/
int nssinfo_lso_rx_init(void *data);
void nssinfo_lso_rx_deinit(void *data);
#endif /* __NSSINFO_LSO_RX_H*/

View File

@@ -0,0 +1,191 @@
/*
**************************************************************************
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**************************************************************************
*/
#include "nssinfo.h"
#include <getopt.h>
static const char *nssinfo_version = "1.0";
static struct option long_options[] = {
{"verbose", no_argument, NULL, 'v'},
{"higherunit", no_argument, NULL, 'u'},
{"help", no_argument, NULL, 'h'},
{"version", no_argument, NULL, 'V'},
{"output", required_argument, NULL, 'o'},
{"flowfile", required_argument, NULL, 'f'},
{"core", required_argument, NULL, 'c'},
{"rate", required_argument, NULL, 'r'},
{0, 0, 0, 0}
};
static char *short_options = "vuh?Vo:f:c:r:";
static void print_help(void)
{
printf("nssinfo is an userspace tool used to display NODE stats from NSS-FW\n");
printf("Usage: nssinfo [OPTION ...] [-c ID [NODE1 NODE2 ...]]\n");
printf("OPTION:\n");
printf(" -c, --core=ID Display statistics based on core id\n");
printf(" -f, --flowfile=FILE Specify output content in FILE\n");
printf(" -o, --output=FILE Write output to FILE instead of stdout\n");
printf(" -r, --rate=RATE Update screen every RATE seconds\n");
printf(" -u, --higherunit Display stats in higher units, i.e. K, M, B\n");
printf(" -v, --verbose Display all the stats (zero and non-zero stats)\n");
printf(" -V, --version Print program version\n");
printf(" -h, --help Give this help message\n");
printf("Examples:\n");
printf(" nssinfo\n");
printf(" nssinfo -c0\n");
printf(" nssinfo -c0 ipv4 edma[0] edma[4]\n");
printf(" nssinfo -r5 -o stats.log\n");
}
struct arguments arguments;
/*
* getopt_parse()
* Parse command line arguments using getopt_long().
*/
static int getopt_parse(int argc, char **argv, void *a)
{
struct arguments *arguments = (struct arguments *)a;
while (1) {
int key = getopt_long(argc, argv, short_options, long_options, NULL);
/*
* Detect the end of the options.
*/
if (key == -1)
break;
switch (key) {
case 'v':
arguments->verbose = true;
break;
case 'u':
arguments->higher_unit = true;
break;
case 'f':
arguments->flow_file = optarg;
break;
case 'o':
arguments->output_file = optarg;
break;
case 'r': /* -r5 */
arguments->rate = atoi(optarg);
if (arguments->rate <= 0) {
printf("Invalid rate `%s'\n", optarg);
exit(-1);
}
break;
case 'c': /* -c0 */
arguments->core = atoi(optarg);
if (arguments->core >= NSS_MAX_CORES || arguments->core < 0) {
printf("Invalid core id `%s'\n", optarg);
exit(-1);
}
break;
case 'h':
print_help();
exit(0);
case 'V':
printf("%s\n", nssinfo_version);
exit(0);
case '?':
default:
/*
* getopt_long already printed an error message.
*/
exit(-1);
}
}
/* Any remaining non-option arguments start from argv[optind].
* Init arguments->strings so that
* arguments->strings[0] points to the 1st non-option argument
* arguments->strings[1] points to the 2nd non-option argument
* ...
* arguments->strings[n] points to the last non-option argument
* arguments->strings[n+1] is NULL
*
* For example,
* If user enters 'nssinfo -c1 edma1 edma2', optind is 2 at this point and
* arguments->strings[0] = "edma1", arguments->strings[1] = "edma2", arguments->strings[2] = NULL.
* If user does not specify any non-option argument (e.g. nssinfo -v),
* argv[optind] is NULL so arguments->strings[0] is NULL.
*/
arguments->strings = &argv[optind];
return 0;
}
/*
* main()
*/
int main(int argc, char **argv)
{
int error;
arguments.output_file = NULL;
arguments.flow_file = NULL;
arguments.verbose = false;
arguments.higher_unit = false;
arguments.core = -1; /* display stats for all cores */
arguments.rate = 1; /* 1 sec */
getopt_parse(argc, argv, &arguments);
if (arguments.output_file) {
output_file = fopen(arguments.output_file, "w");
if (!output_file) {
nssinfo_error("Error opening output file!\n");
exit(1);
}
}
if (arguments.flow_file) {
flow_file = fopen(arguments.flow_file, "r");
if (!flow_file) {
nssinfo_error("Error opening flow file!\n");
error = -1;
goto end;
}
}
error = nssinfo_init();
if (error) {
nssinfo_info("Nssinfo initialization failed(%d)\n", error);
}
if (flow_file) {
fclose(flow_file);
}
end:
if (output_file) {
fclose(output_file);
}
return error;
}

View File

@@ -0,0 +1,209 @@
/*
**************************************************************************
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**************************************************************************
*/
/*
* @file NSSINFO n2h handler
*/
#include "nssinfo.h"
#include <nss_n2h.h>
#include <nss_nln2h_if.h>
static pthread_mutex_t n2h_lock;
static uint64_t drv_stats[NSS_STATS_DRV_MAX];
static struct nssinfo_stats_info nssinfo_n2h_stats_str[NSS_N2H_STATS_MAX];
/*
* nssinfo_n2h_stats_display()
* N2H display callback function.
*/
static void nssinfo_n2h_stats_display(int core, char *input)
{
struct node *n2h_node;
char str_rx[NSSINFO_STR_LEN], str_tx[NSSINFO_STR_LEN];
if (input && strncmp(input, nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_N2H].subsystem_name, strlen(input))) {
++invalid_input;
nssinfo_trace("Invalid node name: %s\n", input);
return;
}
pthread_mutex_lock(&n2h_lock);
n2h_node = nodes[core][NSS_N2H_INTERFACE];
if (!n2h_node) {
pthread_mutex_unlock(&n2h_lock);
return;
}
if (display_all_stats) {
nssinfo_print_all("n2h", "n2h Stats", nssinfo_n2h_stats_str, NSS_N2H_STATS_MAX, (uint64_t *)n2h_node->node_stats);
pthread_mutex_unlock(&n2h_lock);
return;
}
nssinfo_print_summary("n2h", (uint64_t *)n2h_node->node_stats, NULL, 0);
if (core == (NSS_MAX_CORES - 1)) {
char *format_stats = nssinfo_format_stats(drv_stats[NSS_STATS_DRV_RX_CMD_RESP]);
strlcpy(str_rx, format_stats, sizeof(str_rx));
format_stats = nssinfo_format_stats(drv_stats[NSS_STATS_DRV_TX_CMD_REQ]);
strlcpy(str_tx, format_stats, sizeof(str_tx));
nssinfo_stats_print(nssinfo_summary_fmt, " buf_cmd", str_rx, str_tx, "", "");
memset(str_rx, 0, sizeof(str_rx));
memset(str_tx, 0, sizeof(str_tx));
format_stats = nssinfo_format_stats(drv_stats[NSS_STATS_DRV_RX_EMPTY]);
strlcpy(str_rx, format_stats, sizeof(str_rx));
format_stats = nssinfo_format_stats(drv_stats[NSS_STATS_DRV_TX_EMPTY]);
strlcpy(str_tx, format_stats, sizeof(str_tx));
nssinfo_stats_print(nssinfo_summary_fmt, " buf_emty", str_rx, str_tx, "", "");
memset(str_rx, 0, sizeof(str_rx));
memset(str_tx, 0, sizeof(str_tx));
format_stats = nssinfo_format_stats(drv_stats[NSS_STATS_DRV_RX_PACKET]);
strlcpy(str_rx, format_stats, sizeof(str_rx));
format_stats = nssinfo_format_stats(drv_stats[NSS_STATS_DRV_TX_PACKET]);
strlcpy(str_tx, format_stats, sizeof(str_tx));
nssinfo_stats_print(nssinfo_summary_fmt, " buf_pkt", str_rx, str_tx, "", "");
memset(str_rx, 0, sizeof(str_rx));
format_stats = nssinfo_format_stats(drv_stats[NSS_STATS_DRV_RX_STATUS]);
strlcpy(str_rx, format_stats, sizeof(str_rx));
nssinfo_stats_print(nssinfo_summary_fmt, " status_sync", str_rx, "", "", "");
}
pthread_mutex_unlock(&n2h_lock);
}
/*
* nssinfo_n2h_stats_notify()
* N2H stats notify callback function.
*/
static void nssinfo_n2h_stats_notify(void *data)
{
uint64_t *node_stats;
struct nss_n2h_stats_notification *nss_stats = (struct nss_n2h_stats_notification *)data;
struct node *n2h_node;
struct node **n2h_ptr;
if (!nssinfo_coreid_ifnum_valid(nss_stats->core_id, NSS_N2H_INTERFACE)) {
return;
}
pthread_mutex_lock(&n2h_lock);
n2h_ptr = &nodes[nss_stats->core_id][NSS_N2H_INTERFACE];
n2h_node = *n2h_ptr;
if (n2h_node) {
memcpy(n2h_node->node_stats, &nss_stats->n2h_stats, sizeof(nss_stats->n2h_stats));
memcpy(drv_stats, &nss_stats->drv_stats, sizeof(nss_stats->drv_stats));
pthread_mutex_unlock(&n2h_lock);
return;
}
pthread_mutex_unlock(&n2h_lock);
n2h_node = (struct node *)calloc(1, sizeof(struct node));
if (!n2h_node) {
nssinfo_warn("Failed to allocate memory for N2H node\n");
return;
}
node_stats = (uint64_t *)malloc(sizeof(nss_stats->n2h_stats));
if (!node_stats) {
nssinfo_warn("Failed to allocate memory for n2h node stats\n");
goto n2h_node_free;
}
memcpy(node_stats, &nss_stats->n2h_stats, sizeof(nss_stats->n2h_stats));
memcpy(drv_stats, &nss_stats->drv_stats, sizeof(nss_stats->drv_stats));
n2h_node->node_stats = node_stats;
n2h_node->subsystem_id = NSS_NLCMN_SUBSYS_N2H;
/*
* Notify is guaranteed to be single threaded via Netlink listen callback
*/
pthread_mutex_lock(&n2h_lock);
*n2h_ptr = n2h_node;
pthread_mutex_unlock(&n2h_lock);
return;
n2h_node_free:
free(n2h_node);
}
/*
* nssinfo_n2h_destroy()
* Destroy N2H node.
*/
static void nssinfo_n2h_destroy(uint32_t core_id, uint32_t if_num)
{
if (nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_N2H].is_inited) {
nssinfo_node_stats_destroy(&n2h_lock, core_id, NSS_N2H_INTERFACE);
}
}
/*
* nssinfo_n2h_deinit()
* Deinitialize n2h module.
*/
void nssinfo_n2h_deinit(void *data)
{
struct nss_nlmcast_ctx *ctx = (struct nss_nlmcast_ctx *)data;
if (nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_N2H].is_inited) {
pthread_mutex_destroy(&n2h_lock);
nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_N2H].is_inited = false;
}
nss_nlmcast_sock_leave_grp(ctx, NSS_NLN2H_MCAST_GRP);
}
/*
* nssinfo_n2h_init()
* Initialize N2H module.
*/
int nssinfo_n2h_init(void *data)
{
int error;
struct nss_nlmcast_ctx *ctx = (struct nss_nlmcast_ctx *)data;
/*
* Subscribe for N2H MCAST group.
*/
nss_nlsock_set_family(&ctx->sock, NSS_NLN2H_FAMILY);
error = nss_nlmcast_sock_join_grp(ctx, NSS_NLN2H_MCAST_GRP);
if (error) {
nssinfo_warn("Unable to join N2H mcast group.\n");
return error;
}
if (nssinfo_stats_info_init(nssinfo_n2h_stats_str,
"/sys/kernel/debug/qca-nss-drv/strings/n2h") != 0) {
goto fail;
}
if (pthread_mutex_init(&n2h_lock, NULL) != 0) {
nssinfo_warn("Mutex init has failed for n2h\n");
goto fail;
}
nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_N2H].display = nssinfo_n2h_stats_display;
nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_N2H].notify = nssinfo_n2h_stats_notify;
nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_N2H].destroy = nssinfo_n2h_destroy;
nssinfo_subsystem_array[NSS_NLCMN_SUBSYS_N2H].is_inited = true;
return 0;
fail:
nss_nlmcast_sock_leave_grp(ctx, NSS_NLN2H_MCAST_GRP);
return -1;
}

View File

@@ -0,0 +1,28 @@
/*
**************************************************************************
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**************************************************************************
*/
#ifndef __NSSINFO_N2H_H
#define __NSSINFO_N2H_H
/**
* @brief initialize N2H module.
*
* @return 0 on success or -ve for failure
*/
int nssinfo_n2h_init(void *data);
void nssinfo_n2h_deinit(void *data);
#endif /* __NSSINFO_N2H_H*/

View File

@@ -0,0 +1,68 @@
# NHSS.QSDK.12.2
# by SqTER
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=qca-mcs
PKG_RELEASE:=1
PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/qca-mcs.git
PKG_SOURCE_DATE:=2023-06-01
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=678328971a846e02cb49d00b2d86832f02dff072
PKG_MIRROR_HASH:=6098deddb1fa85a0171344e3b07294df485c32e81fd3c7d9182728373f93a719
PKG_BUILD_PARALLEL:=1
include $(INCLUDE_DIR)/package.mk
define KernelPackage/qca-mcs
SECTION:=kernel
CATEGORY:=Kernel modules
SUBMENU:=Network Support
URL:=http://www.qca.qualcomm.com
MAINTAINER:=Qualcomm Atheros, Inc.
TITLE:=QCA Multicast Snooping Support
DEPENDS:=+@KERNEL_IPV6_MROUTE +@KERNEL_IP_MROUTE
KCONFIG:=CONFIG_NETFILTER=y CONFIG_BRIDGE_NETFILTER=y
FILES:=$(PKG_BUILD_DIR)/qca-mcs.ko
AUTOLOAD:=$(call AutoLoad,41,qca-mcs)
endef
define KernelPackage/qca-mcs/description
This package installs the IGMP/MLD Snooping Module
endef
QCA_MC_SNOOPING_HEADERS= \
$(PKG_BUILD_DIR)/mc_api.h \
$(PKG_BUILD_DIR)/mc_ecm.h \
define Build/InstallDev
$(INSTALL_DIR) $(1)/usr/include/qca-mcs
$(foreach header_file,$(QCA_MC_SNOOPING_HEADERS), $(CP) $(header_file) $(1)/usr/include/qca-mcs;)
$(foreach header_file,$(QCA_MC_SNOOPING_HEADERS), $(CP) $(header_file) $(1)/usr/include/;)
endef
EXTRA_CFLAGS+=-Wno-implicit-fallthrough
QCA_MC_SNOOPING_MAKE_OPTS:= \
$(KERNEL_MAKE_FLAGS) \
CONFIG_SUPPORT_MLD=y \
MDIR=$(PKG_BUILD_DIR) \
KBUILDPATH=$(LINUX_DIR) \
KERNELPATH=$(LINUX_SRC_DIR) \
KERNELRELEASE=$(LINUX_RELEASE)
define Build/Compile
+$(MAKE) $(PKG_JOBS) -C $(LINUX_DIR) \
$(KERNEL_MAKE_FLAGS) \
KBUILDPATH=$(LINUX_DIR) \
$(PKG_MAKE_FLAGS) \
M=$(PKG_BUILD_DIR) \
EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \
$(strip $(QCA_MC_SNOOPING_MAKE_OPTS)) \
modules
endef
$(eval $(call KernelPackage,qca-mcs))

View File

@@ -0,0 +1,56 @@
diff --git a/mc_osdep.h b/mc_osdep.h
index 5d47dc6..acde39a 100644
--- a/mc_osdep.h
+++ b/mc_osdep.h
@@ -24,7 +24,11 @@
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0))
static inline int os_br_pass_frame_up(struct sk_buff *skb)
{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 157))
+ return br_pass_frame_up(skb, false);
+#else
return br_pass_frame_up(skb);
+#endif
}
#else
static inline int os_br_pass_frame_up(struct sk_buff *skb)
@@ -189,7 +193,7 @@ static inline struct net_bridge_port *mc_bridge_get_dst(const struct net_bridge_
dst = os_br_fdb_get((struct net_bridge *)br, eth_hdr(*skb)->h_dest);
- if (dst && !dst->is_local)
+ if (dst && !test_bit(BR_FDB_LOCAL, &dst->flags))
return dst->dst;
return NULL;
diff --git a/mc_snooping.c b/mc_snooping.c
index 378b0f8..03ec6e8 100644
--- a/mc_snooping.c
+++ b/mc_snooping.c
@@ -3450,6 +3450,18 @@ static int mc_proc_snooper_open(struct inode *inode, struct file *file)
return single_open(file, mc_proc_snooper_show, NULL);
}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0)
+#define HAVE_PROC_OPS
+#endif
+
+#ifdef HAVE_PROC_OPS
+static const struct proc_ops mc_proc_snooper_fops = {
+ .proc_open = mc_proc_snooper_open,
+ .proc_read = seq_read,
+ .proc_lseek = seq_lseek,
+ .proc_release = single_release,
+};
+#else
static const struct file_operations mc_proc_snooper_fops = {
.owner = THIS_MODULE,
.open = mc_proc_snooper_open,
@@ -3457,6 +3469,7 @@ static const struct file_operations mc_proc_snooper_fops = {
.llseek = seq_lseek,
.release = single_release,
};
+#endif
/* mc_proc_create_snooper_entry
* create proc entry for information show

View File

@@ -0,0 +1,497 @@
# NHSS.QSDK.12.2
# by SqTER
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=qca-nss-clients
PKG_RELEASE:=2
PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/nss-clients.git
PKG_SOURCE_DATE:=2023-06-01
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=4cc5d7687c69ef1fbc53d5492d9d672d2d8ef030
PKG_MIRROR_HASH:=cc1904bd90a0fc137b114b3232245c973e84068ea52caeaac66c49d958739a4e
PKG_BUILD_DEPENDS:=qca-nss-drv
PKG_BUILD_PARALLEL:=1
include $(INCLUDE_DIR)/package.mk
# Keep default as ipq806x for branches that does not have subtarget framework
ifeq ($(CONFIG_TARGET_ipq),y)
subtarget:=$(SUBTARGET)
else
subtarget:=$(CONFIG_TARGET_BOARD)
endif
define KernelPackage/qca-nss-drv-tun6rd
SECTION:=kernel
CATEGORY:=Kernel modules
SUBMENU:=Network Devices
TITLE:=Kernel driver for NSS (connection manager) - tun6rd
DEPENDS:=+@NSS_DRV_TUN6RD_ENABLE +kmod-sit +6rd \
+PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv
FILES:=$(PKG_BUILD_DIR)/qca-nss-tun6rd.ko
AUTOLOAD:=$(call AutoLoad,60,qca-nss-tun6rd)
endef
define KernelPackage/qca-nss-drv-tun6rd/description
Kernel modules for NSS connection manager - Support for 6rd tunnel
endef
define KernelPackage/qca-nss-drv-l2tpv2
SECTION:=kernel
CATEGORY:=Kernel modules
SUBMENU:=Network Devices
TITLE:=Kernel driver for NSS (connection manager) - l2tp
DEPENDS:=+@NSS_DRV_L2TP_ENABLE +kmod-ppp +kmod-l2tp \
+PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv
FILES:=$(PKG_BUILD_DIR)/l2tp/l2tpv2/qca-nss-l2tpv2.ko
KCONFIG:=CONFIG_L2TP=y
AUTOLOAD:=$(call AutoLoad,51,qca-nss-l2tpv2)
endef
define KernelPackage/qca-nss-drv-l2tp/description
Kernel modules for NSS connection manager - Support for l2tp tunnel
endef
define KernelPackage/qca-nss-drv-pptp
SECTION:=kernel
CATEGORY:=Kernel modules
SUBMENU:=Network Devices
TITLE:=Kernel driver for NSS (connection manager) - PPTP
DEPENDS:=+@NSS_DRV_PPTP_ENABLE +kmod-pptp \
+PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv
FILES:=$(PKG_BUILD_DIR)/pptp/qca-nss-pptp.ko
AUTOLOAD:=$(call AutoLoad,51,qca-nss-pptp)
endef
define KernelPackage/qca-nss-drv-pptp/description
Kernel modules for NSS connection manager - Support for PPTP tunnel
endef
define KernelPackage/qca-nss-drv-pppoe
SECTION:=kernel
CATEGORY:=Kernel modules
SUBMENU:=Network Devices
TITLE:=Kernel driver for NSS (connection manager) - PPPoE
DEPENDS:=+@NSS_DRV_PPPOE_ENABLE +kmod-pppoe \
+PACKAGE_kmod-bonding:kmod-bonding \
+PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv
FILES:=$(PKG_BUILD_DIR)/pppoe/qca-nss-pppoe.ko
AUTOLOAD:=$(call AutoLoad,51,qca-nss-pppoe)
endef
define KernelPackage/qca-nss-drv-pppoe/description
Kernel modules for NSS connection manager - Support for PPPoE
endef
define KernelPackage/qca-nss-drv-gre
SECTION:=kernel
CATEGORY:=Kernel modules
SUBMENU:=Network Devices
TITLE:=Kernel driver for NSS (connection manager) - GRE
DEPENDS:=@TARGET_ipq_ipq806x||TARGET_ipq806x||TARGET_ipq_ipq807x||TARGET_ipq_ipq807x_64||TARGET_ipq807x||TARGET_ipq807x_64||TARGET_ipq_ipq60xx||TARGET_ipq_ipq60xx_64||TARGET_ipq_ipq50xx||TARGET_ipq_ipq50xx_64 \
+@NSS_DRV_GRE_ENABLE +kmod-gre6 \
+PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv
FILES:=$(PKG_BUILD_DIR)/gre/qca-nss-gre.ko $(PKG_BUILD_DIR)/gre/test/qca-nss-gre-test.ko
AUTOLOAD:=$(call AutoLoad,51,qca-nss-gre)
endef
define KernelPackage/qca-nss-drv-gre/description
Kernel modules for NSS connection manager - Support for GRE
endef
define KernelPackage/qca-nss-drv-tunipip6
SECTION:=kernel
CATEGORY:=Kernel modules
SUBMENU:=Network Devices
TITLE:=Kernel driver for NSS (connection manager) - DS-lite and ipip6 Tunnel
DEPENDS:=+@NSS_DRV_TUNIPIP6_ENABLE +kmod-iptunnel6 +kmod-ip6-tunnel \
+PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv
FILES:=$(PKG_BUILD_DIR)/qca-nss-tunipip6.ko
AUTOLOAD:=$(call AutoLoad,60,qca-nss-tunipip6)
endef
define KernelPackage/qca-nss-drv-tunipip6/description
Kernel modules for NSS connection manager
Add support for DS-lite and ipip6 tunnel
endef
define KernelPackage/qca-nss-drv-profile
SECTION:=kernel
CATEGORY:=Kernel modules
SUBMENU:=Network Devices
DEPENDS:=+@NSS_DRV_PROFILE_ENABLE \
+PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv
TITLE:=Profiler for QCA NSS driver (IPQ806x)
FILES:=$(PKG_BUILD_DIR)/profiler/qca-nss-profile-drv.ko
endef
define KernelPackage/qca-nss-drv-profile/description
This package contains a NSS driver profiler for QCA chipset
endef
define KernelPackage/qca-nss-drv-portifmgr
SECTION:=kernel
CATEGORY:=Kernel modules
SUBMENU:=Network Devices
TITLE:=Kernel driver for NSS (qca-nss-drv-portifmgr)
DEPENDS:=+@NSS_DRV_PORTID_ENABLE +kmod-qca-nss-gmac \
+PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv
FILES:=$(PKG_BUILD_DIR)/portifmgr/qca-nss-portifmgr.ko
endef
define KernelPackage/qca-nss-drv-portifmgr/Description
NSS Kernel module for Port interface manager
endef
define KernelPackage/qca-nss-drv-bridge-mgr
SECTION:=kernel
CATEGORY:=Kernel modules
SUBMENU:=Network Devices
TITLE:=Kernel driver for NSS bridge manager
DEPENDS:=@TARGET_ipq_ipq807x||TARGET_ipq_ipq807x_64||TARGET_ipq807x||TARGET_ipq_ipq60xx||TARGET_ipq_ipq60xx_64||TARGET_ipq60xx \
+TARGET_ipq_ipq807x:kmod-qca-nss-drv-vlan-mgr \
+TARGET_ipq_ipq807x_64:kmod-qca-nss-drv-vlan-mgr \
+TARGET_ipq807x:kmod-qca-nss-drv-vlan-mgr \
+TARGET_ipq60xx:kmod-qca-nss-drv-vlan-mgr \
+TARGET_ipq_ipq60xx:kmod-qca-nss-drv-vlan-mgr \
+TARGET_ipq_ipq60xx_64:kmod-qca-nss-drv-vlan-mgr \
+PACKAGE_kmod-bonding:kmod-bonding \
+PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv \
+@NSS_DRV_BRIDGE_ENABLE
ifneq ($(CONFIG_PACKAGE_kmod-qca-ovsmgr),)
DEPENDS+=kmod-qca-ovsmgr
endif
FILES:=$(PKG_BUILD_DIR)/bridge/qca-nss-bridge-mgr.ko
AUTOLOAD:=$(call AutoLoad,51,qca-nss-bridge-mgr)
endef
define KernelPackage/qca-nss-drv-bridge-mgr/description
Kernel modules for NSS bridge manager
endef
define KernelPackage/qca-nss-drv-vlan-mgr
SECTION:=kernel
CATEGORY:=Kernel modules
SUBMENU:=Network Devices
TITLE:=Kernel driver for NSS vlan manager
DEPENDS:=@TARGET_ipq_ipq807x||TARGET_ipq_ipq806x||TARGET_ipq807x||TARGET_ipq_ipq60xx||TARGET_ipq_ipq60xx_64||TARGET_ipq60xx \
+PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv \
+@NSS_DRV_VLAN_ENABLE \
+PACKAGE_kmod-bonding:kmod-bonding
FILES:=$(PKG_BUILD_DIR)/vlan/qca-nss-vlan.ko
AUTOLOAD:=$(call AutoLoad,51,qca-nss-vlan)
endef
define KernelPackage/qca-nss-drv-vlan-mgr/description
Kernel modules for NSS vlan manager
endef
define KernelPackage/qca-nss-drv-qdisc
SECTION:=kernel
CATEGORY:=Kernel modules
SUBMENU:=Network Devices
TITLE:=Qdisc for configuring shapers in NSS
DEPENDS:=+@NSS_DRV_SHAPER_ENABLE +@NSS_DRV_IGS_ENABLE \
+PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv
FILES:=$(PKG_BUILD_DIR)/nss_qdisc/qca-nss-qdisc.ko
KCONFIG:=CONFIG_NET_CLS_ACT=y
AUTOLOAD:=$(call AutoLoad,58,qca-nss-qdisc)
endef
define KernelPackage/qca-nss-drv-qdisc/description
Linux qdisc that aids in configuring shapers in the NSS
endef
define KernelPackage/qca-nss-drv-igs
SECTION:=kernel
CATEGORY:=Kernel modules
SUBMENU:=Network Devices
TITLE:=Action for offloading traffic to an IFB interface to perform ingress shaping.
DEPENDS:=@TARGET_ipq806x||TARGET_ipq_ipq807x||TARGET_ipq_ipq807x_64||TARGET_ipq_ipq60xx||TARGET_ipq_ipq60xx_64||TARGET_ipq_ipq50xx||TARGET_ipq_ipq50xx_64 \
+@NSS_DRV_IGS_ENABLE +kmod-sched-core +kmod-ifb +kmod-qca-nss-drv-qdisc \
+PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv
FILES:=$(PKG_BUILD_DIR)/nss_qdisc/igs/act_nssmirred.ko
endef
define KernelPackage/qca-nss-drv-igs/description
Linux action that helps in offloading traffic to an IFB interface to perform ingress shaping.
endef
define KernelPackage/qca-nss-drv-lag-mgr
SECTION:=kernel
CATEGORY:=Kernel modules
SUBMENU:=Network Devices
TITLE:=Kernel driver for NSS LAG manager
DEPENDS:=+@NSS_DRV_LAG_ENABLE \
+TARGET_ipq_ipq807x:kmod-qca-nss-drv-vlan-mgr \
+TARGET_ipq_ipq807x_64:kmod-qca-nss-drv-vlan-mgr \
+TARGET_ipq807x:kmod-qca-nss-drv-vlan-mgr \
+TARGET_ipq_ipq60xx:kmod-qca-nss-drv-vlan-mgr \
+TARGET_ipq_ipq60xx_64:kmod-qca-nss-drv-vlan-mgr \
+TARGET_ipq60xx:kmod-qca-nss-drv-vlan-mgr \
+PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv \
+kmod-bonding
FILES:=$(PKG_BUILD_DIR)/lag/qca-nss-lag-mgr.ko
AUTOLOAD:=$(call AutoLoad,51,qca-nss-lag-mgr)
endef
define KernelPackage/qca-nss-drv-lag-mgr/description
Kernel modules for NSS LAG manager
endef
define KernelPackage/qca-nss-drv-netlink
SECTION:=kernel
CATEGORY:=Kernel modules
SUBMENU:=Network Devices
DEPENDS:=@TARGET_ipq806x||TARGET_ipq807x||TARGET_ipq_ipq807x_64||TARGET_ipq_ipq60xx||TARGET_ipq_ipq60xx_64||TARGET_ipq60xx||TARGET_ipq_ipq50xx||TARGET_ipq_ipq50xx_64||TARGET_ipq50xx \
+PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv \
+@NSS_DRV_GRE_REDIR_ENABLE
TITLE:=NSS NETLINK Manager for QCA NSS driver
FILES:=$(PKG_BUILD_DIR)/netlink/qca-nss-netlink.ko
endef
define KernelPackage/qca-nss-drv-netlink/description
Kernel module for NSS netlink manager
endef
define KernelPackage/qca-nss-drv-pvxlanmgr
SECTION:=kernel
CATEGORY:=Kernel modules
SUBMENU:=Network Devices
DEPENDS:=+@NSS_DRV_PVXLAN_ENABLE +PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv
TITLE:=NSS PVXLAN Manager for QCA NSS driver
FILES:=$(PKG_BUILD_DIR)/pvxlanmgr/qca-nss-pvxlanmgr.ko
endef
define KernelPackage/qca-nss-drv-pvxlanmgr/description
Kernel module for managing NSS PVxLAN
endef
define KernelPackage/qca-nss-drv-eogremgr
SECTION:=kernel
CATEGORY:=Kernel modules
SUBMENU:=Network Devices
DEPENDS:=+@NSS_DRV_GRE_ENABLE +PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv +kmod-qca-nss-drv-gre
TITLE:=NSS EOGRE Manager for QCA NSS driver
FILES:=$(PKG_BUILD_DIR)/eogremgr/qca-nss-eogremgr.ko
endef
define KernelPackage/qca-nss-drv-eogremgr/description
Kernel module for managing NSS EoGRE
endef
define KernelPackage/qca-nss-drv-clmapmgr
SECTION:=kernel
CATEGORY:=Kernel modules
SUBMENU:=Network Devices
DEPENDS:=+@NSS_DRV_CLMAP_ENABLE +PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv +kmod-qca-nss-drv-eogremgr
TITLE:=NSS clmap Manager for QCA NSS driver
FILES:=$(PKG_BUILD_DIR)/clmapmgr/qca-nss-clmapmgr.ko
endef
define KernelPackage/qca-nss-drv-clmapmgr/description
Kernel module for managing NSS clmap
endef
# define KernelPackage/qca-nss-drv-vxlanmgr
# SECTION:=kernel
# CATEGORY:=Kernel modules
# SUBMENU:=Network Devices
# DEPENDS:=+@NSS_DRV_VXLAN_ENABLE +PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv +kmod-vxlan
# TITLE:=NSS VxLAN Manager for QCA NSS driver
# FILES:=$(PKG_BUILD_DIR)/vxlanmgr/qca-nss-vxlanmgr.ko
# AUTOLOAD:=$(call AutoLoad,51,qca-nss-vxlanmgr)
# endef
#
# define KernelPackage/qca-nss-drv-vxlanmgr/description
# Kernel module for managing NSS VxLAN
# endef
# define KernelPackage/qca-nss-drv-match
# SECTION:=kernel
# CATEGORY:=Kernel modules
# SUBMENU:=Network Devices
# DEPENDS:=+@NSS_DRV_MATCH_ENABLE +PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv
# TITLE:=NSS Match for QCA NSS driver
# FILES:=$(PKG_BUILD_DIR)/match/qca-nss-match.ko
# endef
#
# define KernelPackage/qca-nss-drv-match/description
# Kernel module for managing NSS Match
# endef
#
# define KernelPackage/qca-nss-drv-mirror
# SECTION:=kernel
# CATEGORY:=Kernel modules
# SUBMENU:=Network Devices
# TITLE:=Module for mirroring packets from NSS to host.
# DEPENDS:=+@NSS_DRV_MIRROR_ENABLE +PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv
# FILES:=$(PKG_BUILD_DIR)/mirror/qca-nss-mirror.ko
# endef
#
# define KernelPackage/qca-nss-drv-mirror/Description
# Kernel module for managing NSS Mirror
# endef
# define KernelPackage/qca-nss-drv-wifi-meshmgr
# SECTION:=kernel
# CATEGORY:=Kernel modules
# SUBMENU:=Network Devices
# DEPENDS:=+@NSS_DRV_WIFI_ENABLE +PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv
# TITLE:=NSS WiFi-Mesh Manager for QCA NSS driver
# FILES:=$(PKG_BUILD_DIR)/wifi_meshmgr/qca-nss-wifi-meshmgr.ko
# AUTOLOAD:=$(call AutoLoad,51,qca-nss-wifi-meshmgr)
# endef
# define KernelPackage/qca-nss-drv-wifi-meshmgr/Description
# Kernel module for WiFi Mesh manager
# endef
define Build/InstallDev/qca-nss-clients
$(INSTALL_DIR) $(1)/usr/include/qca-nss-clients
$(CP) $(PKG_BUILD_DIR)/netlink/include/* $(1)/usr/include/qca-nss-clients/
$(CP) $(PKG_BUILD_DIR)/exports/* $(1)/usr/include/qca-nss-clients/
endef
define Build/InstallDev
$(call Build/InstallDev/qca-nss-clients,$(1))
endef
define KernelPackage/qca-nss-drv-igs/install
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./files/qca-nss-mirred.init $(1)/etc/init.d/qca-nss-mirred
endef
EXTRA_CFLAGS+= \
-I$(STAGING_DIR)/usr/include/qca-nss-drv \
-I$(STAGING_DIR)/usr/include/qca-nss-crypto \
-I$(STAGING_DIR)/usr/include/qca-nss-cfi \
-I$(STAGING_DIR)/usr/include/qca-nss-gmac \
-I$(STAGING_DIR)/usr/include/qca-nss-ecm \
-I$(STAGING_DIR)/usr/include/qca-ssdk \
-I$(STAGING_DIR)/usr/include/qca-ssdk/fal
# Build individual packages if selected
ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-portifmgr),)
MAKE_OPTS+=portifmgr=y
EXTRA_CFLAGS += -DNSS_PORTIFMGR_REF_AP148 -I$(PKG_BUILD_DIR)/portifmgr
endif
ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-profile),)
MAKE_OPTS+=profile=y
endif
ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-tun6rd),)
MAKE_OPTS+=tun6rd=m
endif
ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-l2tpv2),)
MAKE_OPTS+=l2tpv2=y
EXTRA_CFLAGS += -DNSS_L2TPV2_ENABLED
endif
ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-pptp),)
MAKE_OPTS+=pptp=y
endif
ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-tunipip6),)
MAKE_OPTS+=tunipip6=m
endif
ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-qdisc),)
MAKE_OPTS+=qdisc=y
endif
ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-igs),)
MAKE_OPTS+=igs=y
EXTRA_CFLAGS+=-DNSS_IGS_DEBUG_LEVEL=4
endif
ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-bridge-mgr),)
MAKE_OPTS+=bridge-mgr=y
#enable OVS bridge if ovsmgr is enabled
ifneq ($(CONFIG_PACKAGE_kmod-qca-ovsmgr),)
MAKE_OPTS+= NSS_BRIDGE_MGR_OVS_ENABLE=y
EXTRA_CFLAGS+= -I$(STAGING_DIR)/usr/include/qca-ovsmgr
endif
endif
ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-vlan-mgr),)
MAKE_OPTS+=vlan-mgr=y
endif
ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-lag-mgr),)
MAKE_OPTS+=lag-mgr=y
endif
ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-gre),)
EXTRA_CFLAGS+= -I$(PKG_BUILD_DIR)/exports
MAKE_OPTS+=gre=y
endif
ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-pppoe),)
MAKE_OPTS+=pppoe=y
endif
ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-netlink),)
MAKE_OPTS+=netlink=y
ifeq ($(CONFIG_KERNEL_IPQ_MEM_PROFILE),256)
EXTRA_CFLAGS+= -DNSS_NETLINK_UDP_ST_NO_RMNET_SUPPORT
else ifeq ($(CONFIG_LOWMEM_FLASH),y)
EXTRA_CFLAGS+= -DNSS_NETLINK_UDP_ST_NO_RMNET_SUPPORT
endif
endif
ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-pvxlanmgr),)
MAKE_OPTS+=pvxlanmgr=y
endif
ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-eogremgr),)
MAKE_OPTS+=eogremgr=y
endif
ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-clmapmgr),)
MAKE_OPTS+=clmapmgr=y
endif
# ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-vxlanmgr),)
# MAKE_OPTS+=vxlanmgr=y
# EXTRA_CFLAGS += -DNSS_VXLAN_ENABLED
# endif
# ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-match),)
# MAKE_OPTS+=match=y
# endif
define Build/Compile
+$(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" $(strip $(MAKE_OPTS)) \
CROSS_COMPILE="$(TARGET_CROSS)" \
ARCH="$(LINUX_KARCH)" \
$(KERNEL_MAKE_FLAGS) \
$(PKG_MAKE_FLAGS) \
M="$(PKG_BUILD_DIR)" \
EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \
SoC="$(subtarget)" \
modules
endef
$(eval $(call KernelPackage,qca-nss-drv-profile))
$(eval $(call KernelPackage,qca-nss-drv-tun6rd))
$(eval $(call KernelPackage,qca-nss-drv-l2tpv2))
$(eval $(call KernelPackage,qca-nss-drv-pptp))
$(eval $(call KernelPackage,qca-nss-drv-pppoe))
$(eval $(call KernelPackage,qca-nss-drv-tunipip6))
$(eval $(call KernelPackage,qca-nss-drv-qdisc))
$(eval $(call KernelPackage,qca-nss-drv-igs))
$(eval $(call KernelPackage,qca-nss-drv-portifmgr))
$(eval $(call KernelPackage,qca-nss-drv-netlink))
$(eval $(call KernelPackage,qca-nss-drv-bridge-mgr))
$(eval $(call KernelPackage,qca-nss-drv-vlan-mgr))
$(eval $(call KernelPackage,qca-nss-drv-lag-mgr))
$(eval $(call KernelPackage,qca-nss-drv-gre))
$(eval $(call KernelPackage,qca-nss-drv-pvxlanmgr))
$(eval $(call KernelPackage,qca-nss-drv-eogremgr))
$(eval $(call KernelPackage,qca-nss-drv-clmapmgr))

View File

@@ -0,0 +1,92 @@
#!/bin/sh /etc/rc.common
#
# Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
NSS_IPSEC_LOG_FILE=/tmp/.nss_ipsec_log
NSS_IPSEC_LOG_STR_ECM="ECM_Loaded"
ecm_load () {
if [ ! -d /sys/module/ecm ]; then
/etc/init.d/qca-nss-ecm start
if [ -d /sys/module/ecm ]; then
echo ${NSS_IPSEC_LOG_STR_ECM} >> ${NSS_IPSEC_LOG_FILE}
fi
fi
}
ecm_unload () {
if [ -f /tmp/.nss_ipsec_log ]; then
str=`grep ${NSS_IPSEC_LOG_STR_ECM} ${NSS_IPSEC_LOG_FILE}`
if [[ $str == ${NSS_IPSEC_LOG_STR_ECM} ]]; then
/etc/init.d/qca-nss-ecm stop
`sed 's/${NSS_IPSEC_LOG_STR_ECM}/ /g' $NSS_IPSEC_LOG_FILE > $NSS_IPSEC_LOG_FILE`
fi
fi
}
ecm_disable() {
if [ ! -d /sys/module/ecm ]; then
return;
fi
echo 1 > /sys/kernel/debug/ecm/front_end_ipv4_stop
echo 1 > /sys/kernel/debug/ecm/front_end_ipv6_stop
echo 1 > /sys/kernel/debug/ecm/ecm_db/defunct_all
sleep 2
}
ecm_enable() {
if [ ! -d /sys/module/ecm ]; then
return;
fi
echo 0 > /sys/kernel/debug/ecm/ecm_db/defunct_all
echo 0 > /sys/kernel/debug/ecm/front_end_ipv4_stop
echo 0 > /sys/kernel/debug/ecm/front_end_ipv6_stop
}
start() {
ecm_load
local kernel_version=$(uname -r)
insmod /lib/modules/${kernel_version}/qca-nss-ipsec-klips.ko
if [ "$?" -gt 0 ]; then
echo "Failed to load plugin. Please start ecm if not done already"
ecm_enable
return
fi
/etc/init.d/ipsec start
sleep 2
ipsec eroute
ecm_enable
}
stop() {
ecm_disable
/etc/init.d/ipsec stop
rmmod qca-nss-ipsec-klips
ecm_unload
}
restart() {
stop
start
}

View File

@@ -0,0 +1,28 @@
#!/bin/sh /etc/rc.common
###########################################################################
# Copyright (c) 2019, The Linux Foundation. All rights reserved.
# Permission to use, copy, modify, and/or distribute this software for
# any purpose with or without fee is hereby granted, provided that the
# above copyright notice and this permission notice appear in all copies.
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
###########################################################################
restart() {
rmmod act_nssmirred.ko
insmod act_nssmirred.ko
}
start() {
insmod act_nssmirred.ko
}
stop() {
rmmod act_nssmirred.ko
}

View File

@@ -0,0 +1,69 @@
#!/bin/sh /etc/rc.common
###########################################################################
# Copyright (c) 2019, The Linux Foundation. All rights reserved.
# Permission to use, copy, modify, and/or distribute this software for
# any purpose with or without fee is hereby granted, provided that the
# above copyright notice and this permission notice appear in all copies.
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
###########################################################################
ecm_disable() {
if [ ! -d /sys/module/ecm ]; then
return
fi
echo 1 > /sys/kernel/debug/ecm/front_end_ipv4_stop
echo 1 > /sys/kernel/debug/ecm/front_end_ipv6_stop
echo 1 > /sys/kernel/debug/ecm/ecm_db/defunct_all
sleep 2
}
ecm_enable() {
if [ ! -d /sys/module/ecm ]; then
return
fi
echo 0 > /sys/kernel/debug/ecm/ecm_db/defunct_all
echo 0 > /sys/kernel/debug/ecm/front_end_ipv4_stop
echo 0 > /sys/kernel/debug/ecm/front_end_ipv6_stop
}
restart() {
ecm_disable
/etc/init.d/openvpn stop
rmmod qca-nss-ovpn-link
rmmod qca-nss-ovpn-mgr
insmod qca-nss-ovpn-mgr
insmod qca-nss-ovpn-link
if [ "$?" -gt 0 ]; then
echo "Failed to load plugin. Please start ecm if not done already"
ecm_enable
return
fi
ecm_enable
}
start() {
restart
}
stop() {
ecm_disable
/etc/init.d/openvpn stop
rmmod qca-nss-ovpn-link
rmmod qca-nss-ovpn-mgr
ecm_enable
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,460 @@
--- a/bridge/nss_bridge_mgr.c
+++ b/bridge/nss_bridge_mgr.c
@@ -18,6 +18,7 @@
* nss_bridge_mgr.c
* NSS to HLOS Bridge Interface manager
*/
+#include <linux/version.h>
#include <linux/sysctl.h>
#include <linux/etherdevice.h>
#include <linux/if_vlan.h>
@@ -1050,7 +1051,11 @@ int nss_bridge_mgr_register_br(struct ne
}
#endif
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ err = nss_bridge_tx_set_mac_addr_msg(ifnum, (uint8_t *)dev->dev_addr);
+#else
err = nss_bridge_tx_set_mac_addr_msg(ifnum, dev->dev_addr);
+#endif
if (err != NSS_TX_SUCCESS) {
nss_bridge_mgr_warn("%px: failed to set mac_addr msg, error = %d\n", b_pvt, err);
goto fail_3;
@@ -1207,7 +1212,12 @@ static int nss_bridge_mgr_changeaddr_eve
nss_bridge_mgr_trace("%px: MAC changed to %pM, update NSS\n", b_pvt, dev->dev_addr);
- if (nss_bridge_tx_set_mac_addr_msg(b_pvt->ifnum, dev->dev_addr) != NSS_TX_SUCCESS) {
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ if (nss_bridge_tx_set_mac_addr_msg(b_pvt->ifnum, (uint8_t *)dev->dev_addr) != NSS_TX_SUCCESS)
+#else
+ if (nss_bridge_tx_set_mac_addr_msg(b_pvt->ifnum, dev->dev_addr) != NSS_TX_SUCCESS)
+#endif
+ {
nss_bridge_mgr_warn("%px: Failed to send change MAC address message to NSS\n", b_pvt);
return NOTIFY_BAD;
}
--- a/dtls/v2.0/nss_dtlsmgr_ctx_dev.c
+++ b/dtls/v2.0/nss_dtlsmgr_ctx_dev.c
@@ -526,7 +526,11 @@ void nss_dtlsmgr_ctx_dev_setup(struct ne
#else
dev->priv_destructor = nss_dtlsmgr_ctx_dev_free;
#endif
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ memcpy((void *)dev->dev_addr, "\xaa\xbb\xcc\xdd\xee\xff", dev->addr_len);
+#else
memcpy(dev->dev_addr, "\xaa\xbb\xcc\xdd\xee\xff", dev->addr_len);
+#endif
memset(dev->broadcast, 0xff, dev->addr_len);
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
}
--- a/gre/test/nss_connmgr_gre_test.c
+++ b/gre/test/nss_connmgr_gre_test.c
@@ -223,7 +223,11 @@ static int nss_connmgr_gre_test_show_pro
*/
static int nss_connmgr_gre_test_open_proc(struct inode *inode, struct file *filp)
{
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ return single_open(filp, nss_connmgr_gre_test_show_proc, pde_data(inode));
+#else
return single_open(filp, nss_connmgr_gre_test_show_proc, PDE_DATA(inode));
+#endif
}
/*
--- a/gre/nss_connmgr_gre.c
+++ b/gre/nss_connmgr_gre.c
@@ -279,10 +279,17 @@ static struct rtnl_link_stats64 *nss_con
#else
start = u64_stats_fetch_begin_irq(&tstats->syncp);
#endif
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ rx_packets = u64_stats_read(&tstats->rx_packets);
+ tx_packets = u64_stats_read(&tstats->tx_packets);
+ rx_bytes = u64_stats_read(&tstats->rx_bytes);
+ tx_bytes = u64_stats_read(&tstats->tx_bytes);
+#else
rx_packets = tstats->rx_packets;
tx_packets = tstats->tx_packets;
rx_bytes = tstats->rx_bytes;
tx_bytes = tstats->tx_bytes;
+#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 15, 0))
} while (u64_stats_fetch_retry_bh(&tstats->syncp, start));
#else
@@ -697,11 +704,21 @@ static void nss_connmgr_gre_event_receiv
tstats = this_cpu_ptr(dev->tstats);
u64_stats_update_begin(&tstats->syncp);
if (interface_type == NSS_DYNAMIC_INTERFACE_TYPE_GRE_INNER) {
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ u64_stats_add(&tstats->tx_packets, stats->tx_packets);
+ u64_stats_add(&tstats->tx_bytes, stats->tx_bytes);
+#else
tstats->tx_packets += stats->tx_packets;
tstats->tx_bytes += stats->tx_bytes;
+#endif
} else if (interface_type == NSS_DYNAMIC_INTERFACE_TYPE_GRE_OUTER) {
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ u64_stats_add(&tstats->rx_packets, stats->rx_packets);
+ u64_stats_add(&tstats->rx_bytes, stats->rx_bytes);
+#else
tstats->rx_packets += stats->rx_packets;
tstats->rx_bytes += stats->rx_bytes;
+#endif
}
u64_stats_update_end(&tstats->syncp);
dev->stats.rx_dropped += nss_cmn_rx_dropped_sum(stats);
--- a/tunipip6/nss_connmgr_tunipip6.c
+++ b/tunipip6/nss_connmgr_tunipip6.c
@@ -353,11 +353,21 @@ static void nss_tunipip6_update_dev_stat
memset(&stats, 0, sizeof(stats));
if (interface_type == NSS_DYNAMIC_INTERFACE_TYPE_TUNIPIP6_INNER) {
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ u64_stats_set(&stats.tx_packets, sync_stats->node_stats.tx_packets);
+ u64_stats_set(&stats.tx_bytes, sync_stats->node_stats.tx_bytes);
+#else
stats.tx_packets = sync_stats->node_stats.tx_packets;
stats.tx_bytes = sync_stats->node_stats.tx_bytes;
+#endif
} else if (interface_type == NSS_DYNAMIC_INTERFACE_TYPE_TUNIPIP6_OUTER) {
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ u64_stats_set(&stats.rx_packets, sync_stats->node_stats.rx_packets);
+ u64_stats_set(&stats.rx_bytes, sync_stats->node_stats.rx_bytes);
+#else
stats.rx_packets = sync_stats->node_stats.rx_packets;
stats.rx_bytes = sync_stats->node_stats.rx_bytes;
+#endif
} else {
nss_tunipip6_warning("%px: Invalid interface type received from NSS\n", dev);
return;
--- a/nss_qdisc/igs/nss_mirred.c
+++ b/nss_qdisc/igs/nss_mirred.c
@@ -317,7 +317,11 @@ static int nss_mirred_act(struct sk_buff
* Update the last use of action.
*/
tcf_lastuse_update(&act->tcf_tm);
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ bstats_update(this_cpu_ptr(act->common.cpu_bstats), skb);
+#else
bstats_cpu_update(this_cpu_ptr(act->common.cpu_bstats), skb);
+#endif
rcu_read_lock();
retval = READ_ONCE(act->tcf_action);
--- a/nss_qdisc/nss_qdisc.h
+++ b/nss_qdisc/nss_qdisc.h
@@ -188,7 +188,11 @@ struct nss_qdisc {
/* Shaper configure callback for reading shaper specific
* responses (e.g. memory size).
*/
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ struct gnet_stats_basic_sync bstats; /* Basic class statistics */
+#else
struct gnet_stats_basic_packed bstats; /* Basic class statistics */
+#endif
struct gnet_stats_queue qstats; /* Qstats for use by classes */
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0))
atomic_t refcnt; /* Reference count for class use */
@@ -444,8 +448,13 @@ extern void nss_qdisc_stop_basic_stats_p
* nss_qdisc_gnet_stats_copy_basic()
* Wrapper around gnet_stats_copy_basic()
*/
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+extern int nss_qdisc_gnet_stats_copy_basic(struct Qdisc *sch,
+ struct gnet_dump *d, struct gnet_stats_basic_sync *b);
+#else
extern int nss_qdisc_gnet_stats_copy_basic(struct Qdisc *sch,
struct gnet_dump *d, struct gnet_stats_basic_packed *b);
+#endif
/*
* nss_qdisc_gnet_stats_copy_queue()
--- a/nss_qdisc/igs/nss_ifb.c
+++ b/nss_qdisc/igs/nss_ifb.c
@@ -544,8 +544,15 @@ static void nss_ifb_update_dev_stats(str
* post shaping. Therefore IFB interface's stats should be updated
* with NSS firmware's IFB TX stats only.
*/
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ u64_stats_set(&stats.rx_packets, node_stats->tx_packets);
+ u64_stats_set(&stats.tx_packets, node_stats->tx_packets);
+ u64_stats_set(&stats.rx_bytes, node_stats->tx_bytes);
+ u64_stats_set(&stats.tx_bytes, node_stats->tx_bytes);
+#else
stats.rx_packets = stats.tx_packets = node_stats->tx_packets;
stats.rx_bytes = stats.tx_bytes = node_stats->tx_bytes;
+#endif
dev->stats.rx_dropped = dev->stats.tx_dropped += sync_stats->igs_stats.tx_dropped;
u64_stats_update_end(&stats.syncp);
--- a/nss_qdisc/nss_qdisc.c
+++ b/nss_qdisc/nss_qdisc.c
@@ -26,6 +26,9 @@
#include "nss_htb.h"
#include "nss_blackhole.h"
#include "nss_wred.h"
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+#include "net/gen_stats.h"
+#endif
void *nss_qdisc_ctx; /* Shaping context for nss_qdisc */
@@ -2563,7 +2566,11 @@ static void nss_qdisc_basic_stats_callba
{
struct nss_qdisc *nq = (struct nss_qdisc *)app_data;
struct Qdisc *qdisc = nq->qdisc;
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ struct gnet_stats_basic_sync *bstats;
+#else
struct gnet_stats_basic_packed *bstats;
+#endif
struct gnet_stats_queue *qstats;
struct nss_shaper_node_stats_response *response;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0))
@@ -2602,8 +2609,13 @@ static void nss_qdisc_basic_stats_callba
* Update qdisc->bstats
*/
spin_lock_bh(&nq->lock);
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ u64_stats_add(&bstats->bytes, (__u64)response->sn_stats.delta.dequeued_bytes);
+ u64_stats_add(&bstats->packets, response->sn_stats.delta.dequeued_packets);
+#else
bstats->bytes += (__u64)response->sn_stats.delta.dequeued_bytes;
bstats->packets += response->sn_stats.delta.dequeued_packets;
+#endif
/*
* Update qdisc->qstats
@@ -2763,12 +2775,18 @@ void nss_qdisc_stop_basic_stats_polling(
* Wrapper around gnet_stats_copy_basic()
*/
int nss_qdisc_gnet_stats_copy_basic(struct Qdisc *sch, struct gnet_dump *d,
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ struct gnet_stats_basic_sync *b)
+#else
struct gnet_stats_basic_packed *b)
+#endif
{
#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 18, 0))
return gnet_stats_copy_basic(d, b);
#elif (LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0))
return gnet_stats_copy_basic(d, NULL, b);
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0))
+ return gnet_stats_copy_basic(d, NULL, b, true);
#else
return gnet_stats_copy_basic(qdisc_root_sleeping_running(sch), d, NULL, b);
#endif
@@ -2799,7 +2817,9 @@ static int nss_qdisc_if_event_cb(struct
struct net_device *br;
struct Qdisc *br_qdisc;
int if_num, br_num;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0))
struct nss_qdisc *nq;
+#endif
dev = nss_qdisc_get_dev(ptr);
if (!dev) {
@@ -2842,7 +2862,9 @@ static int nss_qdisc_if_event_cb(struct
break;
}
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0))
nq = (struct nss_qdisc *)qdisc_priv(br_qdisc);
+#endif
/*
* Call attach or detach according as per event type.
--- a/vlan/nss_vlan_mgr.c
+++ b/vlan/nss_vlan_mgr.c
@@ -18,6 +18,7 @@
* nss_vlan_mgr.c
* NSS to HLOS vlan Interface manager
*/
+#include <linux/version.h>
#include <linux/etherdevice.h>
#include <linux/if_vlan.h>
#include <linux/proc_fs.h>
@@ -808,7 +809,11 @@ static struct nss_vlan_pvt *nss_vlan_mgr
}
v->mtu = dev->mtu;
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ ether_addr_copy(v->dev_addr, (uint8_t *)dev->dev_addr);
+#else
ether_addr_copy(v->dev_addr, dev->dev_addr);
+#endif
v->ifindex = dev->ifindex;
v->refs = 1;
@@ -956,14 +961,23 @@ static int nss_vlan_mgr_changeaddr_event
}
spin_unlock(&vlan_mgr_ctx.lock);
- if (nss_vlan_tx_set_mac_addr_msg(v_pvt->nss_if, dev->dev_addr) != NSS_TX_SUCCESS) {
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ if (nss_vlan_tx_set_mac_addr_msg(v_pvt->nss_if, (uint8_t *)dev->dev_addr) != NSS_TX_SUCCESS)
+#else
+ if (nss_vlan_tx_set_mac_addr_msg(v_pvt->nss_if, dev->dev_addr) != NSS_TX_SUCCESS)
+#endif
+ {
nss_vlan_mgr_warn("%s: Failed to send change MAC address message to NSS\n", dev->name);
nss_vlan_mgr_instance_deref(v_pvt);
return NOTIFY_BAD;
}
spin_lock(&vlan_mgr_ctx.lock);
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ ether_addr_copy(v_pvt->dev_addr, (uint8_t *)dev->dev_addr);
+#else
ether_addr_copy(v_pvt->dev_addr, dev->dev_addr);
+#endif
spin_unlock(&vlan_mgr_ctx.lock);
nss_vlan_mgr_trace("%s: MAC changed to %pM, updated NSS\n", dev->name, dev->dev_addr);
nss_vlan_mgr_instance_deref(v_pvt);
--- a/vxlanmgr/nss_vxlanmgr_tunnel.c
+++ b/vxlanmgr/nss_vxlanmgr_tunnel.c
@@ -465,8 +465,13 @@ static void nss_vxlanmgr_tunnel_inner_st
tstats = this_cpu_ptr(dev->tstats);
u64_stats_update_begin(&tstats->syncp);
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ u64_stats_add(&tstats->tx_packets, stats->node_stats.tx_packets);
+ u64_stats_add(&tstats->tx_bytes, stats->node_stats.tx_bytes);
+#else
tstats->tx_packets += stats->node_stats.tx_packets;
tstats->tx_bytes += stats->node_stats.tx_bytes;
+#endif
u64_stats_update_end(&tstats->syncp);
netdev_stats->tx_dropped += dropped;
dev_put(dev);
@@ -503,8 +508,13 @@ static void nss_vxlanmgr_tunnel_outer_st
tstats = this_cpu_ptr(dev->tstats);
u64_stats_update_begin(&tstats->syncp);
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ u64_stats_add(&tstats->rx_packets, stats->node_stats.tx_packets);
+ u64_stats_add(&tstats->rx_bytes, stats->node_stats.tx_bytes);
+#else
tstats->rx_packets += stats->node_stats.tx_packets;
tstats->rx_bytes += stats->node_stats.tx_bytes;
+#endif
u64_stats_update_end(&tstats->syncp);
netdev_stats->rx_dropped += dropped;
dev_put(dev);
--- a/pvxlanmgr/nss_pvxlanmgr.c
+++ b/pvxlanmgr/nss_pvxlanmgr.c
@@ -177,7 +177,11 @@ static struct rtnl_link_stats64 *nss_pvx
* Netdev seems to be incrementing rx_dropped because we don't give IP header.
* So reset it as it's of no use for us.
*/
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ atomic_long_set(&(dev)->stats.__rx_dropped, 0);
+#else
atomic_long_set(&dev->rx_dropped, 0);
+#endif
priv = netdev_priv(dev);
memset(stats, 0, sizeof(struct rtnl_link_stats64));
memcpy(stats, &priv->stats, sizeof(struct rtnl_link_stats64));
@@ -305,7 +309,11 @@ static void nss_pvxlanmgr_dummy_netdev_s
dev->priv_destructor = NULL;
#endif
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ memcpy((void *)dev->dev_addr, "\x00\x00\x00\x00\x00\x00", dev->addr_len);
+#else
memcpy(dev->dev_addr, "\x00\x00\x00\x00\x00\x00", dev->addr_len);
+#endif
memset(dev->broadcast, 0xff, dev->addr_len);
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
}
--- a/clmapmgr/nss_clmapmgr.c
+++ b/clmapmgr/nss_clmapmgr.c
@@ -102,7 +102,11 @@ void nss_clmapmgr_dev_stats64(struct net
* Netdev seems to be incrementing rx_dropped because we don't give IP header.
* So reset it as it's of no use for us.
*/
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ atomic_long_set(&(dev)->stats.__rx_dropped, 0);
+#else
atomic_long_set(&dev->rx_dropped, 0);
+#endif
priv = netdev_priv(dev);
memset(stats, 0, sizeof(struct rtnl_link_stats64));
memcpy(stats, &priv->stats, sizeof(struct rtnl_link_stats64));
--- a/tls/nss_tlsmgr_tun.c
+++ b/tls/nss_tlsmgr_tun.c
@@ -158,7 +158,11 @@ static void nss_tlsmgr_tun_setup(struct
/*
* Get the MAC address from the ethernet device
*/
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ eth_random_addr((u8 *) dev->dev_addr);
+#else
random_ether_addr(dev->dev_addr);
+#endif
memset(dev->broadcast, 0xff, dev->addr_len);
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
--- a/netlink/nss_nlgre_redir_cmn.c
+++ b/netlink/nss_nlgre_redir_cmn.c
@@ -384,7 +384,11 @@ static int nss_nlgre_redir_cmn_set_mac_a
return -EINVAL;
}
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ memcpy((void *) dev->dev_addr, addr->sa_data, ETH_ALEN);
+#else
memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+#endif
return 0;
}
--- a/nss_connmgr_tun6rd.c
+++ b/nss_connmgr_tun6rd.c
@@ -101,10 +101,17 @@ static void nss_tun6rd_update_dev_stats(
u64_stats_init(&stats.syncp);
u64_stats_update_begin(&stats.syncp);
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ u64_stats_set(&stats.rx_packets, sync_stats->node_stats.rx_packets);
+ u64_stats_set(&stats.rx_bytes, sync_stats->node_stats.rx_bytes);
+ u64_stats_set(&stats.tx_packets, sync_stats->node_stats.tx_packets);
+ u64_stats_set(&stats.tx_bytes, sync_stats->node_stats.tx_bytes);
+#else
stats.rx_packets = sync_stats->node_stats.rx_packets;
stats.rx_bytes = sync_stats->node_stats.rx_bytes;
stats.tx_packets = sync_stats->node_stats.tx_packets;
stats.tx_bytes = sync_stats->node_stats.tx_bytes;
+#endif
u64_stats_update_end(&stats.syncp);
#else
struct nss_tun6rd_stats stats;
--- a/ipsecmgr/v1.0/nss_ipsecmgr.c
+++ b/ipsecmgr/v1.0/nss_ipsecmgr.c
@@ -445,7 +445,11 @@ static void nss_ipsecmgr_tunnel_setup(st
/*
* get the MAC address from the ethernet device
*/
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ eth_random_addr((u8 *) dev->dev_addr);
+#else
random_ether_addr(dev->dev_addr);
+#endif
memset(dev->broadcast, 0xff, dev->addr_len);
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
--- a/ipsecmgr/v2.0/nss_ipsecmgr_tunnel.c
+++ b/ipsecmgr/v2.0/nss_ipsecmgr_tunnel.c
@@ -394,7 +394,11 @@ static void nss_ipsecmgr_tunnel_setup(st
/*
* Get the MAC address from the ethernet device
*/
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ eth_random_addr((u8 *) dev->dev_addr);
+#else
random_ether_addr(dev->dev_addr);
+#endif
memset(dev->broadcast, 0xff, dev->addr_len);
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);

View File

@@ -0,0 +1,195 @@
--- a/gre/nss_connmgr_gre.c
+++ b/gre/nss_connmgr_gre.c
@@ -276,6 +276,8 @@ static struct rtnl_link_stats64 *nss_con
do {
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 15, 0))
start = u64_stats_fetch_begin_bh(&tstats->syncp);
+#elif (LINUX_VERSION_CODE > KERNEL_VERSION(6, 6, 0))
+ start = u64_stats_fetch_begin(&tstats->syncp);
#else
start = u64_stats_fetch_begin_irq(&tstats->syncp);
#endif
@@ -292,6 +294,8 @@ static struct rtnl_link_stats64 *nss_con
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 15, 0))
} while (u64_stats_fetch_retry_bh(&tstats->syncp, start));
+#elif (LINUX_VERSION_CODE > KERNEL_VERSION(6, 6, 0))
+ } while (u64_stats_fetch_retry(&tstats->syncp, start));
#else
} while (u64_stats_fetch_retry_irq(&tstats->syncp, start));
#endif
--- a/l2tp/l2tpv2/nss_connmgr_l2tpv2.c
+++ b/l2tp/l2tpv2/nss_connmgr_l2tpv2.c
@@ -954,7 +954,11 @@ int __init nss_connmgr_l2tpv2_init_modul
return 0;
}
#endif
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 6, 0))
+ ctl_tbl_hdr = register_sysctl("dev/nss/l2tpv2", nss_connmgr_l2tpv2_table);
+#else
ctl_tbl_hdr = register_sysctl_table(nss_connmgr_l2tpv2_sysroot);
+#endif
if (!ctl_tbl_hdr) {
nss_connmgr_l2tpv2_info("Unable to register sysctl table for L2TP conn mgr\n");
return -EFAULT;
--- a/match/nss_match_cmd.c
+++ b/match/nss_match_cmd.c
@@ -20,6 +20,7 @@
* nss_match_cmd.c
*/
+#include <linux/version.h>
#include <linux/sysctl.h>
#include <linux/inetdevice.h>
#include <linux/netdevice.h>
@@ -692,6 +693,7 @@ static struct ctl_table nss_match_table[
{ }
};
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0))
static struct ctl_table nss_match_root_dir[] = {
{
.procname = "match",
@@ -718,6 +720,7 @@ static struct ctl_table nss_match_root[]
},
{ }
};
+#endif
static struct ctl_table_header *nss_match_ctl_header;
@@ -726,7 +729,11 @@ static struct ctl_table_header *nss_matc
* Register command line interface for match.
*/
bool nss_match_ctl_register(void) {
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 6, 0))
+ nss_match_ctl_header = register_sysctl("dev/nss/match", nss_match_table);
+#else
nss_match_ctl_header = register_sysctl_table(nss_match_root);
+#endif
if (!nss_match_ctl_header) {
nss_match_warn("Unable to register command line interface.\n");
return false;
--- a/mirror/nss_mirror_ctl.c
+++ b/mirror/nss_mirror_ctl.c
@@ -16,6 +16,7 @@
***************************************************************************
*/
+#include <linux/version.h>
#include <linux/sysctl.h>
#include <linux/string.h>
@@ -918,6 +919,7 @@ static struct ctl_table nss_mirror_table
{ }
};
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0))
/*
* nss mirror dir
*/
@@ -953,6 +955,7 @@ static struct ctl_table nss_mirror_root[
},
{ }
};
+#endif
/*
* nss_mirror_ctl_register()
@@ -960,7 +963,11 @@ static struct ctl_table nss_mirror_root[
*/
int nss_mirror_ctl_register(void)
{
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 6, 0))
+ nss_mirror_ctl_header = register_sysctl("dev/nss/mirror", nss_mirror_table);
+#else
nss_mirror_ctl_header = register_sysctl_table(nss_mirror_root);
+#endif
if (!nss_mirror_ctl_header) {
nss_mirror_warn("Creating sysctl directory table header for mirror failed\n");
return -1;
--- a/netlink/nss_nl.c
+++ b/netlink/nss_nl.c
@@ -328,7 +328,11 @@ struct nss_nlcmn *nss_nl_get_msg(struct
/*
* validate the common message header version & magic
*/
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0))
cm = info->userhdr;
+#else
+ cm = genl_info_userhdr(info);
+#endif
if (nss_nlcmn_chk_ver(cm, family->version) == false) {
nss_nl_error("%d, %s: version mismatch (%d)\n", pid, family->name, cm->version);
return NULL;
--- a/nss_qdisc/nss_wred.c
+++ b/nss_qdisc/nss_wred.c
@@ -296,7 +296,7 @@ static int nss_wred_change(struct Qdisc
nim.msg.shaper_configure.config.msg.shaper_node_config.qos_tag = q->nq.qos_tag;
nim.msg.shaper_configure.config.msg.shaper_node_config.snc.wred_param.limit = qopt->limit;
- nim.msg.shaper_configure.config.msg.shaper_node_config.snc.wred_param.weight_mode = qopt->weight_mode;
+ nim.msg.shaper_configure.config.msg.shaper_node_config.snc.wred_param.weight_mode = (nss_shaper_config_wred_weight_mode_t)qopt->weight_mode;
nim.msg.shaper_configure.config.msg.shaper_node_config.snc.wred_param.weight_mode_value = qopt->weight_mode_value;
nim.msg.shaper_configure.config.msg.shaper_node_config.snc.wred_param.rap.min = qopt->rap.min;
nim.msg.shaper_configure.config.msg.shaper_node_config.snc.wred_param.rap.max = qopt->rap.max;
--- a/tunipip6/nss_connmgr_tunipip6_sysctl.c
+++ b/tunipip6/nss_connmgr_tunipip6_sysctl.c
@@ -449,6 +449,7 @@ static struct ctl_table nss_tunipip6_tab
{ }
};
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0))
static struct ctl_table nss_tunipip6_root_dir[] = {
{
.procname = "ipip6",
@@ -475,6 +476,7 @@ static struct ctl_table nss_tunipip6_roo
},
{ }
};
+#endif
static struct ctl_table_header *nss_tunipip6_ctl_header;
@@ -483,7 +485,11 @@ static struct ctl_table_header *nss_tuni
* Register command line interface for tunipip6.
*/
bool nss_tunipip6_sysctl_register(void) {
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 6, 0))
+ nss_tunipip6_ctl_header = register_sysctl("drv/nss/ipip6", nss_tunipip6_table);
+#else
nss_tunipip6_ctl_header = register_sysctl_table(nss_tunipip6_root);
+#endif
if (!nss_tunipip6_ctl_header) {
return false;
}
--- a/vlan/nss_vlan_mgr.c
+++ b/vlan/nss_vlan_mgr.c
@@ -1557,6 +1557,7 @@ static struct ctl_table nss_vlan_table[]
{ }
};
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0))
/*
* nss_vlan sysctl dir
*/
@@ -1580,6 +1581,7 @@ static struct ctl_table nss_vlan_root_di
},
{ }
};
+#endif
/*
* nss_vlan_mgr_add_bond_slave()
@@ -1920,7 +1922,11 @@ int __init nss_vlan_mgr_init_module(void
vlan_mgr_ctx.stpid = ETH_P_8021Q;
#ifdef NSS_VLAN_MGR_PPE_SUPPORT
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 6, 0))
+ vlan_mgr_ctx.sys_hdr = register_sysctl("nss/vlan_client", nss_vlan_table);
+#else
vlan_mgr_ctx.sys_hdr = register_sysctl_table(nss_vlan_root_dir);
+#endif
if (!vlan_mgr_ctx.sys_hdr) {
nss_vlan_mgr_warn("Unabled to register sysctl table for vlan manager\n");
return -EFAULT;

View File

@@ -0,0 +1,168 @@
menu "Configuration"
depends on PACKAGE_kmod-qca-nss-drv
comment "Build Options"
config NSS_DRV_BRIDGE_ENABLE
bool
default n
prompt "Enable BRIDGE"
config NSS_DRV_C2C_ENABLE
bool
default n
prompt "Enable C2C"
config NSS_DRV_CAPWAP_ENABLE
bool
default n
prompt "Enable CAPWAP"
config NSS_DRV_CLMAP_ENABLE
bool
default n
prompt "Enable CLMAP"
config NSS_DRV_CRYPTO_ENABLE
bool
default n
prompt "Enable CRYPTO"
config NSS_DRV_DTLS_ENABLE
bool
default n
prompt "Enable DTLS"
config NSS_DRV_EDMA_ENABLE
bool
default n
prompt "Enable EDMA"
config NSS_DRV_GRE_ENABLE
bool
default n
prompt "Enable GRE"
config NSS_DRV_GRE_REDIR_ENABLE
bool
default n
depends on NSS_DRV_GRE_ENABLE
prompt "Enable GRE_REDIR"
config NSS_DRV_GRE_TUNNEL_ENABLE
bool
default n
depends on NSS_DRV_GRE_ENABLE
prompt "Enable GRE_TUNNEL"
config NSS_DRV_IGS_ENABLE
bool
default n
prompt "Enable IGS"
config NSS_DRV_IPSEC_ENABLE
bool
default n
prompt "Enable IPSEC"
config NSS_DRV_IPV4_REASM_ENABLE
bool
default n
prompt "Enable IPV4_REASM"
config NSS_DRV_IPV6_ENABLE
bool
default n
prompt "Enable IPV6"
config NSS_DRV_IPV6_REASM_ENABLE
bool
default n
prompt "Enable IPV6_REASM"
config NSS_DRV_L2TP_ENABLE
bool
default n
prompt "Enable L2TP"
config NSS_DRV_LAG_ENABLE
bool
default n
prompt "Enable LAG"
config NSS_DRV_MAPT_ENABLE
bool
default n
prompt "Enable MAPT"
config NSS_DRV_MATCH_ENABLE
bool
default n
prompt "Enable MATCH"
config NSS_DRV_MIRROR_ENABLE
bool
default n
prompt "Enable MIRROR"
config NSS_DRV_OAM_ENABLE
bool
default n
prompt "Enable OAM"
config NSS_DRV_PORTID_ENABLE
bool
default n
prompt "Enable PORTID"
config NSS_DRV_PPE_ENABLE
bool
default n
prompt "Enable PPE"
config NSS_DRV_PPPOE_ENABLE
bool
default n
prompt "Enable PPPOE"
config NSS_DRV_PPTP_ENABLE
bool
default y
prompt "Enable PPTP"
config NSS_DRV_PVXLAN_ENABLE
bool
default n
prompt "Enable PVXLAN"
config NSS_DRV_QRFS_ENABLE
bool
default n
prompt "Enable QRFS"
config NSS_DRV_QVPN_ENABLE
bool
default n
prompt "Enable QVPN"
config NSS_DRV_RMNET_ENABLE
bool
default n
prompt "Enable RMNET"
config NSS_DRV_SHAPER_ENABLE
bool
default n
prompt "Enable SHAPER"
config NSS_DRV_SJACK_ENABLE
bool
default n
prompt "Enable SJACK (ipq807x)"
config NSS_DRV_TLS_ENABLE
bool
default n
prompt "Enable TLS"
config NSS_DRV_TRUSTSEC_ENABLE
bool
default n
prompt "Enable TRUSTSEC"
config NSS_DRV_TSTAMP_ENABLE
bool
default n
prompt "Enable TSTAMP"
config NSS_DRV_TUN6RD_ENABLE
bool
default n
prompt "Enable TUN6RD"
config NSS_DRV_TUNIPIP6_ENABLE
bool
default n
prompt "Enable TUNIPIP6"
config NSS_DRV_VIRT_IF_ENABLE
bool
default y
prompt "Enable VIRT_IF"
config NSS_DRV_VLAN_ENABLE
bool
default n
prompt "Enable VLAN (ipq807x)"
config NSS_DRV_VXLAN_ENABLE
bool
default n
prompt "Enable VXLAN (ipq807x)"
config NSS_DRV_WIFI_ENABLE
bool
default n
prompt "Enable WIFI"
endmenu

View File

@@ -0,0 +1,272 @@
# NHSS.QSDK.12.2
# by SqTER
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=qca-nss-drv
PKG_RELEASE:=$(AUTORELEASE)
PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/nss-drv.git
PKG_SOURCE_PROTO:=git
PKG_SOURCE_DATE:=2023-06-01
PKG_SOURCE_VERSION:=fe0bc6b077b842d13a06053271115bb9b3dcc505
PKG_MIRROR_HASH:=1011fb113ba40d7919c0718d055ae6be8600fc8e02c1472f7425b7da47372a8a
PKG_BUILD_PARALLEL:=1
PKG_CONFIG_DEPENDS:= \
CONFIG_NSS_DRV_BRIDGE_ENABLE \
CONFIG_NSS_DRV_C2C_ENABLE \
CONFIG_NSS_DRV_CAPWAP_ENABLE \
CONFIG_NSS_DRV_CLMAP_ENABLE \
CONFIG_NSS_DRV_CRYPTO_ENABLE \
CONFIG_NSS_DRV_DMA_ENABLE \
CONFIG_NSS_DRV_EDMA_ENABLE \
CONFIG_NSS_DRV_GRE_ENABLE \
CONFIG_NSS_DRV_GRE_REDIR_ENABLE \
CONFIG_NSS_DRV_GRE_TUNNEL_ENABLE \
CONFIG_NSS_DRV_IGS_ENABLE \
CONFIG_NSS_DRV_IPV4_REASM_ENABLE \
CONFIG_NSS_DRV_IPV6_ENABLE \
CONFIG_NSS_DRV_IPV6_REASM_ENABLE \
CONFIG_NSS_DRV_L2TP_ENABLE \
CONFIG_NSS_DRV_LAG_ENABLE \
CONFIG_NSS_DRV_MAPT_ENABLE \
CONFIG_NSS_DRV_MATCH_ENABLE \
CONFIG_NSS_DRV_MIRROR_ENABLE \
CONFIG_NSS_DRV_OAM_ENABLE \
CONFIG_NSS_DRV_PORTID_ENABLE \
CONFIG_NSS_DRV_PPE_ENABLE \
CONFIG_NSS_DRV_PPPOE_ENABLE \
CONFIG_NSS_DRV_PPTP_ENABLE \
CONFIG_NSS_DRV_PVXLAN_ENABLE \
CONFIG_NSS_DRV_QRFS_ENABLE \
CONFIG_NSS_DRV_QVPN_ENABLE \
CONFIG_NSS_DRV_RMNET_ENABLE \
CONFIG_NSS_DRV_SHAPER_ENABLE \
CONFIG_NSS_DRV_SJACK_ENABLE \
CONFIG_NSS_DRV_TRUSTSEC_ENABLE \
CONFIG_NSS_DRV_TSTAMP_ENABLE \
CONFIG_NSS_DRV_TUN6RD_ENABLE \
CONFIG_NSS_DRV_TUNIPIP6_ENABLE \
CONFIG_NSS_DRV_VIRT_IF_ENABLE \
CONFIG_NSS_DRV_VLAN_ENABLE \
CONFIG_NSS_DRV_VXLAN_ENABLE \
CONFIG_NSS_DRV_WIFI_ENABLE
include $(INCLUDE_DIR)/package.mk
define KernelPackage/qca-nss-drv
SECTION:=kernel
CATEGORY:=Kernel modules
SUBMENU:=Network Devices
DEPENDS:=@TARGET_ipq806x||TARGET_ipq_ipq806x||TARGET_ipq_ipq807x||TARGET_ipq_ipq807x_64||TARGET_ipq807x||TARGET_ipq807x_64||TARGET_ipq_ipq60xx||TARGET_ipq_ipq60xx_64||TARGET_ipq_ipq50xx||TARGET_ipq_ipq50xx_64 \
+kmod-qca-nss-gmac
TITLE:=Kernel driver for NSS (core driver)
FILES:=$(PKG_BUILD_DIR)/qca-nss-drv.ko
AUTOLOAD:=$(call AutoLoad,32,qca-nss-drv,1)
endef
define KernelPackage/qca-nss-drv/config
source "$(SOURCE)/Config.in"
endef
define KernelPackage/qca-nss-drv/install
$(INSTALL_DIR) $(1)/sbin
$(INSTALL_DIR) $(1)/lib/debug
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_DIR) $(1)/etc/sysctl.d
$(INSTALL_DIR) $(1)/etc/hotplug.d/firmware
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_DIR) $(1)/lib/firmware
$(INSTALL_BIN) ./files/qca-nss-drv.sysdebug $(1)/sbin/sysdebug
$(INSTALL_BIN) ./files/qca-nss-drv.debug $(1)/lib/debug/qca-nss-drv
$(INSTALL_BIN) ./files/qca-nss-drv.init $(1)/etc/init.d/qca-nss-drv
$(INSTALL_DATA) ./files/qca-nss-drv.sysctl $(1)/etc/sysctl.d/99-qca-nss-drv.conf
$(INSTALL_BIN) ./files/qca-nss-drv.hotplug $(1)/etc/hotplug.d/firmware/10-qca-nss-fw
$(INSTALL_DATA) ./files/qca-nss-drv.conf $(1)/etc/config/nss
$(INSTALL_DATA) ./files/nss-firmware/qca-nss0-retail.bin $(1)/lib/firmware/qca-nss0.bin
$(INSTALL_DATA) ./files/nss-firmware/qca-nss1-retail.bin $(1)/lib/firmware/qca-nss1.bin
endef
define KernelPackage/qca-nss-drv/Description
This package contains a NSS driver for QCA chipset
endef
define Build/InstallDev
mkdir -p $(1)/usr/include/qca-nss-drv
$(CP) $(PKG_BUILD_DIR)/exports/* $(1)/usr/include/qca-nss-drv/
ifneq (, $(findstring $(subtarget), "ipq807x" "ipq807x_64" "ipq60xx" "ipq60xx_64" "ipq50xx" "ipq50xx_64"))
$(INSTALL_DIR) $(1)/usr/include/qca-nss-clients
endif
endef
EXTRA_CFLAGS+= -I$(STAGING_DIR)/usr/include/qca-nss-gmac -I$(STAGING_DIR)/usr/include/qca-nss-dp
# Keeping default as ipq806x for branches that does not have subtarget framework
ifeq ($(CONFIG_TARGET_ipq),y)
subtarget:=$(SUBTARGET)
else
subtarget:=$(CONFIG_TARGET_BOARD)
endif
ifeq ($(CONFIG_KERNEL_IPQ_MEM_PROFILE),256)
EXTRA_CFLAGS+= -DNSS_MEM_PROFILE_LOW
endif
ifeq ($(CONFIG_KERNEL_IPQ_MEM_PROFILE),512)
EXTRA_CFLAGS+= -DNSS_MEM_PROFILE_MEDIUM
endif
ifeq ($(CONFIG_KERNEL_SKB_FIXED_SIZE_2K),y)
EXTRA_CFLAGS+= -DNSS_SKB_FIXED_SIZE_2K
endif
ifeq ($(CONFIG_TARGET_BOARD), "ipq807x")
SOC="ipq807x_64"
else ifeq ($(CONFIG_TARGET_BOARD), "ipq60xx")
SOC="ipq60xx_64"
else
SOC=$(CONFIG_TARGET_BOARD)
endif
ifndef CONFIG_NSS_DRV_BRIDGE_ENABLE
DRV_MAKE_OPTS += NSS_DRV_BRIDGE_ENABLE=n
endif
ifndef CONFIG_NSS_DRV_C2C_ENABLE
DRV_MAKE_OPTS += NSS_DRV_C2C_ENABLE=n
endif
ifndef CONFIG_NSS_DRV_CAPWAP_ENABLE
DRV_MAKE_OPTS += NSS_DRV_CAPWAP_ENABLE=n
endif
ifndef CONFIG_NSS_DRV_CLMAP_ENABLE
DRV_MAKE_OPTS += NSS_DRV_CLMAP_ENABLE=n
endif
ifndef CONFIG_NSS_DRV_CRYPTO_ENABLE
DRV_MAKE_OPTS += NSS_DRV_CRYPTO_ENABLE=n
endif
ifndef CONFIG_NSS_DRV_DMA_ENABLE
DRV_MAKE_OPTS += NSS_DRV_DMA_ENABLE=n
endif
ifndef CONFIG_NSS_DRV_EDMA_ENABLE
DRV_MAKE_OPTS += NSS_DRV_EDMA_ENABLE=n
endif
ifndef CONFIG_NSS_DRV_GRE_ENABLE
DRV_MAKE_OPTS += NSS_DRV_GRE_ENABLE=n
endif
ifndef CONFIG_NSS_DRV_GRE_REDIR_ENABLE
DRV_MAKE_OPTS += NSS_DRV_GRE_REDIR_ENABLE=n
endif
ifndef CONFIG_NSS_DRV_GRE_TUNNEL_ENABLE
DRV_MAKE_OPTS += NSS_DRV_GRE_TUNNEL_ENABLE=n
endif
ifndef CONFIG_NSS_DRV_IGS_ENABLE
DRV_MAKE_OPTS += NSS_DRV_IGS_ENABLE=n
endif
ifndef CONFIG_NSS_DRV_IPV4_REASM_ENABLE
DRV_MAKE_OPTS += NSS_DRV_IPV4_REASM_ENABLE=n
endif
ifndef CONFIG_NSS_DRV_IPV6_ENABLE
DRV_MAKE_OPTS += NSS_DRV_IPV6_ENABLE=n
endif
ifndef CONFIG_NSS_DRV_IPV6_REASM_ENABLE
DRV_MAKE_OPTS += NSS_DRV_IPV6_REASM_ENABLE=n
endif
ifndef CONFIG_NSS_DRV_L2TP_ENABLE
DRV_MAKE_OPTS += NSS_DRV_L2TP_ENABLE=n
endif
ifndef CONFIG_NSS_DRV_LAG_ENABLE
DRV_MAKE_OPTS += NSS_DRV_LAG_ENABLE=n
endif
ifndef CONFIG_NSS_DRV_MAPT_ENABLE
DRV_MAKE_OPTS += NSS_DRV_MAPT_ENABLE=n
endif
ifndef CONFIG_NSS_DRV_MATCH_ENABLE
DRV_MAKE_OPTS += NSS_DRV_MATCH_ENABLE=n
endif
ifndef CONFIG_NSS_DRV_MIRROR_ENABLE
DRV_MAKE_OPTS += NSS_DRV_MIRROR_ENABLE=n
endif
ifndef CONFIG_NSS_DRV_OAM_ENABLE
DRV_MAKE_OPTS += NSS_DRV_OAM_ENABLE=n
endif
ifndef CONFIG_NSS_DRV_PORTID_ENABLE
DRV_MAKE_OPTS += NSS_DRV_PORTID_ENABLE=n
endif
ifndef CONFIG_NSS_DRV_PPE_ENABLE
DRV_MAKE_OPTS += NSS_DRV_PPE_ENABLE=n
endif
ifndef CONFIG_NSS_DRV_PPPOE_ENABLE
DRV_MAKE_OPTS += NSS_DRV_PPPOE_ENABLE=n
endif
ifndef CONFIG_NSS_DRV_PPTP_ENABLE
DRV_MAKE_OPTS += NSS_DRV_PPTP_ENABLE=n
endif
ifndef CONFIG_NSS_DRV_PVXLAN_ENABLE
DRV_MAKE_OPTS += NSS_DRV_PVXLAN_ENABLE=n
endif
ifndef CONFIG_NSS_DRV_QRFS_ENABLE
DRV_MAKE_OPTS += NSS_DRV_QRFS_ENABLE=n
endif
ifndef CONFIG_NSS_DRV_QVPN_ENABLE
DRV_MAKE_OPTS += NSS_DRV_QVPN_ENABLE=n
endif
ifndef CONFIG_NSS_DRV_RMNET_ENABLE
DRV_MAKE_OPTS += NSS_DRV_RMNET_ENABLE=n
endif
ifndef CONFIG_NSS_DRV_SHAPER_ENABLE
DRV_MAKE_OPTS += NSS_DRV_SHAPER_ENABLE=n
endif
ifndef CONFIG_NSS_DRV_SJACK_ENABLE
DRV_MAKE_OPTS += NSS_DRV_SJACK_ENABLE=n
endif
ifndef CONFIG_NSS_DRV_TRUSTSEC_ENABLE
DRV_MAKE_OPTS += NSS_DRV_TRUSTSEC_ENABLE=n
endif
ifndef CONFIG_NSS_DRV_TSTAMP_ENABLE
DRV_MAKE_OPTS += NSS_DRV_TSTAMP_ENABLE=n
endif
ifndef CONFIG_NSS_DRV_TUN6RD_ENABLE
DRV_MAKE_OPTS += NSS_DRV_TUN6RD_ENABLE=n
endif
ifndef CONFIG_NSS_DRV_TUNIPIP6_ENABLE
DRV_MAKE_OPTS += NSS_DRV_TUNIPIP6_ENABLE=n
endif
ifndef CONFIG_NSS_DRV_VIRT_IF_ENABLE
DRV_MAKE_OPTS += NSS_DRV_VIRT_IF_ENABLE=n
endif
ifndef CONFIG_NSS_DRV_VLAN_ENABLE
DRV_MAKE_OPTS += NSS_DRV_VLAN_ENABLE=n
endif
ifndef CONFIG_NSS_DRV_VXLAN_ENABLE
DRV_MAKE_OPTS += NSS_DRV_VXLAN_ENABLE=n
endif
ifndef CONFIG_NSS_DRV_WIFI_ENABLE
DRV_MAKE_OPTS += NSS_DRV_WIFI_ENABLE=n
endif
ifeq ($(CONFIG_TARGET_BOARD), "ipq806x")
TARGET_NSS_MINOR_VERSION=2
DRV_MAKE_OPTS+= TARGET_NSS_MINOR_VERSION=$(TARGET_NSS_MINOR_VERSION)
endif
define Build/Configure
$(CP) $(TOPDIR)/$(SOURCE)/files/nss-firmware/nss_fw_version.h $(PKG_BUILD_DIR)/exports/nss_fw_version.h
sed -i "s/define NSS_FW_VERSION_MAJOR.*/define NSS_FW_VERSION_MAJOR 11/" $(PKG_BUILD_DIR)/exports/nss_fw_version.h
sed -i "s/define NSS_FW_VERSION_MINOR.*/define NSS_FW_VERSION_MINOR $(TARGET_NSS_MINOR_VERSION)/" $(PKG_BUILD_DIR)/exports/nss_fw_version.h
$(LN) arch/nss_$(SOC).h $(PKG_BUILD_DIR)/exports/nss_arch.h
endef
define Build/Compile
+$(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" $(strip $(DRV_MAKE_OPTS)) \
CROSS_COMPILE="$(TARGET_CROSS)" \
ARCH="$(LINUX_KARCH)" \
M="$(PKG_BUILD_DIR)" \
EXTRA_CFLAGS="$(EXTRA_CFLAGS)" SoC=$(SOC) \
$(KERNEL_MAKE_FLAGS) \
modules
endef
$(eval $(call KernelPackage,qca-nss-drv))

View File

@@ -0,0 +1,45 @@
Copyright (c) 2014 Qualcomm Atheros, Inc.
All rights reserved.
Redistribution and use in binary forms, without
modification, are permitted (subject to the limitations in the
disclaimer below) provided that the following conditions are met:
*Redistributions must reproduce the above copyright
notice, this list of conditions, and the following disclaimer in the
documentation and/or other materials provided with the distribution.
*Neither the name of Qualcomm Atheros, Inc. nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
*No Reverse engineering, decompiling, decrypting, or disassembling of this
software is permitted.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. NO LICENSES OR OTHER RIGHTS,
WHETHER EXPRESS, IMPLIED, BASED ON ESTOPPEL OR OTHERWISE, ARE GRANTED
TO ANY PARTY'S PATENTS, PATENT APPLICATIONS, OR PATENTABLE INVENTIONS
BY VIRTUE OF THIS LICENSE OR THE DELIVERY OR PROVISION BY QUALCOMM
ATHEROS, INC. OF THE SOFTWARE.
IN NO EVENT SHALL THE COPYRIGHT OWNER OR ANY CONTRIBUTOR BE LIABLE FOR
ANY INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND REGARDLESS OF ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF OR RESULTING FROM THE USE OF THE
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. IN ANY
EVENT, THE TOTAL AGGREGATE LIABILITY THAT MAY BE IMPOSED ON QUALCOMM
ATHEROS, INC. FOR ANY DIRECT DAMAGES ARISING UNDER OR RESULTING FROM
THIS AGREEMENT OR IN CONNECTION WITH ANY USE OF THE SOFTWARE SHALL NOT
EXCEED A TOTAL AMOUNT OF US$5.00.
IF ANY OF THE ABOVE PROVISIONS ARE HELD TO BE VOID, INVALID,
UNENFORCEABLE, OR ILLEGAL, THE OTHER PROVISIONS SHALL CONTINUE IN FULL
FORCE AND EFFECT.

View File

@@ -0,0 +1,217 @@
=============================================================================
This Notice.txt file contains certain notices of software components included
with the software that Qualcomm Atheros, Inc. ("Qualcomm Atheros") is required
to provide you. Except where prohibited by the open source license, the content
of this notices file is only provided to satisfy Qualcomm Atheros's attribution
and notice requirement; your use of these software components together with the
Qualcomm Atheros software (Qualcomm Atheros software hereinafter referred to as
"Software") is subject to the terms of your license from Qualcomm Atheros.
Compliance with all copyright laws and software license agreements included in
the notice section of this file are the responsibility of the user. Except as
may be granted by separate express written agreement, this file provides no
license to any Qualcomm Atheros patents, trademarks, copyrights, or other
intellectual property.
Copyright (c) 2014 Qualcomm Atheros, Inc. All rights reserved.
Qualcomm is a trademark of Qualcomm Incorporated, registered in the United
States and other countries. All Qualcomm Incorporated trademarks are used with
permission. Atheros is a trademark of Qualcomm Atheros, Inc., registered in the
United States and other countries. Other products and brand names may be
trademarks or registered trademarks of their respective owners.
NOTICES:
=============================================================================
/*
* doprint.c
* Formatted string print support.
*
* Copyright <A9> 2001-2012 Qualcomm Atheros, Inc. All Rights Reserved.
*
* Qualcomm Atheros Confidential and Proprietary.
*
* This code originates with BSD Unix however it has been extensively
* modified. The original copyright is reproduced below:
*
* Copyright (c) 1988 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted provided
* that: (1) source distributions retain this entire copyright notice and
* comment, and (2) distributions including binaries display the following
* acknowledgement: ``This product includes software developed by the
* University of California, Berkeley and its contributors'' in the
* documentation or other materials provided with the distribution and in
* all advertising materials mentioning features or use of this software.
* Neither the name of the University nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/*
* math.c
* Support for the standard C library.
*
* Copyright <A9> 2006-2012 Qualcomm Atheros, Inc. All Rights Reserved.
*
* Qualcomm Atheros Confidential and Proprietary.
*
* Software contained within this file was originally released with the
* following
* copyright and license statement:
*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
* stdlib.c
* Routines from stdlib.h.
*
* Copyright <A9> 2004-2012 Qualcomm Atheros, Inc. All Rights Reserved.
*
* Qualcomm Atheros Confidential and Proprietary.
*
* The code for strtol() and strtoul() are also subject to the following:
*
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
drr_alg_utils.h:
/****************************************************************************/
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
shaper_list_utils.h:
/****************************************************************************/
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
codel_alg_inv_sqrt.h
/****************************************************************************/
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/

View File

@@ -0,0 +1,10 @@
NSS FIRMWARE
============
This repo contains firmware files to enable the NSS MAC on QCA IPQ806x SoC.
This product includes software developed by the University of California,
Berkeley and its contributors.
NSS firmware extracted from Synology RT2600ac SRM 1.2 - Version: 1.2-7742-4

View File

@@ -0,0 +1,11 @@
#ifndef __NSS_FW_VERSION_H
#define __NSS_FW_VERSION_H
#define NSS_FW_VERSION_MAJOR 11
#define NSS_FW_VERSION_MINOR 4
#define NSS_FW_VERSION(a,b) (((a) << 8) + (b))
#define NSS_FW_VERSION_CODE NSS_FW_VERSION(NSS_FW_VERSION_MAJOR, NSS_FW_VERSION_MINOR)
#endif /* __NSS_FW_VERSION_H */

View File

@@ -0,0 +1,6 @@
config nss_firmware 'qca_nss_0'
config nss_firmware 'qca_nss_1'
config general
option enable_rps '1'

View File

@@ -0,0 +1,4 @@
#!/bin/sh /sbin/sysdebug
#
log cat /sys/kernel/debug/qca-nss-drv/stats/cpu_load_ubi
log cat $(grep -lE "= [1-9]" /sys/kernel/debug/qca-nss-drv/stats/* 2>/dev/null )

View File

@@ -0,0 +1,70 @@
#!/bin/sh
#
# Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
KERNEL=`uname -r`
case "${KERNEL}" in
3.4*)
select_or_load=load_nss_fw
;;
*)
select_or_load=select_nss_fw
;;
esac
load_nss_fw () {
ls -l $1 | awk ' { print $9,$5 } '> /dev/console
echo 1 > /sys/class/firmware/$DEVICENAME/loading
cat $1 > /sys/class/firmware/$DEVICENAME/data
echo 0 > /sys/class/firmware/$DEVICENAME/loading
}
select_nss_fw () {
rm -f /lib/firmware/$DEVICENAME
ln -s $1 /lib/firmware/$DEVICENAME
ls -l /lib/firmware/$DEVICENAME | awk ' { print $9,$5 } '> /dev/console
}
[ "$ACTION" != "add" ] && exit
# dev name for UCI, since it doesn't let you use . or -
SDEVNAME=$(echo ${DEVICENAME} | sed s/[.-]/_/g)
SELECTED_FW=$(uci get nss.${SDEVNAME}.firmware 2>/dev/null)
[ -e "${SELECTED_FW}" ] && {
$select_or_load ${SELECTED_FW}
exit
}
case $DEVICENAME in
qca-nss0* | qca-nss.0*)
if [ -e /lib/firmware/qca-nss0-enterprise.bin ] ; then
$select_or_load /lib/firmware/qca-nss0-enterprise.bin
else
$select_or_load /lib/firmware/qca-nss0-retail.bin
fi
exit
;;
qca-nss1* | qca-nss.1*)
if [ -e /lib/firmware/qca-nss1-enterprise.bin ] ; then
$select_or_load /lib/firmware/qca-nss1-enterprise.bin
else
$select_or_load /lib/firmware/qca-nss1-retail.bin
fi
exit
;;
esac

View File

@@ -0,0 +1,50 @@
#!/bin/sh /etc/rc.common
#
# Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
START=70
enable_rps() {
irq_nss_rps=`grep nss_queue1 /proc/interrupts | cut -d ':' -f 1 | tr -d ' '`
for entry in $irq_nss_rps
do
echo 2 > /proc/irq/$entry/smp_affinity
done
irq_nss_rps=`grep nss_queue2 /proc/interrupts | cut -d ':' -f 1 | tr -d ' '`
for entry in $irq_nss_rps
do
echo 4 > /proc/irq/$entry/smp_affinity
done
irq_nss_rps=`grep nss_queue3 /proc/interrupts | cut -d ':' -f 1 | tr -d ' '`
for entry in $irq_nss_rps
do
echo 8 > /proc/irq/$entry/smp_affinity
done
# Enable NSS RPS
sysctl -w dev.nss.rps.enable=1 >/dev/null 2>/dev/null
}
start() {
local rps_enabled="$(uci_get nss @general[0] enable_rps)"
if [ "$rps_enabled" -eq 1 ]; then
enable_rps
fi
}

View File

@@ -0,0 +1,4 @@
# Default Number of connection configuration
dev.nss.ipv4cfg.ipv4_conn=4096
dev.nss.ipv6cfg.ipv6_conn=4096

View File

@@ -0,0 +1,44 @@
#!/bin/sh
. /lib/functions.sh
DEBUG_DIR=/lib/debug
log() {
echo -n " "; printf "%0.s*" $(seq 1 76); echo ""
echo " * cmd:" "$@"
echo -n " "; printf "%0.s*" $(seq 1 76); echo ""
eval "$@" | sed 's,^\(.*\), | \1,'
echo -n " \\"; printf "%0.s-" $(seq 1 75); echo ""
echo ""
}
run_pkg_debug() {
local pkg="$1"
echo -n "/"; printf "%0.s=" $(seq 1 79); echo ""
printf "| Start: ${pkg}\n"
echo -n "\\"; printf "%0.s=" $(seq 1 79); echo ""
. ${DEBUG_DIR}/"${pkg}"
echo -n "/"; printf "%0.s=" $(seq 1 79); echo ""
printf "| End: ${pkg}\n"
echo -n "\\"; printf "%0.s=" $(seq 1 79); echo ""
echo ""
}
help() {
cat <<EOF
Syntax: $0 [package]
List of available package (default: all):
$(ls -1 /lib/debug | sed 's,^\(.*\), \1,')
EOF
}
[ -d "${DEBUG_DIR}" ] || {
echo "Can't find any debuggable package"
exit 1
}
for pkg in $(ls -1 ${DEBUG_DIR}); do
run_pkg_debug "${pkg}"
done

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,654 @@
--- a/nss_c2c_tx.c
+++ b/nss_c2c_tx.c
@@ -334,6 +334,7 @@ static struct ctl_table nss_c2c_tx_table
{ }
};
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0))
static struct ctl_table nss_c2c_tx_dir[] = {
{
.procname = "c2c_tx",
@@ -360,6 +361,7 @@ static struct ctl_table nss_c2c_tx_root[
},
{ }
};
+#endif
static struct ctl_table_header *nss_c2c_tx_header;
@@ -378,7 +380,11 @@ void nss_c2c_tx_register_sysctl(void)
/*
* Register sysctl table.
*/
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ nss_c2c_tx_header = register_sysctl("dev/nss/c2c_tx", nss_c2c_tx_table);
+#else
nss_c2c_tx_header = register_sysctl_table(nss_c2c_tx_root);
+#endif
}
/*
--- a/nss_core.c
+++ b/nss_core.c
@@ -44,7 +44,7 @@
* following kernel versions. Before enabling the driver in new kernels,
* the skb recycle code must be checked against Linux skb handling.
*
- * Tested on: 3.4, 3.10, 3.14, 3.18, 4.4 and 5.4
+ * Tested on: 3.4, 3.10, 3.14, 3.18, 4.4, 5.4, 5.10, 5.15 and 6.6
*/
#if (!( \
(((LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)))) || \
@@ -54,7 +54,9 @@
(((LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)))) || \
(((LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(5, 5, 0)))) || \
(((LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0)))) || \
-(((LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(5, 16, 0))))))
+(((LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(5, 16, 0)))) || \
+(((LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(6, 2, 0)))) || \
+(((LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(6, 7, 0))))))
#error "Check skb recycle code in this file to match Linux version"
#endif
--- a/nss_dma.c
+++ b/nss_dma.c
@@ -378,6 +378,7 @@ static struct ctl_table nss_dma_table[]
{ }
};
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0))
static struct ctl_table nss_dma_dir[] = {
{
.procname = "dma",
@@ -404,6 +405,7 @@ static struct ctl_table nss_dma_root[] =
},
{ }
};
+#endif
static struct ctl_table_header *nss_dma_header;
@@ -422,7 +424,11 @@ void nss_dma_register_sysctl(void)
/*
* Register sysctl table.
*/
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ nss_dma_header = register_sysctl("dev/nss/dma", nss_dma_table);
+#else
nss_dma_header = register_sysctl_table(nss_dma_root);
+#endif
}
/*
--- a/nss_hal/fsm9010/nss_hal_pvt.c
+++ b/nss_hal/fsm9010/nss_hal_pvt.c
@@ -290,7 +290,11 @@ static int __nss_hal_request_irq(struct
}
int_ctx->irq = npd->irq[irq_num];
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi, 64);
+#else
netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi, 64);
+#endif
return 0;
}
--- a/nss_hal/ipq50xx/nss_hal_pvt.c
+++ b/nss_hal/ipq50xx/nss_hal_pvt.c
@@ -598,7 +598,11 @@ static int __nss_hal_request_irq(struct
return err;
}
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, napi_poll_cb, napi_wgt);
+#else
netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, napi_poll_cb, napi_wgt);
+#endif
int_ctx->cause = cause;
err = request_irq(irq, nss_hal_handle_irq, 0, irq_name, int_ctx);
if (err) {
--- a/nss_hal/ipq60xx/nss_hal_pvt.c
+++ b/nss_hal/ipq60xx/nss_hal_pvt.c
@@ -614,62 +614,102 @@ static int __nss_hal_request_irq(struct
irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY);
if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_EMPTY_BUFFER_SOS) {
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_non_queue, NSS_EMPTY_BUFFER_SOS_PROCESSING_WEIGHT);
+#else
netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_non_queue, NSS_EMPTY_BUFFER_SOS_PROCESSING_WEIGHT);
+#endif
int_ctx->cause = NSS_N2H_INTR_EMPTY_BUFFERS_SOS;
err = request_irq(irq, nss_hal_handle_irq, 0, "nss_empty_buf_sos", int_ctx);
}
if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_EMPTY_BUFFER_QUEUE) {
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_EMPTY_BUFFER_RETURN_PROCESSING_WEIGHT);
+#else
netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_EMPTY_BUFFER_RETURN_PROCESSING_WEIGHT);
+#endif
int_ctx->cause = NSS_N2H_INTR_EMPTY_BUFFER_QUEUE;
err = request_irq(irq, nss_hal_handle_irq, 0, "nss_empty_buf_queue", int_ctx);
}
if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_TX_UNBLOCKED) {
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_non_queue, NSS_TX_UNBLOCKED_PROCESSING_WEIGHT);
+#else
netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_non_queue, NSS_TX_UNBLOCKED_PROCESSING_WEIGHT);
+#endif
int_ctx->cause = NSS_N2H_INTR_TX_UNBLOCKED;
err = request_irq(irq, nss_hal_handle_irq, 0, "nss-tx-unblock", int_ctx);
}
if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_0) {
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT);
+#else
netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT);
+#endif
int_ctx->cause = NSS_N2H_INTR_DATA_QUEUE_0;
err = request_irq(irq, nss_hal_handle_irq, 0, "nss_queue0", int_ctx);
}
if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_1) {
int_ctx->cause = NSS_N2H_INTR_DATA_QUEUE_1;
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT);
+#else
netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT);
+#endif
err = request_irq(irq, nss_hal_handle_irq, 0, "nss_queue1", int_ctx);
}
if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_2) {
int_ctx->cause = NSS_N2H_INTR_DATA_QUEUE_2;
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT);
+#else
netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT);
+#endif
err = request_irq(irq, nss_hal_handle_irq, 0, "nss_queue2", int_ctx);
}
if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_3) {
int_ctx->cause = NSS_N2H_INTR_DATA_QUEUE_3;
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT);
+#else
netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT);
+#endif
err = request_irq(irq, nss_hal_handle_irq, 0, "nss_queue3", int_ctx);
}
if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_COREDUMP_COMPLETE) {
int_ctx->cause = NSS_N2H_INTR_COREDUMP_COMPLETE;
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_emergency, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT);
+#else
netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_emergency, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT);
+#endif
err = request_irq(irq, nss_hal_handle_irq, 0, "nss_coredump_complete", int_ctx);
}
if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_PAGED_EMPTY_BUFFER_SOS) {
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_non_queue, NSS_EMPTY_BUFFER_SOS_PROCESSING_WEIGHT);
+#else
netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_non_queue, NSS_EMPTY_BUFFER_SOS_PROCESSING_WEIGHT);
+#endif
int_ctx->cause = NSS_N2H_INTR_PAGED_EMPTY_BUFFERS_SOS;
err = request_irq(irq, nss_hal_handle_irq, 0, "nss_paged_empty_buf_sos", int_ctx);
}
if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_PROFILE_DMA) {
int_ctx->cause = NSS_N2H_INTR_PROFILE_DMA;
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_sdma, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT);
+#else
netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_sdma, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT);
+#endif
err = request_irq(irq, nss_hal_handle_irq, 0, "nss_profile_dma", int_ctx);
}
--- a/nss_hal/ipq806x/nss_hal_pvt.c
+++ b/nss_hal/ipq806x/nss_hal_pvt.c
@@ -1183,7 +1183,11 @@ static int __nss_hal_request_irq(struct
}
int_ctx->irq = npd->irq[irq_num];
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi, 64);
+#else
netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi, 64);
+#endif
return 0;
}
--- a/nss_hal/ipq807x/nss_hal_pvt.c
+++ b/nss_hal/ipq807x/nss_hal_pvt.c
@@ -656,62 +656,102 @@ static int __nss_hal_request_irq(struct
irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY);
if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_EMPTY_BUFFER_SOS) {
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_non_queue, NSS_EMPTY_BUFFER_SOS_PROCESSING_WEIGHT);
+#else
netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_non_queue, NSS_EMPTY_BUFFER_SOS_PROCESSING_WEIGHT);
+#endif
int_ctx->cause = NSS_N2H_INTR_EMPTY_BUFFERS_SOS;
err = request_irq(irq, nss_hal_handle_irq, 0, "nss_empty_buf_sos", int_ctx);
}
if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_EMPTY_BUFFER_QUEUE) {
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_EMPTY_BUFFER_RETURN_PROCESSING_WEIGHT);
+#else
netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_EMPTY_BUFFER_RETURN_PROCESSING_WEIGHT);
+#endif
int_ctx->cause = NSS_N2H_INTR_EMPTY_BUFFER_QUEUE;
err = request_irq(irq, nss_hal_handle_irq, 0, "nss_empty_buf_queue", int_ctx);
}
if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_TX_UNBLOCKED) {
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_non_queue, NSS_TX_UNBLOCKED_PROCESSING_WEIGHT);
+#else
netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_non_queue, NSS_TX_UNBLOCKED_PROCESSING_WEIGHT);
+#endif
int_ctx->cause = NSS_N2H_INTR_TX_UNBLOCKED;
err = request_irq(irq, nss_hal_handle_irq, 0, "nss-tx-unblock", int_ctx);
}
if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_0) {
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT);
+#else
netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT);
+#endif
int_ctx->cause = NSS_N2H_INTR_DATA_QUEUE_0;
err = request_irq(irq, nss_hal_handle_irq, 0, "nss_queue0", int_ctx);
}
if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_1) {
int_ctx->cause = NSS_N2H_INTR_DATA_QUEUE_1;
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT);
+#else
netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT);
+#endif
err = request_irq(irq, nss_hal_handle_irq, 0, "nss_queue1", int_ctx);
}
if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_2) {
int_ctx->cause = NSS_N2H_INTR_DATA_QUEUE_2;
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT);
+#else
netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT);
+#endif
err = request_irq(irq, nss_hal_handle_irq, 0, "nss_queue2", int_ctx);
}
if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_3) {
int_ctx->cause = NSS_N2H_INTR_DATA_QUEUE_3;
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT);
+#else
netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT);
+#endif
err = request_irq(irq, nss_hal_handle_irq, 0, "nss_queue3", int_ctx);
}
if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_COREDUMP_COMPLETE) {
int_ctx->cause = NSS_N2H_INTR_COREDUMP_COMPLETE;
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_emergency, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT);
+#else
netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_emergency, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT);
+#endif
err = request_irq(irq, nss_hal_handle_irq, 0, "nss_coredump_complete", int_ctx);
}
if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_PAGED_EMPTY_BUFFER_SOS) {
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_non_queue, NSS_EMPTY_BUFFER_SOS_PROCESSING_WEIGHT);
+#else
netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_non_queue, NSS_EMPTY_BUFFER_SOS_PROCESSING_WEIGHT);
+#endif
int_ctx->cause = NSS_N2H_INTR_PAGED_EMPTY_BUFFERS_SOS;
err = request_irq(irq, nss_hal_handle_irq, 0, "nss_paged_empty_buf_sos", int_ctx);
}
if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_PROFILE_DMA) {
int_ctx->cause = NSS_N2H_INTR_PROFILE_DMA;
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_sdma, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT);
+#else
netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_sdma, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT);
+#endif
err = request_irq(irq, nss_hal_handle_irq, 0, "nss_profile_dma", int_ctx);
}
--- a/nss_init.c
+++ b/nss_init.c
@@ -584,6 +584,11 @@ static struct ctl_table nss_general_tabl
{ }
};
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+static struct ctl_table_header *nss_clock_header;
+static struct ctl_table_header *nss_skb_header;
+static struct ctl_table_header *nss_general_header;
+#else
static struct ctl_table nss_init_dir[] = {
#if (NSS_FREQ_SCALE_SUPPORT == 1)
{
@@ -626,6 +631,7 @@ static struct ctl_table nss_root[] = {
};
static struct ctl_table_header *nss_dev_header;
+#endif
/*
* nss_init()
@@ -734,7 +740,19 @@ static int __init nss_init(void)
/*
* Register sysctl table.
*/
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ nss_general_header = register_sysctl("dev/nss/general", nss_general_table);
+
+#if (NSS_SKB_REUSE_SUPPORT == 1)
+ nss_skb_header = register_sysctl("dev/nss/skb_reuse", nss_skb_reuse_table);
+#endif
+
+#if (NSS_FREQ_SCALE_SUPPORT == 1)
+ nss_clock_header = register_sysctl("dev/nss/clock", nss_freq_table);
+#endif
+#else
nss_dev_header = register_sysctl_table(nss_root);
+#endif
/*
* Registering sysctl for ipv4/6 specific config.
@@ -887,8 +905,23 @@ static void __exit nss_cleanup(void)
{
nss_info("Exit NSS driver");
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ if (nss_general_header)
+ unregister_sysctl_table(nss_general_header);
+
+#if (NSS_SKB_REUSE_SUPPORT == 1)
+ if (nss_skb_header)
+ unregister_sysctl_table(nss_skb_header);
+#endif
+
+#if (NSS_FREQ_SCALE_SUPPORT == 1)
+ if (nss_clock_header)
+ unregister_sysctl_table(nss_clock_header);
+#endif
+#else
if (nss_dev_header)
unregister_sysctl_table(nss_dev_header);
+#endif
/*
* Unregister n2h specific sysctl
--- a/nss_ipv4.c
+++ b/nss_ipv4.c
@@ -697,6 +697,7 @@ static struct ctl_table nss_ipv4_table[]
{ }
};
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0))
static struct ctl_table nss_ipv4_dir[] = {
{
.procname = "ipv4cfg",
@@ -723,6 +724,7 @@ static struct ctl_table nss_ipv4_root[]
},
{ }
};
+#endif
static struct ctl_table_header *nss_ipv4_header;
@@ -738,7 +740,11 @@ void nss_ipv4_register_sysctl(void)
/*
* Register sysctl table.
*/
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ nss_ipv4_header = register_sysctl("dev/nss/ipv4cfg", nss_ipv4_table);
+#else
nss_ipv4_header = register_sysctl_table(nss_ipv4_root);
+#endif
}
/*
--- a/nss_ipv6.c
+++ b/nss_ipv6.c
@@ -706,6 +706,7 @@ static struct ctl_table nss_ipv6_table[]
{ }
};
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0))
static struct ctl_table nss_ipv6_dir[] = {
{
.procname = "ipv6cfg",
@@ -732,6 +733,7 @@ static struct ctl_table nss_ipv6_root[]
},
{ }
};
+#endif
static struct ctl_table_header *nss_ipv6_header;
@@ -747,7 +749,11 @@ void nss_ipv6_register_sysctl(void)
/*
* Register sysctl table.
*/
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ nss_ipv6_header = register_sysctl("dev/nss/ipv6cfg", nss_ipv6_table);
+#else
nss_ipv6_header = register_sysctl_table(nss_ipv6_root);
+#endif
}
/*
--- a/nss_n2h.c
+++ b/nss_n2h.c
@@ -1862,6 +1862,7 @@ static struct ctl_table nss_n2h_table_mu
{ }
};
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0))
/*
* This table will be overwritten during single-core registration
*/
@@ -1891,6 +1892,7 @@ static struct ctl_table nss_n2h_root[] =
},
{ }
};
+#endif
static struct ctl_table_header *nss_n2h_header;
@@ -2133,8 +2135,12 @@ void nss_n2h_single_core_register_sysctl
/*
* Register sysctl table.
*/
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ nss_n2h_header = register_sysctl("dev/nss/n2hcfg", nss_n2h_table_single_core);
+#else
nss_n2h_dir[0].child = nss_n2h_table_single_core;
nss_n2h_header = register_sysctl_table(nss_n2h_root);
+#endif
}
/*
@@ -2232,7 +2238,11 @@ void nss_n2h_multi_core_register_sysctl(
/*
* Register sysctl table.
*/
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ nss_n2h_header = register_sysctl("dev/nss/n2hcfg", nss_n2h_table_multi_core);
+#else
nss_n2h_header = register_sysctl_table(nss_n2h_root);
+#endif
}
/*
--- a/nss_ppe_vp.c
+++ b/nss_ppe_vp.c
@@ -333,6 +333,7 @@ static struct ctl_table nss_ppe_vp_table
{ }
};
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0))
static struct ctl_table nss_ppe_vp_dir[] = {
{
.procname = "ppe_vp",
@@ -350,6 +351,7 @@ static struct ctl_table nss_ppe_vp_root_
},
{ }
};
+#endif
static struct ctl_table_header *nss_ppe_vp_procfs_header;
@@ -362,7 +364,11 @@ void nss_ppe_vp_procfs_register(void)
/*
* Register sysctl table.
*/
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ nss_ppe_vp_procfs_header = register_sysctl("dev/nss/ppe_vp", nss_ppe_vp_table);
+#else
nss_ppe_vp_procfs_header = register_sysctl_table(nss_ppe_vp_root_dir);
+#endif
}
/*
--- a/nss_pppoe.c
+++ b/nss_pppoe.c
@@ -353,6 +353,7 @@ static struct ctl_table nss_pppoe_table[
{ }
};
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0))
static struct ctl_table nss_pppoe_dir[] = {
{
.procname = "pppoe",
@@ -379,6 +380,7 @@ static struct ctl_table nss_pppoe_root[]
},
{ }
};
+#endif
static struct ctl_table_header *nss_pppoe_header;
@@ -391,7 +393,11 @@ void nss_pppoe_register_sysctl(void)
/*
* Register sysctl table.
*/
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ nss_pppoe_header = register_sysctl("dev/nss/pppoe", nss_pppoe_table);
+#else
nss_pppoe_header = register_sysctl_table(nss_pppoe_root);
+#endif
}
/*
--- a/nss_project.c
+++ b/nss_project.c
@@ -279,6 +279,7 @@ static struct ctl_table nss_project_tabl
{ }
};
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0))
static struct ctl_table nss_project_dir[] = {
{
.procname = "project",
@@ -305,6 +306,7 @@ static struct ctl_table nss_project_root
},
{ }
};
+#endif
static struct ctl_table_header *nss_project_header;
@@ -314,7 +316,11 @@ static struct ctl_table_header *nss_proj
*/
void nss_project_register_sysctl(void)
{
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ nss_project_header = register_sysctl("dev/nss/project", nss_project_table);
+#else
nss_project_header = register_sysctl_table(nss_project_root);
+#endif
}
/*
--- a/nss_rps.c
+++ b/nss_rps.c
@@ -557,6 +557,7 @@ static struct ctl_table nss_rps_table[]
{ }
};
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0))
static struct ctl_table nss_rps_dir[] = {
{
.procname = "rps",
@@ -583,6 +584,7 @@ static struct ctl_table nss_rps_root[] =
},
{ }
};
+#endif
static struct ctl_table_header *nss_rps_header;
@@ -620,7 +622,11 @@ void nss_rps_register_sysctl(void)
/*
* Register sysctl table.
*/
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ nss_rps_header = register_sysctl("dev/nss/rps", nss_rps_table);
+#else
nss_rps_header = register_sysctl_table(nss_rps_root);
+#endif
}
/*
--- a/nss_stats.c
+++ b/nss_stats.c
@@ -85,6 +85,7 @@ static struct ctl_table nss_stats_table[
{ }
};
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0))
static struct ctl_table nss_stats_dir[] = {
{
.procname = "stats",
@@ -111,6 +112,8 @@ static struct ctl_table nss_stats_root[]
},
{ }
};
+#endif
+
static struct ctl_table_header *nss_stats_header;
/*
@@ -122,7 +125,11 @@ void nss_stats_register_sysctl(void)
/*
* Register sysctl table.
*/
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ nss_stats_header = register_sysctl("dev/nss/stats", nss_stats_table);
+#else
nss_stats_header = register_sysctl_table(nss_stats_root);
+#endif
}
/*

View File

@@ -0,0 +1,237 @@
--- a/nss_dynamic_interface.c
+++ b/nss_dynamic_interface.c
@@ -226,7 +226,7 @@ int nss_dynamic_interface_alloc_node(enu
core_id = nss_top_main.dynamic_interface_table[type];
nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[core_id];
di_data.if_num = -1;
- di_data.response = false;
+ di_data.response = -1;
init_completion(&di_data.complete);
nss_dynamic_interface_msg_init(&ndim, NSS_DYNAMIC_INTERFACE, NSS_DYNAMIC_INTERFACE_ALLOC_NODE,
@@ -285,7 +285,7 @@ nss_tx_status_t nss_dynamic_interface_de
core_id = nss_top_main.dynamic_interface_table[type];
nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[core_id];
- di_data.response = false;
+ di_data.response = -1;
init_completion(&di_data.complete);
if (nss_is_dynamic_interface(if_num) == false) {
--- a/nss_ipv6.c
+++ b/nss_ipv6.c
@@ -377,7 +377,7 @@ EXPORT_SYMBOL(nss_ipv6_get_mgr);
* nss_ipv6_register_handler()
* Register our handler to receive messages for this interface
*/
-void nss_ipv6_register_handler()
+void nss_ipv6_register_handler(void)
{
struct nss_ctx_instance *nss_ctx = nss_ipv6_get_mgr();
--- a/nss_lag.c
+++ b/nss_lag.c
@@ -237,7 +237,7 @@ nss_tx_status_t nss_lag_tx_slave_state(u
struct nss_lag_pvt lag_msg_state;
init_completion(&lag_msg_state.complete);
- lag_msg_state.response = false;
+ lag_msg_state.response = -1;
/*
* Construct a message to the NSS to update it
@@ -268,6 +268,6 @@ nss_tx_status_t nss_lag_tx_slave_state(u
return NSS_TX_FAILURE;
}
- return lag_msg_state.response;
+ return status;
}
EXPORT_SYMBOL(nss_lag_tx_slave_state);
--- a/nss_n2h.c
+++ b/nss_n2h.c
@@ -1153,16 +1153,16 @@ static nss_tx_status_t nss_n2h_mitigatio
/*
* ACK/NACK received from NSS FW
*/
- if (NSS_FAILURE == nss_n2h_mitigationcp[core_num].response) {
+ if (NSS_TX_FAILURE == nss_n2h_mitigationcp[core_num].response) {
goto failure;
}
up(&nss_n2h_mitigationcp[core_num].sem);
- return NSS_SUCCESS;
+ return NSS_TX_SUCCESS;
failure:
up(&nss_n2h_mitigationcp[core_num].sem);
- return NSS_FAILURE;
+ return NSS_TX_FAILURE;
}
static inline void nss_n2h_buf_pool_free(struct nss_n2h_buf_pool *buf_pool)
@@ -1234,7 +1234,7 @@ static nss_tx_status_t nss_n2h_buf_pool_
/*
* ACK/NACK received from NSS FW
*/
- if (NSS_FAILURE == nss_n2h_bufcp[core_num].response) {
+ if (NSS_TX_FAILURE == nss_n2h_bufcp[core_num].response) {
nss_n2h_buf_pool_free(buf_pool);
goto failure;
@@ -1243,10 +1243,10 @@ static nss_tx_status_t nss_n2h_buf_pool_
up(&nss_n2h_bufcp[core_num].sem);
} while(num_pages);
- return NSS_SUCCESS;
+ return NSS_TX_SUCCESS;
failure:
up(&nss_n2h_bufcp[core_num].sem);
- return NSS_FAILURE;
+ return NSS_TX_FAILURE;
}
/*
@@ -1545,7 +1545,7 @@ static nss_tx_status_t nss_n2h_host_bp_c
if (nss_tx_status != NSS_TX_SUCCESS) {
nss_warning("%px: nss_tx error setting back pressure\n", nss_ctx);
up(&nss_n2h_host_bp_cfg_pvt.sem);
- return NSS_FAILURE;
+ return NSS_TX_FAILURE;
}
/*
@@ -1555,7 +1555,7 @@ static nss_tx_status_t nss_n2h_host_bp_c
if (ret == 0) {
nss_warning("%px: Waiting for ack timed out\n", nss_ctx);
up(&nss_n2h_host_bp_cfg_pvt.sem);
- return NSS_FAILURE;
+ return NSS_TX_FAILURE;
}
/*
@@ -1563,11 +1563,11 @@ static nss_tx_status_t nss_n2h_host_bp_c
*/
if (nss_n2h_host_bp_cfg_pvt.response == NSS_FAILURE) {
up(&nss_n2h_host_bp_cfg_pvt.sem);
- return NSS_FAILURE;
+ return NSS_TX_FAILURE;
}
up(&nss_n2h_host_bp_cfg_pvt.sem);
- return NSS_SUCCESS;
+ return NSS_TX_SUCCESS;
}
/*
--- a/nss_pm.c
+++ b/nss_pm.c
@@ -335,7 +335,7 @@ nss_pm_interface_status_t nss_pm_set_per
break;
default:
- index = NSS_PM_PERF_LEVEL_IDLE;
+ index = (nss_freq_scales_t)NSS_PM_PERF_LEVEL_IDLE;
}
#if !defined(NSS_HAL_IPQ807x_SUPPORT)
--- a/nss_rps.c
+++ b/nss_rps.c
@@ -251,7 +251,7 @@ static nss_tx_status_t nss_rps_cfg(struc
nss_warning("%px: nss_tx error setting rps\n", nss_ctx);
up(&nss_rps_cfg_pvt.sem);
- return NSS_FAILURE;
+ return NSS_TX_FAILURE;
}
/*
@@ -261,7 +261,7 @@ static nss_tx_status_t nss_rps_cfg(struc
if (ret == 0) {
nss_warning("%px: Waiting for ack timed out\n", nss_ctx);
up(&nss_rps_cfg_pvt.sem);
- return NSS_FAILURE;
+ return NSS_TX_FAILURE;
}
/*
@@ -269,13 +269,13 @@ static nss_tx_status_t nss_rps_cfg(struc
* If NACK: Handler function will restore nss_rps_config
* to previous state.
*/
- if (NSS_FAILURE == nss_rps_cfg_pvt.response) {
+ if (NSS_TX_FAILURE == nss_rps_cfg_pvt.response) {
up(&nss_rps_cfg_pvt.sem);
- return NSS_FAILURE;
+ return NSS_TX_FAILURE;
}
up(&nss_rps_cfg_pvt.sem);
- return NSS_SUCCESS;
+ return NSS_TX_SUCCESS;
}
/*
@@ -300,11 +300,11 @@ static nss_tx_status_t nss_rps_ipv4_hash
nss_warning("%px: nss_tx error setting rps\n", nss_ctx);
up(&nss_rps_cfg_pvt.sem);
- return NSS_FAILURE;
+ return NSS_TX_FAILURE;
}
up(&nss_rps_cfg_pvt.sem);
- return NSS_SUCCESS;
+ return NSS_TX_SUCCESS;
}
/*
@@ -329,11 +329,11 @@ static nss_tx_status_t nss_rps_ipv6_hash
nss_warning("%px: nss_tx error setting rps\n", nss_ctx);
up(&nss_rps_cfg_pvt.sem);
- return NSS_FAILURE;
+ return NSS_TX_FAILURE;
}
up(&nss_rps_cfg_pvt.sem);
- return NSS_SUCCESS;
+ return NSS_TX_SUCCESS;
}
/*
@@ -368,7 +368,7 @@ static nss_tx_status_t nss_rps_pri_map_c
nss_warning("%px: nss_tx error setting rps\n", nss_ctx);
up(&nss_rps_cfg_pvt.sem);
- return NSS_FAILURE;
+ return NSS_TX_FAILURE;
}
/*
@@ -378,7 +378,7 @@ static nss_tx_status_t nss_rps_pri_map_c
if (ret == 0) {
nss_warning("%px: Waiting for ack timed out\n", nss_ctx);
up(&nss_rps_cfg_pvt.sem);
- return NSS_FAILURE;
+ return NSS_TX_FAILURE;
}
/*
@@ -386,13 +386,13 @@ static nss_tx_status_t nss_rps_pri_map_c
* If NACK: Handler function will restore nss_rps_config
* to previous state.
*/
- if (NSS_FAILURE == nss_rps_cfg_pvt.response) {
+ if (NSS_TX_FAILURE == nss_rps_cfg_pvt.response) {
up(&nss_rps_cfg_pvt.sem);
- return NSS_FAILURE;
+ return NSS_TX_FAILURE;
}
up(&nss_rps_cfg_pvt.sem);
- return NSS_SUCCESS;
+ return NSS_TX_SUCCESS;
}
/*

View File

@@ -0,0 +1,362 @@
# NHSS.QSDK.12.4.5.r2
# by SqTER
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=qca-nss-ecm
PKG_RELEASE:=1
PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/qca-nss-ecm.git
PKG_SOURCE_DATE:=2023-07-25
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=9acdcb05c04ae177a79c4c34cef0487fbcedbfaa
PKG_MIRROR_HASH:=f36f5b5318e23b0efe38097751f44c7a05b208b1884294eb8aab15d2a1e33677
PKG_BUILD_PARALLEL:=1
include $(INCLUDE_DIR)/package.mk
LOCAL_VARIANT=$(patsubst qca-nss-ecm-%,%,$(patsubst qca-nss-ecm-%,%,$(BUILD_VARIANT)))
ifeq ($(CONFIG_QCA_NSS_ECM_EXAMPLES_PCC),y)
ECM_MAKE_OPTS+=ECM_CLASSIFIER_PCC_ENABLE=y
FILES_EXAMPLES=$(PKG_BUILD_DIR)/examples/ecm_pcc_test.ko
endif
ifeq ($(CONFIG_QCA_NSS_ECM_EXAMPLES_MARK),y)
FILES_EXAMPLES+=$(PKG_BUILD_DIR)/examples/ecm_mark_test.ko
endif
#Explicitly enable OVS external module, if ovsmgr is enabled.
ifneq ($(CONFIG_PACKAGE_kmod-qca-ovsmgr),)
CONFIG_QCA_NSS_ECM_OVS=y
endif
ifeq ($(CONFIG_QCA_NSS_ECM_OVS),y)
FILES_EXAMPLES+=$(PKG_BUILD_DIR)/examples/ecm_ovs.ko
endif
define KernelPackage/qca-nss-ecm/Default
SECTION:=kernel
CATEGORY:=Kernel modules
SUBMENU:=Network Support
TITLE:=QCA NSS Enhanced Connection Manager (ECM)
FILES:=$(PKG_BUILD_DIR)/*.ko $(FILES_EXAMPLES)
KCONFIG:=CONFIG_BRIDGE_NETFILTER=y \
CONFIG_NF_CONNTRACK_EVENTS=y \
CONFIG_NF_CONNTRACK_CHAIN_EVENTS=y \
CONFIG_NF_CONNTRACK_DSCPREMARK_EXT=y
MENU:=1
PROVIDES:=kmod-qca-nss-ecm
$(call AddDepends/qca-nss-ecm/Default)
endef
define KernelPackage/qca-nss-ecm/Description/Default
This package contains the QCA NSS Enhanced Connection Manager
endef
define AddDepends/qca-nss-ecm/Default
SUBMENU:=Network Support
DEPENDS:= \
+@NSS_DRV_IPV6_ENABLE \
+@NSS_DRV_VIRT_IF_ENABLE \
+@NSS_DRV_WIFI_ENABLE \
+@NSS_DRV_PPPOE_ENABLE \
+@NSS_DRV_PPTP_ENABLE \
+PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv \
+kmod-nf-conntrack \
+kmod-ipt-physdev \
+iptables-mod-physdev \
+kmod-ppp +kmod-pppoe +kmod-pptp
endef
define KernelPackage/qca-nss-ecm/Default/install
$(INSTALL_DIR) $(1)/etc/firewall.d $(1)/etc/init.d $(1)/usr/bin $(1)/lib/netifd/offload $(1)/etc/config $(1)/etc/uci-defaults $(1)/etc/sysctl.d
$(INSTALL_DATA) ./files/qca-nss-ecm.firewall $(1)/etc/firewall.d/qca-nss-ecm
$(INSTALL_BIN) ./files/qca-nss-ecm.init $(1)/etc/init.d/qca-nss-ecm
$(INSTALL_BIN) ./files/ecm_dump.sh $(1)/usr/bin/
$(INSTALL_BIN) ./files/on-demand-down $(1)/lib/netifd/offload/on-demand-down
$(INSTALL_DATA) ./files/qca-nss-ecm.uci $(1)/etc/config/ecm
$(INSTALL_DATA) ./files/qca-nss-ecm.defaults $(1)/etc/uci-defaults/99-qca-nss-ecm
$(INSTALL_BIN) ./files/qca-nss-ecm.sysctl $(1)/etc/sysctl.d/99-qca-nss-ecm.conf
ifeq ($(CONFIG_KERNEL_IPQ_MEM_PROFILE),256)
echo 'net.netfilter.nf_conntrack_max=2048' >> $(1)/etc/sysctl.d/99-qca-nss-ecm.conf
endif
ifeq ($(CONFIG_KERNEL_IPQ_MEM_PROFILE),512)
echo 'net.netfilter.nf_conntrack_max=8192' >> $(1)/etc/sysctl.d/99-qca-nss-ecm.conf
endif
endef
define KernelPackage/qca-nss-ecm-standard
$(call KernelPackage/qca-nss-ecm/Default)
ifneq ($(CONFIG_PACKAGE_kmod-pppol2tp),)
DEPENDS+=+PACKAGE_kmod-pppol2tp:kmod-pppol2tp
endif
ifneq ($(CONFIG_PACKAGE_kmod-qca-mcs),)
DEPENDS+=+kmod-qca-mcs
endif
VARIANT:=standard
endef
define KernelPackage/qca-nss-ecm-standard/description
$(call KernelPackage/qca-nss-ecm/Description/Default)
endef
define KernelPackage/qca-nss-ecm-standard/install
$(call KernelPackage/qca-nss-ecm/Default/install, $(1))
endef
# Variant with additional features enabled for premium profile
define KernelPackage/qca-nss-ecm-premium/Default
$(call KernelPackage/qca-nss-ecm/Default)
TITLE+:= (with premium features)
VARIANT:=premium
DEPENDS+:=+kmod-qca-hyfi-bridge +kmod-qca-mcs
ifeq ($(CONFIG_TARGET_ipq_ipq40xx)$(CONFIG_TARGET_ipq40xx),)
DEPENDS+=+kmod-bonding
endif
endef
define KernelPackage/qca-nss-ecm-premium/Description/Default
$(call KernelPackage/qca-nss-ecm/Description/Default)
with the premium features enabled
endef
define KernelPackage/qca-nss-ecm-premium/Default/install
$(call KernelPackage/qca-nss-ecm/install)
endef
define KernelPackage/qca-nss-ecm-premium
$(call KernelPackage/qca-nss-ecm-premium/Default)
endef
define KernelPackage/qca-nss-ecm-premium/description
$(call KernelPackage/qca-nss-ecm-premium/Description/Default)
endef
define KernelPackage/qca-nss-ecm-premium/install
$(call KernelPackage/qca-nss-ecm-standard/install, $(1))
endef
# Variant with additional features enabled for noload profile
define KernelPackage/qca-nss-ecm-noload
$(call KernelPackage/qca-nss-ecm/Default)
TITLE+:= (with noload features)
PROVIDES:=kmod-qca-nss-ecm
VARIANT:=noload
ifeq ($(CONFIG_TARGET_ipq_ipq40xx)$(CONFIG_TARGET_ipq40xx),)
DEPENDS+=+kmod-bonding
endif
endef
define KernelPackage/qca-nss-ecm-noload/description
$(call KernelPackage/qca-nss-ecm/Description/Default)
When selected, this package installs the driver but does not load it at init.
endef
define KernelPackage/qca-nss-ecm-noload/install
$(call KernelPackage/qca-nss-ecm/Default/install, $(1))
#
# Remove the START line from the init script, so that the symlink
# in the /etc/rc.d directory is not created.
#
sed -i '/START=/d' $(1)/etc/init.d/qca-nss-ecm
endef
define KernelPackage/qca-nss-ecm-premium-noload
$(call KernelPackage/qca-nss-ecm-premium/Default)
TITLE+:= (noload)
PROVIDES:=kmod-qca-nss-ecm-premium
VARIANT:=premium-noload
endef
define KernelPackage/qca-nss-ecm-premium-noload/description
$(call KernelPackage/qca-nss-ecm-premium/Description/Default)
When selected, this package installs the driver but does not load it at init.
endef
define KernelPackage/qca-nss-ecm-premium-noload/install
$(call KernelPackage/qca-nss-ecm-premium/Default/install, $(1))
endef
define Build/InstallDev/qca-nss-ecm
$(INSTALL_DIR) $(1)/usr/include/qca-nss-ecm
$(CP) $(PKG_BUILD_DIR)/exports/* $(1)/usr/include/qca-nss-ecm/
endef
define Build/InstallDev
$(call Build/InstallDev/qca-nss-ecm,$(1))
endef
EXTRA_CFLAGS+= \
-I$(STAGING_DIR)/usr/include/hyfibr \
-I$(STAGING_DIR)/usr/include/qca-mcs \
-I$(STAGING_DIR)/usr/include/qca-nss-drv \
-I$(STAGING_DIR)/usr/include/shortcut-fe
ECM_MAKE_OPTS:=ECM_CLASSIFIER_HYFI_ENABLE=n
ifeq ($(LOCAL_VARIANT),standard)
ECM_MAKE_OPTS+=ECM_NON_PORTED_SUPPORT_ENABLE=y \
ECM_STATE_OUTPUT_ENABLE=y \
ECM_INTERFACE_VLAN_ENABLE=y \
ECM_CLASSIFIER_DSCP_ENABLE=y \
ECM_CLASSIFIER_MARK_ENABLE=y \
ECM_CLASSIFIER_NL_ENABLE=y \
ECM_TRACKER_DPI_SUPPORT_ENABLE=y \
ECM_DB_ADVANCED_STATS_ENABLE=y \
ECM_CLASSIFIER_EMESH_ENABLE=n
ifeq ($(CONFIG_TARGET_ipq_ipq40xx)$(CONFIG_TARGET_ipq40xx),)
ECM_MAKE_OPTS+=ECM_INTERFACE_BOND_ENABLE=n
endif
endif
ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-ovpn-link),)
ECM_MAKE_OPTS+=ECM_INTERFACE_OVPN_ENABLE=y
else
ECM_MAKE_OPTS+=ECM_INTERFACE_OVPN_ENABLE=n
endif
ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-vxlanmgr),)
ECM_MAKE_OPTS+=ECM_INTERFACE_VXLAN_ENABLE=y
else
ECM_MAKE_OPTS+=ECM_INTERFACE_VXLAN_ENABLE=n
endif
ifneq ($(CONFIG_PACKAGE_kmod-qca-ovsmgr),)
ECM_MAKE_OPTS+=ECM_INTERFACE_OVS_BRIDGE_ENABLE=y \
ECM_CLASSIFIER_OVS_ENABLE=y
EXTRA_CFLAGS+= -I$(STAGING_DIR)/usr/include/qca-ovsmgr
else
ECM_MAKE_OPTS+=ECM_INTERFACE_OVS_BRIDGE_ENABLE=n \
ECM_CLASSIFIER_OVS_ENABLE=n
endif
ifneq ($(CONFIG_PACKAGE_kmod-macvlan),)
ECM_MAKE_OPTS+=ECM_INTERFACE_MACVLAN_ENABLE=y
else
ECM_MAKE_OPTS+=ECM_INTERFACE_MACVLAN_ENABLE=n
endif
ifneq ($(CONFIG_PACKAGE_kmod-qca-mcs),)
ECM_MAKE_OPTS+=ECM_MULTICAST_ENABLE=y
else
ECM_MAKE_OPTS+=ECM_MULTICAST_ENABLE=n
endif
ifneq ($(CONFIG_PACKAGE_kmod-ipsec),)
ECM_MAKE_OPTS+=ECM_INTERFACE_IPSEC_ENABLE=y
else
ECM_MAKE_OPTS+=ECM_INTERFACE_IPSEC_ENABLE=n
endif
ifneq ($(CONFIG_PACKAGE_kmod-pppoe),)
ECM_MAKE_OPTS+= ECM_INTERFACE_PPPOE_ENABLE=y \
ECM_INTERFACE_PPTP_ENABLE=y \
ECM_INTERFACE_PPP_ENABLE=y
else
ECM_MAKE_OPTS+= ECM_INTERFACE_PPPOE_ENABLE=n \
ECM_INTERFACE_PPTP_ENABLE=n \
ECM_INTERFACE_PPP_ENABLE=n
endif
ifneq ($(CONFIG_PACKAGE_kmod-pppol2tp),)
ECM_MAKE_OPTS+=ECM_INTERFACE_L2TPV2_ENABLE=y
else
ECM_MAKE_OPTS+=ECM_INTERFACE_L2TPV2_ENABLE=n
endif
ifneq ($(CONFIG_PACKAGE_kmod-gre)$(CONFIG_PACKAGE_kmod-gre6),)
ECM_MAKE_OPTS+=ECM_INTERFACE_GRE_TAP_ENABLE=y \
ECM_INTERFACE_GRE_TUN_ENABLE=y
else
ECM_MAKE_OPTS+=ECM_INTERFACE_GRE_TAP_ENABLE=n \
ECM_INTERFACE_GRE_TUN_ENABLE=n
endif
ifneq ($(CONFIG_PACKAGE_kmod-sit),)
ECM_MAKE_OPTS+=ECM_INTERFACE_SIT_ENABLE=y
else
ECM_MAKE_OPTS+=ECM_INTERFACE_SIT_ENABLE=n
endif
ifneq ($(CONFIG_PACKAGE_kmod-ip6-tunnel),)
ECM_MAKE_OPTS+=ECM_INTERFACE_TUNIPIP6_ENABLE=y
else
ECM_MAKE_OPTS+=ECM_INTERFACE_TUNIPIP6_ENABLE=n
endif
ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-mscs),)
ECM_MAKE_OPTS+=ECM_CLASSIFIER_MSCS_ENABLE=y
else
ECM_MAKE_OPTS+=ECM_CLASSIFIER_MSCS_ENABLE=n
endif
# Disable ECM IPv6 support when global IPv6 support is disabled.
ifneq ($(CONFIG_IPV6),)
ECM_MAKE_OPTS+=ECM_IPV6_ENABLE=y
endif
# Enable NSS frontend for all the platforms except ipq40xx
ifeq ($(CONFIG_TARGET_ipq_ipq40xx)$(CONFIG_TARGET_ipq40xx),)
ifneq ($(BUILD_VARIANT), nonss)
ECM_MAKE_OPTS+=ECM_FRONT_END_NSS_ENABLE=y
endif
endif
# Keeping default as ipq806x for branches that does not have subtarget framework
ifeq ($(CONFIG_TARGET_ipq),y)
subtarget:=$(SUBTARGET)
else
subtarget:=$(CONFIG_TARGET_BOARD)
endif
define Build/InstallDev
$(INSTALL_DIR) $(1)/usr/include/qca-nss-ecm
$(CP) $(PKG_BUILD_DIR)/exports/* $(1)/usr/include/qca-nss-ecm
endef
define Build/Compile
+$(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" $(strip $(ECM_MAKE_OPTS)) \
$(KERNEL_MAKE_FLAGS) \
$(PKG_MAKE_FLAGS) \
M="$(PKG_BUILD_DIR)" \
EXTRA_CFLAGS="$(EXTRA_CFLAGS)" SoC="$(subtarget)" \
EXAMPLES_BUILD_PCC="$(CONFIG_QCA_NSS_ECM_EXAMPLES_PCC)" \
EXAMPLES_BUILD_MARK="$(CONFIG_QCA_NSS_ECM_EXAMPLES_MARK)" \
EXAMPLES_BUILD_OVS="$(CONFIG_QCA_NSS_ECM_OVS)" \
ECM_FRONT_END_SFE_ENABLE="$(CONFIG_QCA_ECM_SFE_SUPPORT)" \
modules
endef
define KernelPackage/qca-nss-ecm-standard/config
menu "ECM Configuration"
config QCA_NSS_ECM_EXAMPLES_PCC
bool "Build PCC usage example"
help
Selecting this will build the PCC classifier usage example module.
default n
config QCA_NSS_ECM_EXAMPLES_MARK
bool "Build Mark classifier usage example"
help
Selecting this will build the Mark classifier usage example module.
default n
config QCA_NSS_ECM_OVS
bool "Build OVS classifier external module"
help
Selecting this will build the OVS classifier external module.
default n
config QCA_ECM_SFE_SUPPORT
bool "Add SFE support to ECM driver"
default n
endmenu
endef
$(eval $(call KernelPackage,qca-nss-ecm-noload))
$(eval $(call KernelPackage,qca-nss-ecm-standard))
$(eval $(call KernelPackage,qca-nss-ecm-premium-noload))
$(eval $(call KernelPackage,qca-nss-ecm-premium))

View File

@@ -0,0 +1,95 @@
#!/bin/sh
#
# Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
ECM_MODULE=${1:-ecm_state}
MOUNT_ROOT=/dev/ecm
#
# usage: ecm_dump.sh [module=ecm_db]
#
# with no parameters, ecm_dump.sh will attempt to mount the
# ecm_db state file and cat its contents.
#
# example with a parameter: ecm_dump.sh ecm_classifier_default
#
# this will cause ecm_dump to attempt to find and mount the state
# file for the ecm_classifier_default module, and if successful
# cat the contents.
#
# this is one of the state files, which happens to be the
# last module started in ecm
ECM_STATE=/sys/kernel/debug/ecm/ecm_state/state_dev_major
# tests to see if ECM is up and ready to receive commands.
# returns 0 if ECM is fully up and ready, else 1
ecm_is_ready() {
if [ ! -e "${ECM_STATE}" ]
then
return 1
fi
return 0
}
#
# module_state_mount(module_name)
# Mounts the state file of the module, if supported
#
module_state_mount() {
local module_name=$1
local mount_dir=$2
local state_file="/sys/kernel/debug/ecm/${module_name}/state_dev_major"
if [ -e "${mount_dir}/${module_name}" ]
then
# already mounted
return 0
fi
#echo "Mount state file for $module_name ..."
if [ ! -e "$state_file" ]
then
#echo "... $module_name does not support state"
return 1
fi
local major="`cat $state_file`"
#echo "... Mounting state $state_file with major: $major"
mknod "${mount_dir}/${module_name}" c $major 0
}
#
# main
#
ecm_is_ready || {
#echo "ECM is not running"
exit 1
}
# all state files are mounted under MOUNT_ROOT, so make sure it exists
mkdir -p ${MOUNT_ROOT}
#
# attempt to mount state files for the requested module and cat it
# if the mount succeeded
#
module_state_mount ${ECM_MODULE} ${MOUNT_ROOT} && {
cat ${MOUNT_ROOT}/${ECM_MODULE}
exit 0
}
exit 2

View File

@@ -0,0 +1,6 @@
#!/bin/sh
# Copyright (c) 2016 The Linux Foundation. All rights reserved.
[ -e "/sys/kernel/debug/ecm/ecm_db/defunct_all" ] && {
echo 1 > /sys/kernel/debug/ecm/ecm_db/defunct_all
}

View File

@@ -0,0 +1,13 @@
#!/bin/sh
uci -q batch << EOF
delete firewall.nss_ecm
set firewall.nss_ecm=include
set firewall.nss_ecm.type=script
set firewall.nss_ecm.path=/etc/firewall.d/qca-nss-ecm
set firewall.nss_ecm.family=any
set firewall.nss_ecm.reload=1
commit firewall
EOF
exit 0

View File

@@ -0,0 +1,33 @@
#!/bin/sh
#
# Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
# Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
iptables -nvL FORWARD | grep -q "physdev" && iptables -Z FORWARD 1
iptables -nvL FORWARD | grep -q "physdev" || iptables -I FORWARD -m physdev --physdev-is-bridged -j ACCEPT
if grep -q "fw3" /etc/init.d/firewall; then
iptables -nvL | grep -q "Chain RATE-LIMIT" && iptables -F RATE-LIMIT
iptables -nvL | grep -q "Chain RATE-LIMIT" || iptables -N RATE-LIMIT
iptables -A RATE-LIMIT --match limit --limit 1000/sec --limit-burst 1000 -j RETURN
iptables -A RATE-LIMIT -j DROP
iptables -I zone_wan_forward 5 --match conntrack --ctstate NEW -j RATE-LIMIT
elif grep -q "fw4" /etc/init.d/firewall; then
nft add chain inet fw4 RATE-LIMIT
nft add rule inet fw4 RATE-LIMIT limit rate 1000/second burst 1000 packets counter return
nft add rule inet fw4 RATE-LIMIT counter drop
nft add rule inet fw4 forward_wan ct state new counter jump RATE-LIMIT
fi

View File

@@ -0,0 +1,122 @@
#!/bin/sh /etc/rc.common
#
# Copyright (c) 2014, 2019 The Linux Foundation. All rights reserved.
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
# The shebang above has an extra space intentially to avoid having
# openwrt build scripts automatically enable this package starting
# at boot.
START=19
get_front_end_mode() {
config_load "ecm"
config_get front_end global acceleration_engine "nss"
case $front_end in
auto)
echo '0'
;;
nss)
echo '1'
;;
sfe)
echo '2'
;;
*)
echo 'uci_option_acceleration_engine is invalid'
esac
}
support_bridge() {
#NSS support bridge acceleration
[ -d /sys/kernel/debug/ecm/ecm_nss_ipv4 ] && return 0
#SFE doesn't support bridge acceleration
[ -d /sys/kernel/debug/ecm/ecm_sfe_ipv4 ] && return 1
}
load_sfe() {
[ -d /sys/module/shortcut_fe ] || insmod shortcut-fe
[ -d /sys/module/shortcut_fe_ipv6 ] || insmod shortcut-fe-ipv6
[ -d /sys/module/shortcut_fe_drv ] || insmod shortcut-fe-drv
}
load_ecm() {
[ -d /sys/module/ecm ] || {
insmod ecm front_end_selection=$(get_front_end_mode)
echo 1 > /sys/kernel/debug/ecm/ecm_classifier_default/accel_delay_pkts
}
support_bridge && {
sysctl -w net.bridge.bridge-nf-call-ip6tables=1
sysctl -w net.bridge.bridge-nf-call-iptables=1
}
}
unload_ecm() {
sysctl -w net.bridge.bridge-nf-call-ip6tables=0
sysctl -w net.bridge.bridge-nf-call-iptables=0
if [ -d /sys/module/ecm ]; then
#
# Stop ECM frontends
#
echo 1 > /sys/kernel/debug/ecm/front_end_ipv4_stop
echo 1 > /sys/kernel/debug/ecm/front_end_ipv6_stop
#
# Defunct the connections
#
echo 1 > /sys/kernel/debug/ecm/ecm_db/defunct_all
sleep 5;
rmmod ecm
sleep 1
fi
}
start() {
load_ecm
# If the acceleration engine is NSS, enable wifi redirect.
[ -d /sys/kernel/debug/ecm/ecm_nss_ipv4 ] && sysctl -w dev.nss.general.redirect=1
support_bridge && {
# Delete original configuration before appending new
sed '/net.bridge.bridge-nf-call-ip6tables/d' -i /etc/sysctl.d/qca-nss-ecm.conf
sed '/net.bridge.bridge-nf-call-iptables/d' -i /etc/sysctl.d/qca-nss-ecm.conf
echo 'net.bridge.bridge-nf-call-ip6tables=1' >> /etc/sysctl.d/qca-nss-ecm.conf
echo 'net.bridge.bridge-nf-call-iptables=1' >> /etc/sysctl.d/qca-nss-ecm.conf
}
if [ -d /sys/module/qca_ovsmgr ]; then
insmod ecm_ovs
fi
}
stop() {
# If the acceleration engine is NSS, disable wifi redirect.
[ -d /sys/kernel/debug/ecm/ecm_nss_ipv4 ] && sysctl -w dev.nss.general.redirect=0
sed '/net.bridge.bridge-nf-call-ip6tables=1/d' -i /etc/sysctl.d/qca-nss-ecm.conf
sed '/net.bridge.bridge-nf-call-iptables=1/d' -i /etc/sysctl.d/qca-nss-ecm.conf
if [ -d /sys/module/ecm_ovs ]; then
rmmod ecm_ovs
fi
unload_ecm
}

View File

@@ -0,0 +1,2 @@
# nf_conntrack_tcp_no_window_check is 0 by default, set it to 1
net.netfilter.nf_conntrack_tcp_no_window_check=1

View File

@@ -0,0 +1,2 @@
config ecm 'global'
option acceleration_engine 'auto'

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,51 @@
From 7d7289cbe10bac309db3cc792f2bb13b3befdc07 Mon Sep 17 00:00:00 2001
From: Amruth S <quic_amrus@quicinc.com>
Date: Tue, 5 Dec 2023 21:47:37 -0800
Subject: [PATCH] [qca-nss-ecm]: Fix_dev_put issue for 6.x kernel in ecm module
Explicitly hold netdev refs for 6.1 and above kernels. The API
doesn't hold it in these kernels.
Signed-off-by: Amruth S <quic_amrus@quicinc.com>
Change-Id: I54594dae664610e2a5703b71c1430e325d04aeaa
---
ecm_interface.c | 2 ++
frontends/ecm_front_end_common.c | 2 ++
2 files changed, 4 insertions(+)
--- a/ecm_interface.c
+++ b/ecm_interface.c
@@ -342,6 +342,7 @@ static struct net_device *ecm_interface_
dev = (struct net_device *)ipv6_dev_find(&init_net, &addr6, 1);
#else
dev = (struct net_device *)ipv6_dev_find(&init_net, &addr6, NULL);
+ dev_hold(dev);
#endif
return dev;
}
@@ -805,6 +806,7 @@ static bool ecm_interface_mac_addr_get_i
local_dev = ipv6_dev_find(&init_net, &daddr, 1);
#else
local_dev = ipv6_dev_find(&init_net, &daddr, NULL);
+ dev_hold(local_dev);
#endif
if (local_dev) {
DEBUG_TRACE("%pi6 is a local address\n", &daddr);
--- a/frontends/ecm_front_end_common.c
+++ b/frontends/ecm_front_end_common.c
@@ -611,6 +611,7 @@ bool ecm_front_end_gre_proto_is_accel_al
dev = ipv6_dev_find(&init_net, &(orig_tuple->src.u3.in6), 1);
#else
dev = ipv6_dev_find(&init_net, &(orig_tuple->src.u3.in6), NULL);
+ dev_hold(dev);
#endif
if (dev) {
/*
@@ -625,6 +626,7 @@ bool ecm_front_end_gre_proto_is_accel_al
dev = ipv6_dev_find(&init_net, &(orig_tuple->dst.u3.in6), 1);
#else
dev = ipv6_dev_find(&init_net, &(orig_tuple->dst.u3.in6), NULL);
+ dev_hold(dev);
#endif
if (dev) {
/*

View File

@@ -0,0 +1,178 @@
From 85d8656de0a22dc5b45a5f8810e5863726bd5a9b Mon Sep 17 00:00:00 2001
From: Swati Singh <quic_swasing@quicinc.com>
Date: Mon, 26 Jun 2023 16:33:51 +0530
Subject: [PATCH] [qca-nss-ecm]: Passing structure as params for sawf_hdl
query.
The wifi driver call to get sawf hdl info will have
struct ecm_classifier_sawf_flow_info as params.
Also, the wifi driver signature will be 32 bits to
return sawf_mark.
Change-Id: I5f49be2938887a8c0669e9b760e5fee24b8bd290
Signed-off-by: Swati Singh <quic_swasing@quicinc.com>
---
ecm_classifier_emesh.c | 41 +++++++++++++++++++++---
ecm_wifi_plugins/ecm_wifi_plugin_emesh.c | 19 ++++++++++-
exports/ecm_classifier_emesh_public.h | 22 +++++++++++--
3 files changed, 74 insertions(+), 8 deletions(-)
--- a/ecm_classifier_emesh.c
+++ b/ecm_classifier_emesh.c
@@ -91,6 +91,7 @@
#define ECM_CLASSIFIER_EMESH_SAWF_TAG_GET(sawf_meta) ((sawf_meta >> 24) & 0xFF)
#define ECM_CLASSIFIER_EMESH_SAWF_TAG_IS_VALID(sawf_meta) \
((ECM_CLASSIFIER_EMESH_SAWF_TAG_GET(sawf_meta) == ECM_CLASSIFIER_EMESH_SAWF_VALID_TAG) ? true : false)
+#define ECM_CLASSIFIER_EMESH_SAWF_VALID_MSDUQ_MASK 0xffff
/*
* EMESH classifier type.
@@ -244,6 +245,7 @@ static void ecm_classifier_emesh_sawf_fl
uint16_t msduq_reverse = ECM_CLASSIFIER_EMESH_SAWF_INVALID_MSDUQ;
uint8_t dmac[ETH_ALEN];
uint8_t smac[ETH_ALEN];
+ struct ecm_classifier_emesh_sawf_flow_info sawf_flow_info = {0};
if (msg->ip_version == 4) {
DEBUG_TRACE("%px: flow/return service_class_id=%u/%u %pI4n:%u -> %pI4n:%u protocol=%d\n", msg,
@@ -298,10 +300,25 @@ static void ecm_classifier_emesh_sawf_fl
*/
if (ecm_emesh.update_service_id_get_msduq) {
if (dest_dev) {
- msduq_forward = ecm_emesh.update_service_id_get_msduq(dest_dev, dmac, msg->flow_service_class_id, 0, 0, SP_SAWF_RULE_TYPE_DEFAULT);
+ sawf_flow_info.netdev = dest_dev;
+ sawf_flow_info.peer_mac = dmac;
+ sawf_flow_info.service_id = msg->flow_service_class_id;
+ sawf_flow_info.dscp = 0;
+ sawf_flow_info.rule_id = 0;
+ sawf_flow_info.sawf_rule_type = SP_SAWF_RULE_TYPE_DEFAULT;
+
+ msduq_forward = ecm_emesh.update_service_id_get_msduq(&sawf_flow_info) & ECM_CLASSIFIER_EMESH_SAWF_VALID_MSDUQ_MASK;
}
+
if (src_dev) {
- msduq_reverse = ecm_emesh.update_service_id_get_msduq(src_dev, smac, msg->return_service_class_id, 0, 0, SP_SAWF_RULE_TYPE_DEFAULT);
+ sawf_flow_info.netdev = src_dev;
+ sawf_flow_info.peer_mac = smac;
+ sawf_flow_info.service_id = msg->return_service_class_id;
+ sawf_flow_info.dscp = 0;
+ sawf_flow_info.rule_id = 0;
+ sawf_flow_info.sawf_rule_type = SP_SAWF_RULE_TYPE_DEFAULT;
+
+ msduq_reverse = ecm_emesh.update_service_id_get_msduq(&sawf_flow_info) & ECM_CLASSIFIER_EMESH_SAWF_VALID_MSDUQ_MASK;
}
}
@@ -1136,7 +1153,7 @@ static void ecm_classifier_emesh_sawf_pr
struct sp_rule_output_params flow_output_params;
struct sp_rule_output_params return_output_params;
bool is_sawf_relevant = false;
-
+ struct ecm_classifier_emesh_sawf_flow_info sawf_flow_info = {0};
cemi = (struct ecm_classifier_emesh_sawf_instance *)aci;
DEBUG_CHECK_MAGIC(cemi, ECM_CLASSIFIER_EMESH_INSTANCE_MAGIC, "%px: magic failed\n", cemi);
@@ -1290,7 +1307,14 @@ static void ecm_classifier_emesh_sawf_pr
*/
if (ecm_emesh.update_service_id_get_msduq) {
if (dest_dev) {
- msduq_forward = ecm_emesh.update_service_id_get_msduq(dest_dev, dmac, flow_output_params.service_class_id, cemi->dscp[ECM_CONN_DIR_FLOW], flow_output_params.rule_id, flow_output_params.sawf_rule_type);
+ sawf_flow_info.netdev = dest_dev;
+ sawf_flow_info.peer_mac = dmac;
+ sawf_flow_info.service_id = flow_output_params.service_class_id;
+ sawf_flow_info.dscp = cemi->dscp[ECM_CONN_DIR_FLOW];
+ sawf_flow_info.rule_id = flow_output_params.rule_id;
+ sawf_flow_info.sawf_rule_type = flow_output_params.sawf_rule_type;
+
+ msduq_forward = ecm_emesh.update_service_id_get_msduq(&sawf_flow_info) & ECM_CLASSIFIER_EMESH_SAWF_VALID_MSDUQ_MASK;
/*
* Mark the skb with SAWF meta data for flow creation packet.
@@ -1300,7 +1324,14 @@ static void ecm_classifier_emesh_sawf_pr
msduq_forward);
}
if (src_dev) {
- msduq_reverse = ecm_emesh.update_service_id_get_msduq(src_dev, smac, return_output_params.service_class_id, cemi->dscp[ECM_CONN_DIR_RETURN], return_output_params.rule_id, return_output_params.sawf_rule_type);
+ sawf_flow_info.netdev = src_dev;
+ sawf_flow_info.peer_mac = smac;
+ sawf_flow_info.service_id = return_output_params.service_class_id;
+ sawf_flow_info.dscp = cemi->dscp[ECM_CONN_DIR_RETURN];
+ sawf_flow_info.rule_id = return_output_params.rule_id;
+ sawf_flow_info.sawf_rule_type = return_output_params.sawf_rule_type;
+
+ msduq_reverse = ecm_emesh.update_service_id_get_msduq(&sawf_flow_info) & ECM_CLASSIFIER_EMESH_SAWF_VALID_MSDUQ_MASK;
}
}
--- a/ecm_wifi_plugins/ecm_wifi_plugin_emesh.c
+++ b/ecm_wifi_plugins/ecm_wifi_plugin_emesh.c
@@ -48,12 +48,29 @@ static inline void ecm_wifi_plugin_emesh
}
/*
+ * ecm_wifi_plugin_emesh_sawf_get_mark_data()
+ * get skb mark callback for EMESH-SAWF classifier.
+ */
+static inline uint32_t ecm_wifi_plugin_emesh_sawf_get_mark_data(struct ecm_classifier_emesh_sawf_flow_info *sawf_flow_info)
+{
+ struct qca_sawf_metadata_param sawf_params = {0};
+
+ sawf_params.netdev = sawf_flow_info->netdev;
+ sawf_params.peer_mac = sawf_flow_info->peer_mac;
+ sawf_params.service_id = sawf_flow_info->service_id;
+ sawf_params.dscp = sawf_flow_info->dscp;
+ sawf_params.rule_id = sawf_flow_info->rule_id;
+ sawf_params.sawf_rule_type = sawf_flow_info->sawf_rule_type;
+
+ return qca_sawf_get_mark_metadata(&sawf_params);
+}
+/*
* ecm_wifi_plugin_emesh
* Register EMESH client callback with ECM EMSH classifier to update peer mesh latency parameters.
*/
static struct ecm_classifier_emesh_sawf_callbacks ecm_wifi_plugin_emesh = {
.update_peer_mesh_latency_params = qca_mesh_latency_update_peer_parameter,
- .update_service_id_get_msduq = qca_sawf_get_msduq_v2,
+ .update_service_id_get_msduq = ecm_wifi_plugin_emesh_sawf_get_mark_data,
.sawf_conn_sync = ecm_wifi_plugin_emesh_sawf_conn_sync,
};
--- a/exports/ecm_classifier_emesh_public.h
+++ b/exports/ecm_classifier_emesh_public.h
@@ -61,6 +61,25 @@ struct ecm_classifier_fse_info {
};
/**
+ * ecm_classifier_emesh_sawf_flow_info
+ *
+ * @netdev : Netdevice
+ * @peer_mac : Destination peer mac address
+ * @service_id : Service class id
+ * @dscp : Differentiated Services Code Point
+ * @rule_id : Rule id
+ * @sawf_rule_type: Rule type
+ */
+struct ecm_classifier_emesh_sawf_flow_info {
+ struct net_device *netdev;
+ uint8_t *peer_mac;
+ uint32_t service_id;
+ uint32_t dscp;
+ uint32_t rule_id;
+ uint8_t sawf_rule_type;
+};
+
+/**
* Mesh latency configuration update callback function to which MSCS client will register.
*/
typedef int (*ecm_classifier_emesh_callback_t)(uint8_t dest_mac[],
@@ -71,8 +90,7 @@ typedef int (*ecm_classifier_emesh_callb
/**
* MSDUQ callback to which emesh-sawf will register.
*/
-typedef uint16_t (*ecm_classifier_emesh_msduq_callback_t)(struct net_device *out_dev,
- uint8_t dest_mac[], uint32_t service_class_id, uint32_t dscp, uint32_t rule_id, uint8_t sawf_rule_type);
+typedef uint32_t (*ecm_classifier_emesh_msduq_callback_t)(struct ecm_classifier_emesh_sawf_flow_info *sawf_flow_info);
/**
* SAWF params sync callback function pointer.

View File

@@ -0,0 +1,335 @@
From 12cdc396ed57835c2056f9d524e3661745ac7d57 Mon Sep 17 00:00:00 2001
From: Parikshit Gune <quic_pgune@quicinc.com>
Date: Fri, 28 Jul 2023 11:04:45 +0530
Subject: [PATCH] [qca-nss-ecm] ECM to wlan driver callback signature changes.
1. Signature change to pack the information into structures instead of
individual fields for EMESH, SCS, MSCS wlan callbacks.
2. Add src and dest net devices in the EMESH param sync callback.
Change-Id: Iafbde3f0bbe073a8720ab86371c344d4941158ec
Signed-off-by: Parikshit Gune <quic_pgune@quicinc.com>
---
ecm_classifier_emesh.c | 70 ++++++++++++++++++++----
ecm_classifier_mscs.c | 11 +++-
ecm_wifi_plugins/ecm_wifi_plugin_emesh.c | 23 +++++++-
ecm_wifi_plugins/ecm_wifi_plugin_mscs.c | 33 ++++++++++-
exports/ecm_classifier_emesh_public.h | 21 +++++--
exports/ecm_classifier_mscs_public.h | 26 ++++++++-
6 files changed, 161 insertions(+), 23 deletions(-)
--- a/ecm_classifier_emesh.c
+++ b/ecm_classifier_emesh.c
@@ -1747,7 +1747,10 @@ void ecm_classifier_emesh_sawf_params_sy
void ecm_classifier_emesh_sawf_update_latency_param_on_conn_decel(struct ecm_classifier_instance *aci, struct ecm_classifier_rule_sync *sync)
{
struct ecm_classifier_emesh_sawf_instance *cemi;
+ struct ecm_classifer_emesh_sawf_mesh_latency_params mesh_params = {0};
struct ecm_db_connection_instance *ci;
+ struct net_device *src_dev = NULL;
+ struct net_device *dest_dev = NULL;
uint8_t peer_mac[ETH_ALEN];
cemi = (struct ecm_classifier_emesh_sawf_instance *)aci;
@@ -1775,21 +1778,40 @@ void ecm_classifier_emesh_sawf_update_la
return;
}
+ ecm_db_netdevs_get_and_hold(ci, ECM_TRACKER_SENDER_TYPE_SRC, &src_dev, &dest_dev);
+
/*
* Get mac address for destination node
*/
ecm_db_connection_node_address_get(ci, ECM_DB_OBJ_DIR_TO, peer_mac);
- ecm_emesh.update_peer_mesh_latency_params(peer_mac,
- cemi->service_interval_dl, cemi->burst_size_dl, cemi->service_interval_ul, cemi->burst_size_ul,
- cemi->pcp[ECM_CONN_DIR_FLOW], ECM_CLASSIFIER_EMESH_SUB_LATENCY_PARAMS);
+
+ mesh_params.peer_mac = peer_mac;
+ mesh_params.dst_dev = dest_dev;
+ mesh_params.src_dev = src_dev;
+ mesh_params.service_interval_dl = cemi->service_interval_dl;
+ mesh_params.service_interval_ul = cemi->service_interval_ul;
+ mesh_params.burst_size_dl = cemi->burst_size_dl;
+ mesh_params.burst_size_ul = cemi->burst_size_ul;
+ mesh_params.priority = cemi->pcp[ECM_CONN_DIR_FLOW];
+ mesh_params.accel_or_decel = ECM_CLASSIFIER_EMESH_SUB_LATENCY_PARAMS;
+
+ ecm_emesh.update_peer_mesh_latency_params(&mesh_params);
/*
* Get mac address for source node
*/
ecm_db_connection_node_address_get(ci, ECM_DB_OBJ_DIR_FROM, peer_mac);
- ecm_emesh.update_peer_mesh_latency_params(peer_mac,
- cemi->service_interval_dl, cemi->burst_size_dl, cemi->service_interval_ul, cemi->burst_size_ul,
- cemi->pcp[ECM_CONN_DIR_FLOW], ECM_CLASSIFIER_EMESH_SUB_LATENCY_PARAMS);
+
+ mesh_params.peer_mac = peer_mac;
+ mesh_params.dst_dev = src_dev;
+ mesh_params.src_dev = dest_dev;
+ ecm_emesh.update_peer_mesh_latency_params(&mesh_params);
+
+ if (src_dev)
+ dev_put(src_dev);
+
+ if (dest_dev)
+ dev_put(dest_dev);
ecm_db_connection_deref(ci);
}
@@ -1895,6 +1917,8 @@ static void ecm_classifier_emesh_sawf_up
uint8_t service_interval_ul;
uint32_t burst_size_ul;
struct sk_buff *skb;
+ struct net_device *src_dev, *dest_dev = NULL;
+ struct ecm_classifer_emesh_sawf_mesh_latency_params mesh_params = {0};
uint8_t dmac[ETH_ALEN];
uint8_t smac[ETH_ALEN];
@@ -1933,6 +1957,8 @@ static void ecm_classifier_emesh_sawf_up
return;
}
+ ecm_db_netdevs_get_and_hold(ci, ECM_TRACKER_SENDER_TYPE_SRC, &src_dev, &dest_dev);
+
/*
* Invoke SPM rule lookup API to update skb priority
* When latency config is enabled, fetch latency parameter
@@ -1966,9 +1992,16 @@ static void ecm_classifier_emesh_sawf_up
/*
* Send destination mac address of this connection
*/
- ecm_emesh.update_peer_mesh_latency_params(dmac,
- service_interval_dl, burst_size_dl, service_interval_ul, burst_size_ul,
- skb->priority, ECM_CLASSIFIER_EMESH_ADD_LATENCY_PARAMS);
+ mesh_params.dst_dev = dest_dev;
+ mesh_params.src_dev = src_dev;
+ mesh_params.peer_mac = dmac;
+ mesh_params.service_interval_dl = service_interval_dl;
+ mesh_params.service_interval_ul = service_interval_ul;
+ mesh_params.burst_size_dl = burst_size_dl;
+ mesh_params.burst_size_ul = burst_size_ul;
+ mesh_params.priority = skb->priority;
+ mesh_params.accel_or_decel = ECM_CLASSIFIER_EMESH_ADD_LATENCY_PARAMS;
+ ecm_emesh.update_peer_mesh_latency_params(&mesh_params);
}
/*
@@ -1981,11 +2014,24 @@ static void ecm_classifier_emesh_sawf_up
/*
* Send source mac address of this connection
*/
- ecm_emesh.update_peer_mesh_latency_params(smac,
- service_interval_dl, burst_size_dl, service_interval_ul, burst_size_ul,
- skb->priority, ECM_CLASSIFIER_EMESH_ADD_LATENCY_PARAMS);
+ mesh_params.peer_mac = smac;
+ mesh_params.dst_dev = src_dev;
+ mesh_params.src_dev = dest_dev;
+ mesh_params.service_interval_dl = service_interval_dl;
+ mesh_params.service_interval_ul = service_interval_ul;
+ mesh_params.burst_size_dl = burst_size_dl;
+ mesh_params.burst_size_ul = burst_size_ul;
+ mesh_params.priority = skb->priority;
+ mesh_params.accel_or_decel = ECM_CLASSIFIER_EMESH_ADD_LATENCY_PARAMS;
+ ecm_emesh.update_peer_mesh_latency_params(&mesh_params);
}
+ if (src_dev)
+ dev_put(src_dev);
+
+ if (dest_dev)
+ dev_put(dest_dev);
+
ecm_db_connection_deref(ci);
}
--- a/ecm_classifier_mscs.c
+++ b/ecm_classifier_mscs.c
@@ -425,6 +425,8 @@ static void ecm_classifier_mscs_process(
#ifdef ECM_CLASSIFIER_MSCS_SCS_ENABLE
struct sp_rule_input_params flow_input_params;
struct sp_rule_output_params flow_output_params;
+ struct ecm_classifier_mscs_get_priority_info get_priority_info = {0};
+ struct ecm_classifier_mscs_rule_match_info rule_match_info = {0};
ecm_classifier_mscs_scs_priority_callback_t scs_cb = NULL;
#endif
#ifdef ECM_MULTICAST_ENABLE
@@ -545,7 +547,9 @@ static void ecm_classifier_mscs_process(
goto check_mscs_classifier;
}
- result = scs_cb(flow_output_params.rule_id, dmac);
+ rule_match_info.rule_id = flow_output_params.rule_id;
+ rule_match_info.dst_mac = dmac;
+ result = scs_cb(&rule_match_info);
}
}
@@ -617,7 +621,10 @@ static void ecm_classifier_mscs_process(
/*
* Invoke callback registered to classifier for peer look up
*/
- result = cb(smac, dmac, skb);
+ get_priority_info.src_mac = smac;
+ get_priority_info.dst_mac = dmac;
+ get_priority_info.skb = skb;
+ result = cb(&get_priority_info);
if (result == ECM_CLASSIFIER_MSCS_RESULT_UPDATE_PRIORITY) {
cmscsi->mscs_priority_update = true;
--- a/ecm_wifi_plugins/ecm_wifi_plugin_emesh.c
+++ b/ecm_wifi_plugins/ecm_wifi_plugin_emesh.c
@@ -26,6 +26,27 @@
#include "ecm_wifi_plugin.h"
/*
+ * ecm_wifi_plugin_emesh_sawf_update_peer_mesh_params()
+ * Update mesh latency params.
+ */
+static inline void ecm_wifi_plugin_emesh_sawf_update_peer_mesh_params(struct ecm_classifer_emesh_sawf_mesh_latency_params *mesh_params)
+{
+ struct qca_mesh_latency_update_peer_param wlan_mesh_params = {0};
+
+ wlan_mesh_params.dest_mac = mesh_params->peer_mac;
+ wlan_mesh_params.src_dev = mesh_params->src_dev;
+ wlan_mesh_params.dst_dev = mesh_params->dst_dev;
+ wlan_mesh_params.service_interval_dl = mesh_params->service_interval_dl;
+ wlan_mesh_params.service_interval_ul = mesh_params->service_interval_ul;
+ wlan_mesh_params.burst_size_dl = mesh_params->burst_size_dl;
+ wlan_mesh_params.burst_size_ul = mesh_params->burst_size_ul;
+ wlan_mesh_params.priority = mesh_params->priority;
+ wlan_mesh_params.add_or_sub = mesh_params->accel_or_decel;
+
+ qca_mesh_latency_update_peer_parameter_v2(&wlan_mesh_params);
+}
+
+/*
* ecm_wifi_plugin_emesh_sawf_conn_sync()
* Connection sync callback for EMESH-SAWF classifier.
*/
@@ -69,7 +90,7 @@ static inline uint32_t ecm_wifi_plugin_e
* Register EMESH client callback with ECM EMSH classifier to update peer mesh latency parameters.
*/
static struct ecm_classifier_emesh_sawf_callbacks ecm_wifi_plugin_emesh = {
- .update_peer_mesh_latency_params = qca_mesh_latency_update_peer_parameter,
+ .update_peer_mesh_latency_params = ecm_wifi_plugin_emesh_sawf_update_peer_mesh_params,
.update_service_id_get_msduq = ecm_wifi_plugin_emesh_sawf_get_mark_data,
.sawf_conn_sync = ecm_wifi_plugin_emesh_sawf_conn_sync,
};
--- a/ecm_wifi_plugins/ecm_wifi_plugin_mscs.c
+++ b/ecm_wifi_plugins/ecm_wifi_plugin_mscs.c
@@ -26,13 +26,42 @@
#include "ecm_wifi_plugin.h"
/*
+ * ecm_wifi_plugin_get_peer_priority()
+ * Get peer priority callback into wlan driver.
+ */
+static inline int ecm_wifi_plugin_get_peer_priority(struct ecm_classifier_mscs_get_priority_info *get_priority_info)
+{
+ struct qca_mscs_get_priority_param wlan_get_priority_param = {0};
+
+ wlan_get_priority_param.dst_mac = get_priority_info->dst_mac;
+ wlan_get_priority_param.src_mac = get_priority_info->src_mac;
+ wlan_get_priority_param.skb = get_priority_info->skb;
+
+ return qca_mscs_peer_lookup_n_get_priority_v2(&wlan_get_priority_param);
+}
+
+/*
+ * ecm_wifi_plugin_update_skb_priority()
+ * Update skb priority callback into wlan driver.
+ */
+static inline bool ecm_wifi_plugin_update_skb_priority(struct ecm_classifier_mscs_rule_match_info *match_info)
+{
+ struct qca_scs_peer_lookup_n_rule_match rule_match_param = {0};
+
+ rule_match_param.dst_mac_addr = match_info->dst_mac;
+ rule_match_param.rule_id = match_info->rule_id;
+
+ return qca_scs_peer_lookup_n_rule_match_v2(&rule_match_param);
+}
+
+/*
* ecm_wifi_plugin
* Register MSCS client callback with ECM MSCS classifier to support MSCS wifi peer lookup.
*/
static struct ecm_classifier_mscs_callbacks ecm_wifi_plugin_mscs = {
- .get_peer_priority = qca_mscs_peer_lookup_n_get_priority,
+ .get_peer_priority = ecm_wifi_plugin_get_peer_priority,
#ifdef ECM_CLASSIFIER_MSCS_SCS_ENABLE
- .update_skb_priority = qca_scs_peer_lookup_n_rule_match,
+ .update_skb_priority = ecm_wifi_plugin_update_skb_priority,
#endif
};
--- a/exports/ecm_classifier_emesh_public.h
+++ b/exports/ecm_classifier_emesh_public.h
@@ -80,12 +80,25 @@ struct ecm_classifier_emesh_sawf_flow_in
};
/**
+ * Structure collecting mesh latency params to send it to wlan driver
+ * via registered callback.
+ */
+struct ecm_classifer_emesh_sawf_mesh_latency_params {
+ struct net_device *dst_dev; /**< Destination net dev. */
+ struct net_device *src_dev; /**< Source net dev. */
+ uint8_t *peer_mac; /**< Peer MAC. */
+ uint32_t service_interval_dl; /**< Service interval DL. */
+ uint32_t burst_size_dl; /**< Burst size DL. */
+ uint32_t service_interval_ul; /**< Service interval UL. */
+ uint32_t burst_size_ul; /**< Burst size UL. */
+ uint16_t priority; /**< Priority. */
+ uint8_t accel_or_decel; /**< Time of the callback. */
+};
+
+/**
* Mesh latency configuration update callback function to which MSCS client will register.
*/
-typedef int (*ecm_classifier_emesh_callback_t)(uint8_t dest_mac[],
- uint32_t service_interval_dl, uint32_t burst_size_dl,
- uint32_t service_interval_ul, uint32_t burst_size_ul,
- uint16_t priority, uint8_t add_or_sub);
+typedef void (*ecm_classifier_emesh_callback_t)(struct ecm_classifer_emesh_sawf_mesh_latency_params *mesh_params);
/**
* MSDUQ callback to which emesh-sawf will register.
--- a/exports/ecm_classifier_mscs_public.h
+++ b/exports/ecm_classifier_mscs_public.h
@@ -43,10 +43,32 @@ enum ecm_classifier_mscs_results {
typedef enum /** @cond */ ecm_classifier_mscs_results /** @endcond */ ecm_classifier_mscs_result_t;
/**
+ * Structure containing params to get MSCS priority.
+ */
+struct ecm_classifier_mscs_get_priority_info {
+ struct net_device *dst_dev; /**< Destination net dev. */
+ struct net_device *src_dev; /**< Source net dev. */
+ uint8_t *src_mac; /**< Source MAC address. */
+ uint8_t *dst_mac; /**< Destination MAC address. */
+ struct sk_buff *skb; /**< SKB pointer. */
+};
+
+/**
+ * Structure containing params for SCS rule match info.
+ */
+struct ecm_classifier_mscs_rule_match_info {
+ struct net_device *dst_dev; /**< Destination net dev. */
+ struct net_device *src_dev; /**< Source net dev. */
+ uint8_t *src_mac; /**< Source MAC. */
+ uint8_t *dst_mac; /**< Destination MAC. */
+ uint32_t rule_id; /**< Rule ID. */
+};
+
+/**
* Callback to which MSCS clients will register.
*/
-typedef int (*ecm_classifier_mscs_process_callback_t)(uint8_t src_mac[], uint8_t dst_mac[], struct sk_buff* skb);
-typedef bool (*ecm_classifier_mscs_scs_priority_callback_t)(uint32_t rule_id, uint8_t *dst_mac_addr);
+typedef int (*ecm_classifier_mscs_process_callback_t)(struct ecm_classifier_mscs_get_priority_info *priority_info);
+typedef bool (*ecm_classifier_mscs_scs_priority_callback_t)(struct ecm_classifier_mscs_rule_match_info *rule_match_info);
/**
* Data structure for MSCS classifier callbacks.

View File

@@ -0,0 +1,84 @@
From 5a87f3b9acb7a85958ef220a8f83c3cf24bfba4d Mon Sep 17 00:00:00 2001
From: Parikshit Gune <quic_pgune@quicinc.com>
Date: Wed, 2 Aug 2023 10:28:53 +0530
Subject: [PATCH] [qca-nss-ecm] Adding src and dest dev in MSCS and SCS
callbacks.
Change-Id: Ia3a097606efb875fbe459fe4cbdfc851d0fa24ec
Signed-off-by: Parikshit Gune <quic_pgune@quicinc.com>
---
ecm_classifier_mscs.c | 14 ++++++++++++++
ecm_wifi_plugins/ecm_wifi_plugin_mscs.c | 4 ++++
2 files changed, 18 insertions(+)
--- a/ecm_classifier_mscs.c
+++ b/ecm_classifier_mscs.c
@@ -421,6 +421,8 @@ static void ecm_classifier_mscs_process(
uint8_t dmac[ETH_ALEN];
bool mscs_rule_match = false;
bool scs_rule_match = false;
+ struct net_device *src_dev = NULL;
+ struct net_device *dest_dev = NULL;
uint64_t slow_pkts;
#ifdef ECM_CLASSIFIER_MSCS_SCS_ENABLE
struct sp_rule_input_params flow_input_params;
@@ -507,6 +509,8 @@ static void ecm_classifier_mscs_process(
ecm_db_connection_node_address_get(ci, ECM_DB_OBJ_DIR_FROM, dmac);
}
+ ecm_db_netdevs_get_and_hold(ci, sender, &src_dev, &dest_dev);
+
/*
* Set the invalid SCS rule id, in case if we do not find any SCS rule.
*/
@@ -549,6 +553,8 @@ static void ecm_classifier_mscs_process(
rule_match_info.rule_id = flow_output_params.rule_id;
rule_match_info.dst_mac = dmac;
+ rule_match_info.src_dev = src_dev;
+ rule_match_info.dst_dev = dest_dev;
result = scs_cb(&rule_match_info);
}
}
@@ -623,6 +629,8 @@ static void ecm_classifier_mscs_process(
*/
get_priority_info.src_mac = smac;
get_priority_info.dst_mac = dmac;
+ get_priority_info.src_dev = src_dev;
+ get_priority_info.dst_dev = dest_dev;
get_priority_info.skb = skb;
result = cb(&get_priority_info);
@@ -713,6 +721,12 @@ mscs_classifier_out:
/*
* Return our process response
*/
+ if(src_dev)
+ dev_put(src_dev);
+
+ if(dest_dev)
+ dev_put(dest_dev);
+
*process_response = cmscsi->process_response;
spin_unlock_bh(&ecm_classifier_mscs_lock);
}
--- a/ecm_wifi_plugins/ecm_wifi_plugin_mscs.c
+++ b/ecm_wifi_plugins/ecm_wifi_plugin_mscs.c
@@ -35,6 +35,8 @@ static inline int ecm_wifi_plugin_get_pe
wlan_get_priority_param.dst_mac = get_priority_info->dst_mac;
wlan_get_priority_param.src_mac = get_priority_info->src_mac;
+ wlan_get_priority_param.src_dev = get_priority_info->src_dev;
+ wlan_get_priority_param.dst_dev = get_priority_info->dst_dev;
wlan_get_priority_param.skb = get_priority_info->skb;
return qca_mscs_peer_lookup_n_get_priority_v2(&wlan_get_priority_param);
@@ -50,6 +52,8 @@ static inline bool ecm_wifi_plugin_updat
rule_match_param.dst_mac_addr = match_info->dst_mac;
rule_match_param.rule_id = match_info->rule_id;
+ rule_match_param.src_dev = match_info->src_dev;
+ rule_match_param.dst_dev = match_info->dst_dev;
return qca_scs_peer_lookup_n_rule_match_v2(&rule_match_param);
}

View File

@@ -0,0 +1,212 @@
From 8cfad2eeed8d410f3f9943c535fad002b0b74073 Mon Sep 17 00:00:00 2001
From: Amitesh Anand <quic_amitesh@quicinc.com>
Date: Sat, 23 Dec 2023 23:29:45 +0530
Subject: [PATCH] [qca-nss-ecm] Fixes for kernel 6.6
1) Fix mscs classifier to avoid setting bool values to enum
variables.
2) Change sysctl registration from register_sysctl_table() to
register_sysctl and avoid deprecated method.
3) Kernel v6.6 removed dev->miniq_ingress. Use dev->tcx_ingress
field selectively for v6.6.
Change-Id: I9250a3082811df1917fdfa1fb1e398125871b811
Signed-off-by: Amitesh Anand <quic_amitesh@quicinc.com>
---
ecm_classifier_mscs.c | 14 +++++++------
ecm_interface.c | 22 ++------------------
frontends/ecm_front_end_common.c | 35 ++++++++++++++------------------
3 files changed, 25 insertions(+), 46 deletions(-)
--- a/ecm_classifier_mscs.c
+++ b/ecm_classifier_mscs.c
@@ -1,7 +1,7 @@
/*
**************************************************************************
* Copyright (c) 2020-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -416,7 +416,7 @@ static void ecm_classifier_mscs_process(
int protocol;
uint32_t became_relevant = 0;
ecm_classifier_mscs_process_callback_t cb = NULL;
- ecm_classifier_mscs_result_t result = 0;
+ bool scs_result = false;
uint8_t smac[ETH_ALEN];
uint8_t dmac[ETH_ALEN];
bool mscs_rule_match = false;
@@ -538,7 +538,8 @@ static void ecm_classifier_mscs_process(
/*
* Set result true for Multi AP mode.
*/
- result = true;
+ scs_result = true;
+
/*
* Invoke the WiFi datapath callback registered with MSCS client to check
* if SCS priority is valid for WiFi peer corresponding to
@@ -555,7 +556,7 @@ static void ecm_classifier_mscs_process(
rule_match_info.dst_mac = dmac;
rule_match_info.src_dev = src_dev;
rule_match_info.dst_dev = dest_dev;
- result = scs_cb(&rule_match_info);
+ scs_result = scs_cb(&rule_match_info);
}
}
@@ -563,7 +564,7 @@ static void ecm_classifier_mscs_process(
* Check the result of the callback. If we have a valid priority and peer is SCS
* capable, we set the priority (we do not check MSCS as SCS have higher precedence).
*/
- if (result) {
+ if (scs_result) {
/*
* Update skb priority.
*/
@@ -606,13 +607,14 @@ static void ecm_classifier_mscs_process(
* Check MSCS classifer.
*/
if (ecm_classifier_mscs_enabled) {
- result = false;
/*
* Check if MSCS multi AP mode is enabled or not -
* If yes, we need to query SPM database for rule match.
* Else legacy MSCS should work for single AP mode.
*/
if (!ecm_classifier_mscs_scs_multi_ap_enabled) {
+ ecm_classifier_mscs_result_t result;
+
/*
* Get the WiFi datapath callback registered with MSCS client to check
* if MSCS QoS tag is valid for WiFi peer corresponding to
--- a/ecm_interface.c
+++ b/ecm_interface.c
@@ -1,7 +1,7 @@
/*
**************************************************************************
* Copyright (c) 2014-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -8306,24 +8306,6 @@ static struct ctl_table ecm_interface_ta
{ }
};
-static struct ctl_table ecm_interface_root_dir[] = {
- {
- .procname = "ecm",
- .mode = 0555,
- .child = ecm_interface_table,
- },
- { }
-};
-
-static struct ctl_table ecm_interface_root[] = {
- {
- .procname = "net",
- .mode = 0555,
- .child = ecm_interface_root_dir,
- },
- { }
-};
-
#ifdef ECM_INTERFACE_IPSEC_GLUE_LAYER_SUPPORT_ENABLE
/*
* ecm_interface_ipsec_register_callbacks()
@@ -8820,7 +8802,7 @@ int ecm_interface_init(void)
/*
* Register sysctl table.
*/
- ecm_interface_ctl_table_header = register_sysctl_table(ecm_interface_root);
+ ecm_interface_ctl_table_header = register_sysctl("net/ecm", ecm_interface_table);
result = register_netdevice_notifier(&ecm_interface_netdev_notifier);
if (result != 0) {
--- a/frontends/ecm_front_end_common.c
+++ b/frontends/ecm_front_end_common.c
@@ -1,7 +1,7 @@
/*
**************************************************************************
* Copyright (c) 2015, 2016, 2020-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -35,6 +35,9 @@
#include <net/addrconf.h>
#include <net/gre.h>
#include <net/xfrm.h>
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 6, 0))
+#include <net/tcx.h>
+#endif
#include <linux/hashtable.h>
#include <net/sch_generic.h>
#ifdef ECM_FRONT_END_PPE_ENABLE
@@ -1157,24 +1160,6 @@ static struct ctl_table ecm_front_end_sy
{}
};
-static struct ctl_table ecm_front_end_common_root[] = {
- {
- .procname = "ecm",
- .mode = 0555,
- .child = ecm_front_end_sysctl_tbl,
- },
- { }
-};
-
-static struct ctl_table ecm_front_end_common_root_dir[] = {
- {
- .procname = "net",
- .mode = 0555,
- .child = ecm_front_end_common_root,
- },
- { }
-};
-
/*
* ecm_front_end_common_sysctl_register()
* Function to register sysctl node during front end init
@@ -1184,7 +1169,7 @@ void ecm_front_end_common_sysctl_registe
/*
* Register sysctl table.
*/
- ecm_front_end_ctl_tbl_hdr = register_sysctl_table(ecm_front_end_common_root_dir);
+ ecm_front_end_ctl_tbl_hdr = register_sysctl("net/ecm", ecm_front_end_sysctl_tbl);
#ifdef ECM_FRONT_END_SFE_ENABLE
if (ecm_front_end_ctl_tbl_hdr) {
ecm_sfe_sysctl_tbl_init();
@@ -1704,7 +1689,12 @@ bool ecm_front_end_common_intf_ingress_q
}
BUG_ON(!rcu_read_lock_bh_held());
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0))
miniq = rcu_dereference_bh(dev->miniq_ingress);
+#else
+ struct bpf_mprog_entry *entry = rcu_dereference_bh(dev->tcx_ingress);
+ miniq = entry ? tcx_entry(entry)->miniq : NULL;
+#endif
if (miniq) {
DEBUG_INFO("Ingress Qdisc is present for device[%s]\n", dev->name);
dev_put(dev);
@@ -1759,7 +1749,12 @@ bool ecm_front_end_common_intf_qdisc_che
}
#if defined(CONFIG_NET_CLS_ACT) && defined(CONFIG_NET_EGRESS)
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0))
miniq = rcu_dereference_bh(dev->miniq_egress);
+#else
+ struct bpf_mprog_entry *entry = rcu_dereference_bh(dev->tcx_egress);
+ miniq = entry ? tcx_entry(entry)->miniq : NULL;
+#endif
if (miniq) {
DEBUG_INFO("Egress needed\n");
dev_put(dev);

View File

@@ -0,0 +1,51 @@
# NHSS.QSDK.12.1.r5_CS1
# by SqTER
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=qca-nss-gmac
PKG_RELEASE:=1
PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/nss-gmac.git
PKG_SOURCE_PROTO:=git
PKG_SOURCE_DATE:=2023-06-01
PKG_SOURCE_VERSION:=171767947467662f2407d0cfff26dfb136c3fb4a
PKG_MIRROR_HASH:=3c59139b20bc607f71e8a20e14ea63e6520b2f321347cfa7b3532c15120c9947
include $(INCLUDE_DIR)/package.mk
define KernelPackage/qca-nss-gmac
SECTION:=kernel
CATEGORY:=Kernel modules
SUBMENU:=Network Devices
DEPENDS:=@TARGET_ipq806x||TARGET_ipq_ipq806x
TITLE:=Kernel driver for NSS gmac
FILES:=$(PKG_BUILD_DIR)/ipq806x/qca-nss-gmac.ko
AUTOLOAD:=$(call AutoLoad,31,qca-nss-gmac,1)
endef
define KernelPackage/qca-nss-gmac/Description
This package contains a NSS driver for QCA chipset
endef
define Build/InstallDev
mkdir -p $(1)/usr/include/qca-nss-gmac
$(CP) $(PKG_BUILD_DIR)/ipq806x/exports/* $(1)/usr/include/qca-nss-gmac/
endef
EXTRA_CFLAGS+= \
-DCONFIG_NSS_DEBUG_LEVEL=0 \
-I$(PKG_BUILD_DIR)/nss_hal/include \
-I$(PKG_BUILD_DIR)/nss_hal/$(BOARD)
define Build/Compile
$(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" \
$(KERNEL_MAKE_FLAGS) \
$(PKG_MAKE_FLAGS) \
M="$(PKG_BUILD_DIR)" \
EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \
modules
endef
$(eval $(call KernelPackage,qca-nss-gmac))

View File

@@ -0,0 +1,11 @@
--- a/ipq806x/nss_gmac_ctrl.c
+++ b/ipq806x/nss_gmac_ctrl.c
@@ -1024,7 +1024,7 @@ static int32_t nss_gmac_of_get_pdata(str
gmaccfg->phy_mii_type = of_get_phy_mode(np);
netdev->irq = irq_of_parse_and_map(np, 0);
- if (netdev->irq == NO_IRQ) {
+ if (netdev->irq <= 0) {
pr_err("%s: Can't map interrupt\n", np->name);
return -EFAULT;
}

View File

@@ -0,0 +1,345 @@
--- a/ipq806x/nss_gmac_ctrl.c
+++ b/ipq806x/nss_gmac_ctrl.c
@@ -322,16 +322,15 @@ void nss_gmac_tx_rx_desc_init(struct nss
* (for example "ifconfig eth0").
* @param[in] pointer to net_device structure.
* @param[in] pointer to net_device_stats64 structure.
- * @return Returns pointer to net_device_stats64 structure.
*/
-struct rtnl_link_stats64 *nss_gmac_get_stats64(struct net_device *netdev,
+void nss_gmac_get_stats64(struct net_device *netdev,
struct rtnl_link_stats64 *stats)
{
struct nss_gmac_dev *gmacdev = (struct nss_gmac_dev *)netdev_priv(netdev);
BUG_ON(gmacdev == NULL);
if (!gmacdev->data_plane_ops)
- return stats;
+ return;
spin_lock_bh(&gmacdev->stats_lock);
gmacdev->data_plane_ops->get_stats(gmacdev->data_plane_ctx, &gmacdev->nss_stats);
@@ -354,8 +353,6 @@ struct rtnl_link_stats64 *nss_gmac_get_s
stats->tx_fifo_errors = gmacdev->nss_stats.tx_underflow_errors;
stats->tx_window_errors = gmacdev->nss_stats.tx_late_collision_errors;
spin_unlock_bh(&gmacdev->stats_lock);
-
- return stats;
}
@@ -439,7 +436,7 @@ static int nss_gmac_mtnp_show(struct dev
static int nss_gmac_tstamp_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct nss_gmac_dev *gmacdev = (struct nss_gmac_dev *)netdev_priv(to_net_dev(dev));
- struct timeval tv;
+ struct timespec64 ts64;
uint32_t ret, timeout;
uint32_t ts_hi, ts_lo;
@@ -459,11 +456,12 @@ static int nss_gmac_tstamp_show(struct d
return -1;
}
- do_gettimeofday(&tv);
+ ktime_get_real_ts64(&ts64);
ret = snprintf(
buf, PAGE_SIZE,
- "sec:%u nsec:%u time-of-day: %12d.%06d \n", ts_hi, ts_lo, (int)tv.tv_sec, (int)tv.tv_usec);
+ "sec:%u nsec:%u time-of-day: %12d.%06d \n", \
+ ts_hi, ts_lo, (int)ts64.tv_sec, (int)(ts64.tv_nsec / NSEC_PER_USEC));
return ret;
}
@@ -761,6 +759,7 @@ static uint32_t nss_gmac_tstamp_ioctl(st
{
struct hwtstamp_config cfg;
struct nss_gmac_dev *gmacdev = (struct nss_gmac_dev *)netdev_priv(netdev);
+ int ret = -EINVAL;
/*
* Return if NSS FW is not up
@@ -769,9 +768,11 @@ static uint32_t nss_gmac_tstamp_ioctl(st
netdev_dbg(netdev, "%s: NSS Firmware is not up. Cannot enable Timestamping \n", __func__);
return -EINVAL;
}
-
- copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg));
-
+ ret = copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg));
+ if (ret) {
+ netdev_err(netdev, "%s: Unable to copy NSS Firmware into memory \n", __func__);
+ return -EINVAL;
+ }
/*
* Enable Timestamping if not already enabled
*/
@@ -951,7 +952,7 @@ static const struct net_device_ops nss_g
* @param[in] pointer to advertised features
* @return void
*/
-static void nss_gmac_update_features(uint32_t *supp, uint32_t *adv)
+static void nss_gmac_update_features(long unsigned int *supp, long unsigned int *adv)
{
*supp |= NSS_GMAC_SUPPORTED_FEATURES;
*adv |= NSS_GMAC_ADVERTISED_FEATURES;
@@ -1100,7 +1101,7 @@ static int32_t nss_gmac_do_common_init(s
ctx.msm_clk_ctl_enabled = true;
#endif
- ctx.nss_base = (uint8_t *)ioremap_nocache(res_nss_base.start,
+ ctx.nss_base = (uint8_t *)ioremap(res_nss_base.start,
resource_size(&res_nss_base));
if (!ctx.nss_base) {
pr_info("Error mapping NSS GMAC registers\n");
@@ -1109,7 +1110,7 @@ static int32_t nss_gmac_do_common_init(s
}
pr_debug("%s: NSS base ioremap OK.\n", __func__);
- ctx.qsgmii_base = (uint32_t *)ioremap_nocache(res_qsgmii_base.start,
+ ctx.qsgmii_base = (uint32_t *)ioremap(res_qsgmii_base.start,
resource_size(&res_qsgmii_base));
if (!ctx.qsgmii_base) {
pr_info("Error mapping QSGMII registers\n");
@@ -1119,7 +1120,7 @@ static int32_t nss_gmac_do_common_init(s
pr_debug("%s: QSGMII base ioremap OK, vaddr = 0x%p\n",
__func__, ctx.qsgmii_base);
- ctx.clk_ctl_base = (uint32_t *)ioremap_nocache(res_clk_ctl_base.start,
+ ctx.clk_ctl_base = (uint32_t *)ioremap(res_clk_ctl_base.start,
resource_size(&res_clk_ctl_base));
if (!ctx.clk_ctl_base) {
pr_info("Error mapping Clk control registers\n");
@@ -1409,8 +1410,8 @@ static int32_t nss_gmac_probe(struct pla
goto nss_gmac_phy_attach_fail;
}
- nss_gmac_update_features(&(gmacdev->phydev->supported),
- &(gmacdev->phydev->advertising));
+ nss_gmac_update_features(gmacdev->phydev->supported,
+ gmacdev->phydev->advertising);
gmacdev->phydev->irq = PHY_POLL;
netdev_dbg(netdev, "PHY %s attach OK\n", phy_id);
@@ -1440,6 +1441,8 @@ static int32_t nss_gmac_probe(struct pla
netdev_dbg(netdev, "%s MII_PHYSID2 - 0x%04x\n", netdev->name,
nss_gmac_mii_rd_reg(gmacdev, gmacdev->phy_base, MII_PHYSID2));
} else if (gmacdev->phy_base != NSS_GMAC_NO_MDIO_PHY) {
+ SET_NETDEV_DEV(netdev, gmacdev->miibus->parent);
+
/*
* Issue a phy_attach for the interface connected to a switch
*/
--- a/ipq806x/nss_gmac_ethtool.c
+++ b/ipq806x/nss_gmac_ethtool.c
@@ -143,7 +143,8 @@ static const struct nss_gmac_ethtool_sta
/**
* @brief Array of strings describing private flag names
*/
-static const char *gmac_strings_priv_flags[] = {
+
+static const char gmac_strings_priv_flags[][ETH_GSTRING_LEN] = {
"linkpoll",
"tstamp",
"ignore_rx_csum_err",
@@ -290,6 +291,7 @@ static int nss_gmac_set_pauseparam(struc
{
struct nss_gmac_dev *gmacdev = (struct nss_gmac_dev *)netdev_priv(netdev);
struct phy_device *phydev;
+ long unsigned int *advertising;
BUG_ON(gmacdev == NULL);
BUG_ON(gmacdev->netdev != netdev);
@@ -325,14 +327,15 @@ static int nss_gmac_set_pauseparam(struc
phydev = gmacdev->phydev;
/* Update flow control advertisment */
- phydev->advertising &= ~(ADVERTISED_Pause | ADVERTISED_Asym_Pause);
+ advertising = phydev->advertising;
+ *advertising &= ~(ADVERTISED_Pause | ADVERTISED_Asym_Pause);
if (gmacdev->pause & FLOW_CTRL_RX)
- phydev->advertising |=
+ *advertising |=
(ADVERTISED_Pause | ADVERTISED_Asym_Pause);
if (gmacdev->pause & FLOW_CTRL_TX)
- phydev->advertising |= ADVERTISED_Asym_Pause;
+ *advertising |= ADVERTISED_Asym_Pause;
genphy_config_aneg(gmacdev->phydev);
@@ -392,12 +395,13 @@ static uint32_t nss_gmac_get_msglevel(st
* @param[in] pointer to struct net_device.
* @param[in] pointer to struct ethtool_cmd.
*/
-static int32_t nss_gmac_get_settings(struct net_device *netdev,
- struct ethtool_cmd *ecmd)
+static int nss_gmac_get_settings(struct net_device *netdev,
+ struct ethtool_link_ksettings *elk)
{
struct nss_gmac_dev *gmacdev = (struct nss_gmac_dev *)netdev_priv(netdev);
struct phy_device *phydev = NULL;
uint16_t phyreg;
+ u32 lp_advertising = 0;
BUG_ON(gmacdev == NULL);
@@ -409,10 +413,10 @@ static int32_t nss_gmac_get_settings(str
*/
if (!test_bit(__NSS_GMAC_LINKPOLL, &gmacdev->flags)) {
if (gmacdev->forced_speed != SPEED_UNKNOWN) {
- ethtool_cmd_speed_set(ecmd, gmacdev->forced_speed);
- ecmd->duplex = gmacdev->forced_duplex;
- ecmd->mdio_support = 0;
- ecmd->lp_advertising = 0;
+ elk->base.speed = gmacdev->forced_speed;
+ elk->base.duplex = gmacdev->forced_duplex;
+ elk->base.mdio_support = 0;
+ ethtool_convert_legacy_u32_to_link_mode(elk->link_modes.lp_advertising, 0);
return 0;
} else {
/* Non-link polled interfaced must have a forced
@@ -426,56 +430,59 @@ static int32_t nss_gmac_get_settings(str
/* update PHY status */
if (phydev->is_c45 == true) {
- ecmd->mdio_support = ETH_MDIO_SUPPORTS_C45;
+ elk->base.mdio_support = ETH_MDIO_SUPPORTS_C45;
} else {
if (genphy_read_status(phydev) != 0) {
return -EIO;
}
- ecmd->mdio_support = ETH_MDIO_SUPPORTS_C22;
+ elk->base.mdio_support = ETH_MDIO_SUPPORTS_C22;
}
/* Populate capabilities advertised by self */
- ecmd->advertising = phydev->advertising;
+ bitmap_copy(elk->link_modes.advertising, phydev->advertising, __ETHTOOL_LINK_MODE_MASK_NBITS);
- ecmd->autoneg = phydev->autoneg;
- ethtool_cmd_speed_set(ecmd, phydev->speed);
- ecmd->duplex = phydev->duplex;
- ecmd->port = PORT_TP;
- ecmd->phy_address = gmacdev->phy_base;
- ecmd->transceiver = XCVR_EXTERNAL;
+ elk->base.autoneg = phydev->autoneg;
+ elk->base.speed = phydev->speed;
+ elk->base.duplex = phydev->duplex;
+ elk->base.port = PORT_TP;
+ elk->base.phy_address = gmacdev->phy_base;
+ elk->base.transceiver = XCVR_EXTERNAL;
/* Populate supported capabilities */
- ecmd->supported = phydev->supported;
+ bitmap_copy(elk->link_modes.supported, phydev->supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
if (phydev->is_c45 == true)
return 0;
/* Populate capabilities advertised by link partner */
+ ethtool_convert_link_mode_to_legacy_u32(&lp_advertising, elk->link_modes.lp_advertising);
phyreg = nss_gmac_mii_rd_reg(gmacdev, gmacdev->phy_base, MII_LPA);
if (phyreg & LPA_10HALF)
- ecmd->lp_advertising |= ADVERTISED_10baseT_Half;
+ lp_advertising |= ADVERTISED_10baseT_Half;
if (phyreg & LPA_10FULL)
- ecmd->lp_advertising |= ADVERTISED_10baseT_Full;
+ lp_advertising |= ADVERTISED_10baseT_Full;
if (phyreg & LPA_100HALF)
- ecmd->lp_advertising |= ADVERTISED_100baseT_Half;
+ lp_advertising |= ADVERTISED_100baseT_Half;
if (phyreg & LPA_100FULL)
- ecmd->lp_advertising |= ADVERTISED_100baseT_Full;
+ lp_advertising |= ADVERTISED_100baseT_Full;
if (phyreg & LPA_PAUSE_CAP)
- ecmd->lp_advertising |= ADVERTISED_Pause;
+ lp_advertising |= ADVERTISED_Pause;
if (phyreg & LPA_PAUSE_ASYM)
- ecmd->lp_advertising |= ADVERTISED_Asym_Pause;
+ lp_advertising |= ADVERTISED_Asym_Pause;
phyreg = nss_gmac_mii_rd_reg(gmacdev, gmacdev->phy_base, MII_STAT1000);
if (phyreg & LPA_1000HALF)
- ecmd->lp_advertising |= ADVERTISED_1000baseT_Half;
+ lp_advertising |= ADVERTISED_1000baseT_Half;
if (phyreg & LPA_1000FULL)
- ecmd->lp_advertising |= ADVERTISED_1000baseT_Full;
+ lp_advertising |= ADVERTISED_1000baseT_Full;
+
+ ethtool_convert_legacy_u32_to_link_mode(elk->link_modes.lp_advertising, lp_advertising);
return 0;
}
@@ -485,8 +492,8 @@ static int32_t nss_gmac_get_settings(str
* @param[in] pointer to struct net_device.
* @param[in] pointer to struct ethtool_cmd.
*/
-static int32_t nss_gmac_set_settings(struct net_device *netdev,
- struct ethtool_cmd *ecmd)
+static int nss_gmac_set_settings(struct net_device *netdev,
+ const struct ethtool_link_ksettings *elk)
{
struct nss_gmac_dev *gmacdev = (struct nss_gmac_dev *)netdev_priv(netdev);
struct phy_device *phydev = NULL;
@@ -508,13 +515,13 @@ static int32_t nss_gmac_set_settings(str
return -EPERM;
}
- if (ecmd->autoneg == AUTONEG_ENABLE) {
+ if (elk->base.autoneg == AUTONEG_ENABLE) {
set_bit(__NSS_GMAC_AUTONEG, &gmacdev->flags);
} else {
clear_bit(__NSS_GMAC_AUTONEG, &gmacdev->flags);
}
- return phy_ethtool_sset(phydev, ecmd);
+ return phy_ethtool_ksettings_set(phydev, elk);
}
/**
@@ -592,8 +599,8 @@ struct ethtool_ops nss_gmac_ethtool_ops
.set_pauseparam = &nss_gmac_set_pauseparam,
.nway_reset = &nss_gmac_nway_reset,
.get_wol = &nss_gmac_get_wol,
- .get_settings = &nss_gmac_get_settings,
- .set_settings = &nss_gmac_set_settings,
+ .get_link_ksettings = &nss_gmac_get_settings,
+ .set_link_ksettings = &nss_gmac_set_settings,
.get_strings = &nss_gmac_get_strings,
.get_sset_count = &nss_gmac_get_strset_count,
.get_ethtool_stats = &nss_gmac_get_ethtool_stats,
--- a/ipq806x/nss_gmac_dev.c
+++ b/ipq806x/nss_gmac_dev.c
@@ -1585,7 +1585,7 @@ int32_t nss_gmac_attach(struct nss_gmac_
}
/* ioremap addresses */
- gmacdev->mac_base = ioremap_nocache(reg_base,
+ gmacdev->mac_base = ioremap(reg_base,
NSS_GMAC_REG_BLOCK_LEN);
if (!gmacdev->mac_base) {
netdev_dbg(netdev, "ioremap fail.\n");
--- a/ipq806x/nss_gmac_tx_rx_offload.c
+++ b/ipq806x/nss_gmac_tx_rx_offload.c
@@ -1027,8 +1027,10 @@ int nss_gmac_close(struct net_device *ne
nss_gmac_disable_interrupt_all(gmacdev);
gmacdev->data_plane_ops->link_state(gmacdev->data_plane_ctx, 0);
- if (!IS_ERR(gmacdev->phydev))
- phy_stop(gmacdev->phydev);
+ if (!IS_ERR(gmacdev->phydev)) {
+ if (test_bit(__NSS_GMAC_LINKPOLL, &gmacdev->flags))
+ phy_stop(gmacdev->phydev);
+ }
clear_bit(__NSS_GMAC_UP, &gmacdev->flags);
clear_bit(__NSS_GMAC_CLOSING, &gmacdev->flags);

View File

@@ -0,0 +1,95 @@
--- a/ipq806x/include/msm_nss_gmac.h
+++ b/ipq806x/include/msm_nss_gmac.h
@@ -317,7 +317,7 @@ struct msm_nss_gmac_platform_data {
uint32_t phy_mdio_addr; /* MDIO address of the connected PHY */
uint32_t poll_required; /* [0/1] Link status poll? */
uint32_t rgmii_delay;
- uint32_t phy_mii_type;
+ phy_interface_t phy_mii_type;
uint8_t mac_addr[6];
int32_t forced_speed; /* Forced speed. Values used from
ethtool.h. 0 = Speed not forced */
--- a/ipq806x/include/nss_gmac_dev.h
+++ b/ipq806x/include/nss_gmac_dev.h
@@ -234,7 +234,7 @@ struct nss_gmac_dev {
uint32_t duplex_mode; /* Duplex mode of the Phy */
uint32_t speed; /* Speed of the Phy */
uint32_t loop_back_mode;/* Loopback status of the Phy */
- uint32_t phy_mii_type; /* RGMII/SGMII/QSGMII */
+ phy_interface_t phy_mii_type; /* RGMII/SGMII/QSGMII */
uint32_t rgmii_delay; /* RGMII delay settings */
uint32_t pause; /* Current flow control settings */
uint32_t first_linkup_done; /* when set, it indicates that first
--- a/ipq806x/include/nss_gmac_network_interface.h
+++ b/ipq806x/include/nss_gmac_network_interface.h
@@ -41,7 +41,7 @@ int32_t nss_gmac_xmit_frames(struct sk_b
int32_t nss_gmac_close(struct net_device *netdev);
int32_t nss_gmac_open(struct net_device *netdev);
int32_t nss_gmac_change_mtu(struct net_device *netdev, int32_t newmtu);
-void nss_gmac_tx_timeout(struct net_device *netdev);
+void nss_gmac_tx_timeout(struct net_device *netdev, unsigned int txqueue);
/* NSS driver interface APIs */
void nss_gmac_receive(struct net_device *netdev, struct sk_buff *skb,
--- a/ipq806x/nss_gmac_ctrl.c
+++ b/ipq806x/nss_gmac_ctrl.c
@@ -995,7 +995,6 @@ static int32_t nss_gmac_of_get_pdata(str
struct net_device *netdev,
struct msm_nss_gmac_platform_data *gmaccfg)
{
- uint8_t *maddr = NULL;
struct nss_gmac_dev *gmacdev = (struct nss_gmac_dev *)netdev_priv(netdev);
struct resource memres_devtree = {0};
@@ -1023,15 +1022,14 @@ static int32_t nss_gmac_of_get_pdata(str
of_property_read_u32(np, "qcom,aux-clk-freq", &gmacdev->aux_clk_freq);
- gmaccfg->phy_mii_type = of_get_phy_mode(np);
+ of_get_phy_mode(np, &gmaccfg->phy_mii_type);
netdev->irq = irq_of_parse_and_map(np, 0);
if (netdev->irq <= 0) {
pr_err("%s: Can't map interrupt\n", np->name);
return -EFAULT;
}
- maddr = (uint8_t *)of_get_mac_address(np);
- if (maddr)
- memcpy(gmaccfg->mac_addr, maddr, ETH_ALEN);
+
+ of_get_mac_address(np, gmaccfg->mac_addr);
if (of_address_to_resource(np, 0, &memres_devtree) != 0)
return -EFAULT;
--- a/ipq806x/nss_gmac_dev.c
+++ b/ipq806x/nss_gmac_dev.c
@@ -1526,7 +1526,7 @@ void nss_gmac_set_mac_addr(struct nss_gm
{
uint32_t data;
- netdev_dbg(gmacdev->netdev, "Set addr %02x:%02x:%02x:%02x:%02x:%02x\n",
+ netdev_info(gmacdev->netdev, "Set addr %02x:%02x:%02x:%02x:%02x:%02x\n",
mac_addr[0], mac_addr[1], mac_addr[2],
mac_addr[3], mac_addr[4], mac_addr[5]);
--- a/ipq806x/nss_gmac_init.c
+++ b/ipq806x/nss_gmac_init.c
@@ -940,6 +940,8 @@ void nss_gmac_dev_init(struct nss_gmac_d
case PHY_INTERFACE_MODE_QSGMII:
div = clk_div_qsgmii(gmacdev);
break;
+ default:
+ netdev_err(gmacdev->netdev, "NO interface defined!\n");
}
val = nss_gmac_read_reg(nss_base, NSS_ETH_CLK_DIV0);
val &= ~GMACn_CLK_DIV(id, GMACn_CLK_DIV_SIZE);
--- a/ipq806x/nss_gmac_tx_rx_offload.c
+++ b/ipq806x/nss_gmac_tx_rx_offload.c
@@ -1046,7 +1046,7 @@ int nss_gmac_close(struct net_device *ne
* @param[in] pointer to net_device structure
* @return void.
*/
-void nss_gmac_tx_timeout(struct net_device *netdev)
+void nss_gmac_tx_timeout(struct net_device *netdev, unsigned int txqueue)
{
struct nss_gmac_dev *gmacdev = (struct nss_gmac_dev *)netdev_priv(netdev);
BUG_ON(gmacdev == NULL);

View File

@@ -0,0 +1,109 @@
From 39e953886e9a4c66bd70315ae6c27699b0af31d4 Mon Sep 17 00:00:00 2001
From: Qosmio <datapronix@protonmail.com>
Date: Sat, 10 Sep 2022 01:53:36 -0400
Subject: [PATCH] nss-gmac: add timestamping feature and extra logging
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
requires an entry in dts:
example:
qcom,tstamp-enabled;
use ethtool to enable:
root@R7800 ~
➤ ethtool --set-priv-flags eth1 tstamp on
[Sat Sep 10 01:24:22 2022] ipq8064-mdio 37000000.mdio eth0: nss_gmac_ts_enable: Timestamp enabled
[Sat Sep 10 01:24:22 2022] ipq8064-mdio 37000000.mdio eth0: nss_gmac_set_priv_flags: Enabled 'Timestamp' flag (needed_headroom: 32)
root@R7800 ~
➤ cat /sys/devices/platform/soc/37000000.mdio/net/eth*/tstamp
sec:1084 nsec:752452290 time-of-day: 1662789199.391664
sec:1087 nsec:309864290 time-of-day: 1662789199.391799
--- a/ipq806x/include/nss_gmac_dev.h
+++ b/ipq806x/include/nss_gmac_dev.h
@@ -1342,6 +1342,9 @@ void nss_gmac_disable_rx_chksum_offload(
void nss_gmac_rx_tcpip_chksum_drop_enable(struct nss_gmac_dev *gmacdev);
void nss_gmac_rx_tcpip_chksum_drop_disable(struct nss_gmac_dev *gmacdev);
+void nss_gmac_tstamp_sysfs_create(struct net_device *dev);
+void nss_gmac_tstamp_sysfs_remove(struct net_device *dev);
+
/**
* The check summ offload engine is enabled to do complete checksum computation.
* Hardware computes the tcp ip checksum including the pseudo header checksum.
--- a/ipq806x/nss_gmac_ctrl.c
+++ b/ipq806x/nss_gmac_ctrl.c
@@ -651,7 +651,7 @@ static DEVICE_ATTR(fadj, 0220, NULL, nss
static DEVICE_ATTR(mtnp, 0444, nss_gmac_mtnp_show, NULL);
static DEVICE_ATTR(tstamp, 0444, nss_gmac_tstamp_show, NULL);
-static void nss_gmac_tstamp_sysfs_create(struct net_device *dev)
+void nss_gmac_tstamp_sysfs_create(struct net_device *dev)
{
if (device_create_file(&(dev->dev), &dev_attr_slam) ||
device_create_file(&(dev->dev), &dev_attr_cadj) ||
@@ -662,7 +662,7 @@ static void nss_gmac_tstamp_sysfs_create
return;
}
-static void nss_gmac_tstamp_sysfs_remove(struct net_device *dev)
+void nss_gmac_tstamp_sysfs_remove(struct net_device *dev)
{
device_remove_file(&(dev->dev), &dev_attr_slam);
device_remove_file(&(dev->dev), &dev_attr_cadj);
--- a/ipq806x/nss_gmac_ethtool.c
+++ b/ipq806x/nss_gmac_ethtool.c
@@ -559,6 +559,49 @@ static int32_t nss_gmac_set_priv_flags(s
}
/*
+ * Set timestamp
+ */
+ if (changed & NSS_GMAC_PRIV_FLAG(TSTAMP)) {
+ if (flags & NSS_GMAC_PRIV_FLAG(TSTAMP)) {
+ if (!test_bit(__NSS_GMAC_TSTAMP, &gmacdev->flags)) {
+ /*
+ * Increase headroom for PTP/NTP timestamps
+ */
+ netdev->needed_headroom += 32;
+
+ /*
+ * Create sysfs entries for timestamp registers
+ */
+ nss_gmac_tstamp_sysfs_create(netdev);
+
+ if (nss_gmac_ts_enable(gmacdev)) {
+ netdev_info(netdev, "%s: Reg write error. Cannot enable Timestamping \n", __func__);
+ return -EINVAL;
+ }
+
+ gmacdev->drv_flags |= NSS_GMAC_PRIV_FLAG(TSTAMP);
+ netdev_info(netdev, "%s: Enabled 'Timestamp' flag (needed_headroom: %dx)", __func__, netdev->needed_headroom);
+ } else {
+ netdev_warn(netdev, "%s: Already enabled 'Timestamp' flag", __func__);
+ }
+ } else {
+ /*
+ * Disable Timestamping if not already disabled
+ */
+ if (!test_bit(__NSS_GMAC_TSTAMP, &gmacdev->flags)) {
+ netdev_warn(netdev, "%s: Timestamp is already disabled \n", __func__);
+ return -EINVAL;
+ }
+
+ nss_gmac_ts_disable(gmacdev);
+ gmacdev->drv_flags &= ~NSS_GMAC_PRIV_FLAG(TSTAMP);
+ nss_gmac_tstamp_sysfs_remove(gmacdev->netdev);
+ // netdev->needed_headroom -= 32;
+ netdev_info(netdev, "%s: Disabled 'Timestamp' flag (needed_headroom: %dx)", __func__, netdev->needed_headroom);
+ }
+ }
+
+ /*
* Set ignore rx csum flag
*/
if (changed & NSS_GMAC_PRIV_FLAG(IGNORE_RX_CSUM_ERR)) {

View File

@@ -0,0 +1,32 @@
--- a/ipq806x/nss_gmac_ctrl.c
+++ b/ipq806x/nss_gmac_ctrl.c
@@ -1390,6 +1390,9 @@ static int32_t nss_gmac_probe(struct pla
}
}
+ /* workaround for tplink,onhub eth0 phy_attach_direct panic with poll enabled */
+ SET_NETDEV_DEV(netdev, gmacdev->miibus->parent); /* (netdev, &pdev->dev) ? */
+
/*
* Connect PHY
*/
@@ -1439,8 +1442,6 @@ static int32_t nss_gmac_probe(struct pla
netdev_dbg(netdev, "%s MII_PHYSID2 - 0x%04x\n", netdev->name,
nss_gmac_mii_rd_reg(gmacdev, gmacdev->phy_base, MII_PHYSID2));
} else if (gmacdev->phy_base != NSS_GMAC_NO_MDIO_PHY) {
- SET_NETDEV_DEV(netdev, gmacdev->miibus->parent);
-
/*
* Issue a phy_attach for the interface connected to a switch
*/
@@ -1485,8 +1486,8 @@ static int32_t nss_gmac_probe(struct pla
netdev_change_features(netdev);
rtnl_unlock();
- netdev_dbg(netdev, "Initialized NSS GMAC%d interface %s: (base = 0x%lx, irq = %d, PhyId = %d, PollLink = %d)\n"
- , gmacdev->macid, netdev->name, netdev->base_addr
+ netdev_info(netdev, "Initialized NSS GMAC%d mode: %s, interface %s: (base = 0x%lx, irq = %d, PhyId = %d, PollLink = %d)\n"
+ , gmacdev->macid, phy_modes(gmacdev->phy_mii_type), netdev->name, netdev->base_addr
, netdev->irq, gmacdev->phy_base
, test_bit(__NSS_GMAC_LINKPOLL, &gmacdev->flags));

View File

@@ -0,0 +1,108 @@
--- a/ipq806x/include/msm_nss_gmac.h
+++ b/ipq806x/include/msm_nss_gmac.h
@@ -19,6 +19,7 @@
#ifndef __MSM_NSS_GMAC_H
#define __MSM_NSS_GMAC_H
+#include <linux/version.h>
#include <linux/phy.h>
#include <msm_nss_macsec.h>
@@ -318,7 +319,11 @@ struct msm_nss_gmac_platform_data {
uint32_t poll_required; /* [0/1] Link status poll? */
uint32_t rgmii_delay;
phy_interface_t phy_mii_type;
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ const uint8_t mac_addr[6];
+#else
uint8_t mac_addr[6];
+#endif
int32_t forced_speed; /* Forced speed. Values used from
ethtool.h. 0 = Speed not forced */
int32_t forced_duplex; /* Forced duplex. Values used from
--- a/ipq806x/nss_gmac_ctrl.c
+++ b/ipq806x/nss_gmac_ctrl.c
@@ -379,10 +379,20 @@ static int32_t nss_gmac_set_mac_address(
if (!is_valid_ether_addr(addr->sa_data))
return -EADDRNOTAVAIL;
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ nss_gmac_set_mac_addr(gmacdev, gmac_addr0_high, gmac_addr0_low,
+ (uint8_t *)addr->sa_data);
+#else
nss_gmac_set_mac_addr(gmacdev, gmac_addr0_high, gmac_addr0_low,
addr->sa_data);
+#endif
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ nss_gmac_get_mac_addr(gmacdev, gmac_addr0_high, gmac_addr0_low,
+ (uint8_t *)netdev->dev_addr);
+#else
nss_gmac_get_mac_addr(gmacdev, gmac_addr0_high, gmac_addr0_low,
netdev->dev_addr);
+#endif
return 0;
}
@@ -1029,7 +1039,11 @@ static int32_t nss_gmac_of_get_pdata(str
return -EFAULT;
}
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ of_get_mac_address(np, (uint8_t *)gmaccfg->mac_addr);
+#else
of_get_mac_address(np, gmaccfg->mac_addr);
+#endif
if (of_address_to_resource(np, 0, &memres_devtree) != 0)
return -EFAULT;
@@ -1349,9 +1363,18 @@ static int32_t nss_gmac_probe(struct pla
* This just fill in some default MAC address
*/
if (is_valid_ether_addr(gmaccfg->mac_addr)) {
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ //__dev_addr_set(netdev, &gmaccfg->mac_addr, ETH_ALEN);
+ eth_hw_addr_set(netdev, (uint8_t *)gmaccfg->mac_addr);
+#else
memcpy(netdev->dev_addr, &gmaccfg->mac_addr, ETH_ALEN);
+#endif
} else {
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ eth_random_addr((uint8_t *)netdev->dev_addr);
+#else
random_ether_addr(netdev->dev_addr);
+#endif
pr_info("GMAC%d(%p) Invalid MAC@ - using %02x:%02x:%02x:%02x:%02x:%02x\n",
gmacdev->macid, gmacdev,
*netdev->dev_addr, *netdev->dev_addr+1,
--- a/ipq806x/nss_gmac_dev.c
+++ b/ipq806x/nss_gmac_dev.c
@@ -1166,8 +1166,13 @@ void nss_gmac_mac_init(struct nss_gmac_d
nss_gmac_back_off_limit(gmacdev, gmac_backoff_limit0);
nss_gmac_deferral_check_disable(gmacdev);
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ nss_gmac_set_mac_addr(gmacdev, gmac_addr0_high,
+ gmac_addr0_low, (uint8_t *)gmacdev->netdev->dev_addr);
+#else
nss_gmac_set_mac_addr(gmacdev, gmac_addr0_high,
gmac_addr0_low, gmacdev->netdev->dev_addr);
+#endif
/*Frame Filter Configuration */
nss_gmac_frame_filter_enable(gmacdev);
--- a/ipq806x/nss_gmac_tx_rx_offload.c
+++ b/ipq806x/nss_gmac_tx_rx_offload.c
@@ -945,8 +945,13 @@ int nss_gmac_open(struct net_device *net
netdev_dbg(netdev, "%s: offload is not enabled, bring up gmac with slowpath\n",
__func__);
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(6, 1, 0))
+ netif_napi_add_weight(netdev, &gmacdev->napi, nss_gmac_poll,
+ NSS_GMAC_NAPI_BUDGET);
+#else
netif_napi_add(netdev, &gmacdev->napi, nss_gmac_poll,
NSS_GMAC_NAPI_BUDGET);
+#endif
/* Initial the RX/TX ring */
dma_set_coherent_mask(dev, 0xffffffff);
nss_gmac_setup_rx_desc_queue(gmacdev, dev,

View File

@@ -0,0 +1,10 @@
--- a/ipq806x/nss_gmac_tx_rx_offload.c
+++ b/ipq806x/nss_gmac_tx_rx_offload.c
@@ -952,6 +952,7 @@ int nss_gmac_open(struct net_device *net
netif_napi_add(netdev, &gmacdev->napi, nss_gmac_poll,
NSS_GMAC_NAPI_BUDGET);
#endif
+ dev_set_threaded(netdev, true);
/* Initial the RX/TX ring */
dma_set_coherent_mask(dev, 0xffffffff);
nss_gmac_setup_rx_desc_queue(gmacdev, dev,