diff --git a/nss-userspace-oss/Makefile b/nss-userspace-oss/Makefile new file mode 100644 index 0000000..49c95d9 --- /dev/null +++ b/nss-userspace-oss/Makefile @@ -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)) diff --git a/nss-userspace-oss/nssinfo/Makefile b/nss-userspace-oss/nssinfo/Makefile deleted file mode 100644 index 51c1c81..0000000 --- a/nss-userspace-oss/nssinfo/Makefile +++ /dev/null @@ -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)) diff --git a/nss-userspace-oss/nssinfo/src/Makefile b/nss-userspace-oss/nssinfo/src/Makefile deleted file mode 100644 index 0ef19b3..0000000 --- a/nss-userspace-oss/nssinfo/src/Makefile +++ /dev/null @@ -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 diff --git a/nss-userspace-oss/nssinfo/src/src/nssinfo.c b/nss-userspace-oss/nssinfo/src/src/nssinfo.c deleted file mode 100644 index 60ce1ce..0000000 --- a/nss-userspace-oss/nssinfo/src/src/nssinfo.c +++ /dev/null @@ -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 -#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 , \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; -} diff --git a/nss-userspace-oss/nssinfo/src/src/nssinfo.h b/nss-userspace-oss/nssinfo/src/src/nssinfo.h deleted file mode 100644 index 6a3d10b..0000000 --- a/nss-userspace-oss/nssinfo/src/src/nssinfo.h +++ /dev/null @@ -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*/ diff --git a/nss-userspace-oss/nssinfo/src/src/nssinfo_dynamic_interface.c b/nss-userspace-oss/nssinfo/src/src/nssinfo_dynamic_interface.c deleted file mode 100644 index 3d3c412..0000000 --- a/nss-userspace-oss/nssinfo/src/src/nssinfo_dynamic_interface.c +++ /dev/null @@ -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 - -/* - * 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; -} diff --git a/nss-userspace-oss/nssinfo/src/src/nssinfo_dynamic_interface.h b/nss-userspace-oss/nssinfo/src/src/nssinfo_dynamic_interface.h deleted file mode 100644 index 6e33fa1..0000000 --- a/nss-userspace-oss/nssinfo/src/src/nssinfo_dynamic_interface.h +++ /dev/null @@ -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*/ diff --git a/nss-userspace-oss/nssinfo/src/src/nssinfo_ethrx.c b/nss-userspace-oss/nssinfo/src/src/nssinfo_ethrx.c deleted file mode 100644 index 5b80c15..0000000 --- a/nss-userspace-oss/nssinfo/src/src/nssinfo_ethrx.c +++ /dev/null @@ -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 -#include - -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; -} diff --git a/nss-userspace-oss/nssinfo/src/src/nssinfo_ethrx.h b/nss-userspace-oss/nssinfo/src/src/nssinfo_ethrx.h deleted file mode 100644 index e1261f7..0000000 --- a/nss-userspace-oss/nssinfo/src/src/nssinfo_ethrx.h +++ /dev/null @@ -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*/ diff --git a/nss-userspace-oss/nssinfo/src/src/nssinfo_ipv4.c b/nss-userspace-oss/nssinfo/src/src/nssinfo_ipv4.c deleted file mode 100644 index 83e8386..0000000 --- a/nss-userspace-oss/nssinfo/src/src/nssinfo_ipv4.c +++ /dev/null @@ -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; -} diff --git a/nss-userspace-oss/nssinfo/src/src/nssinfo_ipv4.h b/nss-userspace-oss/nssinfo/src/src/nssinfo_ipv4.h deleted file mode 100644 index ca29939..0000000 --- a/nss-userspace-oss/nssinfo/src/src/nssinfo_ipv4.h +++ /dev/null @@ -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*/ diff --git a/nss-userspace-oss/nssinfo/src/src/nssinfo_ipv6.c b/nss-userspace-oss/nssinfo/src/src/nssinfo_ipv6.c deleted file mode 100644 index 16af31c..0000000 --- a/nss-userspace-oss/nssinfo/src/src/nssinfo_ipv6.c +++ /dev/null @@ -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; -} diff --git a/nss-userspace-oss/nssinfo/src/src/nssinfo_ipv6.h b/nss-userspace-oss/nssinfo/src/src/nssinfo_ipv6.h deleted file mode 100644 index 5bb5fa5..0000000 --- a/nss-userspace-oss/nssinfo/src/src/nssinfo_ipv6.h +++ /dev/null @@ -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*/ diff --git a/nss-userspace-oss/nssinfo/src/src/nssinfo_lso_rx.c b/nss-userspace-oss/nssinfo/src/src/nssinfo_lso_rx.c deleted file mode 100644 index bbe7274..0000000 --- a/nss-userspace-oss/nssinfo/src/src/nssinfo_lso_rx.c +++ /dev/null @@ -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 -#include - -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; -} diff --git a/nss-userspace-oss/nssinfo/src/src/nssinfo_lso_rx.h b/nss-userspace-oss/nssinfo/src/src/nssinfo_lso_rx.h deleted file mode 100644 index 98fa804..0000000 --- a/nss-userspace-oss/nssinfo/src/src/nssinfo_lso_rx.h +++ /dev/null @@ -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*/ diff --git a/nss-userspace-oss/nssinfo/src/src/nssinfo_main.c b/nss-userspace-oss/nssinfo/src/src/nssinfo_main.c deleted file mode 100644 index 6070273..0000000 --- a/nss-userspace-oss/nssinfo/src/src/nssinfo_main.c +++ /dev/null @@ -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 - -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; -} diff --git a/nss-userspace-oss/nssinfo/src/src/nssinfo_n2h.c b/nss-userspace-oss/nssinfo/src/src/nssinfo_n2h.c deleted file mode 100644 index 4aac456..0000000 --- a/nss-userspace-oss/nssinfo/src/src/nssinfo_n2h.c +++ /dev/null @@ -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 -#include - -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; -} diff --git a/nss-userspace-oss/nssinfo/src/src/nssinfo_n2h.h b/nss-userspace-oss/nssinfo/src/src/nssinfo_n2h.h deleted file mode 100644 index eb3897a..0000000 --- a/nss-userspace-oss/nssinfo/src/src/nssinfo_n2h.h +++ /dev/null @@ -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*/ diff --git a/nss-userspace-oss/patches/000-create-makefile.patch b/nss-userspace-oss/patches/000-create-makefile.patch new file mode 100644 index 0000000..ab37f9f --- /dev/null +++ b/nss-userspace-oss/patches/000-create-makefile.patch @@ -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 diff --git a/nss-userspace-oss/patches/001-libnl-nss-revert-Add-timestamp-support-to-udpst.patch b/nss-userspace-oss/patches/001-libnl-nss-revert-Add-timestamp-support-to-udpst.patch new file mode 100644 index 0000000..a6a4b32 --- /dev/null +++ b/nss-userspace-oss/patches/001-libnl-nss-revert-Add-timestamp-support-to-udpst.patch @@ -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); diff --git a/nss-userspace-oss/patches/001-nssinfo-fix-warnings.patch b/nss-userspace-oss/patches/001-nssinfo-fix-warnings.patch new file mode 100644 index 0000000..215d975 --- /dev/null +++ b/nss-userspace-oss/patches/001-nssinfo-fix-warnings.patch @@ -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; + } + diff --git a/nss-userspace-oss/patches/002-libnl-modularize-makefile.patch b/nss-userspace-oss/patches/002-libnl-modularize-makefile.patch new file mode 100644 index 0000000..ca1f314 --- /dev/null +++ b/nss-userspace-oss/patches/002-libnl-modularize-makefile.patch @@ -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) diff --git a/nss-userspace-oss/patches/002-nss-switch-to-nl-tiny.patch b/nss-userspace-oss/patches/002-nss-switch-to-nl-tiny.patch new file mode 100644 index 0000000..d99d1cb --- /dev/null +++ b/nss-userspace-oss/patches/002-nss-switch-to-nl-tiny.patch @@ -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 diff --git a/nss-userspace-oss/patches/0030-fix-build.patch b/nss-userspace-oss/patches/0030-fix-build.patch new file mode 100644 index 0000000..5fdea98 --- /dev/null +++ b/nss-userspace-oss/patches/0030-fix-build.patch @@ -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 + #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; + } +