All informations required for checksum offloading can be deduced by already tracked dp_packet l3_ofs, l4_ofs, inner_l3_ofs and inner_l4_ofs fields. Remove DPDK specific l[2-4]_len from generic OVS code.
netdev-dpdk code then fills mbuf specifics step by step: - outer_l2_len and outer_l3_len are needed for tunneling (and below features), - l2_len and l3_len are needed for IP and L4 checksum (and below features), - l4_len and tso_segsz are needed when doing TSO, Signed-off-by: David Marchand <david.march...@redhat.com> --- lib/dp-packet.h | 37 ------------------------------ lib/netdev-dpdk.c | 35 ++++++++++++++++++----------- lib/netdev-native-tnl.c | 50 +++++------------------------------------ 3 files changed, 27 insertions(+), 95 deletions(-) diff --git a/lib/dp-packet.h b/lib/dp-packet.h index 3622764c47..a75b1c5cdb 100644 --- a/lib/dp-packet.h +++ b/lib/dp-packet.h @@ -604,25 +604,6 @@ dp_packet_get_nd_payload(const struct dp_packet *b) } #ifdef DPDK_NETDEV -static inline void -dp_packet_set_l2_len(struct dp_packet *b, size_t l2_len) -{ - b->mbuf.l2_len = l2_len; -} - -static inline void -dp_packet_set_l3_len(struct dp_packet *b, size_t l3_len) -{ - b->mbuf.l3_len = l3_len; -} - -static inline void -dp_packet_set_l4_len(struct dp_packet *b, size_t l4_len) -{ - b->mbuf.l4_len = l4_len; -} - - static inline uint64_t * dp_packet_ol_flags_ptr(const struct dp_packet *b) { @@ -642,24 +623,6 @@ dp_packet_flow_mark_ptr(const struct dp_packet *b) } #else -static inline void -dp_packet_set_l2_len(struct dp_packet *b OVS_UNUSED, size_t l2_len OVS_UNUSED) -{ - /* There is no implementation. */ -} - -static inline void -dp_packet_set_l3_len(struct dp_packet *b OVS_UNUSED, size_t l3_len OVS_UNUSED) -{ - /* There is no implementation. */ -} - -static inline void -dp_packet_set_l4_len(struct dp_packet *b OVS_UNUSED, size_t l4_len OVS_UNUSED) -{ - /* There is no implementation. */ -} - static inline uint32_t * dp_packet_ol_flags_ptr(const struct dp_packet *b) { diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index 1dad2ef833..31dd6f1d5a 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -2584,6 +2584,9 @@ static bool netdev_dpdk_prep_hwol_packet(struct netdev_dpdk *dev, struct rte_mbuf *mbuf) { struct dp_packet *pkt = CONTAINER_OF(mbuf, struct dp_packet, mbuf); + void *l2; + void *l3; + void *l4; const uint64_t all_inner_requests = (RTE_MBUF_F_TX_IP_CKSUM | RTE_MBUF_F_TX_L4_MASK | @@ -2613,11 +2616,6 @@ netdev_dpdk_prep_hwol_packet(struct netdev_dpdk *dev, struct rte_mbuf *mbuf) return true; } - ovs_assert(dp_packet_l4(pkt)); - - /* If packet is vxlan or geneve tunnel packet, calculate outer - * l2 len and outer l3 len. Inner l2/l3/l4 len are calculated - * before. */ const uint64_t tunnel_type = mbuf->ol_flags & RTE_MBUF_F_TX_TUNNEL_MASK; if (OVS_UNLIKELY(tunnel_type && tunnel_type != RTE_MBUF_F_TX_TUNNEL_GENEVE && @@ -2635,6 +2633,11 @@ netdev_dpdk_prep_hwol_packet(struct netdev_dpdk *dev, struct rte_mbuf *mbuf) (char *) dp_packet_eth(pkt); mbuf->outer_l3_len = (char *) dp_packet_l4(pkt) - (char *) dp_packet_l3(pkt); + + /* Inner L2 length must account for the tunnel header length. */ + l2 = dp_packet_l4(pkt); + l3 = dp_packet_inner_l3(pkt); + l4 = dp_packet_inner_l4(pkt); } else { /* If no outer offloading is requested, clear outer marks. */ mbuf->ol_flags &= ~all_outer_marks; @@ -2642,8 +2645,9 @@ netdev_dpdk_prep_hwol_packet(struct netdev_dpdk *dev, struct rte_mbuf *mbuf) mbuf->outer_l3_len = 0; /* Skip outer headers. */ - mbuf->l2_len += (char *) dp_packet_l4(pkt) - - (char *) dp_packet_eth(pkt); + l2 = dp_packet_eth(pkt); + l3 = dp_packet_inner_l3(pkt); + l4 = dp_packet_inner_l4(pkt); } } else { if (tunnel_type) { @@ -2663,22 +2667,27 @@ netdev_dpdk_prep_hwol_packet(struct netdev_dpdk *dev, struct rte_mbuf *mbuf) } mbuf->outer_l2_len = 0; mbuf->outer_l3_len = 0; - mbuf->l2_len = (char *) dp_packet_l3(pkt) - - (char *) dp_packet_eth(pkt); - mbuf->l3_len = (char *) dp_packet_l4(pkt) - - (char *) dp_packet_l3(pkt); + + l2 = dp_packet_eth(pkt); + l3 = dp_packet_l3(pkt); + l4 = dp_packet_l4(pkt); } + ovs_assert(l4); + + mbuf->l2_len = (char *) l3 - (char *) l2; + mbuf->l3_len = (char *) l4 - (char *) l3; + if (mbuf->ol_flags & RTE_MBUF_F_TX_TCP_SEG) { - struct tcp_header *th = dp_packet_l4(pkt); + struct tcp_header *th = l4; uint16_t link_tso_segsz; int hdr_len; + mbuf->l4_len = TCP_OFFSET(th->tcp_ctl) * 4; if (tunnel_type) { link_tso_segsz = dev->mtu - mbuf->l2_len - mbuf->l3_len - mbuf->l4_len - mbuf->outer_l3_len; } else { - mbuf->l4_len = TCP_OFFSET(th->tcp_ctl) * 4; link_tso_segsz = dev->mtu - mbuf->l3_len - mbuf->l4_len; } diff --git a/lib/netdev-native-tnl.c b/lib/netdev-native-tnl.c index dee9ab344e..0b4c4fed48 100644 --- a/lib/netdev-native-tnl.c +++ b/lib/netdev-native-tnl.c @@ -240,35 +240,15 @@ udp_extract_tnl_md(struct dp_packet *packet, struct flow_tnl *tnl, return udp + 1; } -/* Calculate inner l2 l3 l4 len as tunnel outer header is not - * encapsulated now. */ static void dp_packet_tnl_ol_process(struct dp_packet *packet, const struct ovs_action_push_tnl *data) { - struct udp_header *udp = NULL; - uint8_t opt_len = 0; - struct eth_header *eth = NULL; struct ip_header *ip = NULL; - struct genevehdr *gnh = NULL; - /* l2 l3 l4 len refer to inner len, tunnel outer - * header is not encapsulated here. */ if (dp_packet_hwol_l4_mask(packet)) { ip = dp_packet_l3(packet); - if (ip->ip_proto == IPPROTO_TCP) { - struct tcp_header *th = dp_packet_l4(packet); - dp_packet_set_l4_len(packet, TCP_OFFSET(th->tcp_ctl) * 4); - } else if (ip->ip_proto == IPPROTO_UDP) { - dp_packet_set_l4_len(packet, UDP_HEADER_LEN); - } else if (ip->ip_proto == IPPROTO_SCTP) { - dp_packet_set_l4_len(packet, SCTP_HEADER_LEN); - } - - dp_packet_set_l3_len(packet, (char *) dp_packet_l4(packet) - - (char *) dp_packet_l3(packet)); - if (data->tnl_type == OVS_VPORT_TYPE_GENEVE || data->tnl_type == OVS_VPORT_TYPE_VXLAN) { @@ -279,32 +259,12 @@ dp_packet_tnl_ol_process(struct dp_packet *packet, dp_packet_hwol_set_tx_ipv6(packet); } } + } - /* Attention please, tunnel inner l2 len is consist of udp header - * len and tunnel header len and inner l2 len. */ - if (data->tnl_type == OVS_VPORT_TYPE_GENEVE) { - eth = (struct eth_header *)(data->header); - ip = (struct ip_header *)(eth + 1); - udp = (struct udp_header *)(ip + 1); - gnh = (struct genevehdr *)(udp + 1); - opt_len = gnh->opt_len * 4; - dp_packet_hwol_set_tunnel_geneve(packet); - dp_packet_set_l2_len(packet, (char *) dp_packet_l3(packet) - - (char *) dp_packet_eth(packet) + - GENEVE_BASE_HLEN + opt_len); - } else if (data->tnl_type == OVS_VPORT_TYPE_VXLAN) { - dp_packet_hwol_set_tunnel_vxlan(packet); - dp_packet_set_l2_len(packet, (char *) dp_packet_l3(packet) - - (char *) dp_packet_eth(packet) + - VXLAN_HLEN); - } - } else { - /* Mark non-l4 packets as tunneled. */ - if (data->tnl_type == OVS_VPORT_TYPE_GENEVE) { - dp_packet_hwol_set_tunnel_geneve(packet); - } else if (data->tnl_type == OVS_VPORT_TYPE_VXLAN) { - dp_packet_hwol_set_tunnel_vxlan(packet); - } + if (data->tnl_type == OVS_VPORT_TYPE_GENEVE) { + dp_packet_hwol_set_tunnel_geneve(packet); + } else if (data->tnl_type == OVS_VPORT_TYPE_VXLAN) { + dp_packet_hwol_set_tunnel_vxlan(packet); } } -- 2.44.0 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev