Add CLI support for VXLAN encap. Signed-off-by: Cristian Dumitrescu <cristian.dumitre...@intel.com> --- drivers/net/softnic/rte_eth_softnic_cli.c | 179 +++++++++++++++++++++++++++++- 1 file changed, 176 insertions(+), 3 deletions(-)
diff --git a/drivers/net/softnic/rte_eth_softnic_cli.c b/drivers/net/softnic/rte_eth_softnic_cli.c index 2ddd936..613ec7e 100644 --- a/drivers/net/softnic/rte_eth_softnic_cli.c +++ b/drivers/net/softnic/rte_eth_softnic_cli.c @@ -1272,7 +1272,8 @@ cmd_port_in_action_profile(struct pmd_internals *softnic, * tc <n_tc> * stats none | pkts | bytes | both] * [tm spp <n_subports_per_port> pps <n_pipes_per_subport>] - * [encap ether | vlan | qinq | mpls | pppoe] + * [encap ether | vlan | qinq | mpls | pppoe | + * vxlan offset <ether_offset> ipv4 | ipv6 vlan on | off] * [nat src | dst * proto udp | tcp] * [ttl drop | fwd @@ -1480,6 +1481,8 @@ cmd_table_action_profile(struct pmd_internals *softnic, if (t0 < n_tokens && (strcmp(tokens[t0], "encap") == 0)) { + uint32_t n_extra_tokens = 0; + if (n_tokens < t0 + 2) { snprintf(out, out_size, MSG_ARG_MISMATCH, "action profile encap"); @@ -1496,13 +1499,61 @@ cmd_table_action_profile(struct pmd_internals *softnic, p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_MPLS; } else if (strcmp(tokens[t0 + 1], "pppoe") == 0) { p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_PPPOE; + } else if (strcmp(tokens[t0 + 1], "vxlan") == 0) { + if (n_tokens < t0 + 2 + 5) { + snprintf(out, out_size, MSG_ARG_MISMATCH, + "action profile encap vxlan"); + return; + } + + if (strcmp(tokens[t0 + 2], "offset") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, + "vxlan: offset"); + return; + } + + if (softnic_parser_read_uint32(&p.encap.vxlan.data_offset, + tokens[t0 + 2 + 1]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, + "vxlan: ether_offset"); + return; + } + + if (strcmp(tokens[t0 + 2 + 2], "ipv4") == 0) + p.encap.vxlan.ip_version = 1; + else if (strcmp(tokens[t0 + 2 + 2], "ipv6") == 0) + p.encap.vxlan.ip_version = 0; + else { + snprintf(out, out_size, MSG_ARG_INVALID, + "vxlan: ipv4 or ipv6"); + return; + } + + if (strcmp(tokens[t0 + 2 + 3], "vlan") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, + "vxlan: vlan"); + return; + } + + if (strcmp(tokens[t0 + 2 + 4], "on") == 0) + p.encap.vxlan.vlan = 1; + else if (strcmp(tokens[t0 + 2 + 4], "off") == 0) + p.encap.vxlan.vlan = 0; + else { + snprintf(out, out_size, MSG_ARG_INVALID, + "vxlan: on or off"); + return; + } + + p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_VXLAN; + n_extra_tokens = 5; + } else { snprintf(out, out_size, MSG_ARG_MISMATCH, "encap"); return; } - p.action_mask |= 1LLU << RTE_TABLE_ACTION_ENCAP; - t0 += 2; + t0 += 2 + n_extra_tokens; } /* encap */ if (t0 < n_tokens && @@ -3186,6 +3237,12 @@ parse_match(char **tokens, * [label2 <label> <tc> <ttl> * [label3 <label> <tc> <ttl>]]] * | pppoe <da> <sa> <session_id>] + * | vxlan ether <da> <sa> + * [vlan <pcp> <dei> <vid>] + * ipv4 <sa> <da> <dscp> <ttl> + * | ipv6 <sa> <da> <flow_label> <dscp> <hop_limit> + * udp <sp> <dp> + * vxlan <vni>] * [nat ipv4 | ipv6 <addr> <port>] * [ttl dec | keep] * [stats] @@ -3587,6 +3644,122 @@ parse_table_action_encap(char **tokens, return 1 + 4; } + /* vxlan */ + if (n_tokens && (strcmp(tokens[0], "vxlan") == 0)) { + uint32_t n = 0; + + n_tokens--; + tokens++; + n++; + + /* ether <da> <sa> */ + if ((n_tokens < 3) || + strcmp(tokens[0], "ether") || + softnic_parse_mac_addr(tokens[1], &a->encap.vxlan.ether.da) || + softnic_parse_mac_addr(tokens[2], &a->encap.vxlan.ether.sa)) + return 0; + + n_tokens -= 3; + tokens += 3; + n += 3; + + /* [vlan <pcp> <dei> <vid>] */ + if (strcmp(tokens[0], "vlan") == 0) { + uint32_t pcp, dei, vid; + + if ((n_tokens < 4) || + softnic_parser_read_uint32(&pcp, tokens[1]) || + (pcp > 7) || + softnic_parser_read_uint32(&dei, tokens[2]) || + (dei > 1) || + softnic_parser_read_uint32(&vid, tokens[3]) || + (vid > 0xFFF)) + return 0; + + a->encap.vxlan.vlan.pcp = pcp; + a->encap.vxlan.vlan.dei = dei; + a->encap.vxlan.vlan.vid = vid; + + n_tokens -= 4; + tokens += 4; + n += 4; + } + + /* ipv4 <sa> <da> <dscp> <ttl> + | ipv6 <sa> <da> <flow_label> <dscp> <hop_limit> */ + if (strcmp(tokens[0], "ipv4") == 0) { + struct in_addr sa, da; + uint8_t dscp, ttl; + + if ((n_tokens < 5) || + softnic_parse_ipv4_addr(tokens[1], &sa) || + softnic_parse_ipv4_addr(tokens[2], &da) || + softnic_parser_read_uint8(&dscp, tokens[3]) || + (dscp > 64) || + softnic_parser_read_uint8(&ttl, tokens[4])) + return 0; + + a->encap.vxlan.ipv4.sa = rte_be_to_cpu_32(sa.s_addr); + a->encap.vxlan.ipv4.da = rte_be_to_cpu_32(da.s_addr); + a->encap.vxlan.ipv4.dscp = dscp; + a->encap.vxlan.ipv4.ttl = ttl; + + n_tokens -= 5; + tokens += 5; + n += 5; + } else if (strcmp(tokens[0], "ipv6") == 0) { + struct in6_addr sa, da; + uint32_t flow_label; + uint8_t dscp, hop_limit; + + if ((n_tokens < 6) || + softnic_parse_ipv6_addr(tokens[1], &sa) || + softnic_parse_ipv6_addr(tokens[2], &da) || + softnic_parser_read_uint32(&flow_label, tokens[3]) || + softnic_parser_read_uint8(&dscp, tokens[4]) || + (dscp > 64) || + softnic_parser_read_uint8(&hop_limit, tokens[5])) + return 0; + + memcpy(a->encap.vxlan.ipv6.sa, sa.s6_addr, 16); + memcpy(a->encap.vxlan.ipv6.da, da.s6_addr, 16); + a->encap.vxlan.ipv6.flow_label = flow_label; + a->encap.vxlan.ipv6.dscp = dscp; + a->encap.vxlan.ipv6.hop_limit = hop_limit; + + n_tokens -= 6; + tokens += 6; + n += 6; + } else + return 0; + + /* udp <sp> <dp> */ + if ((n_tokens < 3) || + strcmp(tokens[0], "udp") || + softnic_parser_read_uint16(&a->encap.vxlan.udp.sp, tokens[1]) || + softnic_parser_read_uint16(&a->encap.vxlan.udp.dp, tokens[2])) + return 0; + + n_tokens -= 3; + tokens += 3; + n += 3; + + /* vxlan <vni> */ + if ((n_tokens < 2) || + strcmp(tokens[0], "vxlan") || + softnic_parser_read_uint32(&a->encap.vxlan.vxlan.vni, tokens[1]) || + (a->encap.vxlan.vxlan.vni > 0xFFFFFF)) + return 0; + + n_tokens -= 2; + tokens += 2; + n += 2; + + a->encap.type = RTE_TABLE_ACTION_ENCAP_VXLAN; + a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP; + return 1 + n; + } + return 0; } -- 2.7.4