X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=app%2Ftest-pmd%2Fcmdline.c;h=030beecfd1635cb77cd768a38e465f2ad1076f48;hb=acbf77a6907fde331935955ff2a219edae93c3b9;hp=c8312beb162a97cd66d85fc30426a6117561d948;hpb=edab33b1c01d508fdd934c06ee27f84250d2749a;p=dpdk.git diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index c8312beb16..030beecfd1 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2016 Intel Corporation. All rights reserved. * Copyright(c) 2014 6WIND S.A. * All rights reserved. * @@ -61,7 +61,6 @@ #include #include #include -#include #include #include #include @@ -85,13 +84,14 @@ #include #include #include -#include #ifdef RTE_LIBRTE_PMD_BOND #include #endif #include "testpmd.h" +static struct cmdline *testpmd_cl; + static void cmd_reconfig_device_queue(portid_t id, uint8_t dev, uint8_t queue); #ifdef RTE_NIC_BYPASS @@ -184,7 +184,7 @@ static void cmd_help_long_parsed(void *parsed_result, "Display:\n" "--------\n\n" - "show port (info|stats|xstats|fdir|stat_qmap) (port_id|all)\n" + "show port (info|stats|xstats|fdir|stat_qmap|dcb_tc) (port_id|all)\n" " Display information for port_id, or all.\n\n" "show port X rss reta (size) (mask0,mask1,...)\n" @@ -192,14 +192,19 @@ static void cmd_help_long_parsed(void *parsed_result, " by masks on port X. size is used to indicate the" " hardware supported reta size\n\n" - "show port rss-hash [key]\n" + "show port rss-hash ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|" + "ipv4-sctp|ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|" + "ipv6-other|l2-payload|ipv6-ex|ipv6-tcp-ex|ipv6-udp-ex [key]\n" " Display the RSS hash functions and RSS hash key" " of port X\n\n" "clear port (info|stats|xstats|fdir|stat_qmap) (port_id|all)\n" " Clear information for port_id, or all.\n\n" - "show config (rxtx|cores|fwd)\n" + "show (rxq|txq) info (port_id) (queue_id)\n" + " Display information for configured RX/TX queue.\n\n" + + "show config (rxtx|cores|fwd|txpkts)\n" " Display the given configuration.\n\n" "read rxd (port_id) (queue_id) (rxd_id)\n" @@ -241,12 +246,17 @@ static void cmd_help_long_parsed(void *parsed_result, " Set number of packets per burst.\n\n" "set burst tx delay (microseconds) retry (num)\n" - " Set the transmit delay time and number of retries" - " in mac_retry forwarding mode.\n\n" + " Set the transmit delay time and number of retries," + " effective when retry is enabled.\n\n" "set txpkts (x[,y]*)\n" " Set the length of each segment of TXONLY" - " packets.\n\n" + " and optionally CSUM packets.\n\n" + + "set txsplit (off|on|rand)\n" + " Set the split policy for the TX packets." + " Right now only applicable for CSUM and TXONLY" + " modes\n\n" "set corelist (x[,y]*)\n" " Set the list of forwarding cores.\n\n" @@ -267,8 +277,8 @@ static void cmd_help_long_parsed(void *parsed_result, " Set the VLAN QinQ (extended queue in queue)" " on a port.\n\n" - "vlan set tpid (value) (port_id)\n" - " Set the outer VLAN TPID for Packet Filtering on" + "vlan set (inner|outer) tpid (value) (port_id)\n" + " Set the VLAN TPID for Packet Filtering on" " a port\n\n" "rx_vlan add (vlan_id|all) (port_id)\n" @@ -287,16 +297,14 @@ static void cmd_help_long_parsed(void *parsed_result, " Remove a vlan_id, to the set of VLAN identifiers" "filtered for VF(s) from port_id.\n\n" - "rx_vlan set tpid (value) (port_id)\n" - " Set the outer VLAN TPID for Packet Filtering on" - " a port\n\n" - "tunnel_filter add (port_id) (outer_mac) (inner_mac) (ip_addr) " - "(inner_vlan) (vxlan|nvgre) (filter_type) (tenant_id) (queue_id)\n" + "(inner_vlan) (vxlan|nvgre|ipingre) (imac-ivlan|imac-ivlan-tenid|" + "imac-tenid|imac|omac-imac-tenid|oip|iip) (tenant_id) (queue_id)\n" " add a tunnel filter of a port.\n\n" "tunnel_filter rm (port_id) (outer_mac) (inner_mac) (ip_addr) " - "(inner_vlan) (vxlan|nvgre) (filter_type) (tenant_id) (queue_id)\n" + "(inner_vlan) (vxlan|nvgre|ipingre) (imac-ivlan|imac-ivlan-tenid|" + "imac-tenid|imac|omac-imac-tenid|oip|iip) (tenant_id) (queue_id)\n" " remove a tunnel filter of a port.\n\n" "rx_vxlan_port add (udp_port) (port_id)\n" @@ -305,9 +313,9 @@ static void cmd_help_long_parsed(void *parsed_result, "rx_vxlan_port rm (udp_port) (port_id)\n" " Remove an UDP port for VXLAN packet filter on a port\n\n" - "tx_vlan set vlan_id (port_id)\n" - " Set hardware insertion of VLAN ID in packets sent" - " on a port.\n\n" + "tx_vlan set (port_id) vlan_id[, vlan_id_outer]\n" + " Set hardware insertion of VLAN IDs (single or double VLAN " + "depends on the number of VLAN IDs) in packets sent on a port.\n\n" "tx_vlan set pvid port_id vlan_id (on|off)\n" " Set port based TX VLAN insertion.\n\n" @@ -318,7 +326,7 @@ static void cmd_help_long_parsed(void *parsed_result, "csum set (ip|udp|tcp|sctp|outer-ip) (hw|sw) (port_id)\n" " Select hardware or software calculation of the" - " checksum with when transmitting a packet using the" + " checksum when transmitting a packet using the" " csum forward engine.\n" " ip|udp|tcp|sctp always concern the inner layer.\n" " outer-ip concerns the outer IP layer in" @@ -413,7 +421,7 @@ static void cmd_help_long_parsed(void *parsed_result, " Set rate limit for queues in VF of a port\n\n" "set port (port_id) mirror-rule (rule_id)" - "(pool-mirror|vlan-mirror)\n" + " (pool-mirror-up|pool-mirror-down|vlan-mirror)" " (poolmask|vlanid[,vlanid]*) dst-pool (pool_id) (on|off)\n" " Set pool or vlan type mirror rule on a port.\n" " e.g., 'set port 0 mirror-rule 0 vlan-mirror 0,1" @@ -492,6 +500,27 @@ static void cmd_help_long_parsed(void *parsed_result, "set link-down port (port_id)\n" " Set link down for a port.\n\n" + "E-tag set insertion on port-tag-id (value)" + " port (port_id) vf (vf_id)\n" + " Enable E-tag insertion for a VF on a port\n\n" + + "E-tag set insertion off port (port_id) vf (vf_id)\n" + " Disable E-tag insertion for a VF on a port\n\n" + + "E-tag set stripping (on|off) port (port_id)\n" + " Enable/disable E-tag stripping on a port\n\n" + + "E-tag set forwarding (on|off) port (port_id)\n" + " Enable/disable E-tag based forwarding" + " on a port\n\n" + + "E-tag set filter add e-tag-id (value) dst-pool" + " (pool_id) port (port_id)\n" + " Add an E-tag forwarding filter on a port\n\n" + + "E-tag set filter del e-tag-id (value) port (port_id)\n" + " Delete an E-tag forwarding filter on a port\n\n" + , list_pkt_forwarding_modes() ); } @@ -520,7 +549,7 @@ static void cmd_help_long_parsed(void *parsed_result, " Detach physical or virtual dev by port_id\n\n" "port config (port_id|all)" - " speed (10|100|1000|10000|40000|auto)" + " speed (10|100|1000|10000|40000|100000|auto)" " duplex (half|full|auto)\n" " Set speed and duplex for all ports or port_id\n\n" @@ -530,9 +559,10 @@ static void cmd_help_long_parsed(void *parsed_result, "port config all max-pkt-len (value)\n" " Set the max packet length.\n\n" - "port config all (crc-strip|rx-cksum|hw-vlan|drop-en)" + "port config all (crc-strip|scatter|rx-cksum|hw-vlan|hw-vlan-filter|" + "hw-vlan-strip|hw-vlan-extend|drop-en)" " (on|off)\n" - " Set crc-strip/rx-checksum/hardware-vlan/drop_en" + " Set crc-strip/scatter/rx-checksum/hardware-vlan/drop_en" " for ports.\n\n" "port config all rss (all|ip|tcp|udp|sctp|ether|none)\n" @@ -561,7 +591,15 @@ static void cmd_help_long_parsed(void *parsed_result, "port (port_id) (rxq|txq) (queue_id) (start|stop)\n" " Start/stop a rx/tx queue of port X. Only take effect" - " when port X is started\n" + " when port X is started\n\n" + + "port config (port_id|all) l2-tunnel E-tag ether-type" + " (value)\n" + " Set the value of E-tag ether-type.\n\n" + + "port config (port_id|all) l2-tunnel E-tag" + " (enable|disable)\n" + " Enable/disable the E-tag support.\n\n" ); } @@ -628,42 +666,76 @@ static void cmd_help_long_parsed(void *parsed_result, " priority (prio_value) queue (queue_id)\n" " Add/Del a flex filter.\n\n" - "flow_director_filter (port_id) (add|del|update)" + "flow_director_filter (port_id) mode IP (add|del|update)" " flow (ipv4-other|ipv4-frag|ipv6-other|ipv6-frag)" " src (src_ip_address) dst (dst_ip_address)" + " tos (tos_value) proto (proto_value) ttl (ttl_value)" " vlan (vlan_value) flexbytes (flexbytes_value)" - " (drop|fwd) queue (queue_id) fd_id (fd_id_value)\n" + " (drop|fwd) pf|vf(vf_id) queue (queue_id)" + " fd_id (fd_id_value)\n" " Add/Del an IP type flow director filter.\n\n" - "flow_director_filter (port_id) (add|del|update)" + "flow_director_filter (port_id) mode IP (add|del|update)" " flow (ipv4-tcp|ipv4-udp|ipv6-tcp|ipv6-udp)" " src (src_ip_address) (src_port)" " dst (dst_ip_address) (dst_port)" + " tos (tos_value) ttl (ttl_value)" " vlan (vlan_value) flexbytes (flexbytes_value)" - " (drop|fwd) queue (queue_id) fd_id (fd_id_value)\n" + " (drop|fwd) pf|vf(vf_id) queue (queue_id)" + " fd_id (fd_id_value)\n" " Add/Del an UDP/TCP type flow director filter.\n\n" - "flow_director_filter (port_id) (add|del|update)" + "flow_director_filter (port_id) mode IP (add|del|update)" " flow (ipv4-sctp|ipv6-sctp)" " src (src_ip_address) (src_port)" " dst (dst_ip_address) (dst_port)" - " tag (verification_tag) vlan (vlan_value)" + " tag (verification_tag) " + " tos (tos_value) ttl (ttl_value)" + " vlan (vlan_value)" " flexbytes (flexbytes_value) (drop|fwd)" - " queue (queue_id) fd_id (fd_id_value)\n" + " pf|vf(vf_id) queue (queue_id) fd_id (fd_id_value)\n" " Add/Del a SCTP type flow director filter.\n\n" + "flow_director_filter (port_id) mode IP (add|del|update)" + " flow l2_payload ether (ethertype)" + " flexbytes (flexbytes_value) (drop|fwd)" + " pf|vf(vf_id) queue (queue_id) fd_id (fd_id_value)\n" + " Add/Del a l2 payload type flow director filter.\n\n" + + "flow_director_filter (port_id) mode MAC-VLAN (add|del|update)" + " mac (mac_address) vlan (vlan_value)" + " flexbytes (flexbytes_value) (drop|fwd)" + " queue (queue_id) fd_id (fd_id_value)\n" + " Add/Del a MAC-VLAN flow director filter.\n\n" + + "flow_director_filter (port_id) mode Tunnel (add|del|update)" + " mac (mac_address) vlan (vlan_value)" + " tunnel (NVGRE|VxLAN) tunnel-id (tunnel_id_value)" + " flexbytes (flexbytes_value) (drop|fwd)" + " queue (queue_id) fd_id (fd_id_value)\n" + " Add/Del a Tunnel flow director filter.\n\n" + "flush_flow_director (port_id)\n" " Flush all flow director entries of a device.\n\n" - "flow_director_mask (port_id) vlan (vlan_value)" + "flow_director_mask (port_id) mode IP vlan (vlan_value)" " src_mask (ipv4_src) (ipv6_src) (src_port)" " dst_mask (ipv4_dst) (ipv6_dst) (dst_port)\n" - " Set flow director mask.\n\n" + " Set flow director IP mask.\n\n" + + "flow_director_mask (port_id) mode MAC-VLAN" + " vlan (vlan_value) mac (mac_value)\n" + " Set flow director MAC-VLAN mask.\n\n" + + "flow_director_mask (port_id) mode Tunnel" + " vlan (vlan_value) mac (mac_value)" + " tunnel-type (tunnel_type_value)" + " tunnel-id (tunnel_id_value)\n" + " Set flow director Tunnel mask.\n\n" "flow_director_flex_mask (port_id)" - " flow (raw|ip4|ip4-frag|tcp4|udp4|sctp4|ip6|ip6-frag|tcp6|udp6|sctp6|all)" - " flow (raw|ipv4-other|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|" - "ipv6-other|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|all)" + " flow (none|ipv4-other|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|" + "ipv6-other|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|l2_payload|all)" " (mask)\n" " Configure mask of flex payload.\n\n" @@ -686,6 +758,29 @@ static void cmd_help_long_parsed(void *parsed_result, "ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload)" " (enable|disable)\n" " Set the global configurations of hash filters.\n\n" + + "set_hash_input_set (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) (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) (select|add)\n" + " Set the input set for hash.\n\n" + + "set_fdir_input_set (port_id) " + "(ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|" + "ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|" + "l2_payload) (ivlan|ethertype|src-ipv4|dst-ipv4|src-ipv6|" + "dst-ipv6|ipv4-tos|ipv4-proto|ipv4-ttl|ipv6-tc|" + "ipv6-next-header|ipv6-hop-limits|udp-src-port|" + "udp-dst-port|tcp-src-port|tcp-dst-port|" + "sctp-src-port|sctp-dst-port|sctp-veri-tag|none)" + " (select|add)\n" + " Set the input set for FDir.\n\n" ); } } @@ -893,14 +988,60 @@ struct cmd_config_speed_all { cmdline_fixed_string_t value2; }; +static int +parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint32_t *speed) +{ + + int duplex; + + if (!strcmp(duplexstr, "half")) { + duplex = ETH_LINK_HALF_DUPLEX; + } else if (!strcmp(duplexstr, "full")) { + duplex = ETH_LINK_FULL_DUPLEX; + } else if (!strcmp(duplexstr, "auto")) { + duplex = ETH_LINK_FULL_DUPLEX; + } else { + printf("Unknown duplex parameter\n"); + return -1; + } + + if (!strcmp(speedstr, "10")) { + *speed = (duplex == ETH_LINK_HALF_DUPLEX) ? + ETH_LINK_SPEED_10M_HD : ETH_LINK_SPEED_10M; + } else if (!strcmp(speedstr, "100")) { + *speed = (duplex == ETH_LINK_HALF_DUPLEX) ? + ETH_LINK_SPEED_100M_HD : ETH_LINK_SPEED_100M; + } else { + if (duplex != ETH_LINK_FULL_DUPLEX) { + printf("Invalid speed/duplex parameters\n"); + return -1; + } + if (!strcmp(speedstr, "1000")) { + *speed = ETH_LINK_SPEED_1G; + } else if (!strcmp(speedstr, "10000")) { + *speed = ETH_LINK_SPEED_10G; + } else if (!strcmp(speedstr, "40000")) { + *speed = ETH_LINK_SPEED_40G; + } else if (!strcmp(speedstr, "100000")) { + *speed = ETH_LINK_SPEED_100G; + } else if (!strcmp(speedstr, "auto")) { + *speed = ETH_LINK_SPEED_AUTONEG; + } else { + printf("Unknown speed parameter\n"); + return -1; + } + } + + return 0; +} + static void cmd_config_speed_all_parsed(void *parsed_result, __attribute__((unused)) struct cmdline *cl, __attribute__((unused)) void *data) { struct cmd_config_speed_all *res = parsed_result; - uint16_t link_speed = ETH_LINK_SPEED_AUTONEG; - uint16_t link_duplex = 0; + uint32_t link_speed; portid_t pid; if (!all_ports_stopped()) { @@ -908,37 +1049,12 @@ cmd_config_speed_all_parsed(void *parsed_result, return; } - if (!strcmp(res->value1, "10")) - link_speed = ETH_LINK_SPEED_10; - else if (!strcmp(res->value1, "100")) - link_speed = ETH_LINK_SPEED_100; - else if (!strcmp(res->value1, "1000")) - link_speed = ETH_LINK_SPEED_1000; - else if (!strcmp(res->value1, "10000")) - link_speed = ETH_LINK_SPEED_10G; - else if (!strcmp(res->value1, "40000")) - link_speed = ETH_LINK_SPEED_40G; - else if (!strcmp(res->value1, "auto")) - link_speed = ETH_LINK_SPEED_AUTONEG; - else { - printf("Unknown parameter\n"); - return; - } - - if (!strcmp(res->value2, "half")) - link_duplex = ETH_LINK_HALF_DUPLEX; - else if (!strcmp(res->value2, "full")) - link_duplex = ETH_LINK_FULL_DUPLEX; - else if (!strcmp(res->value2, "auto")) - link_duplex = ETH_LINK_AUTONEG_DUPLEX; - else { - printf("Unknown parameter\n"); + if (parse_and_check_speed_duplex(res->value1, res->value2, + &link_speed) < 0) return; - } FOREACH_PORT(pid, ports) { - ports[pid].dev_conf.link_speed = link_speed; - ports[pid].dev_conf.link_duplex = link_duplex; + ports[pid].dev_conf.link_speeds = link_speed; } cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1); @@ -955,7 +1071,7 @@ cmdline_parse_token_string_t cmd_config_speed_all_item1 = TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, item1, "speed"); cmdline_parse_token_string_t cmd_config_speed_all_value1 = TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, value1, - "10#100#1000#10000#40000#auto"); + "10#100#1000#10000#40000#100000#auto"); cmdline_parse_token_string_t cmd_config_speed_all_item2 = TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, item2, "duplex"); cmdline_parse_token_string_t cmd_config_speed_all_value2 = @@ -965,7 +1081,7 @@ cmdline_parse_token_string_t cmd_config_speed_all_value2 = cmdline_parse_inst_t cmd_config_speed_all = { .f = cmd_config_speed_all_parsed, .data = NULL, - .help_str = "port config all speed 10|100|1000|10000|40000|auto duplex " + .help_str = "port config all speed 10|100|1000|10000|40000|100000|auto duplex " "half|full|auto", .tokens = { (void *)&cmd_config_speed_all_port, @@ -996,8 +1112,7 @@ cmd_config_speed_specific_parsed(void *parsed_result, __attribute__((unused)) void *data) { struct cmd_config_speed_specific *res = parsed_result; - uint16_t link_speed = ETH_LINK_SPEED_AUTONEG; - uint16_t link_duplex = 0; + uint32_t link_speed; if (!all_ports_stopped()) { printf("Please stop all ports first\n"); @@ -1007,36 +1122,11 @@ cmd_config_speed_specific_parsed(void *parsed_result, if (port_id_is_invalid(res->id, ENABLED_WARN)) return; - if (!strcmp(res->value1, "10")) - link_speed = ETH_LINK_SPEED_10; - else if (!strcmp(res->value1, "100")) - link_speed = ETH_LINK_SPEED_100; - else if (!strcmp(res->value1, "1000")) - link_speed = ETH_LINK_SPEED_1000; - else if (!strcmp(res->value1, "10000")) - link_speed = ETH_LINK_SPEED_10000; - else if (!strcmp(res->value1, "40000")) - link_speed = ETH_LINK_SPEED_40G; - else if (!strcmp(res->value1, "auto")) - link_speed = ETH_LINK_SPEED_AUTONEG; - else { - printf("Unknown parameter\n"); - return; - } - - if (!strcmp(res->value2, "half")) - link_duplex = ETH_LINK_HALF_DUPLEX; - else if (!strcmp(res->value2, "full")) - link_duplex = ETH_LINK_FULL_DUPLEX; - else if (!strcmp(res->value2, "auto")) - link_duplex = ETH_LINK_AUTONEG_DUPLEX; - else { - printf("Unknown parameter\n"); + if (parse_and_check_speed_duplex(res->value1, res->value2, + &link_speed) < 0) return; - } - ports[res->id].dev_conf.link_speed = link_speed; - ports[res->id].dev_conf.link_duplex = link_duplex; + ports[res->id].dev_conf.link_speeds = link_speed; cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1); } @@ -1055,7 +1145,7 @@ cmdline_parse_token_string_t cmd_config_speed_specific_item1 = "speed"); cmdline_parse_token_string_t cmd_config_speed_specific_value1 = TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, value1, - "10#100#1000#10000#40000#auto"); + "10#100#1000#10000#40000#100000#auto"); cmdline_parse_token_string_t cmd_config_speed_specific_item2 = TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, item2, "duplex"); @@ -1066,7 +1156,7 @@ cmdline_parse_token_string_t cmd_config_speed_specific_value2 = cmdline_parse_inst_t cmd_config_speed_specific = { .f = cmd_config_speed_specific_parsed, .data = NULL, - .help_str = "port config X speed 10|100|1000|10000|40000|auto duplex " + .help_str = "port config X speed 10|100|1000|10000|40000|100000|auto duplex " "half|full|auto", .tokens = { (void *)&cmd_config_speed_specific_port, @@ -1100,17 +1190,16 @@ cmd_config_rx_tx_parsed(void *parsed_result, printf("Please stop all ports first\n"); return; } - if (!strcmp(res->name, "rxq")) { - if (res->value <= 0) { - printf("rxq %d invalid - must be > 0\n", res->value); + if (!res->value && !nb_txq) { + printf("Warning: Either rx or tx queues should be non zero\n"); return; } nb_rxq = res->value; } else if (!strcmp(res->name, "txq")) { - if (res->value <= 0) { - printf("txq %d invalid - must be > 0\n", res->value); + if (!res->value && !nb_rxq) { + printf("Warning: Either rx or tx queues should be non zero\n"); return; } nb_txq = res->value; @@ -1134,6 +1223,8 @@ cmd_config_rx_tx_parsed(void *parsed_result, return; } + fwd_config_setup(); + init_port_config(); cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1); @@ -1321,6 +1412,15 @@ cmd_config_rx_mode_flag_parsed(void *parsed_result, printf("Unknown parameter\n"); return; } + } else if (!strcmp(res->name, "scatter")) { + if (!strcmp(res->value, "on")) + rx_mode.enable_scatter = 1; + else if (!strcmp(res->value, "off")) + rx_mode.enable_scatter = 0; + else { + printf("Unknown parameter\n"); + return; + } } else if (!strcmp(res->name, "rx-cksum")) { if (!strcmp(res->value, "on")) rx_mode.hw_ip_checksum = 1; @@ -1343,6 +1443,33 @@ cmd_config_rx_mode_flag_parsed(void *parsed_result, printf("Unknown parameter\n"); return; } + } else if (!strcmp(res->name, "hw-vlan-filter")) { + if (!strcmp(res->value, "on")) + rx_mode.hw_vlan_filter = 1; + else if (!strcmp(res->value, "off")) + rx_mode.hw_vlan_filter = 0; + else { + printf("Unknown parameter\n"); + return; + } + } else if (!strcmp(res->name, "hw-vlan-strip")) { + if (!strcmp(res->value, "on")) + rx_mode.hw_vlan_strip = 1; + else if (!strcmp(res->value, "off")) + rx_mode.hw_vlan_strip = 0; + else { + printf("Unknown parameter\n"); + return; + } + } else if (!strcmp(res->name, "hw-vlan-extend")) { + if (!strcmp(res->value, "on")) + rx_mode.hw_vlan_extend = 1; + else if (!strcmp(res->value, "off")) + rx_mode.hw_vlan_extend = 0; + else { + printf("Unknown parameter\n"); + return; + } } else if (!strcmp(res->name, "drop-en")) { if (!strcmp(res->value, "on")) rx_drop_en = 1; @@ -1371,7 +1498,8 @@ cmdline_parse_token_string_t cmd_config_rx_mode_flag_all = TOKEN_STRING_INITIALIZER(struct cmd_config_rx_mode_flag, all, "all"); cmdline_parse_token_string_t cmd_config_rx_mode_flag_name = TOKEN_STRING_INITIALIZER(struct cmd_config_rx_mode_flag, name, - "crc-strip#rx-cksum#hw-vlan"); + "crc-strip#scatter#rx-cksum#hw-vlan#" + "hw-vlan-filter#hw-vlan-strip#hw-vlan-extend"); cmdline_parse_token_string_t cmd_config_rx_mode_flag_value = TOKEN_STRING_INITIALIZER(struct cmd_config_rx_mode_flag, value, "on#off"); @@ -1379,7 +1507,8 @@ cmdline_parse_token_string_t cmd_config_rx_mode_flag_value = cmdline_parse_inst_t cmd_config_rx_mode_flag = { .f = cmd_config_rx_mode_flag_parsed, .data = NULL, - .help_str = "port config all crc-strip|rx-cksum|hw-vlan on|off", + .help_str = "port config all crc-strip|scatter|rx-cksum|hw-vlan|" + "hw-vlan-filter|hw-vlan-strip|hw-vlan-extend on|off", .tokens = { (void *)&cmd_config_rx_mode_flag_port, (void *)&cmd_config_rx_mode_flag_keyword, @@ -1465,6 +1594,7 @@ struct cmd_config_rss_hash_key { cmdline_fixed_string_t config; uint8_t port_id; cmdline_fixed_string_t rss_hash_key; + cmdline_fixed_string_t rss_type; cmdline_fixed_string_t key; }; @@ -1522,7 +1652,8 @@ cmd_config_rss_hash_key_parsed(void *parsed_result, return; hash_key[i] = (uint8_t) ((xdgt0 * 16) + xdgt1); } - port_rss_hash_key_update(res->port_id, hash_key); + port_rss_hash_key_update(res->port_id, res->rss_type, hash_key, + RSS_HASH_KEY_LENGTH); } cmdline_parse_token_string_t cmd_config_rss_hash_key_port = @@ -1535,18 +1666,29 @@ cmdline_parse_token_num_t cmd_config_rss_hash_key_port_id = cmdline_parse_token_string_t cmd_config_rss_hash_key_rss_hash_key = TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key, rss_hash_key, "rss-hash-key"); +cmdline_parse_token_string_t cmd_config_rss_hash_key_rss_type = + TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key, rss_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#ipv6-ex#" + "ipv6-tcp-ex#ipv6-udp-ex"); cmdline_parse_token_string_t cmd_config_rss_hash_key_value = TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key, key, NULL); cmdline_parse_inst_t cmd_config_rss_hash_key = { .f = cmd_config_rss_hash_key_parsed, .data = NULL, - .help_str = "port config X rss-hash-key 80 hexa digits", + .help_str = + "port config X rss-hash-key ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|" + "ipv4-sctp|ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|" + "ipv6-sctp|ipv6-other|l2-payload|" + "ipv6-ex|ipv6-tcp-ex|ipv6-udp-ex 80 hexa digits\n", .tokens = { (void *)&cmd_config_rss_hash_key_port, (void *)&cmd_config_rss_hash_key_config, (void *)&cmd_config_rss_hash_key_port_id, (void *)&cmd_config_rss_hash_key_rss_hash_key, + (void *)&cmd_config_rss_hash_key_rss_type, (void *)&cmd_config_rss_hash_key_value, NULL, }, @@ -1664,7 +1806,7 @@ parse_reta_config(const char *str, int i; unsigned size; uint16_t hash_index, idx, shift; - uint8_t nb_queue; + uint16_t nb_queue; char s[256]; const char *p, *p0 = str; char *end; @@ -1697,7 +1839,7 @@ parse_reta_config(const char *str, } hash_index = (uint16_t)int_fld[FLD_HASH_INDEX]; - nb_queue = (uint8_t)int_fld[FLD_QUEUE]; + nb_queue = (uint16_t)int_fld[FLD_QUEUE]; if (hash_index >= nb_entries) { printf("Invalid RETA hash index=%d\n", hash_index); @@ -1896,6 +2038,7 @@ struct cmd_showport_rss_hash { cmdline_fixed_string_t port; uint8_t port_id; cmdline_fixed_string_t rss_hash; + cmdline_fixed_string_t rss_type; cmdline_fixed_string_t key; /* optional argument */ }; @@ -1905,7 +2048,8 @@ static void cmd_showport_rss_hash_parsed(void *parsed_result, { struct cmd_showport_rss_hash *res = parsed_result; - port_rss_hash_conf_show(res->port_id, show_rss_key != NULL); + port_rss_hash_conf_show(res->port_id, res->rss_type, + show_rss_key != NULL); } cmdline_parse_token_string_t cmd_showport_rss_hash_show = @@ -1917,18 +2061,29 @@ cmdline_parse_token_num_t cmd_showport_rss_hash_port_id = cmdline_parse_token_string_t cmd_showport_rss_hash_rss_hash = TOKEN_STRING_INITIALIZER(struct cmd_showport_rss_hash, rss_hash, "rss-hash"); +cmdline_parse_token_string_t cmd_showport_rss_hash_rss_hash_info = + TOKEN_STRING_INITIALIZER(struct cmd_showport_rss_hash, rss_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#ipv6-ex#" + "ipv6-tcp-ex#ipv6-udp-ex"); cmdline_parse_token_string_t cmd_showport_rss_hash_rss_key = TOKEN_STRING_INITIALIZER(struct cmd_showport_rss_hash, key, "key"); cmdline_parse_inst_t cmd_showport_rss_hash = { .f = cmd_showport_rss_hash_parsed, .data = NULL, - .help_str = "show port X rss-hash (X = port number)\n", + .help_str = + "show port X rss-hash ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|" + "ipv4-sctp|ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|" + "ipv6-sctp|ipv6-other|l2-payload|" + "ipv6-ex|ipv6-tcp-ex|ipv6-udp-ex (X = port number)\n", .tokens = { (void *)&cmd_showport_rss_hash_show, (void *)&cmd_showport_rss_hash_port, (void *)&cmd_showport_rss_hash_port_id, (void *)&cmd_showport_rss_hash_rss_hash, + (void *)&cmd_showport_rss_hash_rss_hash_info, NULL, }, }; @@ -1936,12 +2091,17 @@ cmdline_parse_inst_t cmd_showport_rss_hash = { cmdline_parse_inst_t cmd_showport_rss_hash_key = { .f = cmd_showport_rss_hash_parsed, .data = (void *)1, - .help_str = "show port X rss-hash key (X = port number)\n", + .help_str = + "show port X rss-hash ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|" + "ipv4-sctp|ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|" + "ipv6-sctp|ipv6-other|l2-payload|" + "ipv6-ex|ipv6-tcp-ex|ipv6-udp-ex key (X = port number)\n", .tokens = { (void *)&cmd_showport_rss_hash_show, (void *)&cmd_showport_rss_hash_port, (void *)&cmd_showport_rss_hash_port_id, (void *)&cmd_showport_rss_hash_rss_hash, + (void *)&cmd_showport_rss_hash_rss_hash_info, (void *)&cmd_showport_rss_hash_rss_key, NULL, }, @@ -1966,37 +2126,46 @@ cmd_config_dcb_parsed(void *parsed_result, __attribute__((unused)) void *data) { struct cmd_config_dcb *res = parsed_result; - struct dcb_config dcb_conf; portid_t port_id = res->port_id; struct rte_port *port; + uint8_t pfc_en; + int ret; port = &ports[port_id]; /** Check if the port is not started **/ if (port->port_status != RTE_PORT_STOPPED) { - printf("Please stop port %d first\n",port_id); + printf("Please stop port %d first\n", port_id); return; } - dcb_conf.num_tcs = (enum rte_eth_nb_tcs) res->num_tcs; - if ((dcb_conf.num_tcs != ETH_4_TCS) && (dcb_conf.num_tcs != ETH_8_TCS)){ - printf("The invalid number of traffic class,only 4 or 8 allowed\n"); + if ((res->num_tcs != ETH_4_TCS) && (res->num_tcs != ETH_8_TCS)) { + printf("The invalid number of traffic class," + " only 4 or 8 allowed.\n"); return; } - /* DCB in VT mode */ - if (!strncmp(res->vt_en, "on",2)) - dcb_conf.dcb_mode = DCB_VT_ENABLED; + if (nb_fwd_lcores < res->num_tcs) { + printf("nb_cores shouldn't be less than number of TCs.\n"); + return; + } + if (!strncmp(res->pfc_en, "on", 2)) + pfc_en = 1; else - dcb_conf.dcb_mode = DCB_ENABLED; + pfc_en = 0; - if (!strncmp(res->pfc_en, "on",2)) { - dcb_conf.pfc_en = 1; - } + /* DCB in VT mode */ + if (!strncmp(res->vt_en, "on", 2)) + ret = init_port_dcb_config(port_id, DCB_VT_ENABLED, + (enum rte_eth_nb_tcs)res->num_tcs, + pfc_en); else - dcb_conf.pfc_en = 0; + ret = init_port_dcb_config(port_id, DCB_ENABLED, + (enum rte_eth_nb_tcs)res->num_tcs, + pfc_en); - if (init_port_dcb_config(port_id,&dcb_conf) != 0) { - printf("Cannot initialize network ports\n"); + + if (ret != 0) { + printf("Cannot initialize network ports.\n"); return; } @@ -2288,11 +2457,11 @@ parse_item_list(char* str, const char* item_name, unsigned int max_items, } if (c != ',') { printf("character %c is not a decimal digit\n", c); - return (0); + return 0; } if (! value_ok) { printf("No valid value before comma\n"); - return (0); + return 0; } if (nb_item < max_items) { parsed_items[nb_item] = value; @@ -2304,11 +2473,11 @@ parse_item_list(char* str, const char* item_name, unsigned int max_items, if (nb_item >= max_items) { printf("Number of %s = %u > %u (maximum items)\n", item_name, nb_item + 1, max_items); - return (0); + return 0; } parsed_items[nb_item++] = value; if (! check_unique_values) - return (nb_item); + return nb_item; /* * Then, check that all values in the list are differents. @@ -2319,11 +2488,11 @@ parse_item_list(char* str, const char* item_name, unsigned int max_items, if (parsed_items[j] == parsed_items[i]) { printf("duplicated %s %u at index %u and %u\n", item_name, parsed_items[i], i, j); - return (0); + return 0; } } } - return (nb_item); + return nb_item; } struct cmd_set_list_result { @@ -2353,16 +2522,20 @@ static void cmd_set_list_parsed(void *parsed_result, nb_item = parse_item_list(res->list_of_items, "core", RTE_MAX_LCORE, parsed_items.lcorelist, 1); - if (nb_item > 0) + if (nb_item > 0) { set_fwd_lcores_list(parsed_items.lcorelist, nb_item); + fwd_config_setup(); + } return; } if (!strcmp(res->list_name, "portlist")) { nb_item = parse_item_list(res->list_of_items, "port", RTE_MAX_ETHPORTS, parsed_items.portlist, 1); - if (nb_item > 0) + if (nb_item > 0) { set_fwd_ports_list(parsed_items.portlist, nb_item); + fwd_config_setup(); + } } } @@ -2406,10 +2579,13 @@ static void cmd_set_mask_parsed(void *parsed_result, printf("Please stop forwarding first\n"); return; } - if (!strcmp(res->mask, "coremask")) + if (!strcmp(res->mask, "coremask")) { set_fwd_lcores_mask(res->hexavalue); - else if (!strcmp(res->mask, "portmask")) + fwd_config_setup(); + } else if (!strcmp(res->mask, "portmask")) { set_fwd_ports_mask(res->hexavalue); + fwd_config_setup(); + } } cmdline_parse_token_string_t cmd_setmask_set = @@ -2446,11 +2622,13 @@ static void cmd_set_parsed(void *parsed_result, __attribute__((unused)) void *data) { struct cmd_set_result *res = parsed_result; - if (!strcmp(res->what, "nbport")) + if (!strcmp(res->what, "nbport")) { set_fwd_ports_number(res->value); - else if (!strcmp(res->what, "nbcore")) + fwd_config_setup(); + } else if (!strcmp(res->what, "nbcore")) { set_fwd_lcores_number(res->value); - else if (!strcmp(res->what, "burst")) + fwd_config_setup(); + } else if (!strcmp(res->what, "burst")) set_nb_pkt_per_burst(res->value); else if (!strcmp(res->what, "verbose")) set_verbose_level(res->value); @@ -2522,6 +2700,115 @@ cmdline_parse_inst_t cmd_set_txpkts = { }, }; +/* *** SET COPY AND SPLIT POLICY ON TX PACKETS *** */ + +struct cmd_set_txsplit_result { + cmdline_fixed_string_t cmd_keyword; + cmdline_fixed_string_t txsplit; + cmdline_fixed_string_t mode; +}; + +static void +cmd_set_txsplit_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_set_txsplit_result *res; + + res = parsed_result; + set_tx_pkt_split(res->mode); +} + +cmdline_parse_token_string_t cmd_set_txsplit_keyword = + TOKEN_STRING_INITIALIZER(struct cmd_set_txsplit_result, + cmd_keyword, "set"); +cmdline_parse_token_string_t cmd_set_txsplit_name = + TOKEN_STRING_INITIALIZER(struct cmd_set_txsplit_result, + txsplit, "txsplit"); +cmdline_parse_token_string_t cmd_set_txsplit_mode = + TOKEN_STRING_INITIALIZER(struct cmd_set_txsplit_result, + mode, NULL); + +cmdline_parse_inst_t cmd_set_txsplit = { + .f = cmd_set_txsplit_parsed, + .data = NULL, + .help_str = "set txsplit on|off|rand", + .tokens = { + (void *)&cmd_set_txsplit_keyword, + (void *)&cmd_set_txsplit_name, + (void *)&cmd_set_txsplit_mode, + NULL, + }, +}; + +/* *** CONFIG TX QUEUE FLAGS *** */ + +struct cmd_config_txqflags_result { + cmdline_fixed_string_t port; + cmdline_fixed_string_t config; + cmdline_fixed_string_t all; + cmdline_fixed_string_t what; + int32_t hexvalue; +}; + +static void cmd_config_txqflags_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_config_txqflags_result *res = parsed_result; + + if (!all_ports_stopped()) { + printf("Please stop all ports first\n"); + return; + } + + if (strcmp(res->what, "txqflags")) { + printf("Unknown parameter\n"); + return; + } + + if (res->hexvalue >= 0) { + txq_flags = res->hexvalue; + } else { + printf("txqflags must be >= 0\n"); + return; + } + + init_port_config(); + + cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1); +} + +cmdline_parse_token_string_t cmd_config_txqflags_port = + TOKEN_STRING_INITIALIZER(struct cmd_config_txqflags_result, port, + "port"); +cmdline_parse_token_string_t cmd_config_txqflags_config = + TOKEN_STRING_INITIALIZER(struct cmd_config_txqflags_result, config, + "config"); +cmdline_parse_token_string_t cmd_config_txqflags_all = + TOKEN_STRING_INITIALIZER(struct cmd_config_txqflags_result, all, + "all"); +cmdline_parse_token_string_t cmd_config_txqflags_what = + TOKEN_STRING_INITIALIZER(struct cmd_config_txqflags_result, what, + "txqflags"); +cmdline_parse_token_num_t cmd_config_txqflags_value = + TOKEN_NUM_INITIALIZER(struct cmd_config_txqflags_result, + hexvalue, INT32); + +cmdline_parse_inst_t cmd_config_txqflags = { + .f = cmd_config_txqflags_parsed, + .data = NULL, + .help_str = "port config all txqflags value", + .tokens = { + (void *)&cmd_config_txqflags_port, + (void *)&cmd_config_txqflags_config, + (void *)&cmd_config_txqflags_all, + (void *)&cmd_config_txqflags_what, + (void *)&cmd_config_txqflags_value, + NULL, + }, +}; + /* *** ADD/REMOVE ALL VLAN IDENTIFIERS TO/FROM A PORT VLAN RX FILTER *** */ struct cmd_rx_vlan_filter_all_result { cmdline_fixed_string_t rx_vlan; @@ -2574,6 +2861,7 @@ cmdline_parse_inst_t cmd_rx_vlan_filter_all = { struct cmd_vlan_offload_result { cmdline_fixed_string_t vlan; cmdline_fixed_string_t set; + cmdline_fixed_string_t vlan_type; cmdline_fixed_string_t what; cmdline_fixed_string_t on; cmdline_fixed_string_t port_id; @@ -2674,6 +2962,7 @@ cmdline_parse_inst_t cmd_vlan_offload = { struct cmd_vlan_tpid_result { cmdline_fixed_string_t vlan; cmdline_fixed_string_t set; + cmdline_fixed_string_t vlan_type; cmdline_fixed_string_t what; uint16_t tp_id; uint8_t port_id; @@ -2685,8 +2974,17 @@ cmd_vlan_tpid_parsed(void *parsed_result, __attribute__((unused)) void *data) { struct cmd_vlan_tpid_result *res = parsed_result; - vlan_tpid_set(res->port_id, res->tp_id); - return; + enum rte_vlan_type vlan_type; + + if (!strcmp(res->vlan_type, "inner")) + vlan_type = ETH_VLAN_TYPE_INNER; + else if (!strcmp(res->vlan_type, "outer")) + vlan_type = ETH_VLAN_TYPE_OUTER; + else { + printf("Unknown vlan type\n"); + return; + } + vlan_tpid_set(res->port_id, vlan_type, res->tp_id); } cmdline_parse_token_string_t cmd_vlan_tpid_vlan = @@ -2695,6 +2993,9 @@ cmdline_parse_token_string_t cmd_vlan_tpid_vlan = cmdline_parse_token_string_t cmd_vlan_tpid_set = TOKEN_STRING_INITIALIZER(struct cmd_vlan_tpid_result, set, "set"); +cmdline_parse_token_string_t cmd_vlan_type = + TOKEN_STRING_INITIALIZER(struct cmd_vlan_tpid_result, + vlan_type, "inner#outer"); cmdline_parse_token_string_t cmd_vlan_tpid_what = TOKEN_STRING_INITIALIZER(struct cmd_vlan_tpid_result, what, "tpid"); @@ -2708,10 +3009,12 @@ cmdline_parse_token_num_t cmd_vlan_tpid_portid = cmdline_parse_inst_t cmd_vlan_tpid = { .f = cmd_vlan_tpid_parsed, .data = NULL, - .help_str = "set tpid tp_id port_id, set the Outer VLAN Ether type", + .help_str = "set inner|outer tpid tp_id port_id, set the VLAN " + "Ether type", .tokens = { (void *)&cmd_vlan_tpid_vlan, (void *)&cmd_vlan_tpid_set, + (void *)&cmd_vlan_type, (void *)&cmd_vlan_tpid_what, (void *)&cmd_vlan_tpid_tpid, (void *)&cmd_vlan_tpid_portid, @@ -2771,8 +3074,8 @@ cmdline_parse_inst_t cmd_rx_vlan_filter = { struct cmd_tx_vlan_set_result { cmdline_fixed_string_t tx_vlan; cmdline_fixed_string_t set; - uint16_t vlan_id; uint8_t port_id; + uint16_t vlan_id; }; static void @@ -2781,6 +3084,7 @@ cmd_tx_vlan_set_parsed(void *parsed_result, __attribute__((unused)) void *data) { struct cmd_tx_vlan_set_result *res = parsed_result; + tx_vlan_set(res->port_id, res->vlan_id); } @@ -2790,23 +3094,73 @@ cmdline_parse_token_string_t cmd_tx_vlan_set_tx_vlan = cmdline_parse_token_string_t cmd_tx_vlan_set_set = TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_result, set, "set"); -cmdline_parse_token_num_t cmd_tx_vlan_set_vlanid = - TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_result, - vlan_id, UINT16); cmdline_parse_token_num_t cmd_tx_vlan_set_portid = TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_result, port_id, UINT8); +cmdline_parse_token_num_t cmd_tx_vlan_set_vlanid = + TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_result, + vlan_id, UINT16); cmdline_parse_inst_t cmd_tx_vlan_set = { .f = cmd_tx_vlan_set_parsed, .data = NULL, - .help_str = "enable hardware insertion of a VLAN header with a given " - "TAG Identifier in packets sent on a port", + .help_str = "enable hardware insertion of a single VLAN header " + "with a given TAG Identifier in packets sent on a port", .tokens = { (void *)&cmd_tx_vlan_set_tx_vlan, (void *)&cmd_tx_vlan_set_set, - (void *)&cmd_tx_vlan_set_vlanid, (void *)&cmd_tx_vlan_set_portid, + (void *)&cmd_tx_vlan_set_vlanid, + NULL, + }, +}; + +/* *** ENABLE HARDWARE INSERTION OF Double VLAN HEADER IN TX PACKETS *** */ +struct cmd_tx_vlan_set_qinq_result { + cmdline_fixed_string_t tx_vlan; + cmdline_fixed_string_t set; + uint8_t port_id; + uint16_t vlan_id; + uint16_t vlan_id_outer; +}; + +static void +cmd_tx_vlan_set_qinq_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_tx_vlan_set_qinq_result *res = parsed_result; + + tx_qinq_set(res->port_id, res->vlan_id, res->vlan_id_outer); +} + +cmdline_parse_token_string_t cmd_tx_vlan_set_qinq_tx_vlan = + TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_qinq_result, + tx_vlan, "tx_vlan"); +cmdline_parse_token_string_t cmd_tx_vlan_set_qinq_set = + TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_qinq_result, + set, "set"); +cmdline_parse_token_num_t cmd_tx_vlan_set_qinq_portid = + TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_qinq_result, + port_id, UINT8); +cmdline_parse_token_num_t cmd_tx_vlan_set_qinq_vlanid = + TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_qinq_result, + vlan_id, UINT16); +cmdline_parse_token_num_t cmd_tx_vlan_set_qinq_vlanid_outer = + TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_qinq_result, + vlan_id_outer, UINT16); + +cmdline_parse_inst_t cmd_tx_vlan_set_qinq = { + .f = cmd_tx_vlan_set_qinq_parsed, + .data = NULL, + .help_str = "enable hardware insertion of double VLAN header " + "with given TAG Identifiers in packets sent on a port", + .tokens = { + (void *)&cmd_tx_vlan_set_qinq_tx_vlan, + (void *)&cmd_tx_vlan_set_qinq_set, + (void *)&cmd_tx_vlan_set_qinq_portid, + (void *)&cmd_tx_vlan_set_qinq_vlanid, + (void *)&cmd_tx_vlan_set_qinq_vlanid_outer, NULL, }, }; @@ -3922,6 +4276,7 @@ static void cmd_add_bonding_slave_parsed(void *parsed_result, return; } init_port_config(); + set_port_slave_flag(slave_port_id); } cmdline_parse_token_string_t cmd_addbonding_slave_add = @@ -3978,6 +4333,7 @@ static void cmd_remove_bonding_slave_parsed(void *parsed_result, return; } init_port_config(); + clear_port_slave_flag(slave_port_id); } cmdline_parse_token_string_t cmd_removebonding_slave_remove = @@ -4050,6 +4406,7 @@ static void cmd_create_bonded_device_parsed(void *parsed_result, nb_ports = rte_eth_dev_count(); reconfig(port_id, res->socket); rte_eth_promiscuous_enable(port_id); + ports[port_id].enabled = 1; } } @@ -4211,6 +4568,7 @@ static void cmd_set_fwd_mode_parsed(void *parsed_result, { struct cmd_set_fwd_mode_result *res = parsed_result; + retry_enabled = 0; set_pkt_forwarding_mode(res->mode); } @@ -4256,6 +4614,74 @@ static void cmd_set_fwd_mode_init(void) token_struct->string_data.str = token; } +/* *** SET RETRY FORWARDING MODE *** */ +struct cmd_set_fwd_retry_mode_result { + cmdline_fixed_string_t set; + cmdline_fixed_string_t fwd; + cmdline_fixed_string_t mode; + cmdline_fixed_string_t retry; +}; + +static void cmd_set_fwd_retry_mode_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_set_fwd_retry_mode_result *res = parsed_result; + + retry_enabled = 1; + set_pkt_forwarding_mode(res->mode); +} + +cmdline_parse_token_string_t cmd_setfwd_retry_set = + TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_retry_mode_result, + set, "set"); +cmdline_parse_token_string_t cmd_setfwd_retry_fwd = + TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_retry_mode_result, + fwd, "fwd"); +cmdline_parse_token_string_t cmd_setfwd_retry_mode = + TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_retry_mode_result, + mode, + "" /* defined at init */); +cmdline_parse_token_string_t cmd_setfwd_retry_retry = + TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_retry_mode_result, + retry, "retry"); + +cmdline_parse_inst_t cmd_set_fwd_retry_mode = { + .f = cmd_set_fwd_retry_mode_parsed, + .data = NULL, + .help_str = NULL, /* defined at init */ + .tokens = { + (void *)&cmd_setfwd_retry_set, + (void *)&cmd_setfwd_retry_fwd, + (void *)&cmd_setfwd_retry_mode, + (void *)&cmd_setfwd_retry_retry, + NULL, + }, +}; + +static void cmd_set_fwd_retry_mode_init(void) +{ + char *modes, *c; + static char token[128]; + static char help[256]; + cmdline_parse_token_string_t *token_struct; + + modes = list_pkt_forwarding_retry_modes(); + snprintf(help, sizeof(help), "set fwd %s retry - " + "set packet forwarding mode with retry", modes); + cmd_set_fwd_retry_mode.help_str = help; + + /* string token separator is # */ + for (c = token; *modes != '\0'; modes++) + if (*modes == '|') + *c++ = '#'; + else + *c++ = *modes; + token_struct = (cmdline_parse_token_string_t *) + cmd_set_fwd_retry_mode.tokens[2]; + token_struct->string_data.str = token; +} + /* *** SET BURST TX DELAY TIME RETRY NUMBER *** */ struct cmd_set_burst_tx_retry_result { cmdline_fixed_string_t set; @@ -4714,7 +5140,8 @@ cmd_link_flow_ctrl_set_parsed(void *parsed_result, struct cmd_link_flow_ctrl_set_result *res = parsed_result; cmdline_parse_inst_t *cmd = data; struct rte_eth_fc_conf fc_conf; - int rx_fc_en, tx_fc_en = 0; + int rx_fc_en = 0; + int tx_fc_en = 0; int ret; /* @@ -4970,22 +5397,62 @@ cmdline_parse_inst_t cmd_start_tx_first = { }, }; -/* *** SET LINK UP *** */ -struct cmd_set_link_up_result { - cmdline_fixed_string_t set; - cmdline_fixed_string_t link_up; - cmdline_fixed_string_t port; - uint8_t port_id; +/* *** START FORWARDING WITH N TX BURST FIRST *** */ +struct cmd_start_tx_first_n_result { + cmdline_fixed_string_t start; + cmdline_fixed_string_t tx_first; + uint32_t tx_num; }; -cmdline_parse_token_string_t cmd_set_link_up_set = - TOKEN_STRING_INITIALIZER(struct cmd_set_link_up_result, set, "set"); -cmdline_parse_token_string_t cmd_set_link_up_link_up = - TOKEN_STRING_INITIALIZER(struct cmd_set_link_up_result, link_up, - "link-up"); -cmdline_parse_token_string_t cmd_set_link_up_port = - TOKEN_STRING_INITIALIZER(struct cmd_set_link_up_result, port, "port"); -cmdline_parse_token_num_t cmd_set_link_up_port_id = +static void +cmd_start_tx_first_n_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_start_tx_first_n_result *res = parsed_result; + + start_packet_forwarding(res->tx_num); +} + +cmdline_parse_token_string_t cmd_start_tx_first_n_start = + TOKEN_STRING_INITIALIZER(struct cmd_start_tx_first_n_result, + start, "start"); +cmdline_parse_token_string_t cmd_start_tx_first_n_tx_first = + TOKEN_STRING_INITIALIZER(struct cmd_start_tx_first_n_result, + tx_first, "tx_first"); +cmdline_parse_token_num_t cmd_start_tx_first_n_tx_num = + TOKEN_NUM_INITIALIZER(struct cmd_start_tx_first_n_result, + tx_num, UINT32); + +cmdline_parse_inst_t cmd_start_tx_first_n = { + .f = cmd_start_tx_first_n_parsed, + .data = NULL, + .help_str = "start packet forwarding, after sending " + "bursts of packets", + .tokens = { + (void *)&cmd_start_tx_first_n_start, + (void *)&cmd_start_tx_first_n_tx_first, + (void *)&cmd_start_tx_first_n_tx_num, + NULL, + }, +}; + +/* *** SET LINK UP *** */ +struct cmd_set_link_up_result { + cmdline_fixed_string_t set; + cmdline_fixed_string_t link_up; + cmdline_fixed_string_t port; + uint8_t port_id; +}; + +cmdline_parse_token_string_t cmd_set_link_up_set = + TOKEN_STRING_INITIALIZER(struct cmd_set_link_up_result, set, "set"); +cmdline_parse_token_string_t cmd_set_link_up_link_up = + TOKEN_STRING_INITIALIZER(struct cmd_set_link_up_result, link_up, + "link-up"); +cmdline_parse_token_string_t cmd_set_link_up_port = + TOKEN_STRING_INITIALIZER(struct cmd_set_link_up_result, port, "port"); +cmdline_parse_token_num_t cmd_set_link_up_port_id = TOKEN_NUM_INITIALIZER(struct cmd_set_link_up_result, port_id, UINT8); static void cmd_set_link_up_parsed(__attribute__((unused)) void *parsed_result, @@ -5066,7 +5533,9 @@ static void cmd_showcfg_parsed(void *parsed_result, else if (!strcmp(res->what, "cores")) fwd_lcores_config_display(); else if (!strcmp(res->what, "fwd")) - fwd_config_display(); + pkt_fwd_config_display(&cur_fwd_config); + else if (!strcmp(res->what, "txpkts")) + show_tx_pkt_segments(); } cmdline_parse_token_string_t cmd_showcfg_show = @@ -5075,12 +5544,12 @@ cmdline_parse_token_string_t cmd_showcfg_port = TOKEN_STRING_INITIALIZER(struct cmd_showcfg_result, cfg, "config"); cmdline_parse_token_string_t cmd_showcfg_what = TOKEN_STRING_INITIALIZER(struct cmd_showcfg_result, what, - "rxtx#cores#fwd"); + "rxtx#cores#fwd#txpkts"); cmdline_parse_inst_t cmd_showcfg = { .f = cmd_showcfg_parsed, .data = NULL, - .help_str = "show config rxtx|cores|fwd", + .help_str = "show config rxtx|cores|fwd|txpkts", .tokens = { (void *)&cmd_showcfg_show, (void *)&cmd_showcfg_port, @@ -5126,6 +5595,9 @@ static void cmd_showportall_parsed(void *parsed_result, else if (!strcmp(res->what, "stat_qmap")) FOREACH_PORT(i, ports) nic_stats_mapping_display(i); + else if (!strcmp(res->what, "dcb_tc")) + FOREACH_PORT(i, ports) + port_dcb_info_display(i); } cmdline_parse_token_string_t cmd_showportall_show = @@ -5135,13 +5607,13 @@ cmdline_parse_token_string_t cmd_showportall_port = TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, port, "port"); cmdline_parse_token_string_t cmd_showportall_what = TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, what, - "info#stats#xstats#fdir#stat_qmap"); + "info#stats#xstats#fdir#stat_qmap#dcb_tc"); cmdline_parse_token_string_t cmd_showportall_all = TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, all, "all"); cmdline_parse_inst_t cmd_showportall = { .f = cmd_showportall_parsed, .data = NULL, - .help_str = "show|clear port info|stats|xstats|fdir|stat_qmap all", + .help_str = "show|clear port info|stats|xstats|fdir|stat_qmap|dcb_tc all", .tokens = { (void *)&cmd_showportall_show, (void *)&cmd_showportall_port, @@ -5179,6 +5651,8 @@ static void cmd_showport_parsed(void *parsed_result, fdir_get_infos(res->portnum); else if (!strcmp(res->what, "stat_qmap")) nic_stats_mapping_display(res->portnum); + else if (!strcmp(res->what, "dcb_tc")) + port_dcb_info_display(res->portnum); } cmdline_parse_token_string_t cmd_showport_show = @@ -5188,14 +5662,14 @@ cmdline_parse_token_string_t cmd_showport_port = TOKEN_STRING_INITIALIZER(struct cmd_showport_result, port, "port"); cmdline_parse_token_string_t cmd_showport_what = TOKEN_STRING_INITIALIZER(struct cmd_showport_result, what, - "info#stats#xstats#fdir#stat_qmap"); + "info#stats#xstats#fdir#stat_qmap#dcb_tc"); cmdline_parse_token_num_t cmd_showport_portnum = TOKEN_NUM_INITIALIZER(struct cmd_showport_result, portnum, UINT8); cmdline_parse_inst_t cmd_showport = { .f = cmd_showport_parsed, .data = NULL, - .help_str = "show|clear port info|stats|xstats|fdir|stat_qmap X (X = port number)", + .help_str = "show|clear port info|stats|xstats|fdir|stat_qmap|dcb_tc X (X = port number)", .tokens = { (void *)&cmd_showport_show, (void *)&cmd_showport_port, @@ -5205,6 +5679,53 @@ cmdline_parse_inst_t cmd_showport = { }, }; +/* *** SHOW QUEUE INFO *** */ +struct cmd_showqueue_result { + cmdline_fixed_string_t show; + cmdline_fixed_string_t type; + cmdline_fixed_string_t what; + uint8_t portnum; + uint16_t queuenum; +}; + +static void +cmd_showqueue_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_showqueue_result *res = parsed_result; + + if (!strcmp(res->type, "rxq")) + rx_queue_infos_display(res->portnum, res->queuenum); + else if (!strcmp(res->type, "txq")) + tx_queue_infos_display(res->portnum, res->queuenum); +} + +cmdline_parse_token_string_t cmd_showqueue_show = + TOKEN_STRING_INITIALIZER(struct cmd_showqueue_result, show, "show"); +cmdline_parse_token_string_t cmd_showqueue_type = + TOKEN_STRING_INITIALIZER(struct cmd_showqueue_result, type, "rxq#txq"); +cmdline_parse_token_string_t cmd_showqueue_what = + TOKEN_STRING_INITIALIZER(struct cmd_showqueue_result, what, "info"); +cmdline_parse_token_num_t cmd_showqueue_portnum = + TOKEN_NUM_INITIALIZER(struct cmd_showqueue_result, portnum, UINT8); +cmdline_parse_token_num_t cmd_showqueue_queuenum = + TOKEN_NUM_INITIALIZER(struct cmd_showqueue_result, queuenum, UINT16); + +cmdline_parse_inst_t cmd_showqueue = { + .f = cmd_showqueue_parsed, + .data = NULL, + .help_str = "show rxq|txq info ", + .tokens = { + (void *)&cmd_showqueue_show, + (void *)&cmd_showqueue_type, + (void *)&cmd_showqueue_what, + (void *)&cmd_showqueue_portnum, + (void *)&cmd_showqueue_queuenum, + NULL, + }, +}; + /* *** READ PORT REGISTER *** */ struct cmd_read_reg_result { cmdline_fixed_string_t read; @@ -6346,8 +6867,10 @@ cmd_tunnel_filter_parsed(void *parsed_result, struct rte_eth_tunnel_filter_conf tunnel_filter_conf; int ret = 0; - tunnel_filter_conf.outer_mac = &res->outer_mac; - tunnel_filter_conf.inner_mac = &res->inner_mac; + memset(&tunnel_filter_conf, 0, sizeof(tunnel_filter_conf)); + + ether_addr_copy(&res->outer_mac, &tunnel_filter_conf.outer_mac); + ether_addr_copy(&res->inner_mac, &tunnel_filter_conf.inner_mac); tunnel_filter_conf.inner_vlan = res->inner_vlan; if (res->ip_value.family == AF_INET) { @@ -6373,6 +6896,10 @@ cmd_tunnel_filter_parsed(void *parsed_result, else if (!strcmp(res->filter_type, "omac-imac-tenid")) tunnel_filter_conf.filter_type = RTE_TUNNEL_FILTER_OMAC_TENID_IMAC; + else if (!strcmp(res->filter_type, "oip")) + tunnel_filter_conf.filter_type = ETH_TUNNEL_FILTER_OIP; + else if (!strcmp(res->filter_type, "iip")) + tunnel_filter_conf.filter_type = ETH_TUNNEL_FILTER_IIP; else { printf("The filter type is not supported"); return; @@ -6382,6 +6909,8 @@ cmd_tunnel_filter_parsed(void *parsed_result, tunnel_filter_conf.tunnel_type = RTE_TUNNEL_TYPE_VXLAN; else if (!strcmp(res->tunnel_type, "nvgre")) tunnel_filter_conf.tunnel_type = RTE_TUNNEL_TYPE_NVGRE; + else if (!strcmp(res->tunnel_type, "ipingre")) + tunnel_filter_conf.tunnel_type = RTE_TUNNEL_TYPE_IP_IN_GRE; else { printf("The tunnel type %s not supported.\n", res->tunnel_type); return; @@ -6427,11 +6956,11 @@ cmdline_parse_token_ipaddr_t cmd_tunnel_filter_ip_value = ip_value); cmdline_parse_token_string_t cmd_tunnel_filter_tunnel_type = TOKEN_STRING_INITIALIZER(struct cmd_tunnel_filter_result, - tunnel_type, "vxlan#nvgre"); + tunnel_type, "vxlan#nvgre#ipingre"); cmdline_parse_token_string_t cmd_tunnel_filter_filter_type = TOKEN_STRING_INITIALIZER(struct cmd_tunnel_filter_result, - filter_type, "imac-ivlan#imac-ivlan-tenid#imac-tenid#" + filter_type, "oip#iip#imac-ivlan#imac-ivlan-tenid#imac-tenid#" "imac#omac-imac-tenid"); cmdline_parse_token_num_t cmd_tunnel_filter_tenant_id = TOKEN_NUM_INITIALIZER(struct cmd_tunnel_filter_result, @@ -6445,8 +6974,8 @@ cmdline_parse_inst_t cmd_tunnel_filter = { .data = (void *)0, .help_str = "add/rm tunnel filter of a port: " "tunnel_filter add port_id outer_mac inner_mac ip " - "inner_vlan tunnel_type(vxlan|nvgre) filter_type " - "(imac-ivlan|imac-ivlan-tenid|imac-tenid|" + "inner_vlan tunnel_type(vxlan|nvgre|ipingre) filter_type " + "(oip|iip|imac-ivlan|imac-ivlan-tenid|imac-tenid|" "imac|omac-imac-tenid) " "tenant_id queue_num", .tokens = { @@ -6488,9 +7017,11 @@ cmd_tunnel_udp_config_parsed(void *parsed_result, tunnel_udp.prot_type = RTE_TUNNEL_TYPE_VXLAN; if (!strcmp(res->what, "add")) - ret = rte_eth_dev_udp_tunnel_add(res->port_id, &tunnel_udp); + ret = rte_eth_dev_udp_tunnel_port_add(res->port_id, + &tunnel_udp); else - ret = rte_eth_dev_udp_tunnel_delete(res->port_id, &tunnel_udp); + ret = rte_eth_dev_udp_tunnel_port_delete(res->port_id, + &tunnel_udp); if (ret < 0) printf("udp tunneling add error: (%s)\n", strerror(-ret)); @@ -6523,6 +7054,57 @@ cmdline_parse_inst_t cmd_tunnel_udp_config = { }, }; +/* *** GLOBAL CONFIG *** */ +struct cmd_global_config_result { + cmdline_fixed_string_t cmd; + uint8_t port_id; + cmdline_fixed_string_t cfg_type; + uint8_t len; +}; + +static void +cmd_global_config_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_global_config_result *res = parsed_result; + struct rte_eth_global_cfg conf; + int ret; + + memset(&conf, 0, sizeof(conf)); + conf.cfg_type = RTE_ETH_GLOBAL_CFG_TYPE_GRE_KEY_LEN; + conf.cfg.gre_key_len = res->len; + ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_NONE, + RTE_ETH_FILTER_SET, &conf); + if (ret != 0) + printf("Global config error\n"); +} + +cmdline_parse_token_string_t cmd_global_config_cmd = + TOKEN_STRING_INITIALIZER(struct cmd_global_config_result, cmd, + "global_config"); +cmdline_parse_token_num_t cmd_global_config_port_id = + TOKEN_NUM_INITIALIZER(struct cmd_global_config_result, port_id, UINT8); +cmdline_parse_token_string_t cmd_global_config_type = + TOKEN_STRING_INITIALIZER(struct cmd_global_config_result, + cfg_type, "gre-key-len"); +cmdline_parse_token_num_t cmd_global_config_gre_key_len = + TOKEN_NUM_INITIALIZER(struct cmd_global_config_result, + len, UINT8); + +cmdline_parse_inst_t cmd_global_config = { + .f = cmd_global_config_parsed, + .data = (void *)NULL, + .help_str = "global_config gre-key-len ", + .tokens = { + (void *)&cmd_global_config_cmd, + (void *)&cmd_global_config_port_id, + (void *)&cmd_global_config_type, + (void *)&cmd_global_config_gre_key_len, + NULL, + }, +}; + /* *** CONFIGURE VM MIRROR VLAN/POOL RULE *** */ struct cmd_set_mirror_mask_result { cmdline_fixed_string_t set; @@ -6554,7 +7136,8 @@ cmdline_parse_token_num_t cmd_mirror_mask_ruleid = rule_id, UINT8); cmdline_parse_token_string_t cmd_mirror_mask_what = TOKEN_STRING_INITIALIZER(struct cmd_set_mirror_mask_result, - what, "pool-mirror#vlan-mirror"); + what, "pool-mirror-up#pool-mirror-down" + "#vlan-mirror"); cmdline_parse_token_string_t cmd_mirror_mask_value = TOKEN_STRING_INITIALIZER(struct cmd_set_mirror_mask_result, value, NULL); @@ -6575,25 +7158,28 @@ cmd_set_mirror_mask_parsed(void *parsed_result, { int ret,nb_item,i; struct cmd_set_mirror_mask_result *res = parsed_result; - struct rte_eth_vmdq_mirror_conf mr_conf; + struct rte_eth_mirror_conf mr_conf; - memset(&mr_conf,0,sizeof(struct rte_eth_vmdq_mirror_conf)); + memset(&mr_conf, 0, sizeof(struct rte_eth_mirror_conf)); - unsigned int vlan_list[ETH_VMDQ_MAX_VLAN_FILTERS]; + unsigned int vlan_list[ETH_MIRROR_MAX_VLANS]; mr_conf.dst_pool = res->dstpool_id; - if (!strcmp(res->what, "pool-mirror")) { - mr_conf.pool_mask = strtoull(res->value,NULL,16); - mr_conf.rule_type_mask = ETH_VMDQ_POOL_MIRROR; - } else if(!strcmp(res->what, "vlan-mirror")) { - mr_conf.rule_type_mask = ETH_VMDQ_VLAN_MIRROR; - nb_item = parse_item_list(res->value, "core", - ETH_VMDQ_MAX_VLAN_FILTERS,vlan_list,1); + if (!strcmp(res->what, "pool-mirror-up")) { + mr_conf.pool_mask = strtoull(res->value, NULL, 16); + mr_conf.rule_type = ETH_MIRROR_VIRTUAL_POOL_UP; + } else if (!strcmp(res->what, "pool-mirror-down")) { + mr_conf.pool_mask = strtoull(res->value, NULL, 16); + mr_conf.rule_type = ETH_MIRROR_VIRTUAL_POOL_DOWN; + } else if (!strcmp(res->what, "vlan-mirror")) { + mr_conf.rule_type = ETH_MIRROR_VLAN; + nb_item = parse_item_list(res->value, "vlan", + ETH_MIRROR_MAX_VLANS, vlan_list, 1); if (nb_item <= 0) return; - for(i=0; i < nb_item; i++) { + for (i = 0; i < nb_item; i++) { if (vlan_list[i] > ETHER_MAX_VLAN_ID) { printf("Invalid vlan_id: must be < 4096\n"); return; @@ -6604,21 +7190,21 @@ cmd_set_mirror_mask_parsed(void *parsed_result, } } - if(!strcmp(res->on, "on")) - ret = rte_eth_mirror_rule_set(res->port_id,&mr_conf, + if (!strcmp(res->on, "on")) + ret = rte_eth_mirror_rule_set(res->port_id, &mr_conf, res->rule_id, 1); else - ret = rte_eth_mirror_rule_set(res->port_id,&mr_conf, + ret = rte_eth_mirror_rule_set(res->port_id, &mr_conf, res->rule_id, 0); - if(ret < 0) + if (ret < 0) printf("mirror rule add error: (%s)\n", strerror(-ret)); } cmdline_parse_inst_t cmd_set_mirror_mask = { .f = cmd_set_mirror_mask_parsed, .data = NULL, - .help_str = "set port X mirror-rule Y pool-mirror|vlan-mirror " - "pool_mask|vlan_id[,vlan_id]* dst-pool Z on|off", + .help_str = "set port X mirror-rule Y pool-mirror-up|pool-mirror-down|vlan-mirror" + " pool_mask|vlan_id[,vlan_id]* dst-pool Z on|off", .tokens = { (void *)&cmd_mirror_mask_set, (void *)&cmd_mirror_mask_port, @@ -6682,25 +7268,25 @@ cmd_set_mirror_link_parsed(void *parsed_result, { int ret; struct cmd_set_mirror_link_result *res = parsed_result; - struct rte_eth_vmdq_mirror_conf mr_conf; + struct rte_eth_mirror_conf mr_conf; - memset(&mr_conf,0,sizeof(struct rte_eth_vmdq_mirror_conf)); - if(!strcmp(res->what, "uplink-mirror")) { - mr_conf.rule_type_mask = ETH_VMDQ_UPLINK_MIRROR; - }else if(!strcmp(res->what, "downlink-mirror")) - mr_conf.rule_type_mask = ETH_VMDQ_DOWNLIN_MIRROR; + memset(&mr_conf, 0, sizeof(struct rte_eth_mirror_conf)); + if (!strcmp(res->what, "uplink-mirror")) + mr_conf.rule_type = ETH_MIRROR_UPLINK_PORT; + else + mr_conf.rule_type = ETH_MIRROR_DOWNLINK_PORT; mr_conf.dst_pool = res->dstpool_id; - if(!strcmp(res->on, "on")) - ret = rte_eth_mirror_rule_set(res->port_id,&mr_conf, + if (!strcmp(res->on, "on")) + ret = rte_eth_mirror_rule_set(res->port_id, &mr_conf, res->rule_id, 1); else - ret = rte_eth_mirror_rule_set(res->port_id,&mr_conf, + ret = rte_eth_mirror_rule_set(res->port_id, &mr_conf, res->rule_id, 0); /* check the return value and print it if is < 0 */ - if(ret < 0) + if (ret < 0) printf("mirror rule add error: (%s)\n", strerror(-ret)); } @@ -6802,8 +7388,6 @@ static void cmd_dump_parsed(void *parsed_result, rte_dump_physmem_layout(stdout); else if (!strcmp(res->dump, "dump_memzone")) rte_memzone_dump(stdout); - else if (!strcmp(res->dump, "dump_log_history")) - rte_log_dump_history(stdout); else if (!strcmp(res->dump, "dump_struct_sizes")) dump_struct_sizes(); else if (!strcmp(res->dump, "dump_ring")) @@ -6818,7 +7402,6 @@ cmdline_parse_token_string_t cmd_dump_dump = TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump, "dump_physmem#" "dump_memzone#" - "dump_log_history#" "dump_struct_sizes#" "dump_ring#" "dump_mempool#" @@ -7621,9 +8204,13 @@ cmdline_parse_inst_t cmd_ethertype_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; @@ -7632,15 +8219,28 @@ struct cmd_flow_director_result { 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 inline int @@ -7712,6 +8312,26 @@ str2flowtype(char *string) return RTE_ETH_FLOW_UNKNOWN; } +static enum rte_eth_fdir_tunnel_type +str2fdir_tunneltype(char *string) +{ + uint8_t i = 0; + + static const struct { + char str[32]; + enum rte_eth_fdir_tunnel_type type; + } tunneltype_str[] = { + {"NVGRE", RTE_FDIR_TUNNEL_TYPE_NVGRE}, + {"VxLAN", RTE_FDIR_TUNNEL_TYPE_VXLAN}, + }; + + for (i = 0; i < RTE_DIM(tunneltype_str); i++) { + if (!strcmp(tunneltype_str[i].str, string)) + return tunneltype_str[i].type; + } + return RTE_FDIR_TUNNEL_TYPE_UNKNOWN; +} + #define IPV4_ADDR_TO_UINT(ip_addr, ip) \ do { \ if ((ip_addr).family == AF_INET) \ @@ -7742,6 +8362,8 @@ cmd_flow_director_filter_parsed(void *parsed_result, 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; ret = rte_eth_dev_filter_supported(res->port_id, RTE_ETH_FILTER_FDIR); @@ -7752,6 +8374,25 @@ cmd_flow_director_filter_parsed(void *parsed_result, } memset(flexbytes, 0, sizeof(flexbytes)); memset(&entry, 0, sizeof(struct rte_eth_fdir_filter)); + + 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; + } + entry.input.flow_type = str2flowtype(res->flow_type); + } + ret = parse_flexbytes(res->flexbytes_value, flexbytes, RTE_ETH_FDIR_MAX_FLEXLEN); @@ -7760,16 +8401,18 @@ cmd_flow_director_filter_parsed(void *parsed_result, return; } - entry.input.flow_type = str2flowtype(res->flow_type); 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); @@ -7781,18 +8424,27 @@ cmd_flow_director_filter_parsed(void *parsed_result, 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); @@ -7804,14 +8456,39 @@ cmd_flow_director_filter_parsed(void *parsed_result, 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: - printf("invalid parameter.\n"); - return; + break; + } + + 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); } + (void)rte_memcpy(entry.input.flow_ext.flexbytes, flexbytes, RTE_ETH_FDIR_MAX_FLEXLEN); @@ -7823,6 +8500,27 @@ cmd_flow_director_filter_parsed(void *parsed_result, 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; @@ -7856,7 +8554,13 @@ cmdline_parse_token_string_t cmd_flow_director_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"); + "ipv6-other#ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#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_token_string_t cmd_flow_director_src = TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, src, "src"); @@ -7881,6 +8585,24 @@ cmdline_parse_token_string_t cmd_flow_director_verify_tag = cmdline_parse_token_num_t cmd_flow_director_verify_tag_value = TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, verify_tag_value, UINT32); +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_proto = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + proto, "proto"); +cmdline_parse_token_num_t cmd_flow_director_proto_value = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, + proto_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"); @@ -7896,6 +8618,9 @@ cmdline_parse_token_string_t cmd_flow_director_flexbytes_value = 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"); @@ -7909,6 +8634,37 @@ 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_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_mode_mac_vlan = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + mode_value, "MAC-VLAN"); +cmdline_parse_token_string_t cmd_flow_director_mode_tunnel = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + mode_value, "Tunnel"); +cmdline_parse_token_string_t cmd_flow_director_mac = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + mac, "mac"); +cmdline_parse_token_etheraddr_t cmd_flow_director_mac_addr = + TOKEN_ETHERADDR_INITIALIZER(struct cmd_flow_director_result, + mac_addr); +cmdline_parse_token_string_t cmd_flow_director_tunnel = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + tunnel, "tunnel"); +cmdline_parse_token_string_t cmd_flow_director_tunnel_type = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + tunnel_type, "NVGRE#VxLAN"); +cmdline_parse_token_string_t cmd_flow_director_tunnel_id = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result, + tunnel_id, "tunnel-id"); +cmdline_parse_token_num_t cmd_flow_director_tunnel_id_value = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result, + tunnel_id_value, UINT32); + cmdline_parse_inst_t cmd_add_del_ip_flow_director = { .f = cmd_flow_director_filter_parsed, .data = NULL, @@ -7916,6 +8672,8 @@ cmdline_parse_inst_t cmd_add_del_ip_flow_director = { .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, @@ -7923,11 +8681,18 @@ cmdline_parse_inst_t cmd_add_del_ip_flow_director = { (void *)&cmd_flow_director_ip_src, (void *)&cmd_flow_director_dst, (void *)&cmd_flow_director_ip_dst, + (void *)&cmd_flow_director_tos, + (void *)&cmd_flow_director_tos_value, + (void *)&cmd_flow_director_proto, + (void *)&cmd_flow_director_proto_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, @@ -7943,6 +8708,8 @@ cmdline_parse_inst_t cmd_add_del_udp_flow_director = { .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, @@ -7952,11 +8719,16 @@ cmdline_parse_inst_t cmd_add_del_udp_flow_director = { (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, @@ -7972,6 +8744,8 @@ cmdline_parse_inst_t cmd_add_del_sctp_flow_director = { .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, @@ -7983,8 +8757,93 @@ cmdline_parse_inst_t cmd_add_del_sctp_flow_director = { (void *)&cmd_flow_director_port_dst, (void *)&cmd_flow_director_verify_tag, (void *)&cmd_flow_director_verify_tag_value, + (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, + }, +}; + +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, + }, +}; + +cmdline_parse_inst_t cmd_add_del_mac_vlan_flow_director = { + .f = cmd_flow_director_filter_parsed, + .data = NULL, + .help_str = "add or delete a MAC VLAN 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_mac_vlan, + (void *)&cmd_flow_director_ops, + (void *)&cmd_flow_director_mac, + (void *)&cmd_flow_director_mac_addr, + (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_queue, + (void *)&cmd_flow_director_queue_id, + (void *)&cmd_flow_director_fd_id, + (void *)&cmd_flow_director_fd_id_value, + NULL, + }, +}; + +cmdline_parse_inst_t cmd_add_del_tunnel_flow_director = { + .f = cmd_flow_director_filter_parsed, + .data = NULL, + .help_str = "add or delete a tunnel 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_tunnel, + (void *)&cmd_flow_director_ops, + (void *)&cmd_flow_director_mac, + (void *)&cmd_flow_director_mac_addr, (void *)&cmd_flow_director_vlan, (void *)&cmd_flow_director_vlan_value, + (void *)&cmd_flow_director_tunnel, + (void *)&cmd_flow_director_tunnel_type, + (void *)&cmd_flow_director_tunnel_id, + (void *)&cmd_flow_director_tunnel_id_value, (void *)&cmd_flow_director_flexbytes, (void *)&cmd_flow_director_flexbytes_value, (void *)&cmd_flow_director_drop, @@ -8045,8 +8904,10 @@ cmdline_parse_inst_t cmd_flush_flow_director = { struct cmd_flow_director_mask_result { cmdline_fixed_string_t flow_director_mask; uint8_t port_id; + cmdline_fixed_string_t mode; + cmdline_fixed_string_t mode_value; cmdline_fixed_string_t vlan; - uint16_t vlan_value; + uint16_t vlan_mask; cmdline_fixed_string_t src_mask; cmdline_ipaddr_t ipv4_src; cmdline_ipaddr_t ipv6_src; @@ -8055,6 +8916,12 @@ struct cmd_flow_director_mask_result { cmdline_ipaddr_t ipv4_dst; cmdline_ipaddr_t ipv6_dst; uint16_t port_dst; + cmdline_fixed_string_t mac; + uint8_t mac_addr_byte_mask; + cmdline_fixed_string_t tunnel_id; + uint32_t tunnel_id_mask; + cmdline_fixed_string_t tunnel_type; + uint8_t tunnel_type_mask; }; static void @@ -8077,15 +8944,41 @@ cmd_flow_director_mask_parsed(void *parsed_result, printf("Please stop port %d first\n", res->port_id); return; } + mask = &port->dev_conf.fdir_conf.mask; - mask->vlan_tci_mask = res->vlan_value; - IPV4_ADDR_TO_UINT(res->ipv4_src, mask->ipv4_mask.src_ip); - IPV4_ADDR_TO_UINT(res->ipv4_dst, mask->ipv4_mask.dst_ip); - IPV6_ADDR_TO_ARRAY(res->ipv6_src, mask->ipv6_mask.src_ip); - IPV6_ADDR_TO_ARRAY(res->ipv6_dst, mask->ipv6_mask.dst_ip); - mask->src_port_mask = res->port_src; - mask->dst_port_mask = res->port_dst; + 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; + } + + mask->vlan_tci_mask = res->vlan_mask; + mask->mac_addr_byte_mask = res->mac_addr_byte_mask; + } else if (fdir_conf.mode == RTE_FDIR_MODE_PERFECT_TUNNEL) { + if (strcmp(res->mode_value, "Tunnel")) { + printf("Please set mode to Tunnel.\n"); + return; + } + + mask->vlan_tci_mask = res->vlan_mask; + mask->mac_addr_byte_mask = res->mac_addr_byte_mask; + mask->tunnel_id_mask = res->tunnel_id_mask; + mask->tunnel_type_mask = res->tunnel_type_mask; + } else { + if (strcmp(res->mode_value, "IP")) { + printf("Please set mode to IP.\n"); + return; + } + + mask->vlan_tci_mask = rte_cpu_to_be_16(res->vlan_mask); + IPV4_ADDR_TO_UINT(res->ipv4_src, mask->ipv4_mask.src_ip); + IPV4_ADDR_TO_UINT(res->ipv4_dst, mask->ipv4_mask.dst_ip); + IPV6_ADDR_TO_ARRAY(res->ipv6_src, mask->ipv6_mask.src_ip); + IPV6_ADDR_TO_ARRAY(res->ipv6_dst, mask->ipv6_mask.dst_ip); + mask->src_port_mask = rte_cpu_to_be_16(res->port_src); + mask->dst_port_mask = rte_cpu_to_be_16(res->port_dst); + } cmd_reconfig_device_queue(res->port_id, 1, 1); } @@ -8101,7 +8994,7 @@ cmdline_parse_token_string_t cmd_flow_director_mask_vlan = vlan, "vlan"); cmdline_parse_token_num_t cmd_flow_director_mask_vlan_value = TOKEN_NUM_INITIALIZER(struct cmd_flow_director_mask_result, - vlan_value, UINT16); + vlan_mask, UINT16); cmdline_parse_token_string_t cmd_flow_director_mask_src = TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result, src_mask, "src_mask"); @@ -8126,13 +9019,47 @@ cmdline_parse_token_ipaddr_t cmd_flow_director_mask_ipv6_dst = cmdline_parse_token_num_t cmd_flow_director_mask_port_dst = TOKEN_NUM_INITIALIZER(struct cmd_flow_director_mask_result, port_dst, UINT16); -cmdline_parse_inst_t cmd_set_flow_director_mask = { + +cmdline_parse_token_string_t cmd_flow_director_mask_mode = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result, + mode, "mode"); +cmdline_parse_token_string_t cmd_flow_director_mask_mode_ip = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result, + mode_value, "IP"); +cmdline_parse_token_string_t cmd_flow_director_mask_mode_mac_vlan = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result, + mode_value, "MAC-VLAN"); +cmdline_parse_token_string_t cmd_flow_director_mask_mode_tunnel = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result, + mode_value, "Tunnel"); +cmdline_parse_token_string_t cmd_flow_director_mask_mac = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result, + mac, "mac"); +cmdline_parse_token_num_t cmd_flow_director_mask_mac_value = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_mask_result, + mac_addr_byte_mask, UINT8); +cmdline_parse_token_string_t cmd_flow_director_mask_tunnel_type = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result, + tunnel_type, "tunnel-type"); +cmdline_parse_token_num_t cmd_flow_director_mask_tunnel_type_value = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_mask_result, + tunnel_type_mask, UINT8); +cmdline_parse_token_string_t cmd_flow_director_mask_tunnel_id = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result, + tunnel_id, "tunnel-id"); +cmdline_parse_token_num_t cmd_flow_director_mask_tunnel_id_value = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_mask_result, + tunnel_id_mask, UINT32); + +cmdline_parse_inst_t cmd_set_flow_director_ip_mask = { .f = cmd_flow_director_mask_parsed, .data = NULL, - .help_str = "set flow director's mask on NIC", + .help_str = "set IP mode flow director's mask on NIC", .tokens = { (void *)&cmd_flow_director_mask, (void *)&cmd_flow_director_mask_port_id, + (void *)&cmd_flow_director_mask_mode, + (void *)&cmd_flow_director_mask_mode_ip, (void *)&cmd_flow_director_mask_vlan, (void *)&cmd_flow_director_mask_vlan_value, (void *)&cmd_flow_director_mask_src, @@ -8147,6 +9074,44 @@ cmdline_parse_inst_t cmd_set_flow_director_mask = { }, }; +cmdline_parse_inst_t cmd_set_flow_director_mac_vlan_mask = { + .f = cmd_flow_director_mask_parsed, + .data = NULL, + .help_str = "set MAC VLAN mode flow director's mask on NIC", + .tokens = { + (void *)&cmd_flow_director_mask, + (void *)&cmd_flow_director_mask_port_id, + (void *)&cmd_flow_director_mask_mode, + (void *)&cmd_flow_director_mask_mode_mac_vlan, + (void *)&cmd_flow_director_mask_vlan, + (void *)&cmd_flow_director_mask_vlan_value, + (void *)&cmd_flow_director_mask_mac, + (void *)&cmd_flow_director_mask_mac_value, + NULL, + }, +}; + +cmdline_parse_inst_t cmd_set_flow_director_tunnel_mask = { + .f = cmd_flow_director_mask_parsed, + .data = NULL, + .help_str = "set tunnel mode flow director's mask on NIC", + .tokens = { + (void *)&cmd_flow_director_mask, + (void *)&cmd_flow_director_mask_port_id, + (void *)&cmd_flow_director_mask_mode, + (void *)&cmd_flow_director_mask_mode_tunnel, + (void *)&cmd_flow_director_mask_vlan, + (void *)&cmd_flow_director_mask_vlan_value, + (void *)&cmd_flow_director_mask_mac, + (void *)&cmd_flow_director_mask_mac_value, + (void *)&cmd_flow_director_mask_tunnel_type, + (void *)&cmd_flow_director_mask_tunnel_type_value, + (void *)&cmd_flow_director_mask_tunnel_id, + (void *)&cmd_flow_director_mask_tunnel_id_value, + NULL, + }, +}; + /* *** deal with flow director mask on flexible payload *** */ struct cmd_flow_director_flex_mask_result { cmdline_fixed_string_t flow_director_flexmask; @@ -8198,6 +9163,19 @@ cmd_flow_director_flex_mask_parsed(void *parsed_result, return; } + if (!strcmp(res->flow_type, "none")) { + /* means don't specify the flow type */ + flex_mask.flow_type = RTE_ETH_FLOW_UNKNOWN; + for (i = 0; i < RTE_ETH_FLOW_MAX; i++) + memset(&port->dev_conf.fdir_conf.flex_conf.flex_mask[i], + 0, sizeof(struct rte_eth_fdir_flex_mask)); + port->dev_conf.fdir_conf.flex_conf.nb_flexmasks = 1; + (void)rte_memcpy(&port->dev_conf.fdir_conf.flex_conf.flex_mask[0], + &flex_mask, + sizeof(struct rte_eth_fdir_flex_mask)); + cmd_reconfig_device_queue(res->port_id, 1, 1); + return; + } flow_type_mask = fdir_info.flow_types_mask[0]; if (!strcmp(res->flow_type, "all")) { if (!flow_type_mask) { @@ -8235,8 +9213,8 @@ cmdline_parse_token_string_t cmd_flow_director_flexmask_flow = flow, "flow"); cmdline_parse_token_string_t cmd_flow_director_flexmask_flow_type = TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flex_mask_result, - flow_type, "raw#ipv4-other#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#" - "ipv6-other#ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#all"); + flow_type, "none#ipv4-other#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#" + "ipv6-other#ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#l2_payload#all"); cmdline_parse_token_string_t cmd_flow_director_flexmask_mask = TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flex_mask_result, mask, NULL); @@ -8691,26 +9669,941 @@ cmdline_parse_inst_t cmd_set_hash_global_config = { }, }; -/* ******************************************************************************** */ +/* 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_field; + cmdline_fixed_string_t select; +}; -/* list of instructions */ -cmdline_parse_ctx_t main_ctx[] = { - (cmdline_parse_inst_t *)&cmd_help_brief, +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_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_field); + 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); +} + +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_field = + TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result, + inset_field, + "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"); +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 = { + .f = cmd_set_hash_input_set_parsed, + .data = NULL, + .help_str = "set_hash_input_set " + "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 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_field, + (void *)&cmd_set_hash_input_set_select, + NULL, + }, +}; + +/* Set flow director input set */ +struct cmd_set_fdir_input_set_result { + cmdline_fixed_string_t set_fdir_input_set; + uint8_t port_id; + cmdline_fixed_string_t flow_type; + cmdline_fixed_string_t inset_field; + cmdline_fixed_string_t select; +}; + +static void +cmd_set_fdir_input_set_parsed(void *parsed_result, + __rte_unused struct cmdline *cl, + __rte_unused void *data) +{ + struct cmd_set_fdir_input_set_result *res = parsed_result; + struct rte_eth_fdir_filter_info info; + + memset(&info, 0, sizeof(info)); + info.info_type = RTE_ETH_FDIR_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_field); + 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_FDIR, + RTE_ETH_FILTER_SET, &info); +} + +cmdline_parse_token_string_t cmd_set_fdir_input_set_cmd = + TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result, + set_fdir_input_set, "set_fdir_input_set"); +cmdline_parse_token_num_t cmd_set_fdir_input_set_port_id = + TOKEN_NUM_INITIALIZER(struct cmd_set_fdir_input_set_result, + port_id, UINT8); +cmdline_parse_token_string_t cmd_set_fdir_input_set_flow_type = + TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_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_fdir_input_set_field = + TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result, + inset_field, + "ivlan#ethertype#src-ipv4#dst-ipv4#src-ipv6#dst-ipv6#" + "ipv4-tos#ipv4-proto#ipv4-ttl#ipv6-tc#ipv6-next-header#" + "ipv6-hop-limits#udp-src-port#udp-dst-port#" + "tcp-src-port#tcp-dst-port#sctp-src-port#sctp-dst-port#" + "sctp-veri-tag#none"); +cmdline_parse_token_string_t cmd_set_fdir_input_set_select = + TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result, + select, "select#add"); + +cmdline_parse_inst_t cmd_set_fdir_input_set = { + .f = cmd_set_fdir_input_set_parsed, + .data = NULL, + .help_str = "set_fdir_input_set " + "ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|" + "ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload " + "ivlan|ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|" + "ipv4-tos|ipv4-proto|ipv4-ttl|ipv6-tc|ipv6-next-header|" + "ipv6-hop-limits|udp-src-port|udp-dst-port|" + "tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|" + "sctp-veri-tag|none select|add", + .tokens = { + (void *)&cmd_set_fdir_input_set_cmd, + (void *)&cmd_set_fdir_input_set_port_id, + (void *)&cmd_set_fdir_input_set_flow_type, + (void *)&cmd_set_fdir_input_set_field, + (void *)&cmd_set_fdir_input_set_select, + NULL, + }, +}; + +/* *** ADD/REMOVE A MULTICAST MAC ADDRESS TO/FROM A PORT *** */ +struct cmd_mcast_addr_result { + cmdline_fixed_string_t mcast_addr_cmd; + cmdline_fixed_string_t what; + uint8_t port_num; + struct ether_addr mc_addr; +}; + +static void cmd_mcast_addr_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_mcast_addr_result *res = parsed_result; + + if (!is_multicast_ether_addr(&res->mc_addr)) { + printf("Invalid multicast addr %02X:%02X:%02X:%02X:%02X:%02X\n", + res->mc_addr.addr_bytes[0], res->mc_addr.addr_bytes[1], + res->mc_addr.addr_bytes[2], res->mc_addr.addr_bytes[3], + res->mc_addr.addr_bytes[4], res->mc_addr.addr_bytes[5]); + return; + } + if (strcmp(res->what, "add") == 0) + mcast_addr_add(res->port_num, &res->mc_addr); + else + mcast_addr_remove(res->port_num, &res->mc_addr); +} + +cmdline_parse_token_string_t cmd_mcast_addr_cmd = + TOKEN_STRING_INITIALIZER(struct cmd_mcast_addr_result, + mcast_addr_cmd, "mcast_addr"); +cmdline_parse_token_string_t cmd_mcast_addr_what = + TOKEN_STRING_INITIALIZER(struct cmd_mcast_addr_result, what, + "add#remove"); +cmdline_parse_token_num_t cmd_mcast_addr_portnum = + TOKEN_NUM_INITIALIZER(struct cmd_mcast_addr_result, port_num, UINT8); +cmdline_parse_token_etheraddr_t cmd_mcast_addr_addr = + TOKEN_ETHERADDR_INITIALIZER(struct cmd_mac_addr_result, address); + +cmdline_parse_inst_t cmd_mcast_addr = { + .f = cmd_mcast_addr_parsed, + .data = (void *)0, + .help_str = "mcast_addr add|remove X : add/remove multicast MAC address on port X", + .tokens = { + (void *)&cmd_mcast_addr_cmd, + (void *)&cmd_mcast_addr_what, + (void *)&cmd_mcast_addr_portnum, + (void *)&cmd_mcast_addr_addr, + NULL, + }, +}; + +/* l2 tunnel config + * only support E-tag now. + */ + +/* Ether type config */ +struct cmd_config_l2_tunnel_eth_type_result { + cmdline_fixed_string_t port; + cmdline_fixed_string_t config; + cmdline_fixed_string_t all; + uint8_t id; + cmdline_fixed_string_t l2_tunnel; + cmdline_fixed_string_t l2_tunnel_type; + cmdline_fixed_string_t eth_type; + uint16_t eth_type_val; +}; + +cmdline_parse_token_string_t cmd_config_l2_tunnel_eth_type_port = + TOKEN_STRING_INITIALIZER + (struct cmd_config_l2_tunnel_eth_type_result, + port, "port"); +cmdline_parse_token_string_t cmd_config_l2_tunnel_eth_type_config = + TOKEN_STRING_INITIALIZER + (struct cmd_config_l2_tunnel_eth_type_result, + config, "config"); +cmdline_parse_token_string_t cmd_config_l2_tunnel_eth_type_all_str = + TOKEN_STRING_INITIALIZER + (struct cmd_config_l2_tunnel_eth_type_result, + all, "all"); +cmdline_parse_token_num_t cmd_config_l2_tunnel_eth_type_id = + TOKEN_NUM_INITIALIZER + (struct cmd_config_l2_tunnel_eth_type_result, + id, UINT8); +cmdline_parse_token_string_t cmd_config_l2_tunnel_eth_type_l2_tunnel = + TOKEN_STRING_INITIALIZER + (struct cmd_config_l2_tunnel_eth_type_result, + l2_tunnel, "l2-tunnel"); +cmdline_parse_token_string_t cmd_config_l2_tunnel_eth_type_l2_tunnel_type = + TOKEN_STRING_INITIALIZER + (struct cmd_config_l2_tunnel_eth_type_result, + l2_tunnel_type, "E-tag"); +cmdline_parse_token_string_t cmd_config_l2_tunnel_eth_type_eth_type = + TOKEN_STRING_INITIALIZER + (struct cmd_config_l2_tunnel_eth_type_result, + eth_type, "ether-type"); +cmdline_parse_token_num_t cmd_config_l2_tunnel_eth_type_eth_type_val = + TOKEN_NUM_INITIALIZER + (struct cmd_config_l2_tunnel_eth_type_result, + eth_type_val, UINT16); + +static enum rte_eth_tunnel_type +str2fdir_l2_tunnel_type(char *string) +{ + uint32_t i = 0; + + static const struct { + char str[32]; + enum rte_eth_tunnel_type type; + } l2_tunnel_type_str[] = { + {"E-tag", RTE_L2_TUNNEL_TYPE_E_TAG}, + }; + + for (i = 0; i < RTE_DIM(l2_tunnel_type_str); i++) { + if (!strcmp(l2_tunnel_type_str[i].str, string)) + return l2_tunnel_type_str[i].type; + } + return RTE_TUNNEL_TYPE_NONE; +} + +/* ether type config for all ports */ +static void +cmd_config_l2_tunnel_eth_type_all_parsed + (void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_config_l2_tunnel_eth_type_result *res = parsed_result; + struct rte_eth_l2_tunnel_conf entry; + portid_t pid; + + entry.l2_tunnel_type = str2fdir_l2_tunnel_type(res->l2_tunnel_type); + entry.ether_type = res->eth_type_val; + + FOREACH_PORT(pid, ports) { + rte_eth_dev_l2_tunnel_eth_type_conf(pid, &entry); + } +} + +cmdline_parse_inst_t cmd_config_l2_tunnel_eth_type_all = { + .f = cmd_config_l2_tunnel_eth_type_all_parsed, + .data = NULL, + .help_str = "port config all l2-tunnel ether-type", + .tokens = { + (void *)&cmd_config_l2_tunnel_eth_type_port, + (void *)&cmd_config_l2_tunnel_eth_type_config, + (void *)&cmd_config_l2_tunnel_eth_type_all_str, + (void *)&cmd_config_l2_tunnel_eth_type_l2_tunnel, + (void *)&cmd_config_l2_tunnel_eth_type_l2_tunnel_type, + (void *)&cmd_config_l2_tunnel_eth_type_eth_type, + (void *)&cmd_config_l2_tunnel_eth_type_eth_type_val, + NULL, + }, +}; + +/* ether type config for a specific port */ +static void +cmd_config_l2_tunnel_eth_type_specific_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_config_l2_tunnel_eth_type_result *res = + parsed_result; + struct rte_eth_l2_tunnel_conf entry; + + if (port_id_is_invalid(res->id, ENABLED_WARN)) + return; + + entry.l2_tunnel_type = str2fdir_l2_tunnel_type(res->l2_tunnel_type); + entry.ether_type = res->eth_type_val; + + rte_eth_dev_l2_tunnel_eth_type_conf(res->id, &entry); +} + +cmdline_parse_inst_t cmd_config_l2_tunnel_eth_type_specific = { + .f = cmd_config_l2_tunnel_eth_type_specific_parsed, + .data = NULL, + .help_str = "port config l2-tunnel ether-type", + .tokens = { + (void *)&cmd_config_l2_tunnel_eth_type_port, + (void *)&cmd_config_l2_tunnel_eth_type_config, + (void *)&cmd_config_l2_tunnel_eth_type_id, + (void *)&cmd_config_l2_tunnel_eth_type_l2_tunnel, + (void *)&cmd_config_l2_tunnel_eth_type_l2_tunnel_type, + (void *)&cmd_config_l2_tunnel_eth_type_eth_type, + (void *)&cmd_config_l2_tunnel_eth_type_eth_type_val, + NULL, + }, +}; + +/* Enable/disable l2 tunnel */ +struct cmd_config_l2_tunnel_en_dis_result { + cmdline_fixed_string_t port; + cmdline_fixed_string_t config; + cmdline_fixed_string_t all; + uint8_t id; + cmdline_fixed_string_t l2_tunnel; + cmdline_fixed_string_t l2_tunnel_type; + cmdline_fixed_string_t en_dis; +}; + +cmdline_parse_token_string_t cmd_config_l2_tunnel_en_dis_port = + TOKEN_STRING_INITIALIZER + (struct cmd_config_l2_tunnel_en_dis_result, + port, "port"); +cmdline_parse_token_string_t cmd_config_l2_tunnel_en_dis_config = + TOKEN_STRING_INITIALIZER + (struct cmd_config_l2_tunnel_en_dis_result, + config, "config"); +cmdline_parse_token_string_t cmd_config_l2_tunnel_en_dis_all_str = + TOKEN_STRING_INITIALIZER + (struct cmd_config_l2_tunnel_en_dis_result, + all, "all"); +cmdline_parse_token_num_t cmd_config_l2_tunnel_en_dis_id = + TOKEN_NUM_INITIALIZER + (struct cmd_config_l2_tunnel_en_dis_result, + id, UINT8); +cmdline_parse_token_string_t cmd_config_l2_tunnel_en_dis_l2_tunnel = + TOKEN_STRING_INITIALIZER + (struct cmd_config_l2_tunnel_en_dis_result, + l2_tunnel, "l2-tunnel"); +cmdline_parse_token_string_t cmd_config_l2_tunnel_en_dis_l2_tunnel_type = + TOKEN_STRING_INITIALIZER + (struct cmd_config_l2_tunnel_en_dis_result, + l2_tunnel_type, "E-tag"); +cmdline_parse_token_string_t cmd_config_l2_tunnel_en_dis_en_dis = + TOKEN_STRING_INITIALIZER + (struct cmd_config_l2_tunnel_en_dis_result, + en_dis, "enable#disable"); + +/* enable/disable l2 tunnel for all ports */ +static void +cmd_config_l2_tunnel_en_dis_all_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_config_l2_tunnel_en_dis_result *res = parsed_result; + struct rte_eth_l2_tunnel_conf entry; + portid_t pid; + uint8_t en; + + entry.l2_tunnel_type = str2fdir_l2_tunnel_type(res->l2_tunnel_type); + + if (!strcmp("enable", res->en_dis)) + en = 1; + else + en = 0; + + FOREACH_PORT(pid, ports) { + rte_eth_dev_l2_tunnel_offload_set(pid, + &entry, + ETH_L2_TUNNEL_ENABLE_MASK, + en); + } +} + +cmdline_parse_inst_t cmd_config_l2_tunnel_en_dis_all = { + .f = cmd_config_l2_tunnel_en_dis_all_parsed, + .data = NULL, + .help_str = "port config all l2-tunnel enable/disable", + .tokens = { + (void *)&cmd_config_l2_tunnel_en_dis_port, + (void *)&cmd_config_l2_tunnel_en_dis_config, + (void *)&cmd_config_l2_tunnel_en_dis_all_str, + (void *)&cmd_config_l2_tunnel_en_dis_l2_tunnel, + (void *)&cmd_config_l2_tunnel_en_dis_l2_tunnel_type, + (void *)&cmd_config_l2_tunnel_en_dis_en_dis, + NULL, + }, +}; + +/* enable/disable l2 tunnel for a port */ +static void +cmd_config_l2_tunnel_en_dis_specific_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_config_l2_tunnel_en_dis_result *res = + parsed_result; + struct rte_eth_l2_tunnel_conf entry; + + if (port_id_is_invalid(res->id, ENABLED_WARN)) + return; + + entry.l2_tunnel_type = str2fdir_l2_tunnel_type(res->l2_tunnel_type); + + if (!strcmp("enable", res->en_dis)) + rte_eth_dev_l2_tunnel_offload_set(res->id, + &entry, + ETH_L2_TUNNEL_ENABLE_MASK, + 1); + else + rte_eth_dev_l2_tunnel_offload_set(res->id, + &entry, + ETH_L2_TUNNEL_ENABLE_MASK, + 0); +} + +cmdline_parse_inst_t cmd_config_l2_tunnel_en_dis_specific = { + .f = cmd_config_l2_tunnel_en_dis_specific_parsed, + .data = NULL, + .help_str = "port config l2-tunnel enable/disable", + .tokens = { + (void *)&cmd_config_l2_tunnel_en_dis_port, + (void *)&cmd_config_l2_tunnel_en_dis_config, + (void *)&cmd_config_l2_tunnel_en_dis_id, + (void *)&cmd_config_l2_tunnel_en_dis_l2_tunnel, + (void *)&cmd_config_l2_tunnel_en_dis_l2_tunnel_type, + (void *)&cmd_config_l2_tunnel_en_dis_en_dis, + NULL, + }, +}; + +/* E-tag configuration */ + +/* Common result structure for all E-tag configuration */ +struct cmd_config_e_tag_result { + cmdline_fixed_string_t e_tag; + cmdline_fixed_string_t set; + cmdline_fixed_string_t insertion; + cmdline_fixed_string_t stripping; + cmdline_fixed_string_t forwarding; + cmdline_fixed_string_t filter; + cmdline_fixed_string_t add; + cmdline_fixed_string_t del; + cmdline_fixed_string_t on; + cmdline_fixed_string_t off; + cmdline_fixed_string_t on_off; + cmdline_fixed_string_t port_tag_id; + uint32_t port_tag_id_val; + cmdline_fixed_string_t e_tag_id; + uint16_t e_tag_id_val; + cmdline_fixed_string_t dst_pool; + uint8_t dst_pool_val; + cmdline_fixed_string_t port; + uint8_t port_id; + cmdline_fixed_string_t vf; + uint8_t vf_id; +}; + +/* Common CLI fields for all E-tag configuration */ +cmdline_parse_token_string_t cmd_config_e_tag_e_tag = + TOKEN_STRING_INITIALIZER + (struct cmd_config_e_tag_result, + e_tag, "E-tag"); +cmdline_parse_token_string_t cmd_config_e_tag_set = + TOKEN_STRING_INITIALIZER + (struct cmd_config_e_tag_result, + set, "set"); +cmdline_parse_token_string_t cmd_config_e_tag_insertion = + TOKEN_STRING_INITIALIZER + (struct cmd_config_e_tag_result, + insertion, "insertion"); +cmdline_parse_token_string_t cmd_config_e_tag_stripping = + TOKEN_STRING_INITIALIZER + (struct cmd_config_e_tag_result, + stripping, "stripping"); +cmdline_parse_token_string_t cmd_config_e_tag_forwarding = + TOKEN_STRING_INITIALIZER + (struct cmd_config_e_tag_result, + forwarding, "forwarding"); +cmdline_parse_token_string_t cmd_config_e_tag_filter = + TOKEN_STRING_INITIALIZER + (struct cmd_config_e_tag_result, + filter, "filter"); +cmdline_parse_token_string_t cmd_config_e_tag_add = + TOKEN_STRING_INITIALIZER + (struct cmd_config_e_tag_result, + add, "add"); +cmdline_parse_token_string_t cmd_config_e_tag_del = + TOKEN_STRING_INITIALIZER + (struct cmd_config_e_tag_result, + del, "del"); +cmdline_parse_token_string_t cmd_config_e_tag_on = + TOKEN_STRING_INITIALIZER + (struct cmd_config_e_tag_result, + on, "on"); +cmdline_parse_token_string_t cmd_config_e_tag_off = + TOKEN_STRING_INITIALIZER + (struct cmd_config_e_tag_result, + off, "off"); +cmdline_parse_token_string_t cmd_config_e_tag_on_off = + TOKEN_STRING_INITIALIZER + (struct cmd_config_e_tag_result, + on_off, "on#off"); +cmdline_parse_token_string_t cmd_config_e_tag_port_tag_id = + TOKEN_STRING_INITIALIZER + (struct cmd_config_e_tag_result, + port_tag_id, "port-tag-id"); +cmdline_parse_token_num_t cmd_config_e_tag_port_tag_id_val = + TOKEN_NUM_INITIALIZER + (struct cmd_config_e_tag_result, + port_tag_id_val, UINT32); +cmdline_parse_token_string_t cmd_config_e_tag_e_tag_id = + TOKEN_STRING_INITIALIZER + (struct cmd_config_e_tag_result, + e_tag_id, "e-tag-id"); +cmdline_parse_token_num_t cmd_config_e_tag_e_tag_id_val = + TOKEN_NUM_INITIALIZER + (struct cmd_config_e_tag_result, + e_tag_id_val, UINT16); +cmdline_parse_token_string_t cmd_config_e_tag_dst_pool = + TOKEN_STRING_INITIALIZER + (struct cmd_config_e_tag_result, + dst_pool, "dst-pool"); +cmdline_parse_token_num_t cmd_config_e_tag_dst_pool_val = + TOKEN_NUM_INITIALIZER + (struct cmd_config_e_tag_result, + dst_pool_val, UINT8); +cmdline_parse_token_string_t cmd_config_e_tag_port = + TOKEN_STRING_INITIALIZER + (struct cmd_config_e_tag_result, + port, "port"); +cmdline_parse_token_num_t cmd_config_e_tag_port_id = + TOKEN_NUM_INITIALIZER + (struct cmd_config_e_tag_result, + port_id, UINT8); +cmdline_parse_token_string_t cmd_config_e_tag_vf = + TOKEN_STRING_INITIALIZER + (struct cmd_config_e_tag_result, + vf, "vf"); +cmdline_parse_token_num_t cmd_config_e_tag_vf_id = + TOKEN_NUM_INITIALIZER + (struct cmd_config_e_tag_result, + vf_id, UINT8); + +/* E-tag insertion configuration */ +static void +cmd_config_e_tag_insertion_en_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_config_e_tag_result *res = + parsed_result; + struct rte_eth_l2_tunnel_conf entry; + + if (port_id_is_invalid(res->port_id, ENABLED_WARN)) + return; + + entry.l2_tunnel_type = RTE_L2_TUNNEL_TYPE_E_TAG; + entry.tunnel_id = res->port_tag_id_val; + entry.vf_id = res->vf_id; + rte_eth_dev_l2_tunnel_offload_set(res->port_id, + &entry, + ETH_L2_TUNNEL_INSERTION_MASK, + 1); +} + +static void +cmd_config_e_tag_insertion_dis_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_config_e_tag_result *res = + parsed_result; + struct rte_eth_l2_tunnel_conf entry; + + if (port_id_is_invalid(res->port_id, ENABLED_WARN)) + return; + + entry.l2_tunnel_type = RTE_L2_TUNNEL_TYPE_E_TAG; + entry.vf_id = res->vf_id; + + rte_eth_dev_l2_tunnel_offload_set(res->port_id, + &entry, + ETH_L2_TUNNEL_INSERTION_MASK, + 0); +} + +cmdline_parse_inst_t cmd_config_e_tag_insertion_en = { + .f = cmd_config_e_tag_insertion_en_parsed, + .data = NULL, + .help_str = "E-tag insertion enable", + .tokens = { + (void *)&cmd_config_e_tag_e_tag, + (void *)&cmd_config_e_tag_set, + (void *)&cmd_config_e_tag_insertion, + (void *)&cmd_config_e_tag_on, + (void *)&cmd_config_e_tag_port_tag_id, + (void *)&cmd_config_e_tag_port_tag_id_val, + (void *)&cmd_config_e_tag_port, + (void *)&cmd_config_e_tag_port_id, + (void *)&cmd_config_e_tag_vf, + (void *)&cmd_config_e_tag_vf_id, + NULL, + }, +}; + +cmdline_parse_inst_t cmd_config_e_tag_insertion_dis = { + .f = cmd_config_e_tag_insertion_dis_parsed, + .data = NULL, + .help_str = "E-tag insertion disable", + .tokens = { + (void *)&cmd_config_e_tag_e_tag, + (void *)&cmd_config_e_tag_set, + (void *)&cmd_config_e_tag_insertion, + (void *)&cmd_config_e_tag_off, + (void *)&cmd_config_e_tag_port, + (void *)&cmd_config_e_tag_port_id, + (void *)&cmd_config_e_tag_vf, + (void *)&cmd_config_e_tag_vf_id, + NULL, + }, +}; + +/* E-tag stripping configuration */ +static void +cmd_config_e_tag_stripping_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_config_e_tag_result *res = + parsed_result; + struct rte_eth_l2_tunnel_conf entry; + + if (port_id_is_invalid(res->port_id, ENABLED_WARN)) + return; + + entry.l2_tunnel_type = RTE_L2_TUNNEL_TYPE_E_TAG; + + if (!strcmp(res->on_off, "on")) + rte_eth_dev_l2_tunnel_offload_set + (res->port_id, + &entry, + ETH_L2_TUNNEL_STRIPPING_MASK, + 1); + else + rte_eth_dev_l2_tunnel_offload_set + (res->port_id, + &entry, + ETH_L2_TUNNEL_STRIPPING_MASK, + 0); +} + +cmdline_parse_inst_t cmd_config_e_tag_stripping_en_dis = { + .f = cmd_config_e_tag_stripping_parsed, + .data = NULL, + .help_str = "E-tag stripping enable/disable", + .tokens = { + (void *)&cmd_config_e_tag_e_tag, + (void *)&cmd_config_e_tag_set, + (void *)&cmd_config_e_tag_stripping, + (void *)&cmd_config_e_tag_on_off, + (void *)&cmd_config_e_tag_port, + (void *)&cmd_config_e_tag_port_id, + NULL, + }, +}; + +/* E-tag forwarding configuration */ +static void +cmd_config_e_tag_forwarding_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_config_e_tag_result *res = parsed_result; + struct rte_eth_l2_tunnel_conf entry; + + if (port_id_is_invalid(res->port_id, ENABLED_WARN)) + return; + + entry.l2_tunnel_type = RTE_L2_TUNNEL_TYPE_E_TAG; + + if (!strcmp(res->on_off, "on")) + rte_eth_dev_l2_tunnel_offload_set + (res->port_id, + &entry, + ETH_L2_TUNNEL_FORWARDING_MASK, + 1); + else + rte_eth_dev_l2_tunnel_offload_set + (res->port_id, + &entry, + ETH_L2_TUNNEL_FORWARDING_MASK, + 0); +} + +cmdline_parse_inst_t cmd_config_e_tag_forwarding_en_dis = { + .f = cmd_config_e_tag_forwarding_parsed, + .data = NULL, + .help_str = "E-tag forwarding enable/disable", + .tokens = { + (void *)&cmd_config_e_tag_e_tag, + (void *)&cmd_config_e_tag_set, + (void *)&cmd_config_e_tag_forwarding, + (void *)&cmd_config_e_tag_on_off, + (void *)&cmd_config_e_tag_port, + (void *)&cmd_config_e_tag_port_id, + NULL, + }, +}; + +/* E-tag filter configuration */ +static void +cmd_config_e_tag_filter_add_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_config_e_tag_result *res = parsed_result; + struct rte_eth_l2_tunnel_conf entry; + int ret = 0; + + if (port_id_is_invalid(res->port_id, ENABLED_WARN)) + return; + + if (res->e_tag_id_val > 0x3fff) { + printf("e-tag-id must be equal or less than 0x3fff.\n"); + return; + } + + ret = rte_eth_dev_filter_supported(res->port_id, + RTE_ETH_FILTER_L2_TUNNEL); + if (ret < 0) { + printf("E-tag filter is not supported on port %u.\n", + res->port_id); + return; + } + + entry.l2_tunnel_type = RTE_L2_TUNNEL_TYPE_E_TAG; + entry.tunnel_id = res->e_tag_id_val; + entry.pool = res->dst_pool_val; + + ret = rte_eth_dev_filter_ctrl(res->port_id, + RTE_ETH_FILTER_L2_TUNNEL, + RTE_ETH_FILTER_ADD, + &entry); + if (ret < 0) + printf("E-tag filter programming error: (%s)\n", + strerror(-ret)); +} + +cmdline_parse_inst_t cmd_config_e_tag_filter_add = { + .f = cmd_config_e_tag_filter_add_parsed, + .data = NULL, + .help_str = "E-tag filter add", + .tokens = { + (void *)&cmd_config_e_tag_e_tag, + (void *)&cmd_config_e_tag_set, + (void *)&cmd_config_e_tag_filter, + (void *)&cmd_config_e_tag_add, + (void *)&cmd_config_e_tag_e_tag_id, + (void *)&cmd_config_e_tag_e_tag_id_val, + (void *)&cmd_config_e_tag_dst_pool, + (void *)&cmd_config_e_tag_dst_pool_val, + (void *)&cmd_config_e_tag_port, + (void *)&cmd_config_e_tag_port_id, + NULL, + }, +}; + +static void +cmd_config_e_tag_filter_del_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_config_e_tag_result *res = parsed_result; + struct rte_eth_l2_tunnel_conf entry; + int ret = 0; + + if (port_id_is_invalid(res->port_id, ENABLED_WARN)) + return; + + if (res->e_tag_id_val > 0x3fff) { + printf("e-tag-id must be less than 0x3fff.\n"); + return; + } + + ret = rte_eth_dev_filter_supported(res->port_id, + RTE_ETH_FILTER_L2_TUNNEL); + if (ret < 0) { + printf("E-tag filter is not supported on port %u.\n", + res->port_id); + return; + } + + entry.l2_tunnel_type = RTE_L2_TUNNEL_TYPE_E_TAG; + entry.tunnel_id = res->e_tag_id_val; + + ret = rte_eth_dev_filter_ctrl(res->port_id, + RTE_ETH_FILTER_L2_TUNNEL, + RTE_ETH_FILTER_DELETE, + &entry); + if (ret < 0) + printf("E-tag filter programming error: (%s)\n", + strerror(-ret)); +} + +cmdline_parse_inst_t cmd_config_e_tag_filter_del = { + .f = cmd_config_e_tag_filter_del_parsed, + .data = NULL, + .help_str = "E-tag filter delete", + .tokens = { + (void *)&cmd_config_e_tag_e_tag, + (void *)&cmd_config_e_tag_set, + (void *)&cmd_config_e_tag_filter, + (void *)&cmd_config_e_tag_del, + (void *)&cmd_config_e_tag_e_tag_id, + (void *)&cmd_config_e_tag_e_tag_id_val, + (void *)&cmd_config_e_tag_port, + (void *)&cmd_config_e_tag_port_id, + NULL, + }, +}; + +/* ******************************************************************************** */ + +/* list of instructions */ +cmdline_parse_ctx_t main_ctx[] = { + (cmdline_parse_inst_t *)&cmd_help_brief, (cmdline_parse_inst_t *)&cmd_help_long, (cmdline_parse_inst_t *)&cmd_quit, (cmdline_parse_inst_t *)&cmd_showport, + (cmdline_parse_inst_t *)&cmd_showqueue, (cmdline_parse_inst_t *)&cmd_showportall, (cmdline_parse_inst_t *)&cmd_showcfg, (cmdline_parse_inst_t *)&cmd_start, (cmdline_parse_inst_t *)&cmd_start_tx_first, + (cmdline_parse_inst_t *)&cmd_start_tx_first_n, (cmdline_parse_inst_t *)&cmd_set_link_up, (cmdline_parse_inst_t *)&cmd_set_link_down, (cmdline_parse_inst_t *)&cmd_reset, (cmdline_parse_inst_t *)&cmd_set_numbers, (cmdline_parse_inst_t *)&cmd_set_txpkts, + (cmdline_parse_inst_t *)&cmd_set_txsplit, (cmdline_parse_inst_t *)&cmd_set_fwd_list, (cmdline_parse_inst_t *)&cmd_set_fwd_mask, (cmdline_parse_inst_t *)&cmd_set_fwd_mode, + (cmdline_parse_inst_t *)&cmd_set_fwd_retry_mode, (cmdline_parse_inst_t *)&cmd_set_burst_tx_retry, (cmdline_parse_inst_t *)&cmd_set_promisc_mode_one, (cmdline_parse_inst_t *)&cmd_set_promisc_mode_all, @@ -8740,6 +10633,7 @@ cmdline_parse_ctx_t main_ctx[] = { (cmdline_parse_inst_t *)&cmd_rx_vlan_filter_all, (cmdline_parse_inst_t *)&cmd_rx_vlan_filter, (cmdline_parse_inst_t *)&cmd_tx_vlan_set, + (cmdline_parse_inst_t *)&cmd_tx_vlan_set_qinq, (cmdline_parse_inst_t *)&cmd_tx_vlan_reset, (cmdline_parse_inst_t *)&cmd_tx_vlan_set_pvid, (cmdline_parse_inst_t *)&cmd_csum_set, @@ -8780,6 +10674,7 @@ cmdline_parse_ctx_t main_ctx[] = { (cmdline_parse_inst_t *)&cmd_config_rx_mode_flag, (cmdline_parse_inst_t *)&cmd_config_rss, (cmdline_parse_inst_t *)&cmd_config_rxtx_queue, + (cmdline_parse_inst_t *)&cmd_config_txqflags, (cmdline_parse_inst_t *)&cmd_config_rss_reta, (cmdline_parse_inst_t *)&cmd_showport_reta, (cmdline_parse_inst_t *)&cmd_config_burst, @@ -8796,6 +10691,7 @@ cmdline_parse_ctx_t main_ctx[] = { (cmdline_parse_inst_t *)&cmd_vf_rate_limit, (cmdline_parse_inst_t *)&cmd_tunnel_filter, (cmdline_parse_inst_t *)&cmd_tunnel_udp_config, + (cmdline_parse_inst_t *)&cmd_global_config, (cmdline_parse_inst_t *)&cmd_set_mirror_mask, (cmdline_parse_inst_t *)&cmd_set_mirror_link, (cmdline_parse_inst_t *)&cmd_reset_mirror_rule, @@ -8812,14 +10708,32 @@ cmdline_parse_ctx_t main_ctx[] = { (cmdline_parse_inst_t *)&cmd_add_del_ip_flow_director, (cmdline_parse_inst_t *)&cmd_add_del_udp_flow_director, (cmdline_parse_inst_t *)&cmd_add_del_sctp_flow_director, + (cmdline_parse_inst_t *)&cmd_add_del_l2_flow_director, + (cmdline_parse_inst_t *)&cmd_add_del_mac_vlan_flow_director, + (cmdline_parse_inst_t *)&cmd_add_del_tunnel_flow_director, (cmdline_parse_inst_t *)&cmd_flush_flow_director, - (cmdline_parse_inst_t *)&cmd_set_flow_director_mask, + (cmdline_parse_inst_t *)&cmd_set_flow_director_ip_mask, + (cmdline_parse_inst_t *)&cmd_set_flow_director_mac_vlan_mask, + (cmdline_parse_inst_t *)&cmd_set_flow_director_tunnel_mask, (cmdline_parse_inst_t *)&cmd_set_flow_director_flex_mask, (cmdline_parse_inst_t *)&cmd_set_flow_director_flex_payload, (cmdline_parse_inst_t *)&cmd_get_sym_hash_ena_per_port, (cmdline_parse_inst_t *)&cmd_set_sym_hash_ena_per_port, (cmdline_parse_inst_t *)&cmd_get_hash_global_config, (cmdline_parse_inst_t *)&cmd_set_hash_global_config, + (cmdline_parse_inst_t *)&cmd_set_hash_input_set, + (cmdline_parse_inst_t *)&cmd_set_fdir_input_set, + (cmdline_parse_inst_t *)&cmd_mcast_addr, + (cmdline_parse_inst_t *)&cmd_config_l2_tunnel_eth_type_all, + (cmdline_parse_inst_t *)&cmd_config_l2_tunnel_eth_type_specific, + (cmdline_parse_inst_t *)&cmd_config_l2_tunnel_en_dis_all, + (cmdline_parse_inst_t *)&cmd_config_l2_tunnel_en_dis_specific, + (cmdline_parse_inst_t *)&cmd_config_e_tag_insertion_en, + (cmdline_parse_inst_t *)&cmd_config_e_tag_insertion_dis, + (cmdline_parse_inst_t *)&cmd_config_e_tag_stripping_en_dis, + (cmdline_parse_inst_t *)&cmd_config_e_tag_forwarding_en_dis, + (cmdline_parse_inst_t *)&cmd_config_e_tag_filter_add, + (cmdline_parse_inst_t *)&cmd_config_e_tag_filter_del, NULL, }; @@ -8827,30 +10741,28 @@ cmdline_parse_ctx_t main_ctx[] = { void prompt(void) { - struct cmdline *cl; - /* initialize non-constant commands */ cmd_set_fwd_mode_init(); + cmd_set_fwd_retry_mode_init(); - cl = cmdline_stdin_new(main_ctx, "testpmd> "); - if (cl == NULL) { + testpmd_cl = cmdline_stdin_new(main_ctx, "testpmd> "); + if (testpmd_cl == NULL) return; - } - cmdline_interact(cl); - cmdline_stdin_exit(cl); + cmdline_interact(testpmd_cl); + cmdline_stdin_exit(testpmd_cl); +} + +void +prompt_exit(void) +{ + if (testpmd_cl != NULL) + cmdline_quit(testpmd_cl); } static void cmd_reconfig_device_queue(portid_t id, uint8_t dev, uint8_t queue) { - if (!port_id_is_invalid(id, DISABLED_WARN)) { - /* check if need_reconfig has been set to 1 */ - if (ports[id].need_reconfig == 0) - ports[id].need_reconfig = dev; - /* check if need_reconfig_queues has been set to 1 */ - if (ports[id].need_reconfig_queues == 0) - ports[id].need_reconfig_queues = queue; - } else { + if (id == (portid_t)RTE_PORT_ALL) { portid_t pid; FOREACH_PORT(pid, ports) { @@ -8861,10 +10773,18 @@ cmd_reconfig_device_queue(portid_t id, uint8_t dev, uint8_t queue) if (ports[pid].need_reconfig_queues == 0) ports[pid].need_reconfig_queues = queue; } + } else if (!port_id_is_invalid(id, DISABLED_WARN)) { + /* check if need_reconfig has been set to 1 */ + if (ports[id].need_reconfig == 0) + ports[id].need_reconfig = dev; + /* check if need_reconfig_queues has been set to 1 */ + if (ports[id].need_reconfig_queues == 0) + ports[id].need_reconfig_queues = queue; } } #ifdef RTE_NIC_BYPASS +#include uint8_t bypass_is_supported(portid_t port_id) {