/* // 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 #include #include #include #include #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 #include #include 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(¶ms->macaddr, rte_cpu_to_be_32(params->ip.addr. ipv4.s_addr), params->port_id , STATIC_ARP ); } else { memcpy(ipv6, params->ip.addr.ipv6.s6_addr, 16); populate_nd_entry(¶ms->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 struct arp_key_ipv4 arp_key; arp_key.port_id = params->port_id; arp_key.ip = rte_cpu_to_be_32(params->ip.addr.ipv4.s_addr); arp_key.filler1 = 0; arp_key.filler2 = 0; arp_key.filler3 = 0; struct arp_entry_data *new_arp_data = retrieve_arp_entry(arp_key, STATIC_ARP); if (params->ip.family == AF_INET) { remove_arp_entry(new_arp_data, &arp_key); } 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, STATIC_ARP); 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; uint32_t ip_type; }; static void cmd_arp_ls_parsed(__rte_unused void *parsed_result, __rte_unused struct cmdline *cl, __rte_unused void *data) { struct cmd_arp_ls_result *params = parsed_result; if (!params->ip_type) { printf("\nARP table ...\n"); printf("-------------\n"); print_arp_table(); } else { 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_token_num_t cmd_arp_ls_ip_type = TOKEN_NUM_INITIALIZER(struct cmd_arp_ls_result, ip_type, UINT32); 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, (void *)&cmd_arp_ls_ip_type, 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=", ð_hdr->s_addr); print_ether_addr(" - dst=", ð_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 " "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 " "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 " "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 " "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 " "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, };