From d52054e70f8982d7d72edec14b5875c2a0ed23da Mon Sep 17 00:00:00 2001 From: Hyong Youb Kim Date: Wed, 9 Sep 2020 07:00:05 -0700 Subject: [PATCH] net/enic: generate VXLAN src port if it is zero in template When VXLAN source port in the template is zero, the adapter is expected to generate a value based on the inner packet flow, when it performs encapsulation. Flow Manager in the VIC adapter currently lacks such ability. So, generate a random port when creating a flow if the port is zero, to avoid transmitting packets with source port 0. Fixes: ea7768b5bba8 ("net/enic: add flow implementation based on Flow Manager API") Cc: stable@dpdk.org Signed-off-by: Hyong Youb Kim Reviewed-by: John Daley --- drivers/net/enic/enic_fm_flow.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/net/enic/enic_fm_flow.c b/drivers/net/enic/enic_fm_flow.c index 94e39a94bf..8e5eb4d743 100644 --- a/drivers/net/enic/enic_fm_flow.c +++ b/drivers/net/enic/enic_fm_flow.c @@ -978,6 +978,17 @@ enic_fm_copy_vxlan_decap(struct enic_flowman *fm, return enic_fm_append_action_op(fm, &fm_op, error); } +/* Generate a reasonable source port number */ +static uint16_t +gen_src_port(void) +{ + /* Min/max below are the default values in OVS-DPDK and Linux */ + uint16_t p = rte_rand(); + p = RTE_MAX(p, 32768); + p = RTE_MIN(p, 61000); + return rte_cpu_to_be_16(p); +} + /* VXLAN encap is done via flowman compound action */ static int enic_fm_copy_vxlan_encap(struct enic_flowman *fm, @@ -986,6 +997,7 @@ enic_fm_copy_vxlan_encap(struct enic_flowman *fm, { struct fm_action_op fm_op; struct rte_ether_hdr *eth; + struct rte_udp_hdr *udp; uint16_t *ethertype; void *template; uint8_t off; @@ -1084,8 +1096,17 @@ enic_fm_copy_vxlan_encap(struct enic_flowman *fm, off + offsetof(struct rte_udp_hdr, dgram_len); fm_op.encap.len2_delta = sizeof(struct rte_udp_hdr) + sizeof(struct rte_vxlan_hdr); + udp = (struct rte_udp_hdr *)template; append_template(&template, &off, item->spec, sizeof(struct rte_udp_hdr)); + /* + * Firmware does not hash/fill source port yet. Generate a + * random port, as there is *usually* one rte_flow for the + * given inner packet stream (i.e. a single stream has one + * random port). + */ + if (udp->src_port == 0) + udp->src_port = gen_src_port(); item++; flow_item_skip_void(&item); -- 2.20.1