From e38f829d0c2f0e46b4c026044ed69ebbb4d2821d Mon Sep 17 00:00:00 2001
From: wuchangye <wuchangye@huawei.com>
Date: Fri, 8 Dec 2023 01:23:14 +0800
Subject: [PATCH] support show nic offload and features

---
 src/common/gazelle_dfx_msg.h           |  8 ++++++++
 src/lstack/Makefile                    |  4 ++--
 src/lstack/core/lstack_control_plane.c |  3 ++-
 src/lstack/core/lstack_dpdk.c          | 17 +++++++++++++++++
 src/lstack/core/lstack_stack_stat.c    | 10 +++++++---
 src/lstack/include/lstack_dpdk.h       |  1 +
 src/ltran/ltran_dfx.c                  | 23 +++++++++++++++++++++++
 8 files changed, 61 insertions(+), 6 deletions(-)

diff --git a/src/common/gazelle_dfx_msg.h b/src/common/gazelle_dfx_msg.h
index e2485ef..04fe996 100644
--- a/src/common/gazelle_dfx_msg.h
+++ b/src/common/gazelle_dfx_msg.h
@@ -48,6 +48,7 @@ enum GAZELLE_STAT_MODE {
     GAZELLE_STAT_LSTACK_LOW_POWER_MDF,
     GAZELLE_STAT_LSTACK_SHOW_XSTATS,
     GAZELLE_STAT_LSTACK_SHOW_AGGREGATE,
+    GAZELLE_STAT_LSTACK_SHOW_NIC_FEATURES,
 
     GAZELLE_STAT_MODE_MAX,
 };
@@ -236,6 +237,12 @@ struct nic_eth_xstats {
     uint16_t port_id;
 };
 
+struct nic_eth_features {
+    uint16_t port_id;
+    uint64_t rx_offload;
+    uint64_t tx_offload;
+};
+
 struct gazelle_stack_dfx_data {
     /* indicates whether the current message is the last */
     uint32_t eof;
@@ -250,6 +257,7 @@ struct gazelle_stack_dfx_data {
         struct gazelle_stat_lstack_conn conn;
         struct gazelle_stat_lstack_snmp snmp;
         struct nic_eth_xstats nic_xstats;
+        struct nic_eth_features nic_features;
     } data;
 };
 
diff --git a/src/lstack/Makefile b/src/lstack/Makefile
index 30965f8..d585040 100644
--- a/src/lstack/Makefile
+++ b/src/lstack/Makefile
@@ -29,9 +29,9 @@ LDFLAGS = -shared -ldl -lm -lpthread -lrt -lnuma -lconfig -lboundscheck
 ARCH := $(shell uname -m)
 
 ifneq ($(CC),clang)
-	SEC_FLAGS = -fstack-protector-strong -Werror -Wall -Wl,-z,relro, -Wl,-z,now -Wl,-z,noexecstack -Wtrampolines -fPIC -D_FORTIFY_SOURCE=2
+	SEC_FLAGS = -fstack-protector-strong -Werror -Wall -Wno-deprecated-declarations -Wl,-z,relro, -Wl,-z,now -Wl,-z,noexecstack -Wtrampolines -fPIC -D_FORTIFY_SOURCE=2
 else
-	SEC_FLAGS = -fstack-protector-strong -Werror -Wall -fPIC
+	SEC_FLAGS = -fstack-protector-strong -Werror -Wall -Wno-deprecated-declarations -fPIC
 endif
 $(info $(CC):$(SEC_FLAGS))
 
diff --git a/src/lstack/core/lstack_control_plane.c b/src/lstack/core/lstack_control_plane.c
index e7fcd26..668ff80 100644
--- a/src/lstack/core/lstack_control_plane.c
+++ b/src/lstack/core/lstack_control_plane.c
@@ -586,7 +586,8 @@ static int32_t handle_stat_request(int32_t sockfd)
     if (msg.stat_mode == GAZELLE_STAT_LSTACK_LOG_LEVEL_SET ||
         msg.stat_mode == GAZELLE_STAT_LSTACK_LOW_POWER_MDF) {
         return handle_proc_cmd(sockfd, &msg);
-    } else if (msg.stat_mode == GAZELLE_STAT_LSTACK_SHOW_XSTATS) {
+    } else if (msg.stat_mode == GAZELLE_STAT_LSTACK_SHOW_XSTATS ||
+        msg.stat_mode == GAZELLE_STAT_LSTACK_SHOW_NIC_FEATURES) {
         return handle_dpdk_cmd(sockfd, msg.stat_mode);
     } else {
         ret = handle_stack_cmd(sockfd, msg.stat_mode);
diff --git a/src/lstack/core/lstack_dpdk.c b/src/lstack/core/lstack_dpdk.c
index 5eff915..936fd89 100644
--- a/src/lstack/core/lstack_dpdk.c
+++ b/src/lstack/core/lstack_dpdk.c
@@ -881,3 +881,20 @@ void dpdk_nic_xstats_get(struct gazelle_stack_dfx_data *dfx, uint16_t port_id)
     }
     dfx->data.nic_xstats.len = len;
 }
