summaryrefslogtreecommitdiffstats
path: root/common/VIL/pipeline_arpicmp/pipeline_arpicmp.c
diff options
context:
space:
mode:
authorVishwesh M Rudramuni <vishweshmr@gmail.com>2017-04-18 19:41:40 +0530
committerDeepak S <deepak.s@linux.intel.com>2017-04-18 02:59:07 -0700
commit51cd08d9a3f2826088d122e2a5683315c77a2786 (patch)
tree3fac17a8f7bf362f0c77f1003615b2063d900d35 /common/VIL/pipeline_arpicmp/pipeline_arpicmp.c
parent03aef84e240c5be8813634735d825420129f1460 (diff)
common: Adding common library for sample vnf
JIRA: SAMPLEVNF-3 This patch adds common libraries required as part of the sample vnf. This includes the following libraries 1. ACL library 2. SIP 3. FTP 4. Connection tracker 5. L2l3 stack - Interface Manager - ARP & ICMPv4 - ND & ICMPv6 and other common libraries needed for ip pipeline framework Change-Id: I117690b6b63fbcd76974cd7274518484e60980ab Signed-off-by: Vishwesh M Rudramuni <vishwesh.m.rudramuni@intel.com> [Push patch to gerrit] Signed-off-by: Deepak S <deepak.s@linux.intel.com>
Diffstat (limited to 'common/VIL/pipeline_arpicmp/pipeline_arpicmp.c')
-rw-r--r--common/VIL/pipeline_arpicmp/pipeline_arpicmp.c2118
1 files changed, 2118 insertions, 0 deletions
diff --git a/common/VIL/pipeline_arpicmp/pipeline_arpicmp.c b/common/VIL/pipeline_arpicmp/pipeline_arpicmp.c
new file mode 100644
index 00000000..1ea9e749
--- /dev/null
+++ b/common/VIL/pipeline_arpicmp/pipeline_arpicmp.c
@@ -0,0 +1,2118 @@
+/*
+// Copyright (c) 2017 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+
+#include <cmdline_parse.h>
+#include <cmdline_parse_num.h>
+#include <cmdline_parse_string.h>
+#include <cmdline_parse_ipaddr.h>
+#include <cmdline_parse_etheraddr.h>
+
+#include "app.h"
+#include "pipeline_common_fe.h"
+#include "pipeline_arpicmp_be.h"
+#include "pipeline_arpicmp.h"
+#include "vnf_common.h"
+
+#include "app.h"
+#include "vnf_common.h"
+#ifndef VNF_ACL
+#include "lib_arp.h"
+#endif
+
+#include <rte_ip.h>
+#include <rte_udp.h>
+#include <rte_string_fns.h>
+
+uint16_t verbose_level = 1; /**< should be Silent by default. */
+uint16_t nb_pkt_per_burst = DEF_PKT_BURST; /**< Number of packets per burst. */
+
+/*
+ * Work-around of a compilation error with ICC on invocations of the
+ * rte_be_to_cpu_16() function.
+ */
+#ifdef __GCC__
+#define RTE_BE_TO_CPU_16(be_16_v) rte_be_to_cpu_16((be_16_v))
+#define RTE_CPU_TO_BE_16(cpu_16_v) rte_cpu_to_be_16((cpu_16_v))
+#else
+#if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
+#define RTE_BE_TO_CPU_16(be_16_v) (be_16_v)
+#define RTE_CPU_TO_BE_16(cpu_16_v) (cpu_16_v)
+#else
+#define RTE_BE_TO_CPU_16(be_16_v) \
+ ((uint16_t) ((((be_16_v) & 0xFF) << 8) | ((be_16_v) >> 8)))
+#define RTE_CPU_TO_BE_16(cpu_16_v) \
+ ((uint16_t) ((((cpu_16_v) & 0xFF) << 8) | ((cpu_16_v) >> 8)))
+#endif
+#endif
+
+/*
+ * arp add
+ */
+
+struct cmd_arp_add_result {
+ cmdline_fixed_string_t p_string;
+ uint32_t p;
+ cmdline_fixed_string_t arpadd_string;
+ uint32_t port_id;
+ cmdline_ipaddr_t ip;
+ struct ether_addr macaddr;
+
+};
+
+static void
+cmd_arp_add_parsed(void *parsed_result,
+ __rte_unused struct cmdline *cl, __rte_unused void *data)
+{
+ struct cmd_arp_add_result *params = parsed_result;
+ uint8_t ipv6[16];
+
+ #if 0
+ struct pipeline_arp_icmp_arp_key key;
+ key.type = PIPELINE_ARP_ICMP_ARP_IPV4;
+ key.key.ipv4.port_id = params->port_id;
+ key.key.ipv4.ip = rte_cpu_to_be_32(params->ip.addr.ipv4.s_addr);
+ populate_arp_entry(&req->macaddr, rte_bswap32(req->key.key.ipv4.ip),
+ req->key.key.ipv4.port_id);
+ #endif
+ if (params->ip.family == AF_INET) {
+ populate_arp_entry(&params->macaddr,
+ rte_cpu_to_be_32(params->ip.addr.
+ ipv4.s_addr),
+ params->port_id
+ #ifndef VNF_ACL
+ , STATIC_ARP
+ #endif
+ );
+ } else {
+ memcpy(ipv6, params->ip.addr.ipv6.s6_addr, 16);
+ populate_nd_entry(&params->macaddr, ipv6, params->port_id
+ #ifndef VNF_ACL
+ , STATIC_ND
+ #endif
+ );
+ }
+}
+
+static cmdline_parse_token_string_t cmd_arp_add_p_string =
+TOKEN_STRING_INITIALIZER(struct cmd_arp_add_result, p_string,
+ "p");
+
+static cmdline_parse_token_num_t cmd_arp_add_p =
+TOKEN_NUM_INITIALIZER(struct cmd_arp_add_result, p, UINT32);
+
+static cmdline_parse_token_string_t cmd_arp_add_arp_string =
+TOKEN_STRING_INITIALIZER(struct cmd_arp_add_result, arpadd_string, "arpadd");
+
+static cmdline_parse_token_num_t cmd_arp_add_port_id =
+TOKEN_NUM_INITIALIZER(struct cmd_arp_add_result, port_id, UINT32);
+
+static cmdline_parse_token_ipaddr_t cmd_arp_add_ip =
+TOKEN_IPADDR_INITIALIZER(struct cmd_arp_add_result, ip);
+
+static cmdline_parse_token_etheraddr_t cmd_arp_add_macaddr =
+TOKEN_ETHERADDR_INITIALIZER(struct cmd_arp_add_result, macaddr);
+
+static cmdline_parse_inst_t cmd_arp_add = {
+ .f = cmd_arp_add_parsed,
+ .data = NULL,
+ .help_str = "ARP add",
+ .tokens = {
+ (void *)&cmd_arp_add_p_string,
+ (void *)&cmd_arp_add_p,
+ (void *)&cmd_arp_add_arp_string,
+ (void *)&cmd_arp_add_port_id,
+ (void *)&cmd_arp_add_ip,
+ (void *)&cmd_arp_add_macaddr,
+ NULL,
+ },
+};
+
+/*
+ * arp del
+ */
+
+struct cmd_arp_del_result {
+ cmdline_fixed_string_t p_string;
+ uint32_t p;
+ cmdline_fixed_string_t arp_string;
+ uint32_t port_id;
+ cmdline_ipaddr_t ip;
+};
+
+static void
+cmd_arp_del_parsed(void *parsed_result,
+ __rte_unused struct cmdline *cl, __rte_unused void *data)
+{
+ struct cmd_arp_del_result *params = parsed_result;
+ uint8_t ipv6[16];
+
+ #if 0
+ struct pipeline_arp_icmp_arp_key key;
+ key.type = PIPELINE_ARP_ICMP_ARP_IPV4;
+ key.key.ipv4.ip = rte_cpu_to_be_32(params->ip.addr.ipv4.s_addr);
+ key.key.ipv4.port_id = params->port_id;
+ remove_arp_entry(rte_bswap32(req->key.key.ipv4.ip),
+ req->key.key.ipv4.port_id);
+ #endif
+ if (params->ip.family == AF_INET) {
+ remove_arp_entry(rte_cpu_to_be_32(params->ip.addr.ipv4.s_addr),
+ params->port_id
+ #ifndef VNF_ACL
+ , NULL
+ #endif
+ );
+ } else {
+ memcpy(ipv6, params->ip.addr.ipv6.s6_addr, 16);
+ remove_nd_entry_ipv6(ipv6, params->port_id);
+ }
+}
+
+static cmdline_parse_token_string_t cmd_arp_del_p_string =
+TOKEN_STRING_INITIALIZER(struct cmd_arp_del_result, p_string,
+ "p");
+
+static cmdline_parse_token_num_t cmd_arp_del_p =
+TOKEN_NUM_INITIALIZER(struct cmd_arp_del_result, p, UINT32);
+
+static cmdline_parse_token_string_t cmd_arp_del_arp_string =
+TOKEN_STRING_INITIALIZER(struct cmd_arp_del_result, arp_string, "arpdel");
+
+static cmdline_parse_token_num_t cmd_arp_del_port_id =
+TOKEN_NUM_INITIALIZER(struct cmd_arp_del_result, port_id, UINT32);
+
+static cmdline_parse_token_ipaddr_t cmd_arp_del_ip =
+TOKEN_IPADDR_INITIALIZER(struct cmd_arp_del_result, ip);
+
+static cmdline_parse_inst_t cmd_arp_del = {
+ .f = cmd_arp_del_parsed,
+ .data = NULL,
+ .help_str = "ARP delete",
+ .tokens = {
+ (void *)&cmd_arp_del_p_string,
+ (void *)&cmd_arp_del_p,
+ (void *)&cmd_arp_del_arp_string,
+ (void *)&cmd_arp_del_port_id,
+ (void *)&cmd_arp_del_ip,
+ NULL,
+ },
+};
+
+/*
+ * arp req
+ */
+
+/*Re-uses delete structures*/
+
+static void
+cmd_arp_req_parsed(void *parsed_result,
+ __rte_unused struct cmdline *cl, __rte_unused void *data)
+{
+ struct cmd_arp_del_result *params = parsed_result;
+ /*struct app_params *app = data;*/
+
+ struct arp_key_ipv4 key;
+/* int status;*/
+
+/* key.type = ARP_IPV4;*/
+/* key.key.ipv4.ip = rte_cpu_to_be_32(params->ip.addr.ipv4.s_addr);*/
+/* key.key.ipv4.port_id = params->port_id;*/
+ key.ip = rte_cpu_to_be_32(params->ip.addr.ipv4.s_addr);
+ key.port_id = params->port_id;
+ key.filler1 = 0;
+ key.filler2 = 0;
+ key.filler3 = 0;
+
+ struct arp_entry_data *arp_data = retrieve_arp_entry(key);
+
+ if (arp_data) {
+ if (ARPICMP_DEBUG)
+ printf("ARP entry exists for ip 0x%x, port %d\n",
+ params->ip.addr.ipv4.s_addr, params->port_id);
+ return;
+ }
+ /* else request an arp*/
+ if (ARPICMP_DEBUG)
+ printf("ARP - requesting arp for ip 0x%x, port %d\n",
+ params->ip.addr.ipv4.s_addr, params->port_id);
+
+ #ifdef VNF_ACL
+ request_arp_wrap(params->port_id, params->ip.addr.ipv4.s_addr);
+ #else
+ request_arp(params->port_id, params->ip.addr.ipv4.s_addr);
+ #endif
+ /*give pipeline number too*/
+}
+
+static cmdline_parse_token_string_t cmd_arp_req_string =
+TOKEN_STRING_INITIALIZER(struct cmd_arp_del_result, arp_string, "arpreq");
+
+static cmdline_parse_inst_t cmd_arp_req = {
+ .f = cmd_arp_req_parsed,
+ .data = NULL,
+ .help_str = "ARP request",
+ .tokens = {
+ (void *)&cmd_arp_del_p_string,
+ (void *)&cmd_arp_del_p,
+ (void *)&cmd_arp_req_string,
+ (void *)&cmd_arp_del_port_id,
+ (void *)&cmd_arp_del_ip,
+ NULL,
+ },
+};
+
+/*
+ * arpicmp echo req
+ */
+
+/*Re-uses delete structures*/
+
+static void
+cmd_icmp_echo_req_parsed(void *parsed_result,
+ __rte_unused struct cmdline *cl,
+ __rte_unused void *data)
+{
+ struct cmd_arp_del_result *params = parsed_result;
+
+ if (ARPICMP_DEBUG)
+ printf("Echo Req Handler ip %x, port %d\n",
+ params->ip.addr.ipv4.s_addr, params->port_id);
+
+ request_echo(params->port_id, params->ip.addr.ipv4.s_addr);
+}
+
+static cmdline_parse_token_string_t cmd_icmp_echo_req_string =
+TOKEN_STRING_INITIALIZER(struct cmd_arp_del_result, arp_string, "icmpecho");
+
+static cmdline_parse_inst_t cmd_icmp_echo_req = {
+ .f = cmd_icmp_echo_req_parsed,
+ .data = NULL,
+ .help_str = "ICMP echo request",
+ .tokens = {
+ (void *)&cmd_arp_del_p_string,
+ (void *)&cmd_arp_del_p,
+ (void *)&cmd_icmp_echo_req_string,
+ (void *)&cmd_arp_del_port_id,
+ (void *)&cmd_arp_del_ip,
+ NULL,
+ },
+};
+
+/*
+ * arp ls
+ */
+
+struct cmd_arp_ls_result {
+ cmdline_fixed_string_t p_string;
+ uint32_t p;
+ cmdline_fixed_string_t arp_string;
+};
+
+static void
+cmd_arp_ls_parsed(__rte_unused void *parsed_result,
+ __rte_unused struct cmdline *cl, __rte_unused void *data)
+{
+ printf("\nARP table ...\n");
+ printf("-------------\n");
+ print_arp_table();
+
+ printf
+ ("............................................................\n");
+
+ printf("\nND IPv6 table:\n");
+ printf("--------------\n");
+ print_nd_table();
+}
+
+static cmdline_parse_token_string_t cmd_arp_ls_p_string =
+TOKEN_STRING_INITIALIZER(struct cmd_arp_ls_result, p_string,
+ "p");
+
+static cmdline_parse_token_num_t cmd_arp_ls_p =
+TOKEN_NUM_INITIALIZER(struct cmd_arp_ls_result, p, UINT32);
+
+static cmdline_parse_token_string_t cmd_arp_ls_arp_string =
+TOKEN_STRING_INITIALIZER(struct cmd_arp_ls_result, arp_string,
+ "arpls");
+
+static cmdline_parse_inst_t cmd_arp_ls = {
+ .f = cmd_arp_ls_parsed,
+ .data = NULL,
+ .help_str = "ARP list",
+ .tokens = {
+ (void *)&cmd_arp_ls_p_string,
+ (void *)&cmd_arp_ls_p,
+ (void *)&cmd_arp_ls_arp_string,
+ NULL,
+ },
+};
+
+/*
+ * show ports info
+ */
+
+struct cmd_show_ports_info_result {
+ cmdline_fixed_string_t p_string;
+ uint32_t p;
+ cmdline_fixed_string_t arp_string;
+};
+
+static void
+cmd_show_ports_info_parsed(__rte_unused void *parsed_result,
+ __rte_unused struct cmdline *cl,
+ __rte_unused void *data)
+{
+ show_ports_info();
+}
+
+static cmdline_parse_token_string_t cmd_show_ports_info_string =
+TOKEN_STRING_INITIALIZER(struct cmd_arp_ls_result, arp_string,
+ "showPortsInfo");
+
+static cmdline_parse_inst_t cmd_show_ports_info = {
+ .f = cmd_show_ports_info_parsed,
+ .data = NULL,
+ .help_str = "show ports info",
+ .tokens = {
+ (void *)&cmd_arp_ls_p_string,
+ (void *)&cmd_arp_ls_p,
+ (void *)&cmd_show_ports_info_string,
+ NULL,
+ },
+};
+
+#ifndef VNF_ACL
+struct cmd_arp_dbg_result {
+ cmdline_fixed_string_t arpdbg_str;
+ uint32_t flag;
+};
+
+cmdline_parse_token_string_t cmd_arp_dbg_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_arp_dbg_result, arpdbg_str,
+ "arpdbg");
+cmdline_parse_token_num_t cmd_arp_dbg_flag =
+ TOKEN_NUM_INITIALIZER(struct cmd_arp_dbg_result, flag, UINT32);
+
+static void
+cmd_arp_dbg_parse(
+ void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __rte_unused void *data)
+{
+ struct cmd_arp_dbg_result *params = parsed_result;
+ if(params)
+ {
+ set_arpdebug(params->flag);
+ }
+ else
+ {
+ printf("%s: Params is NULL",__FUNCTION__);
+ }
+}
+
+cmdline_parse_inst_t cmd_arp_dbg = {
+ .f = cmd_arp_dbg_parse,
+ .data = NULL,
+ .help_str = "Turn on/off(1/0) arp debug",
+ .tokens = {
+ (void *)&cmd_arp_dbg_string,
+ (void *)&cmd_arp_dbg_flag,
+ NULL,
+ },
+};
+
+struct cmd_arp_timer_result {
+ cmdline_fixed_string_t arptimer_str;
+ uint32_t arptimer_val;
+};
+
+cmdline_parse_token_string_t cmd_arp_timer_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_arp_timer_result, arptimer_str,
+ "arptimerexpiry");
+cmdline_parse_token_num_t cmd_arp_timer_val =
+ TOKEN_NUM_INITIALIZER(struct cmd_arp_timer_result, arptimer_val, UINT32);
+
+static void
+cmd_arp_timer_parse(
+ void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __rte_unused void *data)
+{
+ struct cmd_arp_timer_result *params = parsed_result;
+ if(params)
+ {
+ set_arptimeout(params->arptimer_val);
+ }
+ else
+ {
+ printf("%s: Params is NULL",__FUNCTION__);
+ }
+}
+
+cmdline_parse_inst_t cmd_arp_timer = {
+ .f = cmd_arp_timer_parse,
+ .data = NULL,
+ .help_str = "Timer expiry val by def 10 sec",
+ .tokens = {
+ (void *)&cmd_arp_timer_string,
+ (void *)&cmd_arp_timer_val,
+ NULL,
+ },
+};
+#endif
+
+/*
+ * Forwarding of packets in I/O mode.
+ * Forward packets "as-is".
+ * This is the fastest possible forwarding operation, as it does not access
+ * to packets data.
+ */
+ static void
+pkt_burst_io_forward(struct fwd_stream *fs)
+{
+ struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
+ uint16_t nb_rx;
+ uint16_t nb_tx;
+
+ #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
+ uint64_t start_tsc;
+ uint64_t end_tsc;
+ uint64_t core_cycles;
+ #endif
+
+ #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
+ start_tsc = rte_rdtsc();
+ #endif
+
+ /*
+ * Receive a burst of packets and forward them.
+ */
+ nb_rx = rte_eth_rx_burst(fs->rx_port, fs->rx_queue, pkts_burst,
+ nb_pkt_per_burst);
+ if (unlikely(nb_rx == 0))
+ return;
+
+ #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
+ fs->rx_burst_stats.pkt_burst_spread[nb_rx]++;
+ #endif
+
+ fs->rx_packets += nb_rx;
+ nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, pkts_burst, nb_rx);
+ fs->tx_packets += nb_tx;
+
+ #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
+ fs->tx_burst_stats.pkt_burst_spread[nb_tx]++;
+ #endif
+
+ if (unlikely(nb_tx < nb_rx)) {
+ fs->fwd_dropped += (nb_rx - nb_tx);
+ do {
+ rte_pktmbuf_free(pkts_burst[nb_tx]);
+ } while (++nb_tx < nb_rx);
+ }
+
+ #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
+ end_tsc = rte_rdtsc();
+ core_cycles = (end_tsc - start_tsc);
+ fs->core_cycles = (uint64_t) (fs->core_cycles + core_cycles);
+ #endif
+}
+
+
+struct fwd_engine io_fwd_engine = {
+ .fwd_mode_name = "io",
+ .port_fwd_begin = NULL,
+ .port_fwd_end = NULL,
+ .packet_fwd = pkt_burst_io_forward,
+};
+
+static inline void print_ether_addr(
+ const char *what,
+ struct ether_addr *eth_addr)
+{
+ char buf[ETHER_ADDR_FMT_SIZE];
+ ether_format_addr(buf, ETHER_ADDR_FMT_SIZE, eth_addr);
+ printf("%s%s", what, buf);
+}
+
+/*
+ * Received a burst of packets.
+ */
+ static void
+pkt_burst_receive(struct fwd_stream *fs)
+{
+ struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
+ struct rte_mbuf *mb;
+ struct ether_hdr *eth_hdr;
+ uint16_t eth_type;
+ uint64_t ol_flags;
+ uint16_t nb_rx;
+ uint16_t i, packet_type;
+ uint16_t is_encapsulation;
+
+ #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
+ uint64_t start_tsc;
+ uint64_t end_tsc;
+ uint64_t core_cycles;
+ #endif
+
+ #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
+ start_tsc = rte_rdtsc();
+ #endif
+
+ /*
+ * Receive a burst of packets.
+ */
+ nb_rx = rte_eth_rx_burst(fs->rx_port, fs->rx_queue, pkts_burst,
+ nb_pkt_per_burst);
+ if (unlikely(nb_rx == 0))
+ return;
+
+ #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
+ fs->rx_burst_stats.pkt_burst_spread[nb_rx]++;
+ #endif
+
+ fs->rx_packets += nb_rx;
+
+ /*
+ * Dump each received packet if verbose_level > 0.
+ */
+ if (verbose_level > 0)
+ printf("port %u/queue %u: received %u packets\n",
+ (unsigned int) fs->rx_port,
+ (unsigned int) fs->rx_queue,
+ (unsigned int) nb_rx);
+ for (i = 0; i < nb_rx; i++) {
+ mb = pkts_burst[i];
+ if (verbose_level == 0) {
+ rte_pktmbuf_free(mb);
+ continue;
+ }
+ eth_hdr = rte_pktmbuf_mtod(mb, struct ether_hdr *);
+ eth_type = RTE_BE_TO_CPU_16(eth_hdr->ether_type);
+ ol_flags = mb->ol_flags;
+ packet_type = mb->packet_type;
+ is_encapsulation = RTE_ETH_IS_TUNNEL_PKT(packet_type);
+
+ print_ether_addr(" src=", &eth_hdr->s_addr);
+ print_ether_addr(" - dst=", &eth_hdr->d_addr);
+ printf(" - type=0x%04x - length=%u - nb_segs=%d",
+ eth_type, (unsigned int) mb->pkt_len,
+ (int)mb->nb_segs);
+ if (ol_flags & PKT_RX_RSS_HASH) {
+ printf(" - RSS hash=0x%x", (unsigned int)
+ mb->hash.rss);
+ printf(" - RSS queue=0x%x", (unsigned int)
+ fs->rx_queue);
+ } else if (ol_flags & PKT_RX_FDIR) {
+ printf(" - FDIR matched ");
+ if (ol_flags & PKT_RX_FDIR_ID)
+ printf("ID=0x%x",
+ mb->hash.fdir.hi);
+ else if (ol_flags & PKT_RX_FDIR_FLX)
+ printf("flex bytes=0x%08x %08x",
+ mb->hash.fdir.hi, mb->hash.fdir.lo);
+ else
+ printf("hash=0x%x ID=0x%x ",
+ mb->hash.fdir.hash, mb->hash.fdir.id);
+ }
+ if (ol_flags & PKT_RX_VLAN_PKT)
+ printf(" - VLAN tci=0x%x", mb->vlan_tci);
+ if (ol_flags & PKT_RX_QINQ_PKT)
+ printf(" - QinQ VLAN tci=0x%x, VLAN tci outer=0x%x",
+ mb->vlan_tci, mb->vlan_tci_outer);
+ if (mb->packet_type) {
+ uint32_t ptype;
+
+ /* (outer) L2 packet type */
+ ptype = mb->packet_type & RTE_PTYPE_L2_MASK;
+ switch (ptype) {
+ case RTE_PTYPE_L2_ETHER:
+ printf(" - (outer) L2 type: ETHER");
+ break;
+ case RTE_PTYPE_L2_ETHER_TIMESYNC:
+ printf(" - (outer) L2 type: ETHER_Timesync");
+ break;
+ case RTE_PTYPE_L2_ETHER_ARP:
+ printf(" - (outer) L2 type: ETHER_ARP");
+ break;
+ case RTE_PTYPE_L2_ETHER_LLDP:
+ printf(" - (outer) L2 type: ETHER_LLDP");
+ break;
+ default:
+ printf(" - (outer) L2 type: Unknown");
+ break;
+ }
+
+ /* (outer) L3 packet type */
+ ptype = mb->packet_type & RTE_PTYPE_L3_MASK;
+ switch (ptype) {
+ case RTE_PTYPE_L3_IPV4:
+ printf(" - (outer) L3 type: IPV4");
+ break;
+ case RTE_PTYPE_L3_IPV4_EXT:
+ printf(" - (outer) L3 type: IPV4_EXT");
+ break;
+ case RTE_PTYPE_L3_IPV6:
+ printf(" - (outer) L3 type: IPV6");
+ break;
+ case RTE_PTYPE_L3_IPV4_EXT_UNKNOWN:
+ printf(" - (outer) L3 type: IPV4_EXT_UNKNOWN");
+ break;
+ case RTE_PTYPE_L3_IPV6_EXT:
+ printf(" - (outer) L3 type: IPV6_EXT");
+ break;
+ case RTE_PTYPE_L3_IPV6_EXT_UNKNOWN:
+ printf(" - (outer) L3 type: IPV6_EXT_UNKNOWN");
+ break;
+ default:
+ printf(" - (outer) L3 type: Unknown");
+ break;
+ }
+
+ /* (outer) L4 packet type */
+ ptype = mb->packet_type & RTE_PTYPE_L4_MASK;
+ switch (ptype) {
+ case RTE_PTYPE_L4_TCP:
+ printf(" - (outer) L4 type: TCP");
+ break;
+ case RTE_PTYPE_L4_UDP:
+ printf(" - (outer) L4 type: UDP");
+ break;
+ case RTE_PTYPE_L4_FRAG:
+ printf(" - (outer) L4 type: L4_FRAG");
+ break;
+ case RTE_PTYPE_L4_SCTP:
+ printf(" - (outer) L4 type: SCTP");
+ break;
+ case RTE_PTYPE_L4_ICMP:
+ printf(" - (outer) L4 type: ICMP");
+ break;
+ case RTE_PTYPE_L4_NONFRAG:
+ printf(" - (outer) L4 type: L4_NONFRAG");
+ break;
+ default:
+ printf(" - (outer) L4 type: Unknown");
+ break;
+ }
+
+ /* packet tunnel type */
+ ptype = mb->packet_type & RTE_PTYPE_TUNNEL_MASK;
+ switch (ptype) {
+ case RTE_PTYPE_TUNNEL_IP:
+ printf(" - Tunnel type: IP");
+ break;
+ case RTE_PTYPE_TUNNEL_GRE:
+ printf(" - Tunnel type: GRE");
+ break;
+ case RTE_PTYPE_TUNNEL_VXLAN:
+ printf(" - Tunnel type: VXLAN");
+ break;
+ case RTE_PTYPE_TUNNEL_NVGRE:
+ printf(" - Tunnel type: NVGRE");
+ break;
+ case RTE_PTYPE_TUNNEL_GENEVE:
+ printf(" - Tunnel type: GENEVE");
+ break;
+ case RTE_PTYPE_TUNNEL_GRENAT:
+ printf(" - Tunnel type: GRENAT");
+ break;
+ default:
+ printf(" - Tunnel type: Unknown");
+ break;
+ }
+
+ /* inner L2 packet type */
+ ptype = mb->packet_type & RTE_PTYPE_INNER_L2_MASK;
+ switch (ptype) {
+ case RTE_PTYPE_INNER_L2_ETHER:
+ printf(" - Inner L2 type: ETHER");
+ break;
+ case RTE_PTYPE_INNER_L2_ETHER_VLAN:
+ printf(" - Inner L2 type: ETHER_VLAN");
+ break;
+ default:
+ printf(" - Inner L2 type: Unknown");
+ break;
+ }
+ /* inner L3 packet type */
+ ptype = mb->packet_type & RTE_PTYPE_INNER_L3_MASK;
+ switch (ptype) {
+ case RTE_PTYPE_INNER_L3_IPV4:
+ printf(" - Inner L3 type: IPV4");
+ break;
+ case RTE_PTYPE_INNER_L3_IPV4_EXT:
+ printf(" - Inner L3 type: IPV4_EXT");
+ break;
+ case RTE_PTYPE_INNER_L3_IPV6:
+ printf(" - Inner L3 type: IPV6");
+ break;
+ case RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN:
+ printf(" - Inner L3 type: "
+ "IPV4_EXT_UNKNOWN");
+ break;
+ case RTE_PTYPE_INNER_L3_IPV6_EXT:
+ printf(" - Inner L3 type: IPV6_EXT");
+ break;
+ case RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN:
+ printf(" - Inner L3 type: "
+ "IPV6_EXT_UNKNOWN");
+ break;
+ default:
+ printf(" - Inner L3 type: Unknown");
+ break;
+ }
+
+ /* inner L4 packet type */
+ ptype = mb->packet_type & RTE_PTYPE_INNER_L4_MASK;
+ switch (ptype) {
+ case RTE_PTYPE_INNER_L4_TCP:
+ printf(" - Inner L4 type: TCP");
+ break;
+ case RTE_PTYPE_INNER_L4_UDP:
+ printf(" - Inner L4 type: UDP");
+ break;
+ case RTE_PTYPE_INNER_L4_FRAG:
+ printf(" - Inner L4 type: L4_FRAG");
+ break;
+ case RTE_PTYPE_INNER_L4_SCTP:
+ printf(" - Inner L4 type: SCTP");
+ break;
+ case RTE_PTYPE_INNER_L4_ICMP:
+ printf(" - Inner L4 type: ICMP");
+ break;
+ case RTE_PTYPE_INNER_L4_NONFRAG:
+ printf(" - Inner L4 type: L4_NONFRAG");
+ break;
+ default:
+ printf(" - Inner L4 type: Unknown");
+ break;
+ }
+ printf("\n");
+ } else
+ printf("Unknown packet type\n");
+ if (is_encapsulation) {
+ struct ipv4_hdr *ipv4_hdr;
+ struct ipv6_hdr *ipv6_hdr;
+ struct udp_hdr *udp_hdr;
+ uint8_t l2_len;
+ uint8_t l3_len;
+ uint8_t l4_len;
+ uint8_t l4_proto;
+ struct vxlan_hdr *vxlan_hdr;
+
+ l2_len = sizeof(struct ether_hdr);
+
+ /* Do not support ipv4 option field */
+ if (RTE_ETH_IS_IPV4_HDR(packet_type)) {
+ l3_len = sizeof(struct ipv4_hdr);
+ ipv4_hdr = rte_pktmbuf_mtod_offset(mb,
+ struct ipv4_hdr *,
+ l2_len);
+ l4_proto = ipv4_hdr->next_proto_id;
+ } else {
+ l3_len = sizeof(struct ipv6_hdr);
+ ipv6_hdr = rte_pktmbuf_mtod_offset(mb,
+ struct ipv6_hdr *,
+ l2_len);
+ l4_proto = ipv6_hdr->proto;
+ }
+ if (l4_proto == IPPROTO_UDP) {
+ udp_hdr = rte_pktmbuf_mtod_offset(mb,
+ struct udp_hdr *,
+ l2_len + l3_len);
+ l4_len = sizeof(struct udp_hdr);
+ vxlan_hdr = rte_pktmbuf_mtod_offset(mb,
+ struct vxlan_hdr *,
+ l2_len + l3_len + l4_len);
+
+ printf(" - VXLAN packet: packet type =%d, "
+ "Destination UDP port =%d, VNI = %d",
+ packet_type,
+ RTE_BE_TO_CPU_16(udp_hdr->dst_port),
+ rte_be_to_cpu_32(
+ vxlan_hdr->vx_vni) >> 8);
+ }
+ }
+ printf(" - Receive queue=0x%x", (unsigned int) fs->rx_queue);
+ printf("\n");
+ if (ol_flags != 0) {
+ unsigned int rxf;
+ const char *name;
+
+ for (rxf = 0; rxf < sizeof(mb->ol_flags) * 8; rxf++) {
+ if ((ol_flags & (1ULL << rxf)) == 0)
+ continue;
+ name = rte_get_rx_ol_flag_name(1ULL << rxf);
+ if (name == NULL)
+ continue;
+ printf(" %s\n", name);
+ }
+ }
+ rte_pktmbuf_free(mb);
+ }
+
+ #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
+ end_tsc = rte_rdtsc();
+ core_cycles = (end_tsc - start_tsc);
+ fs->core_cycles = (uint64_t) (fs->core_cycles + core_cycles);
+ #endif
+}
+
+struct fwd_engine rx_only_engine = {
+ .fwd_mode_name = "rxonly",
+ .port_fwd_begin = NULL,
+ .port_fwd_end = NULL,
+ .packet_fwd = pkt_burst_receive,
+};
+
+/* *** SET FORWARDING MODE *** */
+struct cmd_set_fwd_mode_result {
+ cmdline_fixed_string_t set;
+ cmdline_fixed_string_t fwd;
+ cmdline_fixed_string_t mode;
+};
+
+/*
+ * Forwarding engines.
+ */
+struct fwd_engine *fwd_engines[] = {
+ &io_fwd_engine,
+ #if 0
+ &mac_fwd_engine,
+ &mac_retry_fwd_engine,
+ &mac_swap_engine,
+ &flow_gen_engine,
+ #endif
+ &rx_only_engine,
+ #if 0
+ &tx_only_engine,
+ &csum_fwd_engine,
+ &icmp_echo_engine,
+ #ifdef RTE_LIBRTE_IEEE1588
+ &ieee1588_fwd_engine,
+ #endif
+ #endif
+ NULL,
+};
+
+struct fwd_engine *cur_fwd_eng = &io_fwd_engine; /**< IO mode by default. */
+
+void set_pkt_forwarding_mode(const char *fwd_mode_name)
+{
+ struct fwd_engine *fwd_eng;
+ unsigned int i;
+
+ i = 0;
+ while ((fwd_eng = fwd_engines[i]) != NULL) {
+ if (!strcmp(fwd_eng->fwd_mode_name, fwd_mode_name)) {
+ printf("Set %s packet forwarding mode\n",
+ fwd_mode_name);
+ cur_fwd_eng = fwd_eng;
+ return;
+ }
+ i++;
+ }
+ printf("Invalid %s packet forwarding mode\n", fwd_mode_name);
+}
+
+static void cmd_set_fwd_mode_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_set_fwd_mode_result *res = parsed_result;
+
+ set_pkt_forwarding_mode(res->mode);
+}
+
+cmdline_parse_token_string_t cmd_setfwd_set =
+TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_mode_result, set, "set");
+cmdline_parse_token_string_t cmd_setfwd_fwd =
+TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_mode_result, fwd, "fwd");
+cmdline_parse_token_string_t cmd_setfwd_mode =
+TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_mode_result, mode,
+ "rxonly" /* defined at init */);
+
+cmdline_parse_inst_t cmd_set_fwd_mode = {
+ .f = cmd_set_fwd_mode_parsed,
+ .data = NULL,
+ .help_str = NULL, /* defined at init */
+ .tokens = {
+ (void *)&cmd_setfwd_set,
+ (void *)&cmd_setfwd_fwd,
+ (void *)&cmd_setfwd_mode,
+ NULL,
+ },
+};
+
+#if 1
+
+static uint16_t
+str2flowtype(char *string)
+{
+ uint8_t i = 0;
+ static const struct {
+ char str[32];
+ uint16_t type;
+ } flowtype_str[] = {
+ {"raw", RTE_ETH_FLOW_RAW},
+ {"ipv4", RTE_ETH_FLOW_IPV4},
+ {"ipv4-frag", RTE_ETH_FLOW_FRAG_IPV4},
+ {"ipv4-tcp", RTE_ETH_FLOW_NONFRAG_IPV4_TCP},
+ {"ipv4-udp", RTE_ETH_FLOW_NONFRAG_IPV4_UDP},
+ {"ipv4-sctp", RTE_ETH_FLOW_NONFRAG_IPV4_SCTP},
+ {"ipv4-other", RTE_ETH_FLOW_NONFRAG_IPV4_OTHER},
+ {"ipv6", RTE_ETH_FLOW_IPV6},
+ {"ipv6-frag", RTE_ETH_FLOW_FRAG_IPV6},
+ {"ipv6-tcp", RTE_ETH_FLOW_NONFRAG_IPV6_TCP},
+ {"ipv6-udp", RTE_ETH_FLOW_NONFRAG_IPV6_UDP},
+ {"ipv6-sctp", RTE_ETH_FLOW_NONFRAG_IPV6_SCTP},
+ {"ipv6-other", RTE_ETH_FLOW_NONFRAG_IPV6_OTHER},
+ {"l2_payload", RTE_ETH_FLOW_L2_PAYLOAD},
+ };
+
+ for (i = 0; i < RTE_DIM(flowtype_str); i++) {
+ if (!strcmp(flowtype_str[i].str, string))
+ return flowtype_str[i].type;
+ }
+ return RTE_ETH_FLOW_UNKNOWN;
+}
+
+static inline int
+parse_flexbytes(const char *q_arg, uint8_t *flexbytes, uint16_t max_num)
+{
+ char s[256];
+ const char *p, *p0 = q_arg;
+ char *end;
+ unsigned long int_fld;
+ char *str_fld[max_num];
+ int i;
+ unsigned int size;
+ int ret = -1;
+
+ p = strchr(p0, '(');
+ if (p == NULL)
+ return -1;
+ ++p;
+ p0 = strchr(p, ')');
+ if (p0 == NULL)
+ return -1;
+
+ size = p0 - p;
+ if (size >= sizeof(s))
+ return -1;
+
+ snprintf(s, sizeof(s), "%.*s", size, p);
+ ret = rte_strsplit(s, sizeof(s), str_fld, max_num, ',');
+ if (ret < 0 || ret > max_num)
+ return -1;
+ for (i = 0; i < ret; i++) {
+ errno = 0;
+ int_fld = strtoul(str_fld[i], &end, 0);
+ if (errno != 0 || *end != '\0' || int_fld > UINT8_MAX)
+ return -1;
+ flexbytes[i] = (uint8_t)int_fld;
+ }
+ return ret;
+}
+
+/* *** deal with flow director filter *** */
+struct cmd_flow_director_result {
+ cmdline_fixed_string_t flow_director_filter;
+ uint8_t port_id;
+ cmdline_fixed_string_t mode;
+ cmdline_fixed_string_t mode_value;
+ cmdline_fixed_string_t ops;
+ cmdline_fixed_string_t flow;
+ cmdline_fixed_string_t flow_type;
+ cmdline_fixed_string_t ether;
+ uint16_t ether_type;
+ cmdline_fixed_string_t src;
+ cmdline_ipaddr_t ip_src;
+ uint16_t port_src;
+ cmdline_fixed_string_t dst;
+ cmdline_ipaddr_t ip_dst;
+ uint16_t port_dst;
+ cmdline_fixed_string_t verify_tag;
+ uint32_t verify_tag_value;
+ cmdline_ipaddr_t tos;
+ uint8_t tos_value;
+ cmdline_ipaddr_t proto;
+ uint8_t proto_value;
+ cmdline_ipaddr_t ttl;
+ uint8_t ttl_value;
+ cmdline_fixed_string_t vlan;
+ uint16_t vlan_value;
+ cmdline_fixed_string_t flexbytes;
+ cmdline_fixed_string_t flexbytes_value;
+ cmdline_fixed_string_t pf_vf;
+ cmdline_fixed_string_t drop;
+ cmdline_fixed_string_t queue;
+ uint16_t queue_id;
+ cmdline_fixed_string_t fd_id;
+ uint32_t fd_id_value;
+ cmdline_fixed_string_t mac;
+ struct ether_addr mac_addr;
+ cmdline_fixed_string_t tunnel;
+ cmdline_fixed_string_t tunnel_type;
+ cmdline_fixed_string_t tunnel_id;
+ uint32_t tunnel_id_value;
+};
+
+static void
+cmd_flow_director_filter_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_flow_director_result *res = parsed_result;
+ struct rte_eth_fdir_filter entry;
+ uint8_t flexbytes[RTE_ETH_FDIR_MAX_FLEXLEN];
+ char *end;
+ unsigned long vf_id;
+ int ret = 0;
+
+ if (enable_hwlb) {
+ printf("Hash Filter is already Defined !\n");
+ printf("Please undefine HWLD flag and define "
+ "FDIR_FILTER flag\n");
+ return;
+ }
+
+ ret = rte_eth_dev_filter_supported(res->port_id, RTE_ETH_FILTER_FDIR);
+ if (ret < 0) {
+ printf("flow director is not supported on port %u.\n",
+ res->port_id);
+ return;
+ }
+ memset(flexbytes, 0, sizeof(flexbytes));
+ memset(&entry, 0, sizeof(struct rte_eth_fdir_filter));
+#if 0
+ if (fdir_conf.mode == RTE_FDIR_MODE_PERFECT_MAC_VLAN) {
+ if (strcmp(res->mode_value, "MAC-VLAN")) {
+ printf("Please set mode to MAC-VLAN.\n");
+ return;
+ }
+ } else if (fdir_conf.mode == RTE_FDIR_MODE_PERFECT_TUNNEL) {
+ if (strcmp(res->mode_value, "Tunnel")) {
+ printf("Please set mode to Tunnel.\n");
+ return;
+ }
+ } else {
+ if (strcmp(res->mode_value, "IP")) {
+ printf("Please set mode to IP.\n");
+ return;
+ }
+#endif
+ {
+ entry.input.flow_type = str2flowtype(res->flow_type);
+ }
+
+ ret = parse_flexbytes(res->flexbytes_value,
+ flexbytes,
+ RTE_ETH_FDIR_MAX_FLEXLEN);
+ if (ret < 0) {
+ printf("error: Cannot parse flexbytes input.\n");
+ return;
+ }
+
+ switch (entry.input.flow_type) {
+ case RTE_ETH_FLOW_FRAG_IPV4:
+ case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER:
+ entry.input.flow.ip4_flow.proto = res->proto_value;
+ case RTE_ETH_FLOW_NONFRAG_IPV4_UDP:
+ case RTE_ETH_FLOW_NONFRAG_IPV4_TCP:
+ IPV4_ADDR_TO_UINT(res->ip_dst,
+ entry.input.flow.ip4_flow.dst_ip);
+ IPV4_ADDR_TO_UINT(res->ip_src,
+ entry.input.flow.ip4_flow.src_ip);
+ entry.input.flow.ip4_flow.tos = res->tos_value;
+ entry.input.flow.ip4_flow.ttl = res->ttl_value;
+ /* need convert to big endian. */
+ entry.input.flow.udp4_flow.dst_port =
+ rte_cpu_to_be_16(res->port_dst);
+ entry.input.flow.udp4_flow.src_port =
+ rte_cpu_to_be_16(res->port_src);
+ break;
+
+ case RTE_ETH_FLOW_NONFRAG_IPV4_SCTP:
+ IPV4_ADDR_TO_UINT(res->ip_dst,
+ entry.input.flow.sctp4_flow.ip.dst_ip);
+ IPV4_ADDR_TO_UINT(res->ip_src,
+ entry.input.flow.sctp4_flow.ip.src_ip);
+ entry.input.flow.ip4_flow.tos = res->tos_value;
+ entry.input.flow.ip4_flow.ttl = res->ttl_value;
+ /* need convert to big endian. */
+ entry.input.flow.sctp4_flow.dst_port =
+ rte_cpu_to_be_16(res->port_dst);
+ entry.input.flow.sctp4_flow.src_port =
+ rte_cpu_to_be_16(res->port_src);
+ entry.input.flow.sctp4_flow.verify_tag =
+ rte_cpu_to_be_32(res->verify_tag_value);
+ break;
+
+ case RTE_ETH_FLOW_FRAG_IPV6:
+ case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER:
+ entry.input.flow.ipv6_flow.proto = res->proto_value;
+ case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
+ case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
+ IPV6_ADDR_TO_ARRAY(res->ip_dst,
+ entry.input.flow.ipv6_flow.dst_ip);
+ IPV6_ADDR_TO_ARRAY(res->ip_src,
+ entry.input.flow.ipv6_flow.src_ip);
+ entry.input.flow.ipv6_flow.tc = res->tos_value;
+ entry.input.flow.ipv6_flow.hop_limits = res->ttl_value;
+ /* need convert to big endian. */
+ entry.input.flow.udp6_flow.dst_port =
+ rte_cpu_to_be_16(res->port_dst);
+ entry.input.flow.udp6_flow.src_port =
+ rte_cpu_to_be_16(res->port_src);
+ break;
+
+ case RTE_ETH_FLOW_NONFRAG_IPV6_SCTP:
+ IPV6_ADDR_TO_ARRAY(res->ip_dst,
+ entry.input.flow.sctp6_flow.ip.dst_ip);
+ IPV6_ADDR_TO_ARRAY(res->ip_src,
+ entry.input.flow.sctp6_flow.ip.src_ip);
+ entry.input.flow.ipv6_flow.tc = res->tos_value;
+ entry.input.flow.ipv6_flow.hop_limits = res->ttl_value;
+ /* need convert to big endian. */
+ entry.input.flow.sctp6_flow.dst_port =
+ rte_cpu_to_be_16(res->port_dst);
+ entry.input.flow.sctp6_flow.src_port =
+ rte_cpu_to_be_16(res->port_src);
+ entry.input.flow.sctp6_flow.verify_tag =
+ rte_cpu_to_be_32(res->verify_tag_value);
+ break;
+ case RTE_ETH_FLOW_L2_PAYLOAD:
+ entry.input.flow.l2_flow.ether_type =
+ rte_cpu_to_be_16(res->ether_type);
+ break;
+ default:
+ break;
+ }
+#if 0
+ if (fdir_conf.mode == RTE_FDIR_MODE_PERFECT_MAC_VLAN)
+ (void)rte_memcpy(&entry.input.flow.mac_vlan_flow.mac_addr,
+ &res->mac_addr,
+ sizeof(struct ether_addr));
+
+ if (fdir_conf.mode == RTE_FDIR_MODE_PERFECT_TUNNEL) {
+ (void)rte_memcpy(&entry.input.flow.tunnel_flow.mac_addr,
+ &res->mac_addr,
+ sizeof(struct ether_addr));
+ entry.input.flow.tunnel_flow.tunnel_type =
+ str2fdir_tunneltype(res->tunnel_type);
+ entry.input.flow.tunnel_flow.tunnel_id =
+ rte_cpu_to_be_32(res->tunnel_id_value);
+ }
+#endif
+
+ (void)rte_memcpy(entry.input.flow_ext.flexbytes,
+ flexbytes,
+ RTE_ETH_FDIR_MAX_FLEXLEN);
+
+ entry.input.flow_ext.vlan_tci = rte_cpu_to_be_16(res->vlan_value);
+
+ entry.action.flex_off = 0; /*use 0 by default */
+ if (!strcmp(res->drop, "drop"))
+ entry.action.behavior = RTE_ETH_FDIR_REJECT;
+ else
+ entry.action.behavior = RTE_ETH_FDIR_ACCEPT;
+
+ if (!strcmp(res->pf_vf, "pf"))
+ entry.input.flow_ext.is_vf = 0;
+ else if (!strncmp(res->pf_vf, "vf", 2)) {
+ struct rte_eth_dev_info dev_info;
+
+ memset(&dev_info, 0, sizeof(dev_info));
+ rte_eth_dev_info_get(res->port_id, &dev_info);
+ errno = 0;
+ vf_id = strtoul(res->pf_vf + 2, &end, 10);
+ if (errno != 0 || *end != '\0' || vf_id >= dev_info.max_vfs) {
+ printf("invalid parameter %s.\n", res->pf_vf);
+ return;
+ }
+ entry.input.flow_ext.is_vf = 1;
+ entry.input.flow_ext.dst_id = (uint16_t)vf_id;
+ } else {
+ printf("invalid parameter %s.\n", res->pf_vf);
+ return;
+ }
+ /* set to report FD ID by default */
+ entry.action.report_status = RTE_ETH_FDIR_REPORT_ID;
+ entry.action.rx_queue = res->queue_id;
+ entry.soft_id = res->fd_id_value;
+ if (!strcmp(res->ops, "add"))
+ ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_FDIR,
+ RTE_ETH_FILTER_ADD, &entry);
+ else if (!strcmp(res->ops, "del"))
+ ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_FDIR,
+ RTE_ETH_FILTER_DELETE, &entry);
+ else
+ ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_FDIR,
+ RTE_ETH_FILTER_UPDATE, &entry);
+ if (ret < 0)
+ printf("flow director programming error: (%s)\n",
+ strerror(-ret));
+// fdir_filter_enabled = 1;
+}
+
+
+
+cmdline_parse_token_string_t cmd_flow_director_filter =
+TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+ flow_director_filter, "flow_director_filter");
+
+cmdline_parse_token_num_t cmd_flow_director_port_id =
+TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
+ port_id, UINT8);
+
+
+cmdline_parse_token_string_t cmd_flow_director_mode =
+TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+ mode, "mode");
+
+cmdline_parse_token_string_t cmd_flow_director_mode_ip =
+TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+ mode_value, "IP");
+
+cmdline_parse_token_string_t cmd_flow_director_ops =
+TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+ ops, "add#del#update");
+
+cmdline_parse_token_string_t cmd_flow_director_flow =
+TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+ flow, "flow");
+
+cmdline_parse_token_string_t cmd_flow_director_flow_type =
+TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+ flow_type, "ipv4-other#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#"
+ "ipv6-other#ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#l2_payload");
+
+cmdline_parse_token_string_t cmd_flow_director_src =
+TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+ src, "src");
+cmdline_parse_token_ipaddr_t cmd_flow_director_ip_src =
+TOKEN_IPADDR_INITIALIZER(struct cmd_flow_director_result,
+ ip_src);
+cmdline_parse_token_num_t cmd_flow_director_port_src =
+TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
+ port_src, UINT16);
+cmdline_parse_token_string_t cmd_flow_director_dst =
+TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+ dst, "dst");
+cmdline_parse_token_ipaddr_t cmd_flow_director_ip_dst =
+TOKEN_IPADDR_INITIALIZER(struct cmd_flow_director_result,
+ ip_dst);
+cmdline_parse_token_num_t cmd_flow_director_port_dst =
+TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
+ port_dst, UINT16);
+
+cmdline_parse_token_string_t cmd_flow_director_tos =
+TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+ tos, "tos");
+cmdline_parse_token_num_t cmd_flow_director_tos_value =
+TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
+ tos_value, UINT8);
+
+cmdline_parse_token_string_t cmd_flow_director_ttl =
+TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+ ttl, "ttl");
+cmdline_parse_token_num_t cmd_flow_director_ttl_value =
+TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
+ ttl_value, UINT8);
+
+cmdline_parse_token_string_t cmd_flow_director_vlan =
+TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+ vlan, "vlan");
+cmdline_parse_token_num_t cmd_flow_director_vlan_value =
+TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
+ vlan_value, UINT16);
+cmdline_parse_token_string_t cmd_flow_director_flexbytes =
+TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+ flexbytes, "flexbytes");
+cmdline_parse_token_string_t cmd_flow_director_flexbytes_value =
+TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+ flexbytes_value, NULL);
+cmdline_parse_token_string_t cmd_flow_director_drop =
+TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+ drop, "drop#fwd");
+cmdline_parse_token_string_t cmd_flow_director_pf_vf =
+TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+ pf_vf, NULL);
+cmdline_parse_token_string_t cmd_flow_director_queue =
+TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+ queue, "queue");
+cmdline_parse_token_num_t cmd_flow_director_queue_id =
+TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
+ queue_id, UINT16);
+cmdline_parse_token_string_t cmd_flow_director_fd_id =
+TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+ fd_id, "fd_id");
+cmdline_parse_token_num_t cmd_flow_director_fd_id_value =
+TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
+ fd_id_value, UINT32);
+
+
+cmdline_parse_inst_t cmd_add_del_udp_flow_director = {
+ .f = cmd_flow_director_filter_parsed,
+ .data = NULL,
+ .help_str = "add or delete an udp/tcp flow director entry on NIC",
+ .tokens = {
+ (void *)&cmd_flow_director_filter,
+ (void *)&cmd_flow_director_port_id,
+ (void *)&cmd_flow_director_mode,
+ (void *)&cmd_flow_director_mode_ip,
+ (void *)&cmd_flow_director_ops,
+ (void *)&cmd_flow_director_flow,
+ (void *)&cmd_flow_director_flow_type,
+ (void *)&cmd_flow_director_src,
+ (void *)&cmd_flow_director_ip_src,
+ (void *)&cmd_flow_director_port_src,
+ (void *)&cmd_flow_director_dst,
+ (void *)&cmd_flow_director_ip_dst,
+ (void *)&cmd_flow_director_port_dst,
+ (void *)&cmd_flow_director_tos,
+ (void *)&cmd_flow_director_tos_value,
+ (void *)&cmd_flow_director_ttl,
+ (void *)&cmd_flow_director_ttl_value,
+ (void *)&cmd_flow_director_vlan,
+ (void *)&cmd_flow_director_vlan_value,
+ (void *)&cmd_flow_director_flexbytes,
+ (void *)&cmd_flow_director_flexbytes_value,
+ (void *)&cmd_flow_director_drop,
+ (void *)&cmd_flow_director_pf_vf,
+ (void *)&cmd_flow_director_queue,
+ (void *)&cmd_flow_director_queue_id,
+ (void *)&cmd_flow_director_fd_id,
+ (void *)&cmd_flow_director_fd_id_value,
+ NULL,
+ },
+};
+/* L2 payload*/
+cmdline_parse_token_string_t cmd_flow_director_ether =
+ TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+ ether, "ether");
+cmdline_parse_token_num_t cmd_flow_director_ether_type =
+ TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
+ ether_type, UINT16);
+
+cmdline_parse_inst_t cmd_add_del_l2_flow_director = {
+ .f = cmd_flow_director_filter_parsed,
+ .data = NULL,
+ .help_str = "add or delete a L2 flow director entry on NIC",
+ .tokens = {
+ (void *)&cmd_flow_director_filter,
+ (void *)&cmd_flow_director_port_id,
+ (void *)&cmd_flow_director_mode,
+ (void *)&cmd_flow_director_mode_ip,
+ (void *)&cmd_flow_director_ops,
+ (void *)&cmd_flow_director_flow,
+ (void *)&cmd_flow_director_flow_type,
+ (void *)&cmd_flow_director_ether,
+ (void *)&cmd_flow_director_ether_type,
+ (void *)&cmd_flow_director_flexbytes,
+ (void *)&cmd_flow_director_flexbytes_value,
+ (void *)&cmd_flow_director_drop,
+ (void *)&cmd_flow_director_pf_vf,
+ (void *)&cmd_flow_director_queue,
+ (void *)&cmd_flow_director_queue_id,
+ (void *)&cmd_flow_director_fd_id,
+ (void *)&cmd_flow_director_fd_id_value,
+ NULL,
+ },
+};
+
+#if 1
+/* Set hash input set */
+struct cmd_set_hash_input_set_result {
+ cmdline_fixed_string_t set_hash_input_set;
+ uint8_t port_id;
+ cmdline_fixed_string_t flow_type;
+ cmdline_fixed_string_t inset_field0;
+ cmdline_fixed_string_t inset_field1;
+ cmdline_fixed_string_t inset_field2;
+ cmdline_fixed_string_t inset_field3;
+ cmdline_fixed_string_t inset_field4;
+ cmdline_fixed_string_t select;
+};
+
+static enum rte_eth_input_set_field
+str2inset(char *string)
+{
+ uint16_t i;
+
+ static const struct {
+ char str[32];
+ enum rte_eth_input_set_field inset;
+ } inset_table[] = {
+ {"ethertype", RTE_ETH_INPUT_SET_L2_ETHERTYPE},
+ {"ovlan", RTE_ETH_INPUT_SET_L2_OUTER_VLAN},
+ {"ivlan", RTE_ETH_INPUT_SET_L2_INNER_VLAN},
+ {"src-ipv4", RTE_ETH_INPUT_SET_L3_SRC_IP4},
+ {"dst-ipv4", RTE_ETH_INPUT_SET_L3_DST_IP4},
+ {"ipv4-tos", RTE_ETH_INPUT_SET_L3_IP4_TOS},
+ {"ipv4-proto", RTE_ETH_INPUT_SET_L3_IP4_PROTO},
+ {"ipv4-ttl", RTE_ETH_INPUT_SET_L3_IP4_TTL},
+ {"src-ipv6", RTE_ETH_INPUT_SET_L3_SRC_IP6},
+ {"dst-ipv6", RTE_ETH_INPUT_SET_L3_DST_IP6},
+ {"ipv6-tc", RTE_ETH_INPUT_SET_L3_IP6_TC},
+ {"ipv6-next-header", RTE_ETH_INPUT_SET_L3_IP6_NEXT_HEADER},
+ {"ipv6-hop-limits", RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS},
+ {"udp-src-port", RTE_ETH_INPUT_SET_L4_UDP_SRC_PORT},
+ {"udp-dst-port", RTE_ETH_INPUT_SET_L4_UDP_DST_PORT},
+ {"tcp-src-port", RTE_ETH_INPUT_SET_L4_TCP_SRC_PORT},
+ {"tcp-dst-port", RTE_ETH_INPUT_SET_L4_TCP_DST_PORT},
+ {"sctp-src-port", RTE_ETH_INPUT_SET_L4_SCTP_SRC_PORT},
+ {"sctp-dst-port", RTE_ETH_INPUT_SET_L4_SCTP_DST_PORT},
+ {"sctp-veri-tag", RTE_ETH_INPUT_SET_L4_SCTP_VERIFICATION_TAG},
+ {"udp-key", RTE_ETH_INPUT_SET_TUNNEL_L4_UDP_KEY},
+ {"gre-key", RTE_ETH_INPUT_SET_TUNNEL_GRE_KEY},
+ {"fld-1st", RTE_ETH_INPUT_SET_FLEX_PAYLOAD_1ST_WORD},
+ {"fld-2nd", RTE_ETH_INPUT_SET_FLEX_PAYLOAD_2ND_WORD},
+ {"fld-3rd", RTE_ETH_INPUT_SET_FLEX_PAYLOAD_3RD_WORD},
+ {"fld-4th", RTE_ETH_INPUT_SET_FLEX_PAYLOAD_4TH_WORD},
+ {"fld-5th", RTE_ETH_INPUT_SET_FLEX_PAYLOAD_5TH_WORD},
+ {"fld-6th", RTE_ETH_INPUT_SET_FLEX_PAYLOAD_6TH_WORD},
+ {"fld-7th", RTE_ETH_INPUT_SET_FLEX_PAYLOAD_7TH_WORD},
+ {"fld-8th", RTE_ETH_INPUT_SET_FLEX_PAYLOAD_8TH_WORD},
+ {"none", RTE_ETH_INPUT_SET_NONE},
+ };
+ for (i = 0; i < RTE_DIM(inset_table); i++) {
+ if (!strcmp(string, inset_table[i].str))
+ return inset_table[i].inset;
+ }
+
+ return RTE_ETH_INPUT_SET_UNKNOWN;
+}
+
+static void
+cmd_set_hash_input_set_1_parsed(void *parsed_result,
+ __rte_unused struct cmdline *cl,
+ __rte_unused void *data)
+{
+ struct cmd_set_hash_input_set_result *res = parsed_result;
+ struct rte_eth_hash_filter_info info;
+
+ if (enable_flow_dir) {
+ printf("FDIR Filter is Defined!\n");
+ printf("Please undefine FDIR_FILTER flag and define "
+ "HWLD flag\n");
+ return;
+ }
+
+ memset(&info, 0, sizeof(info));
+ info.info_type = RTE_ETH_HASH_FILTER_INPUT_SET_SELECT;
+ info.info.input_set_conf.flow_type = str2flowtype(res->flow_type);
+
+ info.info.input_set_conf.field[0] = str2inset(res->inset_field0);
+ info.info.input_set_conf.inset_size = 1;
+
+ if (!strcmp(res->select, "select"))
+ info.info.input_set_conf.op = RTE_ETH_INPUT_SET_SELECT;
+ else if (!strcmp(res->select, "add"))
+ info.info.input_set_conf.op = RTE_ETH_INPUT_SET_ADD;
+
+ rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_HASH,
+ RTE_ETH_FILTER_SET, &info);
+
+ //hash_filter_enabled = 1;
+}
+
+static void
+cmd_set_hash_input_set_2_parsed(void *parsed_result,
+ __rte_unused struct cmdline *cl,
+ __rte_unused void *data)
+{
+ struct cmd_set_hash_input_set_result *res = parsed_result;
+ struct rte_eth_hash_filter_info info;
+
+ if (enable_flow_dir) {
+ printf("FDIR Filter is Defined!\n");
+ printf("Please undefine FDIR_FILTER flag and define "
+ "HWLD flag\n");
+ return;
+ }
+
+ memset(&info, 0, sizeof(info));
+ info.info_type = RTE_ETH_HASH_FILTER_INPUT_SET_SELECT;
+ info.info.input_set_conf.flow_type = str2flowtype(res->flow_type);
+
+ info.info.input_set_conf.field[0] = str2inset(res->inset_field0);
+ info.info.input_set_conf.field[1] = str2inset(res->inset_field1);
+
+ info.info.input_set_conf.inset_size = 2;
+
+ if (!strcmp(res->select, "select"))
+ info.info.input_set_conf.op = RTE_ETH_INPUT_SET_SELECT;
+ else if (!strcmp(res->select, "add"))
+ info.info.input_set_conf.op = RTE_ETH_INPUT_SET_ADD;
+
+ rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_HASH,
+ RTE_ETH_FILTER_SET, &info);
+
+ //hash_filter_enabled = 1;
+}
+
+#if 0
+static void
+cmd_set_hash_input_set_3_parsed(void *parsed_result,
+ __rte_unused struct cmdline *cl,
+ __rte_unused void *data)
+{
+ struct cmd_set_hash_input_set_result *res = parsed_result;
+ struct rte_eth_hash_filter_info info;
+
+ memset(&info, 0, sizeof(info));
+ info.info_type = RTE_ETH_HASH_FILTER_INPUT_SET_SELECT;
+ info.info.input_set_conf.flow_type = str2flowtype(res->flow_type);
+
+ info.info.input_set_conf.field[0] = str2inset(res->inset_field0);
+ info.info.input_set_conf.field[1] = str2inset(res->inset_field1);
+ info.info.input_set_conf.field[2] = str2inset(res->inset_field2);
+ info.info.input_set_conf.inset_size = 3;
+
+ if (!strcmp(res->select, "select"))
+ info.info.input_set_conf.op = RTE_ETH_INPUT_SET_SELECT;
+ else if (!strcmp(res->select, "add"))
+ info.info.input_set_conf.op = RTE_ETH_INPUT_SET_ADD;
+
+ rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_HASH,
+ RTE_ETH_FILTER_SET, &info);
+}
+#endif
+static void
+cmd_set_hash_input_set_4_parsed(void *parsed_result,
+ __rte_unused struct cmdline *cl,
+ __rte_unused void *data)
+{
+ struct cmd_set_hash_input_set_result *res = parsed_result;
+ struct rte_eth_hash_filter_info info;
+
+ if (enable_flow_dir) {
+ printf("FDIR Filter is Defined!\n");
+ printf("Please undefine FDIR_FILTER flag and define "
+ "HWLD flag\n");
+ return;
+ }
+
+ memset(&info, 0, sizeof(info));
+ info.info_type = RTE_ETH_HASH_FILTER_INPUT_SET_SELECT;
+ info.info.input_set_conf.flow_type = str2flowtype(res->flow_type);
+
+ info.info.input_set_conf.field[0] = str2inset(res->inset_field0);
+ info.info.input_set_conf.field[1] = str2inset(res->inset_field1);
+ info.info.input_set_conf.field[2] = str2inset(res->inset_field2);
+ info.info.input_set_conf.field[3] = str2inset(res->inset_field3);
+
+ info.info.input_set_conf.inset_size = 4;
+ if (!strcmp(res->select, "select"))
+ info.info.input_set_conf.op = RTE_ETH_INPUT_SET_SELECT;
+ else if (!strcmp(res->select, "add"))
+ info.info.input_set_conf.op = RTE_ETH_INPUT_SET_ADD;
+
+ rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_HASH,
+ RTE_ETH_FILTER_SET, &info);
+ //hash_filter_enabled = 1;
+}
+
+#if 0
+static void
+cmd_set_hash_input_set_5_parsed(void *parsed_result,
+ __rte_unused struct cmdline *cl,
+ __rte_unused void *data)
+{
+ struct cmd_set_hash_input_set_result *res = parsed_result;
+ struct rte_eth_hash_filter_info info;
+
+ memset(&info, 0, sizeof(info));
+ info.info_type = RTE_ETH_HASH_FILTER_INPUT_SET_SELECT;
+ info.info.input_set_conf.flow_type = str2flowtype(res->flow_type);
+
+ info.info.input_set_conf.field[0] = str2inset(res->inset_field0);
+ info.info.input_set_conf.field[1] = str2inset(res->inset_field1);
+ info.info.input_set_conf.field[2] = str2inset(res->inset_field2);
+ info.info.input_set_conf.field[3] = str2inset(res->inset_field3);
+ info.info.input_set_conf.field[4] = str2inset(res->inset_field4);
+
+ info.info.input_set_conf.inset_size = 5;
+ if (!strcmp(res->select, "select"))
+ info.info.input_set_conf.op = RTE_ETH_INPUT_SET_SELECT;
+ else if (!strcmp(res->select, "add"))
+ info.info.input_set_conf.op = RTE_ETH_INPUT_SET_ADD;
+ rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_HASH,
+ RTE_ETH_FILTER_SET, &info);
+}
+#endif
+
+cmdline_parse_token_string_t cmd_set_hash_input_set_cmd =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
+ set_hash_input_set, "set_hash_input_set");
+cmdline_parse_token_num_t cmd_set_hash_input_set_port_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_set_hash_input_set_result,
+ port_id, UINT8);
+cmdline_parse_token_string_t cmd_set_hash_input_set_flow_type =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
+ flow_type,
+ "ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#"
+ "ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#ipv6-other#l2_payload");
+
+cmdline_parse_token_string_t cmd_set_hash_input_set_field0 =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
+ inset_field0,
+ "src-ipv4#src-ipv6#dst-ipv4#dst-ipv6#"
+ "udp-src-port#udp-dst-port#tcp-src-port#tcp-dst-port#none");
+
+cmdline_parse_token_string_t cmd_set_hash_input_set_field1 =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
+ inset_field1,
+ "dst-ipv4#dst-ipv6#"
+ "udp-src-port#tcp-src-port#udp-dst-port#tcp-dst-port#none");
+
+cmdline_parse_token_string_t cmd_set_hash_input_set_field2 =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
+ inset_field2,
+ "udp-src-port#tcp-src-port#none");
+
+cmdline_parse_token_string_t cmd_set_hash_input_set_field3 =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
+ inset_field3,
+ "udp-dst-port#tcp-dst-port#none");
+#if 0
+cmdline_parse_token_string_t cmd_set_hash_input_set_field4 =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
+ inset_field4, "ipv4-proto#ipv6-next-header#none");
+#endif
+
+cmdline_parse_token_string_t cmd_set_hash_input_set_select =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
+ select, "select#add");
+
+cmdline_parse_inst_t cmd_set_hash_input_set_1 = {
+ .f = cmd_set_hash_input_set_1_parsed,
+ .data = NULL,
+ .help_str = "set_hash_input_set_1 <port_id> "
+ "ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
+ "ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
+ "src-ipv4|src-ipv6|dst-ipv4|dst-ipv6|"
+ "udp-src-port|udp-dst-port|tcp-src-port|tcp-dst-port|none "
+ "select|add",
+ .tokens = {
+ (void *)&cmd_set_hash_input_set_cmd,
+ (void *)&cmd_set_hash_input_set_port_id,
+ (void *)&cmd_set_hash_input_set_flow_type,
+ (void *)&cmd_set_hash_input_set_field0,
+ (void *)&cmd_set_hash_input_set_select,
+ NULL,
+ },
+};
+
+cmdline_parse_inst_t cmd_set_hash_input_set_2 = {
+ .f = cmd_set_hash_input_set_2_parsed,
+ .data = NULL,
+ .help_str = "set_hash_input_set_2 <port_id> "
+ "ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other| "
+ "ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
+ "src-ipv4|src-ipv6|dst-ipv4|dst-ipv6| "
+ "udp-src-port|udp-dst-port|tcp-src-port|tcp-dst-port|none "
+ "udp-src-port|tcp-src-port|udp-dst-port|tcp-dst-port|none "
+ "select|add",
+ .tokens = {
+ (void *)&cmd_set_hash_input_set_cmd,
+ (void *)&cmd_set_hash_input_set_port_id,
+ (void *)&cmd_set_hash_input_set_flow_type,
+ (void *)&cmd_set_hash_input_set_field0,
+ (void *)&cmd_set_hash_input_set_field1,
+ (void *)&cmd_set_hash_input_set_select,
+ NULL,
+ },
+};
+
+#if 0
+cmdline_parse_inst_t cmd_set_hash_input_set_3 = {
+ .f = cmd_set_hash_input_set_3_parsed,
+ .data = NULL,
+ .help_str = "set_hash_input_set_3 <port_id> "
+ "ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
+ "ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
+ "ovlan|ivlan|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos|ipv4-proto|"
+ "ipv6-tc|ipv6-next-header|udp-src-port|udp-dst-port|tcp-src-port|"
+ "tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag|udp-key|"
+ "gre-key|fld-1st|fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|"
+ "fld-7th|fld-8th|none "
+ "udp-src-port|udp-dst-port|tcp-src-port|tcp-dst-port|none "
+ "select|add",
+ .tokens = {
+ (void *)&cmd_set_hash_input_set_cmd,
+ (void *)&cmd_set_hash_input_set_port_id,
+ (void *)&cmd_set_hash_input_set_flow_type,
+ (void *)&cmd_set_hash_input_set_field0,
+ (void *)&cmd_set_hash_input_set_field1,
+ (void *)&cmd_set_hash_input_set_field2,
+ (void *)&cmd_set_hash_input_set_select,
+ NULL,
+ },
+};
+#endif
+
+cmdline_parse_inst_t cmd_set_hash_input_set_4 = {
+ .f = cmd_set_hash_input_set_4_parsed,
+ .data = NULL,
+ .help_str = "set_hash_input_set_4 <port_id> "
+ "ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
+ "ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
+ "src-ipv4|src-ipv6|dst-ipv4|dst-ipv6|"
+ "udp-src-port|udp-dst-port|tcp-src-port|tcp-dst-port|none "
+ "udp-src-port|tcp-src-port|udp-dst-port|tcp-dst-port|none "
+ "udp-src-port|tcp-src-port|dst-ipv4|none "
+ "udp-dst-port|tcp-dst-port|none "
+ "select|add",
+ .tokens = {
+ (void *)&cmd_set_hash_input_set_cmd,
+ (void *)&cmd_set_hash_input_set_port_id,
+ (void *)&cmd_set_hash_input_set_flow_type,
+ (void *)&cmd_set_hash_input_set_field0,
+ (void *)&cmd_set_hash_input_set_field1,
+ (void *)&cmd_set_hash_input_set_field2,
+ (void *)&cmd_set_hash_input_set_field3,
+ (void *)&cmd_set_hash_input_set_select,
+ NULL,
+ },
+};
+#if 0
+cmdline_parse_inst_t cmd_set_hash_input_set_5 = {
+ .f = cmd_set_hash_input_set_5_parsed,
+ .data = NULL,
+ .help_str = "set_hash_input_set_5 <port_id> "
+ "ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
+ "ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
+ "src-ipv4|src-ipv6|none "
+ "dst-ipv4|dst-ipv6|none "
+ "udp-src-port|tcp-src-port|none "
+ "udp-dst-port|tcp-dst-port|none "
+ "ipv4-proto|ipv6-next-header|none "
+ "select|add",
+
+ .tokens = {
+ (void *)&cmd_set_hash_input_set_cmd,
+ (void *)&cmd_set_hash_input_set_port_id,
+ (void *)&cmd_set_hash_input_set_flow_type,
+ (void *)&cmd_set_hash_input_set_field0,
+ (void *)&cmd_set_hash_input_set_field1,
+ (void *)&cmd_set_hash_input_set_field2,
+ (void *)&cmd_set_hash_input_set_field3,
+ (void *)&cmd_set_hash_input_set_field4,
+ (void *)&cmd_set_hash_input_set_select,
+ NULL,
+ },
+};
+#endif
+#endif
+/* set hash global config */
+struct cmd_set_hash_global_config_result {
+ cmdline_fixed_string_t set_hash_global_config;
+ uint8_t port_id;
+ cmdline_fixed_string_t hash_func;
+ cmdline_fixed_string_t flow_type;
+ cmdline_fixed_string_t enable;
+};
+
+static void
+cmd_set_hash_global_config_parsed(void *parsed_result,
+ __rte_unused struct cmdline *cl,
+ __rte_unused void *data)
+{
+ struct cmd_set_hash_global_config_result *res = parsed_result;
+ struct rte_eth_hash_filter_info info;
+ uint32_t ftype, idx, offset;
+ int ret;
+
+ if (rte_eth_dev_filter_supported(res->port_id,
+ RTE_ETH_FILTER_HASH) < 0) {
+ printf("RTE_ETH_FILTER_HASH not supported on port %d\n",
+ res->port_id);
+ return;
+ }
+ memset(&info, 0, sizeof(info));
+ info.info_type = RTE_ETH_HASH_FILTER_GLOBAL_CONFIG;
+ if (!strcmp(res->hash_func, "toeplitz"))
+ info.info.global_conf.hash_func =
+ RTE_ETH_HASH_FUNCTION_TOEPLITZ;
+ else if (!strcmp(res->hash_func, "simple_xor"))
+ info.info.global_conf.hash_func =
+ RTE_ETH_HASH_FUNCTION_SIMPLE_XOR;
+ else if (!strcmp(res->hash_func, "default"))
+ info.info.global_conf.hash_func =
+ RTE_ETH_HASH_FUNCTION_DEFAULT;
+
+ ftype = str2flowtype(res->flow_type);
+ idx = ftype / (CHAR_BIT * sizeof(uint32_t));
+ offset = ftype % (CHAR_BIT * sizeof(uint32_t));
+ info.info.global_conf.valid_bit_mask[idx] |= (1UL << offset);
+ if (!strcmp(res->enable, "enable"))
+ if(idx < RTE_SYM_HASH_MASK_ARRAY_SIZE)
+ info.info.global_conf.sym_hash_enable_mask[idx] |=
+ (1UL << offset);
+ ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_HASH,
+ RTE_ETH_FILTER_SET, &info);
+ if (ret < 0)
+ printf("Cannot set global hash configurations by port %d\n",
+ res->port_id);
+ else
+ printf("Global hash configurations have been set "
+ "succcessfully by port %d\n", res->port_id);
+}
+cmdline_parse_token_string_t cmd_set_hash_global_config_all =
+TOKEN_STRING_INITIALIZER(struct cmd_set_hash_global_config_result,
+ set_hash_global_config, "set_hash_global_config");
+cmdline_parse_token_num_t cmd_set_hash_global_config_port_id =
+TOKEN_NUM_INITIALIZER(struct cmd_set_hash_global_config_result,
+ port_id, UINT8);
+cmdline_parse_token_string_t cmd_set_hash_global_config_hash_func =
+TOKEN_STRING_INITIALIZER(struct cmd_set_hash_global_config_result,
+ hash_func, "toeplitz#simple_xor#default");
+cmdline_parse_token_string_t cmd_set_hash_global_config_flow_type =
+TOKEN_STRING_INITIALIZER(struct cmd_set_hash_global_config_result,
+ flow_type,
+ "ipv4#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#ipv6#"
+ "ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#ipv6-other#l2_payload");
+cmdline_parse_token_string_t cmd_set_hash_global_config_enable =
+TOKEN_STRING_INITIALIZER(struct cmd_set_hash_global_config_result,
+ enable, "enable#disable");
+
+cmdline_parse_inst_t cmd_set_hash_global_config = {
+ .f = cmd_set_hash_global_config_parsed,
+ .data = NULL,
+ .help_str = "set_hash_global_config port_id "
+ "toeplitz|simple_xor|default "
+ "ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|"
+ "ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
+ "enable|disable",
+ .tokens = {
+ (void *)&cmd_set_hash_global_config_all,
+ (void *)&cmd_set_hash_global_config_port_id,
+ (void *)&cmd_set_hash_global_config_hash_func,
+ (void *)&cmd_set_hash_global_config_flow_type,
+ (void *)&cmd_set_hash_global_config_enable,
+ NULL,
+ },
+};
+
+/* *** Set symmetric hash enable per port *** */
+struct cmd_set_sym_hash_ena_per_port_result {
+ cmdline_fixed_string_t set_sym_hash_ena_per_port;
+ cmdline_fixed_string_t enable;
+ uint8_t port_id;
+};
+
+static void
+cmd_set_sym_hash_per_port_parsed(void *parsed_result,
+ __rte_unused struct cmdline *cl,
+ __rte_unused void *data)
+{
+ struct cmd_set_sym_hash_ena_per_port_result *res = parsed_result;
+ struct rte_eth_hash_filter_info info;
+ int ret;
+
+ if (rte_eth_dev_filter_supported(res->port_id,
+ RTE_ETH_FILTER_HASH) < 0) {
+ printf("RTE_ETH_FILTER_HASH not supported on port: %d\n",
+ res->port_id);
+ return;
+ }
+
+ memset(&info, 0, sizeof(info));
+ info.info_type = RTE_ETH_HASH_FILTER_SYM_HASH_ENA_PER_PORT;
+
+ if (!strcmp(res->enable, "enable"))
+ info.info.enable = 1;
+
+ ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_HASH,
+ RTE_ETH_FILTER_SET, &info);
+ if (ret < 0) {
+ printf("Cannot set symmetric hash enable per port on "
+ "port %u\n", res->port_id);
+ return;
+ }
+ printf("Symmetric hash has been set to %s on port %u\n",
+ res->enable, res->port_id);
+}
+
+cmdline_parse_token_string_t cmd_set_sym_hash_ena_per_port_all =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_sym_hash_ena_per_port_result,
+ set_sym_hash_ena_per_port, "set_sym_hash_ena_per_port");
+cmdline_parse_token_num_t cmd_set_sym_hash_ena_per_port_port_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_set_sym_hash_ena_per_port_result,
+ port_id, UINT8);
+cmdline_parse_token_string_t cmd_set_sym_hash_ena_per_port_enable =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_sym_hash_ena_per_port_result,
+ enable, "enable#disable");
+
+cmdline_parse_inst_t cmd_set_sym_hash_ena_per_port = {
+ .f = cmd_set_sym_hash_per_port_parsed,
+ .data = NULL,
+ .help_str = "set_sym_hash_ena_per_port port_id enable|disable",
+ .tokens = {
+ (void *)&cmd_set_sym_hash_ena_per_port_all,
+ (void *)&cmd_set_sym_hash_ena_per_port_port_id,
+ (void *)&cmd_set_sym_hash_ena_per_port_enable,
+ NULL,
+ },
+};
+#endif
+
+static int
+app_pipeline_arpicmp_entry_dbg(struct app_params *app,
+ uint32_t pipeline_id, uint8_t *msg)
+{
+ struct pipeline_arpicmp_entry_dbg_msg_req *req;
+ struct pipeline_arpicmp_entry_dbg_msg_rsp *rsp;
+
+ /* Check input arguments */
+ if (app == NULL)
+ return -1;
+
+ /* Allocate and write request */
+ req = app_msg_alloc(app);
+ if (req == NULL)
+ return -1;
+
+ req->type = PIPELINE_MSG_REQ_CUSTOM;
+ req->subtype = PIPELINE_ARPICMP_MSG_REQ_ENTRY_DBG;
+ req->data[0] = msg[0];
+ req->data[1] = msg[1];
+
+ rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
+ if (rsp == NULL)
+ return -1;
+
+ /* Read response */
+ if (rsp->status) {
+ app_msg_free(app, rsp);
+ printf("Error rsp->status %d\n", rsp->status);
+ return -1;
+ }
+
+ /* Free response */
+ app_msg_free(app, rsp);
+
+ return 0;
+}
+
+/*
+ * entry dbg
+ */
+
+
+struct cmd_entry_dbg_result {
+ cmdline_fixed_string_t p_string;
+ uint32_t p;
+ cmdline_fixed_string_t entry_string;
+ cmdline_fixed_string_t dbg_string;
+ uint8_t cmd;
+ uint8_t d1;
+};
+
+static void
+cmd_entry_dbg_parsed(void *parsed_result,
+ __rte_unused struct cmdline *cl, void *data)
+{
+ struct cmd_entry_dbg_result *params = parsed_result;
+ struct app_params *app = data;
+ uint8_t msg[2];
+ int status;
+
+ msg[0] = params->cmd;
+ msg[1] = params->d1;
+ status = app_pipeline_arpicmp_entry_dbg(app, params->p, msg);
+
+ if (status != 0) {
+ printf("Dbg Command failed\n");
+ return;
+ }
+}
+
+static cmdline_parse_token_string_t lb_cmd_entry_dbg_p_string =
+TOKEN_STRING_INITIALIZER(struct cmd_entry_dbg_result, p_string, "p");
+
+static cmdline_parse_token_num_t lb_cmd_entry_dbg_p =
+TOKEN_NUM_INITIALIZER(struct cmd_entry_dbg_result, p, UINT32);
+
+static cmdline_parse_token_string_t lb_cmd_entry_dbg_entry_string =
+TOKEN_STRING_INITIALIZER(struct cmd_entry_dbg_result,
+ entry_string, "txrx");
+
+static cmdline_parse_token_string_t lb_cmd_entry_dbg_dbg_string =
+TOKEN_STRING_INITIALIZER(struct cmd_entry_dbg_result, dbg_string,
+ "dbg");
+
+static cmdline_parse_token_num_t lb_cmd_entry_dbg_cmd =
+TOKEN_NUM_INITIALIZER(struct cmd_entry_dbg_result, cmd, UINT8);
+
+static cmdline_parse_token_num_t lb_cmd_entry_dbg_d1 =
+TOKEN_NUM_INITIALIZER(struct cmd_entry_dbg_result, d1, UINT8);
+
+static cmdline_parse_inst_t lb_cmd_entry_dbg = {
+ .f = cmd_entry_dbg_parsed,
+ .data = NULL,
+ .help_str = "ARPICMP dbg cmd",
+ .tokens = {
+ (void *)&lb_cmd_entry_dbg_p_string,
+ (void *)&lb_cmd_entry_dbg_p,
+ (void *)&lb_cmd_entry_dbg_entry_string,
+ (void *)&lb_cmd_entry_dbg_dbg_string,
+ (void *)&lb_cmd_entry_dbg_cmd,
+ (void *)&lb_cmd_entry_dbg_d1,
+ NULL,
+ },
+};
+
+static cmdline_parse_ctx_t pipeline_cmds[] = {
+ (cmdline_parse_inst_t *) &lb_cmd_entry_dbg,
+ (cmdline_parse_inst_t *) &cmd_arp_add,
+ (cmdline_parse_inst_t *) &cmd_arp_del,
+ (cmdline_parse_inst_t *) &cmd_arp_req,
+ (cmdline_parse_inst_t *) &cmd_icmp_echo_req,
+ (cmdline_parse_inst_t *) &cmd_arp_ls,
+ (cmdline_parse_inst_t *) &cmd_show_ports_info,
+ /*HWLB cmds*/
+ (cmdline_parse_inst_t *) &cmd_set_fwd_mode,
+ (cmdline_parse_inst_t *) &cmd_add_del_udp_flow_director,
+ (cmdline_parse_inst_t *) &cmd_add_del_l2_flow_director,
+ (cmdline_parse_inst_t *) &cmd_set_hash_input_set_1,
+ (cmdline_parse_inst_t *) &cmd_set_hash_input_set_2,
+/* (cmdline_parse_inst_t *) & cmd_set_hash_input_set_3,*/
+ (cmdline_parse_inst_t *) &cmd_set_hash_input_set_4,
+/* (cmdline_parse_inst_t *) & cmd_set_hash_input_set_5,*/
+ (cmdline_parse_inst_t *) &cmd_set_hash_global_config,
+ (cmdline_parse_inst_t *) &cmd_set_sym_hash_ena_per_port,
+ #ifndef VNF_ACL
+ (cmdline_parse_inst_t *) &cmd_arp_dbg,
+ (cmdline_parse_inst_t *) &cmd_arp_timer,
+ #endif
+ NULL,
+};
+
+static struct pipeline_fe_ops pipeline_arpicmp_fe_ops = {
+ .f_init = NULL,
+ .f_free = NULL,
+ .cmds = pipeline_cmds,
+};
+
+struct pipeline_type pipeline_arpicmp = {
+ .name = "ARPICMP",
+ .be_ops = &pipeline_arpicmp_be_ops,
+ .fe_ops = &pipeline_arpicmp_fe_ops,
+};