[dpdk-dev] [PATCH v2 4/5] app/testpmd: introduce new tunnel VXLAN-GPE

Nélio Laranjeiro nelio.laranjeiro at 6wind.com
Tue Apr 10 16:07:29 CEST 2018


On Tue, Apr 10, 2018 at 09:00:35PM +0800, Xueming Li wrote:
> Add VXLAN-GPE support to csum forwarding engine and rte flow.
> 
> Signed-off-by: Xueming Li <xuemingl at mellanox.com>
> ---
>  app/test-pmd/cmdline_flow.c           | 24 ++++++++++
>  app/test-pmd/config.c                 |  2 +
>  app/test-pmd/csumonly.c               | 83 +++++++++++++++++++++++++++++++++--
>  app/test-pmd/parameters.c             | 12 ++++-
>  app/test-pmd/testpmd.h                |  2 +
>  doc/guides/testpmd_app_ug/run_app.rst |  5 +++
>  6 files changed, 124 insertions(+), 4 deletions(-)
> 
> diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
> index f85c1c57f..f5abd589d 100644
> --- a/app/test-pmd/cmdline_flow.c
> +++ b/app/test-pmd/cmdline_flow.c
> @@ -137,6 +137,8 @@ enum index {
>  	ITEM_SCTP_CKSUM,
>  	ITEM_VXLAN,
>  	ITEM_VXLAN_VNI,
> +	ITEM_VXLAN_GPE,
> +	ITEM_VXLAN_GPE_VNI,
>  	ITEM_E_TAG,
>  	ITEM_E_TAG_GRP_ECID_B,
>  	ITEM_NVGRE,
> @@ -461,6 +463,7 @@ static const enum index next_item[] = {
>  	ITEM_TCP,
>  	ITEM_SCTP,
>  	ITEM_VXLAN,
> +	ITEM_VXLAN_GPE,
>  	ITEM_E_TAG,
>  	ITEM_NVGRE,
>  	ITEM_MPLS,
> @@ -589,6 +592,12 @@ static const enum index item_vxlan[] = {
>  	ZERO,
>  };
>  
> +static const enum index item_vxlan_gpe[] = {
> +	ITEM_VXLAN_GPE_VNI,
> +	ITEM_NEXT,
> +	ZERO,
> +};
> +
>  static const enum index item_e_tag[] = {
>  	ITEM_E_TAG_GRP_ECID_B,
>  	ITEM_NEXT,
> @@ -1441,6 +1450,21 @@ static const struct token token_list[] = {
>  		.next = NEXT(item_vxlan, NEXT_ENTRY(UNSIGNED), item_param),
>  		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, vni)),
>  	},
> +	[ITEM_VXLAN_GPE] = {
> +		.name = "vxlan-gpe",
> +		.help = "match VXLAN-GPE header",
> +		.priv = PRIV_ITEM(VXLAN_GPE,
> +				  sizeof(struct rte_flow_item_vxlan_gpe)),
> +		.next = NEXT(item_vxlan_gpe),
> +		.call = parse_vc,
> +	},
> +	[ITEM_VXLAN_GPE_VNI] = {
> +		.name = "vni",
> +		.help = "VXLAN-GPE identifier",
> +		.next = NEXT(item_vxlan_gpe, NEXT_ENTRY(UNSIGNED), item_param),
> +		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe,
> +					     vni)),
> +	},
>  	[ITEM_E_TAG] = {
>  		.name = "e_tag",
>  		.help = "match E-Tag header",
> diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
> index 4a273eff7..1a9bc37ed 100644
> --- a/app/test-pmd/config.c
> +++ b/app/test-pmd/config.c
> @@ -972,6 +972,7 @@ static const struct {
>  	MK_FLOW_ITEM(TCP, sizeof(struct rte_flow_item_tcp)),
>  	MK_FLOW_ITEM(SCTP, sizeof(struct rte_flow_item_sctp)),
>  	MK_FLOW_ITEM(VXLAN, sizeof(struct rte_flow_item_vxlan)),
> +	MK_FLOW_ITEM(VXLAN_GPE, sizeof(struct rte_flow_item_vxlan_gpe)),
>  	MK_FLOW_ITEM(E_TAG, sizeof(struct rte_flow_item_e_tag)),
>  	MK_FLOW_ITEM(NVGRE, sizeof(struct rte_flow_item_nvgre)),
>  	MK_FLOW_ITEM(MPLS, sizeof(struct rte_flow_item_mpls)),
> @@ -3080,6 +3081,7 @@ flowtype_to_str(uint16_t flow_type)
>  		{"l2_payload", RTE_ETH_FLOW_L2_PAYLOAD},
>  		{"port", RTE_ETH_FLOW_PORT},
>  		{"vxlan", RTE_ETH_FLOW_VXLAN},
> +		{"vxlan-gpe", RTE_ETH_FLOW_VXLAN_GPE},
>  		{"geneve", RTE_ETH_FLOW_GENEVE},
>  		{"nvgre", RTE_ETH_FLOW_NVGRE},
>  	};
> diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c
> index 5f5ab64aa..213888374 100644
> --- a/app/test-pmd/csumonly.c
> +++ b/app/test-pmd/csumonly.c
> @@ -60,6 +60,8 @@
>  #define _htons(x) (x)
>  #endif
>  
> +uint16_t vxlan_gpe_udp_port = 4790;
> +
>  /* structure that caches offload info for the current packet */
>  struct testpmd_offload_info {
>  	uint16_t ethertype;
> @@ -194,6 +196,70 @@ parse_vxlan(struct udp_hdr *udp_hdr,
>  	info->l2_len += ETHER_VXLAN_HLEN; /* add udp + vxlan */
>  }
>  
> +/* Parse a vxlan-gpe header */
> +static void
> +parse_vxlan_gpe(struct udp_hdr *udp_hdr,
> +	    struct testpmd_offload_info *info)
> +{
> +	struct ether_hdr *eth_hdr;
> +	struct ipv4_hdr *ipv4_hdr;
> +	struct ipv6_hdr *ipv6_hdr;
> +	struct vxlan_gpe_hdr *vxlan_gpe_hdr;
> +	uint8_t vxlan_gpe_len = sizeof(*vxlan_gpe_hdr);
> +
> +	/* check udp destination port, 4790 is the default vxlan-gpe port */

The second part of the comment should be with the global variable.  At
this stage, the user may already have changed the udp port and it is no
more comparing with the default value.

> +	if (udp_hdr->dst_port != _htons(vxlan_gpe_udp_port))
> +		return;
> +
> +	vxlan_gpe_hdr = (struct vxlan_gpe_hdr *)((char *)udp_hdr +
> +				sizeof(struct udp_hdr));
> +
> +	if (!vxlan_gpe_hdr->proto || vxlan_gpe_hdr->proto ==
> +	    VXLAN_GPE_TYPE_IPv4) {
> +		info->is_tunnel = 1;
> +		info->outer_ethertype = info->ethertype;
> +		info->outer_l2_len = info->l2_len;
> +		info->outer_l3_len = info->l3_len;
> +		info->outer_l4_proto = info->l4_proto;
> +
> +		ipv4_hdr = (struct ipv4_hdr *)((char *)vxlan_gpe_hdr +
> +			   vxlan_gpe_len);
> +
> +		parse_ipv4(ipv4_hdr, info);
> +		info->ethertype = _htons(ETHER_TYPE_IPv4);
> +		info->l2_len = 0;
> +
> +	} else if (vxlan_gpe_hdr->proto == VXLAN_GPE_TYPE_IPv6) {
> +		info->is_tunnel = 1;
> +		info->outer_ethertype = info->ethertype;
> +		info->outer_l2_len = info->l2_len;
> +		info->outer_l3_len = info->l3_len;
> +		info->outer_l4_proto = info->l4_proto;
> +
> +		ipv6_hdr = (struct ipv6_hdr *)((char *)vxlan_gpe_hdr +
> +			   vxlan_gpe_len);
> +
> +		info->ethertype = _htons(ETHER_TYPE_IPv6);
> +		parse_ipv6(ipv6_hdr, info);
> +		info->l2_len = 0;
> +
> +	} else if (vxlan_gpe_hdr->proto == VXLAN_GPE_TYPE_ETH) {
> +		info->is_tunnel = 1;
> +		info->outer_ethertype = info->ethertype;
> +		info->outer_l2_len = info->l2_len;
> +		info->outer_l3_len = info->l3_len;
> +		info->outer_l4_proto = info->l4_proto;
> +
> +		eth_hdr = (struct ether_hdr *)((char *)vxlan_gpe_hdr +
> +			  vxlan_gpe_len);
> +
> +		parse_ethernet(eth_hdr, info);
> +	} else
> +		return;
> +
> +	info->l2_len += ETHER_VXLAN_GPE_HLEN;
> +}
> +
>  /* Parse a gre header */
>  static void
>  parse_gre(struct simple_gre_hdr *gre_hdr, struct testpmd_offload_info *info)
> @@ -588,6 +654,10 @@ pkt_copy_split(const struct rte_mbuf *pkt)
>   *   Ether / (vlan) / IP|IP6 / UDP|TCP|SCTP .
>   *   Ether / (vlan) / outer IP|IP6 / outer UDP / VxLAN / Ether / IP|IP6 /
>   *           UDP|TCP|SCTP
> + *   Ether / (vlan) / outer IP|IP6 / outer UDP / VXLAN-GPE / Ether / IP|IP6 /
> + *           UDP|TCP|SCTP
> + *   Ether / (vlan) / outer IP|IP6 / outer UDP / VXLAN-GPE / IP|IP6 /
> + *           UDP|TCP|SCTP
>   *   Ether / (vlan) / outer IP|IP6 / GRE / Ether / IP|IP6 / UDP|TCP|SCTP
>   *   Ether / (vlan) / outer IP|IP6 / GRE / IP|IP6 / UDP|TCP|SCTP
>   *   Ether / (vlan) / outer IP|IP6 / IP|IP6 / UDP|TCP|SCTP
> @@ -691,9 +761,16 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
>  
>  				udp_hdr = (struct udp_hdr *)((char *)l3_hdr +
>  					info.l3_len);
> -				parse_vxlan(udp_hdr, &info, m->packet_type);
> -				if (info.is_tunnel)
> -					tx_ol_flags |= PKT_TX_TUNNEL_VXLAN;
> +				parse_vxlan_gpe(udp_hdr, &info);
> +				if (info.is_tunnel) {
> +					tx_ol_flags |= PKT_TX_TUNNEL_VXLAN_GPE;
> +				} else {
> +					parse_vxlan(udp_hdr, &info,
> +						    m->packet_type);
> +					if (info.is_tunnel)
> +						tx_ol_flags |=
> +							PKT_TX_TUNNEL_VXLAN;
> +				}
>  			} else if (info.l4_proto == IPPROTO_GRE) {
>  				struct simple_gre_hdr *gre_hdr;
>  
> diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c
> index 2192bdcdf..68063b7a4 100644
> --- a/app/test-pmd/parameters.c
> +++ b/app/test-pmd/parameters.c
> @@ -70,7 +70,7 @@ usage(char* progname)
>  	       "--rss-ip | --rss-udp | "
>  	       "--rxpt= | --rxht= | --rxwt= | --rxfreet= | "
>  	       "--txpt= | --txht= | --txwt= | --txfreet= | "
> -	       "--txrst= | --tx-offloads ]\n",
> +	       "--txrst= | --tx-offloads= | --vxlan-gpe-port= ]\n",
>  	       progname);
>  #ifdef RTE_LIBRTE_CMDLINE
>  	printf("  --interactive: run in interactive mode.\n");
> @@ -186,6 +186,7 @@ usage(char* progname)
>  	printf("  --flow-isolate-all: "
>  	       "requests flow API isolated mode on all ports at initialization time.\n");
>  	printf("  --tx-offloads=0xXXXXXXXX: hexadecimal bitmask of TX queue offloads\n");
> +	printf("  --vxlan-gpe-port=N: UPD port of tunnel VXLAN-GPE\n");
>  }
>  
>  #ifdef RTE_LIBRTE_CMDLINE
> @@ -621,6 +622,7 @@ launch_args_parse(int argc, char** argv)
>  		{ "print-event",		1, 0, 0 },
>  		{ "mask-event",			1, 0, 0 },
>  		{ "tx-offloads",		1, 0, 0 },
> +		{ "vxlan-gpe-port",		1, 0, 0 },
>  		{ 0, 0, 0, 0 },
>  	};
>  
> @@ -1091,6 +1093,14 @@ launch_args_parse(int argc, char** argv)
>  					rte_exit(EXIT_FAILURE,
>  						 "tx-offloads must be >= 0\n");
>  			}
> +			if (!strcmp(lgopts[opt_idx].name, "vxlan-gpe-port")) {
> +				n = atoi(optarg);
> +				if (n >= 0)
> +					vxlan_gpe_udp_port = (uint16_t)n;
> +				else
> +					rte_exit(EXIT_FAILURE,
> +						 "vxlan-gpe-port must be >= 0\n");
> +			}
>  			if (!strcmp(lgopts[opt_idx].name, "print-event"))
>  				if (parse_event_printing_config(optarg, 1)) {
>  					rte_exit(EXIT_FAILURE,
> diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
> index 593ae2160..b270602d9 100644
> --- a/app/test-pmd/testpmd.h
> +++ b/app/test-pmd/testpmd.h
> @@ -446,6 +446,8 @@ extern uint32_t retry_enabled;
>  extern struct fwd_lcore  **fwd_lcores;
>  extern struct fwd_stream **fwd_streams;
>  
> +extern uint16_t vxlan_gpe_udp_port; /**< UDP port of tunnel VXLAN-GPE. */
> +
>  extern portid_t nb_peer_eth_addrs; /**< Number of peer ethernet addresses. */
>  extern struct ether_addr peer_eth_addrs[RTE_MAX_ETHPORTS];
>  
> diff --git a/doc/guides/testpmd_app_ug/run_app.rst b/doc/guides/testpmd_app_ug/run_app.rst
> index 1fd53958a..2e8690f41 100644
> --- a/doc/guides/testpmd_app_ug/run_app.rst
> +++ b/doc/guides/testpmd_app_ug/run_app.rst
> @@ -479,3 +479,8 @@ The commandline options are:
>  
>      Set the hexadecimal bitmask of TX queue offloads.
>      The default value is 0.
> +
> +*   ``--vxlan-gpe-port=N``
> +
> +    Set the UDP port number of tunnel VXLAN-GPE to N.
> +    The default value is 4790.
> -- 
> 2.13.3
> 

-- 
Nélio Laranjeiro
6WIND


More information about the dev mailing list