+
+void dpdk_nic_features_get(struct gazelle_stack_dfx_data *dfx, uint16_t port_id)
+{
+    int ret;
+    struct rte_eth_conf dev_conf;
+
+    ret = rte_eth_dev_conf_get(port_id, &dev_conf);
+    if (ret != 0) {
+        LSTACK_LOG(ERR, LSTACK, "rte_eth_dev_conf_get failed:%d.\n", ret);
+        return;
+    }
+
+    dfx->data.nic_features.port_id = port_id;
+    dfx->data.nic_features.tx_offload = dev_conf.txmode.offloads;
+    dfx->data.nic_features.rx_offload = dev_conf.rxmode.offloads;
+    return;
+}
\ No newline at end of file
diff --git a/src/lstack/core/lstack_stack_stat.c b/src/lstack/core/lstack_stack_stat.c
index 45237b0..2d85efa 100644
--- a/src/lstack/core/lstack_stack_stat.c
+++ b/src/lstack/core/lstack_stack_stat.c
@@ -265,11 +265,15 @@ int handle_dpdk_cmd(int fd, enum GAZELLE_STAT_MODE stat_mode)
 
     if (stat_mode == GAZELLE_STAT_LSTACK_SHOW_XSTATS) {
         dpdk_nic_xstats_get(&dfx, get_protocol_stack_group()->port_id);
-        dfx.tid = 0;
-        dfx.eof = 1;
-        send_control_cmd_data(fd, &dfx);
+    } else if (stat_mode == GAZELLE_STAT_LSTACK_SHOW_NIC_FEATURES) {
+        dpdk_nic_features_get(&dfx, get_protocol_stack_group()->port_id);
+    } else {
+        return 0;
     }
 
+    dfx.tid = 0;
+    dfx.eof = 1;
+    send_control_cmd_data(fd, &dfx);
     return 0;
 }
 
