From 2ab5c84605f03e125eaa917cf6c1d5338729098e Mon Sep 17 00:00:00 2001 From: Bernard Iremonger Date: Tue, 28 Jan 2020 13:48:45 +0000 Subject: [PATCH] net/i40e: fix ESP flow creation Merge of ESP and L2TP code in i40e_fdir.c added checks on cus_pctype->index which caused flow creation for ESP to fail. Added fill_ipv4_function() Refactored code to have one path for customized and non customized pctype's. Fixes: c5f8365bc85d ("net/i40e: support flow director for L2TPv3 over IP") Signed-off-by: Bernard Iremonger Acked-by: Rory Sexton --- drivers/net/i40e/i40e_fdir.c | 139 ++++++++++++++++------------------- 1 file changed, 64 insertions(+), 75 deletions(-) diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c index c3460739bf..931f259765 100644 --- a/drivers/net/i40e/i40e_fdir.c +++ b/drivers/net/i40e/i40e_fdir.c @@ -1007,6 +1007,36 @@ fill_ip6_head(const struct i40e_fdir_input *fdir_input, unsigned char *raw_pkt, return len; } +static inline int +fill_ip4_head(const struct i40e_fdir_input *fdir_input, unsigned char *raw_pkt, + uint8_t next_proto, uint8_t len, uint16_t *ether_type) +{ + struct rte_ipv4_hdr *ip4; + + ip4 = (struct rte_ipv4_hdr *)raw_pkt; + + *ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); + ip4->version_ihl = I40E_FDIR_IP_DEFAULT_VERSION_IHL; + /* set len to by default */ + ip4->total_length = rte_cpu_to_be_16(I40E_FDIR_IP_DEFAULT_LEN); + ip4->time_to_live = fdir_input->flow.ip4_flow.ttl ? + fdir_input->flow.ip4_flow.ttl : + I40E_FDIR_IP_DEFAULT_TTL; + ip4->type_of_service = fdir_input->flow.ip4_flow.tos; + ip4->next_proto_id = fdir_input->flow.ip4_flow.proto ? + fdir_input->flow.ip4_flow.proto : next_proto; + /** + * The source and destination fields in the transmitted packet + * need to be presented in a reversed order with respect + * to the expected received packets. + */ + ip4->src_addr = fdir_input->flow.ip4_flow.dst_ip; + ip4->dst_addr = fdir_input->flow.ip4_flow.src_ip; + len += sizeof(struct rte_ipv4_hdr); + + return len; +} + static inline int i40e_flow_fdir_fill_eth_ip_head(struct i40e_pf *pf, const struct i40e_fdir_input *fdir_input, @@ -1017,8 +1047,6 @@ i40e_flow_fdir_fill_eth_ip_head(struct i40e_pf *pf, static uint8_t vlan_frame[] = {0x81, 0, 0, 0}; uint16_t *ether_type; uint8_t len = 2 * sizeof(struct rte_ether_addr); - struct rte_ipv4_hdr *ip; - struct rte_ipv6_hdr *ip6; uint8_t pctype = fdir_input->pctype; bool is_customized_pctype = fdir_input->flow_ext.customized_pctype; static const uint8_t next_proto[] = { @@ -1063,93 +1091,54 @@ i40e_flow_fdir_fill_eth_ip_head(struct i40e_pf *pf, pctype == I40E_FILTER_PCTYPE_NONF_IPV4_SCTP || pctype == I40E_FILTER_PCTYPE_NONF_IPV4_OTHER || pctype == I40E_FILTER_PCTYPE_FRAG_IPV4 || - ((is_customized_pctype) && - ((cus_pctype->index == I40E_CUSTOMIZED_GTPC) || - (cus_pctype->index == I40E_CUSTOMIZED_GTPU_IPV4) || - (cus_pctype->index == I40E_CUSTOMIZED_GTPU_IPV6) || - (cus_pctype->index == I40E_CUSTOMIZED_GTPU) || - (cus_pctype->index == I40E_CUSTOMIZED_IPV4_L2TPV3)))) { - ip = (struct rte_ipv4_hdr *)raw_pkt; - - *ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); - ip->version_ihl = I40E_FDIR_IP_DEFAULT_VERSION_IHL; - /* set len to by default */ - ip->total_length = rte_cpu_to_be_16(I40E_FDIR_IP_DEFAULT_LEN); - ip->time_to_live = fdir_input->flow.ip4_flow.ttl ? - fdir_input->flow.ip4_flow.ttl : - I40E_FDIR_IP_DEFAULT_TTL; - ip->type_of_service = fdir_input->flow.ip4_flow.tos; - /** - * The source and destination fields in the transmitted packet - * need to be presented in a reversed order with respect - * to the expected received packets. - */ - ip->src_addr = fdir_input->flow.ip4_flow.dst_ip; - ip->dst_addr = fdir_input->flow.ip4_flow.src_ip; - - if (!is_customized_pctype) { - ip->next_proto_id = fdir_input->flow.ip4_flow.proto ? - fdir_input->flow.ip4_flow.proto : - next_proto[fdir_input->pctype]; - len += sizeof(struct rte_ipv4_hdr); + pctype == I40E_FILTER_PCTYPE_NONF_IPV6_TCP || + pctype == I40E_FILTER_PCTYPE_NONF_IPV6_UDP || + pctype == I40E_FILTER_PCTYPE_NONF_IPV6_SCTP || + pctype == I40E_FILTER_PCTYPE_NONF_IPV6_OTHER || + pctype == I40E_FILTER_PCTYPE_FRAG_IPV6 || + is_customized_pctype) { + if (pctype == I40E_FILTER_PCTYPE_NONF_IPV4_TCP || + pctype == I40E_FILTER_PCTYPE_NONF_IPV4_UDP || + pctype == I40E_FILTER_PCTYPE_NONF_IPV4_SCTP || + pctype == I40E_FILTER_PCTYPE_NONF_IPV4_OTHER || + pctype == I40E_FILTER_PCTYPE_FRAG_IPV4) { + len = fill_ip4_head(fdir_input, raw_pkt, + next_proto[pctype], len, ether_type); + } else if (pctype == I40E_FILTER_PCTYPE_NONF_IPV6_TCP || + pctype == I40E_FILTER_PCTYPE_NONF_IPV6_UDP || + pctype == I40E_FILTER_PCTYPE_NONF_IPV6_SCTP || + pctype == I40E_FILTER_PCTYPE_NONF_IPV6_OTHER || + pctype == I40E_FILTER_PCTYPE_FRAG_IPV6) { + len = fill_ip6_head(fdir_input, raw_pkt, + next_proto[pctype], len, + ether_type); } else if (cus_pctype->index == I40E_CUSTOMIZED_GTPC || cus_pctype->index == I40E_CUSTOMIZED_GTPU_IPV4 || cus_pctype->index == I40E_CUSTOMIZED_GTPU_IPV6 || cus_pctype->index == I40E_CUSTOMIZED_GTPU) { - ip->next_proto_id = IPPROTO_UDP; - len += sizeof(struct rte_ipv4_hdr); + len = fill_ip4_head(fdir_input, raw_pkt, IPPROTO_UDP, + len, ether_type); } else if (cus_pctype->index == I40E_CUSTOMIZED_IPV4_L2TPV3) { - ip->next_proto_id = IPPROTO_L2TP; - len += sizeof(struct rte_ipv4_hdr); + len = fill_ip4_head(fdir_input, raw_pkt, IPPROTO_L2TP, + len, ether_type); } else if (cus_pctype->index == I40E_CUSTOMIZED_ESP_IPV4) { - ip->next_proto_id = IPPROTO_ESP; - len += sizeof(struct rte_ipv4_hdr); + len = fill_ip4_head(fdir_input, raw_pkt, IPPROTO_ESP, + len, ether_type); + } else if (cus_pctype->index == I40E_CUSTOMIZED_ESP_IPV4_UDP) { + len = fill_ip4_head(fdir_input, raw_pkt, IPPROTO_UDP, + len, ether_type); } else if (cus_pctype->index == I40E_CUSTOMIZED_ESP_IPV4_UDP) { - ip->next_proto_id = IPPROTO_UDP; - len += sizeof(struct rte_ipv4_hdr); + len = fill_ip4_head(fdir_input, raw_pkt, IPPROTO_UDP, + len, ether_type); } else if (cus_pctype->index == I40E_CUSTOMIZED_ESP_IPV6) len = fill_ip6_head(fdir_input, raw_pkt, IPPROTO_ESP, len, ether_type); else if (cus_pctype->index == I40E_CUSTOMIZED_ESP_IPV6_UDP) len = fill_ip6_head(fdir_input, raw_pkt, IPPROTO_UDP, len, ether_type); - } else if (pctype == I40E_FILTER_PCTYPE_NONF_IPV6_TCP || - pctype == I40E_FILTER_PCTYPE_NONF_IPV6_UDP || - pctype == I40E_FILTER_PCTYPE_NONF_IPV6_SCTP || - pctype == I40E_FILTER_PCTYPE_NONF_IPV6_OTHER || - pctype == I40E_FILTER_PCTYPE_FRAG_IPV6 || - ((is_customized_pctype) && - (cus_pctype->index == I40E_CUSTOMIZED_IPV6_L2TPV3))) { - ip6 = (struct rte_ipv6_hdr *)raw_pkt; - - *ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); - ip6->vtc_flow = - rte_cpu_to_be_32(I40E_FDIR_IPv6_DEFAULT_VTC_FLOW | - (fdir_input->flow.ipv6_flow.tc << - I40E_FDIR_IPv6_TC_OFFSET)); - ip6->payload_len = - rte_cpu_to_be_16(I40E_FDIR_IPv6_PAYLOAD_LEN); - if (!is_customized_pctype) - ip6->proto = fdir_input->flow.ipv6_flow.proto ? - fdir_input->flow.ipv6_flow.proto : - next_proto[fdir_input->pctype]; else if (cus_pctype->index == I40E_CUSTOMIZED_IPV6_L2TPV3) - ip6->proto = IPPROTO_L2TP; - ip6->hop_limits = fdir_input->flow.ipv6_flow.hop_limits ? - fdir_input->flow.ipv6_flow.hop_limits : - I40E_FDIR_IPv6_DEFAULT_HOP_LIMITS; - /** - * The source and destination fields in the transmitted packet - * need to be presented in a reversed order with respect - * to the expected received packets. - */ - rte_memcpy(&ip6->src_addr, - &fdir_input->flow.ipv6_flow.dst_ip, - IPV6_ADDR_LEN); - rte_memcpy(&ip6->dst_addr, - &fdir_input->flow.ipv6_flow.src_ip, - IPV6_ADDR_LEN); - len += sizeof(struct rte_ipv6_hdr); + len = fill_ip6_head(fdir_input, raw_pkt, IPPROTO_L2TP, + len, ether_type); } else { PMD_DRV_LOG(ERR, "unknown pctype %u.", fdir_input->pctype); return -1; -- 2.20.1