Signed-off-by: Dexia Li <dexia...@jaguarmicro.com> --- lib/dp-packet.h | 7 +++--- lib/netdev-dpdk.c | 45 +++++++++++++++++++++++++++++--------- lib/netdev-native-tnl.c | 48 +++++++++++++++++++++++++++++++++++++++++ lib/netdev.c | 17 +++++++++------ 4 files changed, 97 insertions(+), 20 deletions(-)
diff --git a/lib/dp-packet.h b/lib/dp-packet.h index 70ddf8aa4..aad478452 100644 --- a/lib/dp-packet.h +++ b/lib/dp-packet.h @@ -615,9 +615,10 @@ dp_packet_set_size(struct dp_packet *b, uint32_t v) * (and thus 'v') will always be <= UINT16_MAX; this means that there is no * loss of accuracy in assigning 'v' to 'data_len'. */ - b->mbuf.data_len = (uint16_t)v; /* Current seg length. */ - b->mbuf.pkt_len = v; /* Total length of all segments linked to - * this segment. */ + /* Current seg length. */ + b->mbuf.data_len += (uint16_t)(v - b->mbuf.pkt_len); + /* Total length of all segments linked to this segment. */ + b->mbuf.pkt_len = v; } static inline uint16_t diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index aa87ee546..1db3b34b1 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -2378,29 +2378,54 @@ netdev_dpdk_prep_hwol_packet(struct netdev_dpdk *dev, struct rte_mbuf *mbuf) return true; } - 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); - mbuf->l4_len = 0; - mbuf->outer_l2_len = 0; - mbuf->outer_l3_len = 0; + if (mbuf->ol_flags & RTE_MBUF_F_TX_L4_MASK) { + if (mbuf->ol_flags & + (RTE_MBUF_F_TX_TUNNEL_GENEVE | RTE_MBUF_F_TX_TUNNEL_VXLAN)) { + mbuf->outer_l2_len = (char *) dp_packet_l3(pkt) - + (char *) dp_packet_eth(pkt); + mbuf->outer_l3_len = (char *) dp_packet_l4(pkt) - + (char *) dp_packet_l3(pkt); + } else { + 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); + mbuf->outer_l2_len = 0; + mbuf->outer_l3_len = 0; + } + } if (mbuf->ol_flags & RTE_MBUF_F_TX_TCP_SEG) { struct tcp_header *th = dp_packet_l4(pkt); if (!th) { - VLOG_WARN_RL(&rl, "%s: TCP Segmentation without L4 header" - " pkt len: %"PRIu32"", dev->up.name, mbuf->pkt_len); + VLOG_WARN_RL(&rl, + "%s: TCP Segmentation without L4 header,pkt len: %"PRIu32"", + dev->up.name, mbuf->pkt_len); return false; } - mbuf->l4_len = TCP_OFFSET(th->tcp_ctl) * 4; - mbuf->ol_flags |= RTE_MBUF_F_TX_TCP_CKSUM; - mbuf->tso_segsz = dev->mtu - mbuf->l3_len - mbuf->l4_len; + if (mbuf->ol_flags & (RTE_MBUF_F_TX_TUNNEL_GENEVE | + RTE_MBUF_F_TX_TUNNEL_VXLAN)) { + mbuf->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; + mbuf->tso_segsz = dev->mtu - mbuf->l3_len - mbuf->l4_len; + } + + mbuf->ol_flags &= (~RTE_MBUF_F_TX_TCP_CKSUM); if (mbuf->ol_flags & RTE_MBUF_F_TX_IPV4) { mbuf->ol_flags |= RTE_MBUF_F_TX_IP_CKSUM; } } + + /* when tcp checksum offload, ip checksum is set to 0 */ + if ((mbuf->ol_flags & (RTE_MBUF_F_TX_TCP_CKSUM | RTE_MBUF_F_TX_UDP_CKSUM)) + && !(mbuf->ol_flags & RTE_MBUF_F_TX_IPV6)) + mbuf->ol_flags |= RTE_MBUF_F_TX_IP_CKSUM; + return true; } diff --git a/lib/netdev-native-tnl.c b/lib/netdev-native-tnl.c index 715bbab2b..e5708aeb9 100644 --- a/lib/netdev-native-tnl.c +++ b/lib/netdev-native-tnl.c @@ -184,6 +184,15 @@ netdev_tnl_push_ip_header(struct dp_packet *packet, const void *header, dp_packet_ol_reset_ip_csum_good(packet); *ip_tot_size -= IP_HEADER_LEN; packet->l4_ofs = dp_packet_size(packet) - *ip_tot_size; + + if (packet->mbuf.ol_flags & + (RTE_MBUF_F_TX_TUNNEL_GENEVE | RTE_MBUF_F_TX_TUNNEL_VXLAN)) { + packet->mbuf.ol_flags |= RTE_MBUF_F_TX_OUTER_IPV4; + packet->mbuf.ol_flags |= RTE_MBUF_F_TX_OUTER_IP_CKSUM; + } else { + ip->ip_csum = recalc_csum16(ip->ip_csum, 0, ip->ip_tot_len); + } + return ip + 1; } } @@ -232,6 +241,45 @@ netdev_tnl_push_udp_header(const struct netdev *netdev OVS_UNUSED, { struct udp_header *udp; int ip_tot_size; + uint8_t opt_len = 0; + struct eth_header *eth; + struct ip_header *ip; + struct genevehdr *gnh; + + if (dp_packet_hwol_l4_mask(packet)) { + struct ip_header *ip = dp_packet_l3(packet); + + if (ip->ip_proto == IPPROTO_TCP) { + struct tcp_header *th = dp_packet_l4(packet); + + packet->mbuf.l4_len = TCP_OFFSET(th->tcp_ctl) * 4; + } else if (ip->ip_proto == IPPROTO_UDP) + packet->mbuf.l4_len = UDP_HEADER_LEN; + + packet->mbuf.l3_len = (char *) dp_packet_l4(packet) - + (char *) dp_packet_l3(packet); + + if ((packet->mbuf.ol_flags & RTE_MBUF_F_TX_TCP_CKSUM) && + !(packet->mbuf.ol_flags & RTE_MBUF_F_TX_IPV6)) + packet->mbuf.ol_flags |= RTE_MBUF_F_TX_IP_CKSUM; + + if (!strcmp(netdev_get_type(netdev), "geneve")) { + eth = (data->header); + ip = eth + 1; + udp = ip + 1; + gnh = udp + 1; + opt_len = gnh->opt_len * 4; + packet->mbuf.ol_flags |= RTE_MBUF_F_TX_TUNNEL_GENEVE; + packet->mbuf.l2_len = (char *) dp_packet_l3(packet) - + (char *) dp_packet_eth(packet) + + GENEVE_BASE_HLEN + opt_len; + } else if (!strcmp(netdev_get_type(netdev), "vxlan")) { + packet->mbuf.ol_flags |= RTE_MBUF_F_TX_TUNNEL_VXLAN; + packet->mbuf.l2_len = (char *) dp_packet_l3(packet) - + (char *) dp_packet_eth(packet) + + VXLAN_HLEN; + } + } udp = netdev_tnl_push_ip_header(packet, data->header, data->header_len, &ip_tot_size, 0); diff --git a/lib/netdev.c b/lib/netdev.c index 8df7f8737..e72bd1c2e 100644 --- a/lib/netdev.c +++ b/lib/netdev.c @@ -953,13 +953,16 @@ netdev_push_header(const struct netdev *netdev, size_t i, size = dp_packet_batch_size(batch); DP_PACKET_BATCH_REFILL_FOR_EACH (i, size, packet, batch) { - if (OVS_UNLIKELY(dp_packet_hwol_is_tso(packet))) { - COVERAGE_INC(netdev_push_header_drops); - dp_packet_delete(packet); - VLOG_WARN_RL(&rl, "%s: Tunneling packets with TSO is " - "not supported: packet dropped", - netdev_get_name(netdev)); - } else { + if (OVS_UNLIKELY(strcmp(netdev_get_type(netdev), "vxlan") && + strcmp(netdev_get_type(netdev), "geneve") && + (dp_packet_hwol_l4_mask(packet) || dp_packet_hwol_is_tso(packet)))) { + COVERAGE_INC(netdev_push_header_drops); + dp_packet_delete(packet); + VLOG_WARN_RL(&rl, + "%s: Tunneling packets with csum or tso HW offload flags" + "is not supported: packet dropped", + netdev_get_name(netdev)); + } else { /* The packet is going to be encapsulated and there is * no support yet for inner network header csum offloading. */ dp_packet_ol_send_prepare(packet, 0); -- 2.33.0.windows.2 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev