mirror of
https://github.com/qosmio/nss-packages.git
synced 2025-12-16 08:12:53 +00:00
nss-info: remove source and switch to repo based build
Signed-off-by: Sean Khan <datapronix@protonmail.com>
This commit is contained in:
parent
99700f4bf9
commit
ff7d2b1c00
113
nss-userspace-oss/Makefile
Normal file
113
nss-userspace-oss/Makefile
Normal file
@ -0,0 +1,113 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=nss-userspace-oss
|
||||
PKG_RELEASE:=2
|
||||
|
||||
PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/nss-userspace.git
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_DATE:=2024-11-27
|
||||
PKG_SOURCE_VERSION:=7233e22
|
||||
PKG_MIRROR_HASH:=03dea072feb18916f32798f7bfd8c8811733e0681c4e9e1d77dd895f121de734
|
||||
QSDK_VERSION:=13.0
|
||||
PKG_VERSION:=$(QSDK_VERSION).$(subst -,.,$(PKG_SOURCE_DATE))~$(PKG_SOURCE_VERSION)
|
||||
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
PKG_FLAGS:=nonshared
|
||||
PKG_BUILD_FLAGS:=gc-sections lto
|
||||
|
||||
PKG_CONFIG_DEPENDS:= \
|
||||
CONFIG_NSS_NLCAPWAP_ENABLE \
|
||||
CONFIG_NSS_NLDTLS_ENABLE \
|
||||
CONFIG_NSS_NLGRE_REDIR_ENABLE \
|
||||
CONFIG_NSS_NLIPSEC_ENABLE \
|
||||
CONFIG_NSS_NLQRFS_ENABLE \
|
||||
CONFIG_NSS_NLUDP_ST_ENABLE
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/nss-userspace
|
||||
TITLE:=Userspace utilities for NSS
|
||||
endef
|
||||
|
||||
define Package/libnl-nss
|
||||
$(call Package/nss-userspace)
|
||||
SECTION:=Libs
|
||||
CATEGORY:=Libraries
|
||||
TITLE += (libnl-nss)
|
||||
DEPENDS:=+libpthread +libnl-tiny +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
|
||||
|
||||
define Package/nssinfo
|
||||
$(call Package/nss-userspace)
|
||||
SECTION:=Utils
|
||||
CATEGORY:=Utilities
|
||||
TITLE += (nssinfo)
|
||||
DEPENDS:=+libncurses +libnl-nss
|
||||
endef
|
||||
|
||||
define Package/nssinfo/description
|
||||
A userspace utility for fetching stats from NSS.
|
||||
endef
|
||||
|
||||
TARGET_CFLAGS += $(FPIC) -D_GNU_SOURCE=1
|
||||
|
||||
TARGET_CPPFLAGS:= \
|
||||
-I$(STAGING_DIR)/usr/include/qca-nss-clients \
|
||||
-I$(STAGING_DIR)/usr/include/qca-nss-drv \
|
||||
-I$(STAGING_DIR)/usr/include/libnl-tiny \
|
||||
-I$(STAGING_DIR)/usr/include/libnl-nss
|
||||
|
||||
ifneq ($(CONFIG_PACKAGE_libnl-nss),)
|
||||
MAKE_FLAGS+=BUILD_LIBNSS=y
|
||||
|
||||
ifdef CONFIG_NSS_NLUDP_ST_ENABLE
|
||||
MAKE_FLAGS+=udp_st=y
|
||||
endif
|
||||
|
||||
ifdef CONFIG_NSS_NLQRFS_ENABLE
|
||||
MAKE_FLAGS+=qrfs=y
|
||||
endif
|
||||
|
||||
ifdef CONFIG_NSS_NLGRE_REDIR_ENABLE
|
||||
MAKE_FLAGS+=gre_redir=y
|
||||
endif
|
||||
|
||||
ifdef CONFIG_NSS_NLIPSEC_ENABLE
|
||||
MAKE_FLAGS+=ipsec=y
|
||||
endif
|
||||
|
||||
ifdef CONFIG_NSS_NLDTLS_ENABLE
|
||||
MAKE_FLAGS+=dtls=y
|
||||
endif
|
||||
|
||||
ifdef CONFIG_NSS_NLCAPWAP_ENABLE
|
||||
MAKE_FLAGS+=capwap=y
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(CONFIG_PACKAGE_nssinfo),)
|
||||
MAKE_FLAGS+=BUILD_NSSINFO=y
|
||||
endif
|
||||
|
||||
define Build/libnl-nss/InstallDev
|
||||
$(INSTALL_DIR) $(STAGING_DIR)/usr/include/libnl-nss
|
||||
$(CP) $(PKG_BUILD_DIR)/lib/obj/libnl-nss.so $(STAGING_DIR)/usr/lib
|
||||
$(CP) $(PKG_BUILD_DIR)/lib/include/* $(STAGING_DIR)/usr/include/libnl-nss
|
||||
endef
|
||||
|
||||
define Package/libnl-nss/install
|
||||
$(INSTALL_DIR) $(1)/usr/lib
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/lib/obj/libnl-nss.so $(1)/usr/lib
|
||||
endef
|
||||
|
||||
define Package/nssinfo/install
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/nssinfo/obj/nssinfo $(1)/usr/sbin/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,nssinfo))
|
||||
$(eval $(call BuildPackage,libnl-nss))
|
||||
@ -1,39 +0,0 @@
|
||||
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))
|
||||
@ -1,35 +0,0 @@
|
||||
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
|
||||
@ -1,714 +0,0 @@
|
||||
/*
|
||||
**************************************************************************
|
||||
* 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;
|
||||
}
|
||||
@ -1,233 +0,0 @@
|
||||
/*
|
||||
**************************************************************************
|
||||
* 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*/
|
||||
@ -1,72 +0,0 @@
|
||||
/*
|
||||
**************************************************************************
|
||||
* 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;
|
||||
}
|
||||
@ -1,28 +0,0 @@
|
||||
/*
|
||||
**************************************************************************
|
||||
* 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*/
|
||||
@ -1,215 +0,0 @@
|
||||
/*
|
||||
**************************************************************************
|
||||
* 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(ð_rx_lock);
|
||||
eth_rx_node = nodes[core][NSS_ETH_RX_INTERFACE];
|
||||
if (!eth_rx_node) {
|
||||
pthread_mutex_unlock(ð_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(ð_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(ð_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(ð_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(ð_rx_lock);
|
||||
return;
|
||||
}
|
||||
pthread_mutex_unlock(ð_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(ð_rx_lock);
|
||||
nodes[nss_stats->core_id][NSS_ETH_RX_INTERFACE] = eth_rx_node;
|
||||
pthread_mutex_unlock(ð_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(ð_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(ð_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(ð_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;
|
||||
}
|
||||
@ -1,28 +0,0 @@
|
||||
/*
|
||||
**************************************************************************
|
||||
* 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*/
|
||||
@ -1,215 +0,0 @@
|
||||
/*
|
||||
**************************************************************************
|
||||
* 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;
|
||||
}
|
||||
@ -1,30 +0,0 @@
|
||||
/*
|
||||
**************************************************************************
|
||||
* 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*/
|
||||
@ -1,212 +0,0 @@
|
||||
/*
|
||||
**************************************************************************
|
||||
* 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;
|
||||
}
|
||||
@ -1,30 +0,0 @@
|
||||
/*
|
||||
**************************************************************************
|
||||
* 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*/
|
||||
@ -1,195 +0,0 @@
|
||||
/*
|
||||
**************************************************************************
|
||||
* 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;
|
||||
}
|
||||
@ -1,28 +0,0 @@
|
||||
/*
|
||||
**************************************************************************
|
||||
* 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*/
|
||||
@ -1,191 +0,0 @@
|
||||
/*
|
||||
**************************************************************************
|
||||
* 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;
|
||||
}
|
||||
@ -1,209 +0,0 @@
|
||||
/*
|
||||
**************************************************************************
|
||||
* 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;
|
||||
}
|
||||
@ -1,28 +0,0 @@
|
||||
/*
|
||||
**************************************************************************
|
||||
* 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*/
|
||||
28
nss-userspace-oss/patches/000-create-makefile.patch
Normal file
28
nss-userspace-oss/patches/000-create-makefile.patch
Normal file
@ -0,0 +1,28 @@
|
||||
--- /dev/null
|
||||
+++ b/Makefile
|
||||
@@ -0,0 +1,24 @@
|
||||
+# Define the build directories based on flags
|
||||
+DIRS-y :=
|
||||
+DIRS-$(BUILD_LIBNSS) += lib
|
||||
+DIRS-$(BUILD_NSSINFO) += nssinfo
|
||||
+DIRS-$(BUILD_NETFN) += netfn
|
||||
+DIRS-$(BUILD_LIBPPE) += ppe/ppenl_lib
|
||||
+DIRS-$(BUILD_PPECFG) += ppe/ppecfg
|
||||
+
|
||||
+# Main targets
|
||||
+all: $(DIRS-y)
|
||||
+ @echo "Build complete"
|
||||
+
|
||||
+# Pattern rule to build each directory
|
||||
+$(DIRS-y):
|
||||
+ $(MAKE) -C $@
|
||||
+
|
||||
+clean:
|
||||
+ @for dir in $(DIRS-y); do \
|
||||
+ if [ -d $$dir ]; then \
|
||||
+ $(MAKE) -C $$dir clean; \
|
||||
+ fi \
|
||||
+ done
|
||||
+
|
||||
+.PHONY: all clean $(DIRS-y)
|
||||
\ No newline at end of file
|
||||
@ -0,0 +1,24 @@
|
||||
--- a/lib/nss_nludp_st_api.c
|
||||
+++ b/lib/nss_nludp_st_api.c
|
||||
@@ -1,12 +1,9 @@
|
||||
/*
|
||||
**************************************************************************
|
||||
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
- * Copyright (c) 2022 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
|
||||
@@ -52,8 +49,6 @@ int nss_nludp_st_sock_cb(struct nl_msg *
|
||||
case NSS_UDP_ST_STOP_MSG:
|
||||
case NSS_UDP_ST_TX_CREATE_MSG:
|
||||
case NSS_UDP_ST_TX_DESTROY_MSG:
|
||||
- case NSS_UDP_ST_TX_UPDATE_RATE_MSG:
|
||||
- case NSS_UDP_ST_RX_MODE_SET_MSG:
|
||||
case NSS_UDP_ST_RESET_STATS_MSG:
|
||||
{
|
||||
void *cb_data = nss_nlcmn_get_cb_data(&rule->cm, sock->family_id);
|
||||
29
nss-userspace-oss/patches/001-nssinfo-fix-warnings.patch
Normal file
29
nss-userspace-oss/patches/001-nssinfo-fix-warnings.patch
Normal file
@ -0,0 +1,29 @@
|
||||
--- a/nssinfo/src/nssinfo.c
|
||||
+++ b/nssinfo/src/nssinfo.c
|
||||
@@ -176,8 +176,6 @@ void nssinfo_print_all(char *node, char
|
||||
}
|
||||
}
|
||||
nssinfo_stats_print("\n");
|
||||
-
|
||||
- return;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -278,7 +276,6 @@ void nssinfo_node_stats_destroy(pthread_
|
||||
p = next;
|
||||
}
|
||||
|
||||
- return;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -293,7 +290,8 @@ static char* nssinfo_add_comma(uint64_t
|
||||
}
|
||||
|
||||
nssinfo_add_comma(num/1000);
|
||||
- snprintf(buf + strlen(buf), sizeof(buf + strlen(buf)), ",%03lu", num % 1000);
|
||||
+ snprintf(buf + strlen(buf), sizeof(buf[NSSINFO_STR_LEN] + strlen(buf)), ",%03lu",
|
||||
+ num % 1000);
|
||||
return buf;
|
||||
}
|
||||
|
||||
@ -0,0 +1,48 @@
|
||||
--- a/lib/Makefile
|
||||
+++ b/lib/Makefile
|
||||
@@ -4,13 +4,44 @@ OBJPATH = obj
|
||||
|
||||
BINARY = $(OBJPATH)/libnl-nss.so
|
||||
SOURCES = $(wildcard $(SRCPATH)/*.c)
|
||||
-OBJECTS = $(SOURCES:$(SRCPATH)/%.c=$(OBJPATH)/%.o)
|
||||
HEADERS = $(wildcard $(SRCPATH)/*.h)
|
||||
|
||||
INCLUDE += -I./include
|
||||
EXTRA_CFLAGS = -Wall -Werror -fPIC -Wl,-z,relro -Wl,-z,now
|
||||
EXTRA_LDFLAGS = -pie -Wl,-z,relro -Wl,-z,now
|
||||
|
||||
+# Base objects that are always needed
|
||||
+BASE_OBJS = ipv4_api ipv6_api mcast_api sock
|
||||
+
|
||||
+# Feature objects that depend on flags
|
||||
+FEATURE_OBJS =
|
||||
+
|
||||
+ifeq ($(capwap),y)
|
||||
+ FEATURE_OBJS += capwap_api
|
||||
+endif
|
||||
+ifeq ($(dtls),y)
|
||||
+ FEATURE_OBJS += dtls_api
|
||||
+endif
|
||||
+ifeq ($(gre_redir),y)
|
||||
+ FEATURE_OBJS += gre_redir_api
|
||||
+endif
|
||||
+ifeq ($(ipsec),y)
|
||||
+ FEATURE_OBJS += ipsec_api
|
||||
+endif
|
||||
+ifeq ($(qrfs),y)
|
||||
+ FEATURE_OBJS += qrfs_api
|
||||
+endif
|
||||
+ifeq ($(udp_st),y)
|
||||
+ FEATURE_OBJS += udp_st_api
|
||||
+endif
|
||||
+
|
||||
+# All objects to build
|
||||
+OBJS = $(BASE_OBJS) $(FEATURE_OBJS)
|
||||
+
|
||||
+# Convert to actual object file paths
|
||||
+OBJECTS = $(patsubst %,$(OBJPATH)/nss_nl%.o,$(OBJS))
|
||||
+HEADERS = $(wildcard $(SRCPATH)/*.h)
|
||||
+
|
||||
all: release
|
||||
|
||||
release: $(BINARY)
|
||||
40
nss-userspace-oss/patches/002-nss-switch-to-nl-tiny.patch
Normal file
40
nss-userspace-oss/patches/002-nss-switch-to-nl-tiny.patch
Normal file
@ -0,0 +1,40 @@
|
||||
--- a/lib/nss_nlsock.c
|
||||
+++ b/lib/nss_nlsock.c
|
||||
@@ -379,7 +379,7 @@ int nss_nlsock_send(struct nss_nlsock_ct
|
||||
* 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);
|
||||
+ error = nl_send_auto_complete(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);
|
||||
@@ -387,6 +387,17 @@ int nss_nlsock_send(struct nss_nlsock_ct
|
||||
return error;
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * Wait for ACK response from netlink
|
||||
+ */
|
||||
+ /* error = nl_wait_for_ack(sock->nl_sk); */
|
||||
+ /* if (error < 0) { */
|
||||
+ /* nss_nlsock_log_error("%d:failed to get ACK (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);
|
||||
}
|
||||
--- a/nssinfo/Makefile
|
||||
+++ b/nssinfo/Makefile
|
||||
@@ -10,7 +10,7 @@ OBJECTS = $(SOURCES:$(SRCDIR)/src/%.c=$(
|
||||
|
||||
INCLUDE += -I../lib/include
|
||||
EXTRA_CFLAGS = -Wall -Werror -UENABLE_DEBUG
|
||||
-LDFLAGS = -lnl-genl-3 -lnl-nss -lncurses -lglib-2.0
|
||||
+LDFLAGS = -lnl-nss -lnl-tiny -lncurses
|
||||
LDLIBS = -L../lib/obj
|
||||
|
||||
all: release
|
||||
281
nss-userspace-oss/patches/0030-fix-build.patch
Normal file
281
nss-userspace-oss/patches/0030-fix-build.patch
Normal file
@ -0,0 +1,281 @@
|
||||
diff --git a/lib/nss_nlmcast_api.c b/lib/nss_nlmcast_api.c
|
||||
index 7646440..11ec59b 100644
|
||||
--- a/lib/nss_nlmcast_api.c
|
||||
+++ b/lib/nss_nlmcast_api.c
|
||||
@@ -94,7 +94,7 @@ int nss_nlmcast_sock_join_grp(struct nss_nlmcast_ctx *ctx, char *grp_name)
|
||||
|
||||
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);
|
||||
+ /* nss_nlsock_log_error("Unable to subscribe for mcast group, error(%d)\n", error); */
|
||||
return error;
|
||||
}
|
||||
|
||||
diff --git a/lib/nss_nlsock.c b/lib/nss_nlsock.c
|
||||
index 5b231e5..bde0670 100644
|
||||
--- a/lib/nss_nlsock.c
|
||||
+++ b/lib/nss_nlsock.c
|
||||
@@ -221,15 +221,23 @@ int nss_nlsock_leave_grp(struct nss_nlsock_ctx *sock, char *grp_name)
|
||||
{
|
||||
int error;
|
||||
|
||||
- assert(sock->ref_cnt > 0);
|
||||
+ /* Skip if socket is invalid */
|
||||
+ if (!sock || !sock->nl_sk) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ /* Safety check: Don't assert on ref_cnt */
|
||||
+ if (sock->ref_cnt <= 0) {
|
||||
+ return 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;
|
||||
+ /* Don't report error, just return success since we can't leave a group that doesn't exist */
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -259,7 +267,7 @@ int nss_nlsock_join_grp(struct nss_nlsock_ctx *sock, char *grp_name)
|
||||
*/
|
||||
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);
|
||||
+ /* nss_nlsock_log_error("failed to resolve group(%s)\n", grp_name); */
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
--- a/nssinfo/src/nssinfo.c
|
||||
+++ b/nssinfo/src/nssinfo.c
|
||||
@@ -20,12 +20,25 @@
|
||||
#include <signal.h>
|
||||
#include "nssinfo.h"
|
||||
|
||||
+/* Keyboard control definitions */
|
||||
+#define KEY_QUIT 'q'
|
||||
+// stop fucking using KEY_HELP as it conflicts with the help key in ncurses
|
||||
+#define KEY_HELP_ 'h'
|
||||
+#define KEY_VERBOSE 'v'
|
||||
+#define KEY_LIST_STATS '?'
|
||||
+
|
||||
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 */
|
||||
+static volatile bool quit_requested = false; /* Flag to indicate quit request */
|
||||
+
|
||||
+/* Forward declarations for new functions */
|
||||
+static void nssinfo_display_help(void);
|
||||
+static void nssinfo_list_available_stats(void);
|
||||
+static void nssinfo_handle_keyboard_input(void);
|
||||
|
||||
/* Array of pointers to node stats */
|
||||
struct node *nodes[NSS_MAX_CORES][NSS_MAX_NET_INTERFACES];
|
||||
@@ -350,6 +363,16 @@ static void *nssinfo_stats_display(void *arg)
|
||||
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
|
||||
|
||||
for (;;) {
|
||||
+ /* Check for keyboard input */
|
||||
+ if (!output_file) {
|
||||
+ nssinfo_handle_keyboard_input();
|
||||
+
|
||||
+ /* Check if quit was requested */
|
||||
+ if (quit_requested) {
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
nssinfo_stats_print("\t\t\t%s\n", mesg);
|
||||
|
||||
/*
|
||||
@@ -505,6 +528,8 @@ done:
|
||||
invalid_input = 0;
|
||||
sleep(arguments.rate);
|
||||
}
|
||||
+
|
||||
+ return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -607,11 +632,16 @@ 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);
|
||||
+ /* Silently ignore unknown message types */
|
||||
+ if (arguments.verbose) {
|
||||
+ nssinfo_warn("Ignoring unknown message type %d\n", cmd);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
+ * nssinfo_deinit()
|
||||
+ * Release all resources
|
||||
*/
|
||||
static void nssinfo_deinit(struct nss_nlmcast_ctx *ctx)
|
||||
{
|
||||
@@ -639,10 +669,11 @@ static void nssinfo_deinit(struct nss_nlmcast_ctx *ctx)
|
||||
|
||||
/*
|
||||
* Release resources used by each subsystem
|
||||
+ * Only deinitialize subsystems that were successfully initialized
|
||||
*/
|
||||
for (i = 0; i < NSS_NLCMN_SUBSYS_MAX; i++) {
|
||||
- deinit = nssinfo_subsystem_array[i].deinit;
|
||||
- if (deinit) {
|
||||
+ if (nssinfo_subsystem_array[i].is_inited && nssinfo_subsystem_array[i].deinit) {
|
||||
+ deinit = nssinfo_subsystem_array[i].deinit;
|
||||
deinit(ctx);
|
||||
}
|
||||
}
|
||||
@@ -671,16 +702,25 @@ int nssinfo_init(void)
|
||||
|
||||
/*
|
||||
* Initialize all the subsystems and subscribe for mcast groups.
|
||||
+ * Don't exit on subsystem initialization failures - these are expected
|
||||
+ * if certain kernel modules aren't loaded.
|
||||
*/
|
||||
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);
|
||||
+ /* Mark as not initialized so we won't try to use it later */
|
||||
+ nssinfo_subsystem_array[i].is_inited = 0;
|
||||
+
|
||||
+ /* Only log warnings in verbose mode */
|
||||
+ if (arguments.verbose) {
|
||||
+ nssinfo_warn("%s init failed, error(%d) - subsystem may not be available\n",
|
||||
+ nssinfo_subsystem_array[i].subsystem_name, error);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
}
|
||||
- }
|
||||
|
||||
/*
|
||||
* Listen for MCAST events from kernel.
|
||||
@@ -700,7 +740,7 @@ int nssinfo_init(void)
|
||||
}
|
||||
|
||||
/*
|
||||
- * Install CTRL-C handler
|
||||
+ * Install CTRL-C handler and other signal handlers
|
||||
*/
|
||||
struct sigaction new_action;
|
||||
new_action.sa_handler = nssinfo_termination_handler;
|
||||
@@ -721,3 +761,91 @@ end:
|
||||
nssinfo_deinit(&ctx);
|
||||
return error;
|
||||
}
|
||||
+
|
||||
+/*
|
||||
+ * nssinfo_display_help()
|
||||
+ * Display help information for keyboard controls
|
||||
+ */
|
||||
+static void nssinfo_display_help(void)
|
||||
+{
|
||||
+ clear();
|
||||
+ mvprintw(0, 0, "NSSINFO Keyboard Controls Help");
|
||||
+ mvprintw(2, 0, "q - Quit the application");
|
||||
+ mvprintw(3, 0, "h - Display this help screen");
|
||||
+ mvprintw(4, 0, "v - Toggle verbose mode");
|
||||
+ mvprintw(5, 0, "? - List available statistics");
|
||||
+ mvprintw(7, 0, "Press any key to return to stats display...");
|
||||
+ refresh();
|
||||
+
|
||||
+ /* Wait for key press before returning to stats display */
|
||||
+ nodelay(stdscr, FALSE);
|
||||
+ getch();
|
||||
+ nodelay(stdscr, TRUE);
|
||||
+ clear();
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * nssinfo_list_available_stats()
|
||||
+ * Display list of available statistics modules
|
||||
+ */
|
||||
+static void nssinfo_list_available_stats(void)
|
||||
+{
|
||||
+ int i, row = 0;
|
||||
+
|
||||
+ clear();
|
||||
+ mvprintw(row++, 0, "Available Statistics Modules:");
|
||||
+ row++;
|
||||
+
|
||||
+ for (i = 0; i < NSS_NLCMN_SUBSYS_MAX; i++) {
|
||||
+ if (nssinfo_subsystem_array[i].is_inited) {
|
||||
+ mvprintw(row++, 2, "- %s", nssinfo_subsystem_array[i].subsystem_name);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ mvprintw(row + 2, 0, "Press any key to return to stats display...");
|
||||
+ refresh();
|
||||
+
|
||||
+ /* Wait for key press before returning to stats display */
|
||||
+ nodelay(stdscr, FALSE);
|
||||
+ getch();
|
||||
+ nodelay(stdscr, TRUE);
|
||||
+ clear();
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * nssinfo_handle_keyboard_input()
|
||||
+ * Process keyboard input for interactive controls
|
||||
+ */
|
||||
+static void nssinfo_handle_keyboard_input(void)
|
||||
+{
|
||||
+ int ch = getch();
|
||||
+
|
||||
+ if (ch == ERR) {
|
||||
+ /* No input available */
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ switch (ch) {
|
||||
+ case KEY_QUIT:
|
||||
+ /* Set quit flag to exit application gracefully */
|
||||
+ quit_requested = true;
|
||||
+ raise(SIGINT); /* Signal to terminate */
|
||||
+ break;
|
||||
+
|
||||
+ case KEY_HELP_:
|
||||
+ nssinfo_display_help();
|
||||
+ break;
|
||||
+
|
||||
+ case KEY_VERBOSE:
|
||||
+ /* Toggle verbose mode */
|
||||
+ arguments.verbose = !arguments.verbose;
|
||||
+ break;
|
||||
+
|
||||
+ case KEY_LIST_STATS:
|
||||
+ nssinfo_list_available_stats();
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/nssinfo/src/nssinfo_lso_rx.c b/nssinfo/src/nssinfo_lso_rx.c
|
||||
index bbe7274..9f5bd6e 100644
|
||||
--- a/nssinfo/src/nssinfo_lso_rx.c
|
||||
+++ b/nssinfo/src/nssinfo_lso_rx.c
|
||||
@@ -43,7 +43,7 @@ static void nssinfo_lso_rx_stats_display(int core, char *input)
|
||||
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);
|
||||
+ /* nssinfo_error("%s is not running on the NPU\n", input); */
|
||||
return;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user