diff --git a/src/lstack/include/lstack_dpdk.h b/src/lstack/include/lstack_dpdk.h
index 724ab24..05f5bc6 100644
--- a/src/lstack/include/lstack_dpdk.h
+++ b/src/lstack/include/lstack_dpdk.h
@@ -60,4 +60,5 @@ struct rte_mempool *create_pktmbuf_mempool(const char *name, uint32_t nb_mbuf,
 
 void dpdk_nic_xstats_get(struct gazelle_stack_dfx_data *dfx, uint16_t port_id);
 int32_t dpdk_alloc_pktmbuf(struct rte_mempool *pool, struct rte_mbuf **mbufs, uint32_t num);
+void dpdk_nic_features_get(struct gazelle_stack_dfx_data *dfx, uint16_t port_id);
 #endif /* GAZELLE_DPDK_H */
diff --git a/src/ltran/ltran_dfx.c b/src/ltran/ltran_dfx.c
index b999d20..dfcdc0c 100644
--- a/src/ltran/ltran_dfx.c
+++ b/src/ltran/ltran_dfx.c
@@ -24,6 +24,7 @@
 #include <securec.h>
 #include <unistd.h>
 #include <rte_log.h>
+#include <rte_ethdev.h>
 
 #include "ltran_stat.h"
 #include "ltran_base.h"
@@ -91,6 +92,7 @@ static void gazelle_print_ltran_sock(void *buf, const struct gazelle_stat_msg_re
 static void gazelle_print_ltran_conn(void *buf, const struct gazelle_stat_msg_request *req_msg);
 static void gazelle_print_lstack_xstats(void *buf, const struct gazelle_stat_msg_request *req_msg);
 static void gazelle_print_lstack_aggregate(void *buf, const struct gazelle_stat_msg_request *req_msg);
+static void gazelle_print_lstack_nic_features(void *buf, const struct gazelle_stat_msg_request *req_msg);
 
 static struct gazelle_dfx_list g_gazelle_dfx_tbl[] = {
     {GAZELLE_STAT_LTRAN_SHOW,          sizeof(struct gazelle_stat_ltran_total),  gazelle_print_ltran_stat_total},
@@ -117,6 +119,7 @@ static struct gazelle_dfx_list g_gazelle_dfx_tbl[] = {
     {GAZELLE_STAT_LSTACK_LOW_POWER_MDF, sizeof(struct gazelle_stack_dfx_data),  gazelle_print_lstack_stat_lpm},
     {GAZELLE_STAT_LSTACK_SHOW_XSTATS, sizeof(struct gazelle_stack_dfx_data), gazelle_print_lstack_xstats},
     {GAZELLE_STAT_LSTACK_SHOW_AGGREGATE, sizeof(struct gazelle_stack_dfx_data), gazelle_print_lstack_aggregate},
+    {GAZELLE_STAT_LSTACK_SHOW_NIC_FEATURES, sizeof(struct gazelle_stack_dfx_data), gazelle_print_lstack_nic_features},
 };
 
 static int32_t g_wait_reply = 1;
@@ -158,6 +161,23 @@ static void gazelle_print_lstack_xstats(void *buf, const struct gazelle_stat_msg
     printf("%s############################\n", nic_stats_border);
 }
 
+static void gazelle_print_lstack_nic_features(void *buf, const struct gazelle_stat_msg_request *req_msg)
+{
+    struct nic_eth_features *f = &(((struct gazelle_stack_dfx_data *)buf)->data.nic_features);
+    printf("###### NIC offload and other features for port %-2d #########\n", f->port_id);
+
+    printf("tx-ipv4-checksum: %s\n", (f->tx_offload & DEV_TX_OFFLOAD_IPV4_CKSUM) ? "on" : "off");
+    printf("tx-tcp_checksum: %s\n", (f->tx_offload & DEV_TX_OFFLOAD_TCP_CKSUM) ? "on" : "off");
+    printf("tx-tcp-tso: %s\n", (f->tx_offload & DEV_TX_OFFLOAD_TCP_TSO) ? "on" : "off");
+    printf("tx-udp-checksum: %s\n", (f->tx_offload & DEV_TX_OFFLOAD_UDP_CKSUM) ? "on" : "off");
+    printf("tx-vlan-insert: %s\n", (f->tx_offload & DEV_TX_OFFLOAD_VLAN_INSERT) ? "on" : "off");
+
+    printf("rx-ipv4-checksum: %s\n", (f->rx_offload & DEV_RX_OFFLOAD_IPV4_CKSUM) ? "on" : "off");
+    printf("rx-tcp-checksum: %s\n", (f->rx_offload & DEV_RX_OFFLOAD_TCP_CKSUM) ? "on" : "off");
+    printf("rx-udp-checksum: %s\n", (f->rx_offload & DEV_RX_OFFLOAD_UDP_CKSUM) ? "on" : "off");
+    printf("rx-vlan-strip: %s\n", (f->rx_offload & DEV_RX_OFFLOAD_VLAN_STRIP) ? "on" : "off");
+}
+
 static void gazelle_print_ltran_conn(void *buf, const struct gazelle_stat_msg_request *req_msg)
 {
     struct gazelle_stat_forward_table *table = (struct gazelle_stat_forward_table *)buf;
@@ -1069,6 +1089,7 @@ static void show_usage(void)
            "  -c, connect     show lstack connect \n"
            "  -l, latency     [time]   show lstack latency \n"
            "  -x, xstats      show lstack xstats \n"
+           "  -k, nic-features     show state of protocol offload and other features \n"
            "  -a, aggregatin  [time]   show lstack send/recv aggregation \n"
            "  set: \n"
            "  loglevel        {error | info | debug}  set lstack loglevel \n"
@@ -1316,6 +1337,8 @@ static int32_t parse_dfx_lstack_show_args(int32_t argc, char *argv[], struct gaz
         if (parse_delay_arg(argc, argv, delay) != 0) {
             return 0;
         }
+    } else if (strcmp(param, "-k") == 0 || strcmp(param, "nic-features") == 0) {
+        req_msg[cmd_index++].stat_mode = GAZELLE_STAT_LSTACK_SHOW_NIC_FEATURES;
     }
 
     return cmd_index;
-- 
2.27.0

