This patch adds command support for portfwd, to enable run time configuration.
Command details: 1) set fwd port switch forwarding engine to portfwd 2) show route show port info and forwarding rules for portfwd 3) set route <srcport> <dstport> packets from <srcport> will be dispatched to <dstport> 4) set route <srcport> ip packets from <srcport> will be dispatched based on dst ip 5) set ip <srcport> <num0> <num1> <num2> <num3> set ip addr for <srcport>, portfwd will use this ip addr to do ip route 6) set affinity <fsid> <lcid> forwarding stream <fsid> will be handled by core <lcid> (info can be read from "show route") 7) show port perf all show perf stats (rx/tx cycles, burst size distribution, tx pktloss) of each port 8) set drain <ns> set drain interval to drain buffered packets which is not sent because buffer not full (0 to disable) Below are 3 examples to show how to use portfwd to build traffic flow in the host (Guest traffic can be built likewise): 1) PVP test: NIC-VM-NIC * 2 VMs each with 2 vhost ports: port 0, 1 and 2, 3 * 1 NIC with 2 ports: port 4, 5 * Traffic from 4 goes to 0 and 2, and back from 1, 3 to 5 Commands: set fwd port set ip 0 192 168 1 1 set ip 2 192 168 1 2 set route 4 ip (Make sure traffic has the right dst ip) set route 1 5 set route 3 5 set drain 0 show route 2) PVVP test: NIC-VM-VM-NIC * 2 VMs each with 2 vhost ports: port 0, 1 and 2, 3 * 1 NIC with 2 ports: port 4, 5 * Traffic from 4 goes to 0, and 1 to 2, finally 3 to 5 Commands: set fwd port set route 4 0 set route 1 2 set route 3 5 set drain 0 show route 3) PVP bi-directional test: NIC-VM-NIC * 1 VM with 2 vhost ports: port 0, 1 * 1 NIC with 2 ports: port 2, 3 * Traffic from 0 to 2, 1 to 3, and 2 to 0, 3 to 1 Commands: set fwd port set route 0 2 set route 2 0 set route 1 3 set route 3 1 set drain 0 show route Signed-off-by: Zhihong Wang <zhihong.wang at intel.com> --- app/test-pmd/cmdline.c | 279 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 277 insertions(+), 2 deletions(-) diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index c5b9479..6a076a4 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -187,6 +187,9 @@ static void cmd_help_long_parsed(void *parsed_result, "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 perf all\n" + " Display performance information for all.\n\n" + "show port X rss reta (size) (mask0,mask1,...)\n" " Display the rss redirection table entry indicated" " by masks on port X. size is used to indicate the" @@ -5401,6 +5404,9 @@ static void cmd_showportall_parsed(void *parsed_result, else if (!strcmp(res->what, "dcb_tc")) FOREACH_PORT(i, ports) port_dcb_info_display(i); + else if (!strcmp(res->what, "perf")) + if (cur_fwd_eng == &port_fwd_engine) + print_perf_stats(); } cmdline_parse_token_string_t cmd_showportall_show = @@ -5410,13 +5416,14 @@ 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#dcb_tc"); + "info#stats#xstats#fdir#stat_qmap#dcb_tc#perf"); 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|dcb_tc all", + .help_str = "show|clear port info|stats|xstats|fdir|stat_qmap|" + "dcb_tc|perf all", .tokens = { (void *)&cmd_showportall_show, (void *)&cmd_showportall_port, @@ -9725,6 +9732,268 @@ cmdline_parse_inst_t cmd_mcast_addr = { }, }; +/* *** SHOW ROUTE *** */ +struct cmd_show_route_result { + cmdline_fixed_string_t show; + cmdline_fixed_string_t route; +}; + +static void cmd_show_route_parsed( + __attribute__((unused)) void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + fwd_config_display(); + print_port_info(); + show_route(); +} + +cmdline_parse_token_string_t cmd_show_route_show = + TOKEN_STRING_INITIALIZER(struct cmd_show_route_result, + show, "show"); +cmdline_parse_token_string_t cmd_show_route_route = + TOKEN_STRING_INITIALIZER(struct cmd_show_route_result, + route, "route"); + +cmdline_parse_inst_t cmd_show_route = { + .f = cmd_show_route_parsed, + .data = NULL, + .help_str = "show route table: show route", + .tokens = { + (void *)&cmd_show_route_show, + (void *)&cmd_show_route_route, + NULL, + }, +}; + +/* *** SET DRAIN INTERVAL NS *** */ +struct cmd_set_drain_ns_result { + cmdline_fixed_string_t set; + cmdline_fixed_string_t drain; + uint32_t drain_ns; +}; + +static void cmd_set_drain_ns_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_set_drain_ns_result *res = parsed_result; + + set_drain_interval_ns(res->drain_ns); +} + +cmdline_parse_token_string_t cmd_set_drain_ns_set = + TOKEN_STRING_INITIALIZER(struct cmd_set_drain_ns_result, + set, "set"); +cmdline_parse_token_string_t cmd_set_drain_ns_drain = + TOKEN_STRING_INITIALIZER(struct cmd_set_drain_ns_result, + drain, "drain"); +cmdline_parse_token_num_t cmd_set_drain_ns_drain_ns = + TOKEN_NUM_INITIALIZER(struct cmd_set_drain_ns_result, + drain_ns, UINT32); + +cmdline_parse_inst_t cmd_set_drain_ns = { + .f = cmd_set_drain_ns_parsed, + .data = NULL, + .help_str = "set portfwd drain interval (ns): set drain <ns>", + .tokens = { + (void *)&cmd_set_drain_ns_set, + (void *)&cmd_set_drain_ns_drain, + (void *)&cmd_set_drain_ns_drain_ns, + NULL, + }, +}; + +/* *** SET IP ROUTE *** */ +struct cmd_set_ip_route_result { + cmdline_fixed_string_t set; + cmdline_fixed_string_t route; + uint32_t srcp; + cmdline_fixed_string_t dstp; +}; + +static void cmd_set_route_ip_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_set_ip_route_result *res = parsed_result; + + set_ip_route(res->srcp); +} + +cmdline_parse_token_string_t cmd_set_ip_route_set = + TOKEN_STRING_INITIALIZER(struct cmd_set_ip_route_result, + set, "set"); +cmdline_parse_token_string_t cmd_set_ip_route_route = + TOKEN_STRING_INITIALIZER(struct cmd_set_ip_route_result, + route, "route"); +cmdline_parse_token_num_t cmd_set_ip_route_srcp = + TOKEN_NUM_INITIALIZER(struct cmd_set_ip_route_result, + srcp, UINT32); +cmdline_parse_token_string_t cmd_set_ip_route_dstp = + TOKEN_STRING_INITIALIZER(struct cmd_set_ip_route_result, + dstp, "ip"); + +cmdline_parse_inst_t cmd_set_ip_route = { + .f = cmd_set_route_ip_parsed, + .data = NULL, + .help_str = "set ip route on <srcport>: set route <srcport> ip", + .tokens = { + (void *)&cmd_set_ip_route_set, + (void *)&cmd_set_ip_route_route, + (void *)&cmd_set_ip_route_srcp, + (void *)&cmd_set_ip_route_dstp, + NULL, + }, +}; + +/* *** SET FIXED ROUTE *** */ +struct cmd_set_fixed_route_result { + cmdline_fixed_string_t set; + cmdline_fixed_string_t route; + uint32_t srcp; + uint32_t dstp; +}; + +static void cmd_set_route_fixed_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_set_fixed_route_result *res = parsed_result; + + set_fixed_route(res->srcp, res->dstp); +} + +cmdline_parse_token_string_t cmd_set_fixed_route_set = + TOKEN_STRING_INITIALIZER(struct cmd_set_fixed_route_result, + set, "set"); +cmdline_parse_token_string_t cmd_set_fixed_route_route = + TOKEN_STRING_INITIALIZER(struct cmd_set_fixed_route_result, + route, "route"); +cmdline_parse_token_num_t cmd_set_fixed_route_srcp = + TOKEN_NUM_INITIALIZER(struct cmd_set_fixed_route_result, + srcp, UINT32); +cmdline_parse_token_num_t cmd_set_fixed_route_dstp = + TOKEN_NUM_INITIALIZER(struct cmd_set_fixed_route_result, + dstp, UINT32); + +cmdline_parse_inst_t cmd_set_fixed_route = { + .f = cmd_set_route_fixed_parsed, + .data = NULL, + .help_str = "set fixed route from <srcport> to <dstport>: " + "set route <srcport> <dstport>", + .tokens = { + (void *)&cmd_set_fixed_route_set, + (void *)&cmd_set_fixed_route_route, + (void *)&cmd_set_fixed_route_srcp, + (void *)&cmd_set_fixed_route_dstp, + NULL, + }, +}; + +/* *** SET AFFINITY *** */ +struct cmd_set_affinity_result { + cmdline_fixed_string_t set; + cmdline_fixed_string_t affinity; + uint32_t fsid; + uint32_t lcid; +}; + +static void cmd_set_affinity_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_set_affinity_result *res = parsed_result; + + set_fwd_stream_affinity(res->fsid, res->lcid); +} + +cmdline_parse_token_string_t cmd_set_affinity_set = + TOKEN_STRING_INITIALIZER(struct cmd_set_affinity_result, + set, "set"); +cmdline_parse_token_string_t cmd_set_affinity_affinity = + TOKEN_STRING_INITIALIZER(struct cmd_set_affinity_result, + affinity, "affinity"); +cmdline_parse_token_num_t cmd_set_affinity_fsid = + TOKEN_NUM_INITIALIZER(struct cmd_set_affinity_result, + fsid, UINT32); +cmdline_parse_token_num_t cmd_set_affinity_lcid = + TOKEN_NUM_INITIALIZER(struct cmd_set_affinity_result, + lcid, UINT32); + +cmdline_parse_inst_t cmd_set_affinity = { + .f = cmd_set_affinity_parsed, + .data = NULL, + .help_str = "set lcore affinity for fwd stream <fsid> to <lcid>: " + "set affinity <fsid> <lcid>", + .tokens = { + (void *)&cmd_set_affinity_set, + (void *)&cmd_set_affinity_affinity, + (void *)&cmd_set_affinity_fsid, + (void *)&cmd_set_affinity_lcid, + NULL, + }, +}; + +/* *** SET IP *** */ +struct cmd_set_ip_result { + cmdline_fixed_string_t set; + cmdline_fixed_string_t ip; + uint32_t srcp; + uint32_t num0; + uint32_t num1; + uint32_t num2; + uint32_t num3; +}; + +static void cmd_set_ip_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_set_ip_result *res = parsed_result; + + set_ip(res->srcp, res->num0, res->num1, res->num2, res->num3); +} + +cmdline_parse_token_string_t cmd_set_ip_set = + TOKEN_STRING_INITIALIZER(struct cmd_set_ip_result, + set, "set"); +cmdline_parse_token_string_t cmd_set_ip_ip = + TOKEN_STRING_INITIALIZER(struct cmd_set_ip_result, + ip, "ip"); +cmdline_parse_token_num_t cmd_set_ip_srcp = + TOKEN_NUM_INITIALIZER(struct cmd_set_ip_result, + srcp, UINT32); +cmdline_parse_token_num_t cmd_set_ip_num0 = + TOKEN_NUM_INITIALIZER(struct cmd_set_ip_result, + num0, UINT32); +cmdline_parse_token_num_t cmd_set_ip_num1 = + TOKEN_NUM_INITIALIZER(struct cmd_set_ip_result, + num1, UINT32); +cmdline_parse_token_num_t cmd_set_ip_num2 = + TOKEN_NUM_INITIALIZER(struct cmd_set_ip_result, + num2, UINT32); +cmdline_parse_token_num_t cmd_set_ip_num3 = + TOKEN_NUM_INITIALIZER(struct cmd_set_ip_result, + num3, UINT32); + +cmdline_parse_inst_t cmd_set_ip = { + .f = cmd_set_ip_parsed, + .data = NULL, + .help_str = "set ip for <srcport>: set ip <srcport> " + "<num0> <num1> <num2> <num3>", + .tokens = { + (void *)&cmd_set_ip_set, + (void *)&cmd_set_ip_ip, + (void *)&cmd_set_ip_srcp, + (void *)&cmd_set_ip_num0, + (void *)&cmd_set_ip_num1, + (void *)&cmd_set_ip_num2, + (void *)&cmd_set_ip_num3, + NULL, + }, +}; + /* l2 tunnel config * only support E-tag now. */ @@ -10537,6 +10806,12 @@ cmdline_parse_ctx_t main_ctx[] = { (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, + (cmdline_parse_inst_t *)&cmd_show_route, + (cmdline_parse_inst_t *)&cmd_set_drain_ns, + (cmdline_parse_inst_t *)&cmd_set_ip_route, + (cmdline_parse_inst_t *)&cmd_set_fixed_route, + (cmdline_parse_inst_t *)&cmd_set_ip, + (cmdline_parse_inst_t *)&cmd_set_affinity, NULL, }; -- 2.5.0