2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-22 01:51:26 +00:00

dp-packet: Remove DPDK specific IP version.

Flagging packets with IP version is only needed at the netdev-dpdk level.

In most cases, OVS is already inspecting the IP header in packet data,
so maintaining such IP version metadata won't save much cycles
(given the cost of additional branches necessary for handling
outer/inner flags).

Cleanup OVS shared code and only set these flags in netdev-dpdk.c.

Signed-off-by: David Marchand <david.marchand@redhat.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
This commit is contained in:
David Marchand 2025-06-17 09:20:53 +02:00 committed by Ilya Maximets
parent 52fdeda11a
commit 19ef1b1f0f
9 changed files with 80 additions and 198 deletions

View File

@ -81,16 +81,12 @@ Rules
5) The ingress packet parser can only set ``DP_PACKET_OL_TX_IP_CKSUM`` if the 5) The ingress packet parser can only set ``DP_PACKET_OL_TX_IP_CKSUM`` if the
packet has ``DP_PACKET_OL_RX_IP_CKSUM_GOOD`` to not violate rule #2. packet has ``DP_PACKET_OL_RX_IP_CKSUM_GOOD`` to not violate rule #2.
6) Packet with flag ``DP_PACKET_OL_TX_IPV4`` is an IPv4 packet. 6) Packet with flag ``DP_PACKET_OL_TX_IP_CKSUM`` tells the datapath to skip
7) Packet with flag ``DP_PACKET_OL_TX_IPV6`` is an IPv6 packet.
8) Packet with flag ``DP_PACKET_OL_TX_IP_CKSUM`` tells the datapath to skip
updating the IP checksum if the packet is modified. The IP checksum will be updating the IP checksum if the packet is modified. The IP checksum will be
calculated by the egress interface if that supports IP checksum offload, calculated by the egress interface if that supports IP checksum offload,
otherwise the IP checksum will be performed in software before handing over otherwise the IP checksum will be performed in software before handing over
the packet to the interface. the packet to the interface.
9) When there are modifications to the packet that requires a checksum update, 7) When there are modifications to the packet that requires a checksum update,
the datapath needs to remove the ``DP_PACKET_OL_RX_IP_CKSUM_GOOD`` flag, the datapath needs to remove the ``DP_PACKET_OL_RX_IP_CKSUM_GOOD`` flag,
otherwise the checksum is assumed to be good in the packet. otherwise the checksum is assumed to be good in the packet.

View File

@ -95,6 +95,7 @@ dp_packet_gso(struct dp_packet *p, struct dp_packet_batch **batches)
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
struct dp_packet_batch *curr_batch = *batches; struct dp_packet_batch *curr_batch = *batches;
struct tcp_header *tcp_hdr; struct tcp_header *tcp_hdr;
struct ip_header *ip_hdr;
uint16_t inner_ip_id = 0; uint16_t inner_ip_id = 0;
uint16_t outer_ip_id = 0; uint16_t outer_ip_id = 0;
struct dp_packet *seg; struct dp_packet *seg;
@ -116,24 +117,20 @@ dp_packet_gso(struct dp_packet *p, struct dp_packet_batch **batches)
} }
if (udp_tnl || gre_tnl) { if (udp_tnl || gre_tnl) {
outer_ipv4 = dp_packet_hwol_is_outer_ipv4(p); ip_hdr = dp_packet_inner_l3(p);
tcp_hdr = dp_packet_inner_l4(p); if (IP_VER(ip_hdr->ip_ihl_ver) == 4) {
if (outer_ipv4) {
outer_ip_id = ntohs(((struct ip_header *) dp_packet_l3(p))->ip_id);
}
if (dp_packet_hwol_is_ipv4(p)) {
struct ip_header *ip_hdr = dp_packet_inner_l3(p);
inner_ip_id = ntohs(ip_hdr->ip_id); inner_ip_id = ntohs(ip_hdr->ip_id);
} }
} else {
outer_ipv4 = dp_packet_hwol_is_ipv4(p);
tcp_hdr = dp_packet_l4(p);
if (outer_ipv4) { tcp_hdr = dp_packet_inner_l4(p);
struct ip_header *ip_hdr = dp_packet_l3(p); } else {
outer_ip_id = ntohs(ip_hdr->ip_id); tcp_hdr = dp_packet_l4(p);
} }
ip_hdr = dp_packet_l3(p);
outer_ipv4 = IP_VER(ip_hdr->ip_ihl_ver) == 4;
if (outer_ipv4) {
outer_ip_id = ntohs(ip_hdr->ip_id);
} }
tcp_offset = TCP_OFFSET(tcp_hdr->tcp_ctl); tcp_offset = TCP_OFFSET(tcp_hdr->tcp_ctl);
@ -164,8 +161,8 @@ dp_packet_gso(struct dp_packet *p, struct dp_packet_batch **batches)
if (udp_tnl || gre_tnl) { if (udp_tnl || gre_tnl) {
/* Update tunnel inner L3 header. */ /* Update tunnel inner L3 header. */
if (dp_packet_hwol_is_ipv4(seg)) { ip_hdr = dp_packet_inner_l3(seg);
struct ip_header *ip_hdr = dp_packet_inner_l3(seg); if (IP_VER(ip_hdr->ip_ihl_ver) == 4) {
ip_hdr->ip_tot_len = htons(dp_packet_inner_l3_size(seg)); ip_hdr->ip_tot_len = htons(dp_packet_inner_l3_size(seg));
ip_hdr->ip_id = htons(inner_ip_id); ip_hdr->ip_id = htons(inner_ip_id);
ip_hdr->ip_csum = 0; ip_hdr->ip_csum = 0;
@ -181,7 +178,7 @@ dp_packet_gso(struct dp_packet *p, struct dp_packet_batch **batches)
/* Update L3 header. */ /* Update L3 header. */
if (outer_ipv4) { if (outer_ipv4) {
struct ip_header *ip_hdr = dp_packet_l3(seg); ip_hdr = dp_packet_l3(seg);
ip_hdr->ip_tot_len = htons(dp_packet_l3_size(seg)); ip_hdr->ip_tot_len = htons(dp_packet_l3_size(seg));
ip_hdr->ip_id = htons(outer_ip_id); ip_hdr->ip_id = htons(outer_ip_id);
ip_hdr->ip_csum = 0; ip_hdr->ip_csum = 0;

View File

@ -74,10 +74,6 @@ enum dp_packet_offload_mask {
0x20), 0x20),
/* TCP Segmentation Offload. */ /* TCP Segmentation Offload. */
DEF_OL_FLAG(DP_PACKET_OL_TX_TCP_SEG, RTE_MBUF_F_TX_TCP_SEG, 0x40), DEF_OL_FLAG(DP_PACKET_OL_TX_TCP_SEG, RTE_MBUF_F_TX_TCP_SEG, 0x40),
/* Offloaded packet is IPv4. */
DEF_OL_FLAG(DP_PACKET_OL_TX_IPV4, RTE_MBUF_F_TX_IPV4, 0x80),
/* Offloaded packet is IPv6. */
DEF_OL_FLAG(DP_PACKET_OL_TX_IPV6, RTE_MBUF_F_TX_IPV6, 0x100),
/* Offload TCP checksum. */ /* Offload TCP checksum. */
DEF_OL_FLAG(DP_PACKET_OL_TX_TCP_CKSUM, RTE_MBUF_F_TX_TCP_CKSUM, 0x200), DEF_OL_FLAG(DP_PACKET_OL_TX_TCP_CKSUM, RTE_MBUF_F_TX_TCP_CKSUM, 0x200),
/* Offload UDP checksum. */ /* Offload UDP checksum. */
@ -92,18 +88,12 @@ enum dp_packet_offload_mask {
/* Offload packet is tunnel VXLAN. */ /* Offload packet is tunnel VXLAN. */
DEF_OL_FLAG(DP_PACKET_OL_TX_TUNNEL_VXLAN, DEF_OL_FLAG(DP_PACKET_OL_TX_TUNNEL_VXLAN,
RTE_MBUF_F_TX_TUNNEL_VXLAN, 0x4000), RTE_MBUF_F_TX_TUNNEL_VXLAN, 0x4000),
/* Offload tunnel packet, outer header is IPv4. */
DEF_OL_FLAG(DP_PACKET_OL_TX_OUTER_IPV4,
RTE_MBUF_F_TX_OUTER_IPV4, 0x8000),
/* Offload tunnel outer IPv4 checksum. */ /* Offload tunnel outer IPv4 checksum. */
DEF_OL_FLAG(DP_PACKET_OL_TX_OUTER_IP_CKSUM, DEF_OL_FLAG(DP_PACKET_OL_TX_OUTER_IP_CKSUM,
RTE_MBUF_F_TX_OUTER_IP_CKSUM, 0x10000), RTE_MBUF_F_TX_OUTER_IP_CKSUM, 0x10000),
/* Offload tunnel outer UDP checksum. */ /* Offload tunnel outer UDP checksum. */
DEF_OL_FLAG(DP_PACKET_OL_TX_OUTER_UDP_CKSUM, DEF_OL_FLAG(DP_PACKET_OL_TX_OUTER_UDP_CKSUM,
RTE_MBUF_F_TX_OUTER_UDP_CKSUM, 0x20000), RTE_MBUF_F_TX_OUTER_UDP_CKSUM, 0x20000),
/* Offload tunnel packet, outer header is IPv6. */
DEF_OL_FLAG(DP_PACKET_OL_TX_OUTER_IPV6,
RTE_MBUF_F_TX_OUTER_IPV6, 0x40000),
/* Offload packet is GRE tunnel. */ /* Offload packet is GRE tunnel. */
DEF_OL_FLAG(DP_PACKET_OL_TX_TUNNEL_GRE, DEF_OL_FLAG(DP_PACKET_OL_TX_TUNNEL_GRE,
RTE_MBUF_F_TX_TUNNEL_GRE, 0x80000), RTE_MBUF_F_TX_TUNNEL_GRE, 0x80000),
@ -118,8 +108,6 @@ enum dp_packet_offload_mask {
DP_PACKET_OL_RX_L4_CKSUM_GOOD | \ DP_PACKET_OL_RX_L4_CKSUM_GOOD | \
DP_PACKET_OL_RX_IP_CKSUM_GOOD | \ DP_PACKET_OL_RX_IP_CKSUM_GOOD | \
DP_PACKET_OL_TX_TCP_SEG | \ DP_PACKET_OL_TX_TCP_SEG | \
DP_PACKET_OL_TX_IPV4 | \
DP_PACKET_OL_TX_IPV6 | \
DP_PACKET_OL_TX_TCP_CKSUM | \ DP_PACKET_OL_TX_TCP_CKSUM | \
DP_PACKET_OL_TX_UDP_CKSUM | \ DP_PACKET_OL_TX_UDP_CKSUM | \
DP_PACKET_OL_TX_SCTP_CKSUM | \ DP_PACKET_OL_TX_SCTP_CKSUM | \
@ -127,10 +115,8 @@ enum dp_packet_offload_mask {
DP_PACKET_OL_TX_TUNNEL_GENEVE | \ DP_PACKET_OL_TX_TUNNEL_GENEVE | \
DP_PACKET_OL_TX_TUNNEL_VXLAN | \ DP_PACKET_OL_TX_TUNNEL_VXLAN | \
DP_PACKET_OL_TX_TUNNEL_GRE | \ DP_PACKET_OL_TX_TUNNEL_GRE | \
DP_PACKET_OL_TX_OUTER_IPV4 | \
DP_PACKET_OL_TX_OUTER_IP_CKSUM | \ DP_PACKET_OL_TX_OUTER_IP_CKSUM | \
DP_PACKET_OL_TX_OUTER_UDP_CKSUM | \ DP_PACKET_OL_TX_OUTER_UDP_CKSUM)
DP_PACKET_OL_TX_OUTER_IPV6)
#define DP_PACKET_OL_TX_L4_MASK (DP_PACKET_OL_TX_TCP_CKSUM | \ #define DP_PACKET_OL_TX_L4_MASK (DP_PACKET_OL_TX_TCP_CKSUM | \
DP_PACKET_OL_TX_UDP_CKSUM | \ DP_PACKET_OL_TX_UDP_CKSUM | \
@ -1113,20 +1099,6 @@ dp_packet_hwol_is_tso(const struct dp_packet *b)
return !!(*dp_packet_ol_flags_ptr(b) & DP_PACKET_OL_TX_TCP_SEG); return !!(*dp_packet_ol_flags_ptr(b) & DP_PACKET_OL_TX_TCP_SEG);
} }
/* Returns 'true' if packet 'b' is marked for IPv4 checksum offloading. */
static inline bool
dp_packet_hwol_is_ipv4(const struct dp_packet *b)
{
return !!(*dp_packet_ol_flags_ptr(b) & DP_PACKET_OL_TX_IPV4);
}
/* Returns 'true' if packet 'p' is marked as IPv6. */
static inline bool
dp_packet_hwol_tx_ipv6(const struct dp_packet *p)
{
return !!(*dp_packet_ol_flags_ptr(p) & DP_PACKET_OL_TX_IPV6);
}
/* Returns 'true' if packet 'b' is marked for TCP checksum offloading. */ /* Returns 'true' if packet 'b' is marked for TCP checksum offloading. */
static inline bool static inline bool
dp_packet_hwol_l4_is_tcp(const struct dp_packet *b) dp_packet_hwol_l4_is_tcp(const struct dp_packet *b)
@ -1151,20 +1123,6 @@ dp_packet_hwol_l4_is_sctp(struct dp_packet *b)
DP_PACKET_OL_TX_SCTP_CKSUM; DP_PACKET_OL_TX_SCTP_CKSUM;
} }
/* Returns 'true' if packet 'b' is marked as having an outer IPv6 header. */
static inline bool
dp_packet_hwol_is_outer_ipv6(const struct dp_packet *b)
{
return *dp_packet_ol_flags_ptr(b) & DP_PACKET_OL_TX_OUTER_IPV6;
}
/* Returns 'true' if packet 'b' is marked as having an outer IPv4 header. */
static inline bool
dp_packet_hwol_is_outer_ipv4(const struct dp_packet *b)
{
return *dp_packet_ol_flags_ptr(b) & DP_PACKET_OL_TX_OUTER_IPV4;
}
/* Returns 'true' if packet 'b' is marked for tunnel GENEVE /* Returns 'true' if packet 'b' is marked for tunnel GENEVE
* checksum offloading. */ * checksum offloading. */
static inline bool static inline bool
@ -1190,7 +1148,7 @@ dp_packet_hwol_is_tunnel_gre(struct dp_packet *b)
/* Returns true if packet 'b' has any offloadable tunnel type. */ /* Returns true if packet 'b' has any offloadable tunnel type. */
static inline bool static inline bool
dp_packet_hwol_is_tunnel(struct dp_packet *b) dp_packet_hwol_is_tunnel(const struct dp_packet *b)
{ {
return !!(*dp_packet_ol_flags_ptr(b) & (DP_PACKET_OL_TX_TUNNEL_VXLAN | return !!(*dp_packet_ol_flags_ptr(b) & (DP_PACKET_OL_TX_TUNNEL_VXLAN |
DP_PACKET_OL_TX_TUNNEL_GRE | DP_PACKET_OL_TX_TUNNEL_GRE |
@ -1224,30 +1182,6 @@ dp_packet_hwol_reset_tx_l4_csum(struct dp_packet *p)
*dp_packet_ol_flags_ptr(p) &= ~DP_PACKET_OL_TX_L4_MASK; *dp_packet_ol_flags_ptr(p) &= ~DP_PACKET_OL_TX_L4_MASK;
} }
/* Mark packet 'p' as IPv4. */
static inline void
dp_packet_hwol_set_tx_ipv4(struct dp_packet *p)
{
*dp_packet_ol_flags_ptr(p) &= ~DP_PACKET_OL_TX_IPV6;
*dp_packet_ol_flags_ptr(p) |= DP_PACKET_OL_TX_IPV4;
}
/* Mark packet 'a' as IPv6. */
static inline void
dp_packet_hwol_set_tx_ipv6(struct dp_packet *a)
{
*dp_packet_ol_flags_ptr(a) &= ~DP_PACKET_OL_TX_IPV4;
*dp_packet_ol_flags_ptr(a) |= DP_PACKET_OL_TX_IPV6;
}
/* Mark packet 'a' as a tunnel packet with outer IPv6 header. */
static inline void
dp_packet_hwol_set_tx_outer_ipv6(struct dp_packet *a)
{
*dp_packet_ol_flags_ptr(a) &= ~DP_PACKET_OL_TX_OUTER_IPV4;
*dp_packet_ol_flags_ptr(a) |= DP_PACKET_OL_TX_OUTER_IPV6;
}
/* Returns 'true' if packet 'p' is marked for IPv4 checksum offloading. */ /* Returns 'true' if packet 'p' is marked for IPv4 checksum offloading. */
static inline bool static inline bool
dp_packet_hwol_tx_ip_csum(const struct dp_packet *p) dp_packet_hwol_tx_ip_csum(const struct dp_packet *p)
@ -1322,13 +1256,6 @@ dp_packet_hwol_set_tunnel_gre(struct dp_packet *b)
*dp_packet_ol_flags_ptr(b) |= DP_PACKET_OL_TX_TUNNEL_GRE; *dp_packet_ol_flags_ptr(b) |= DP_PACKET_OL_TX_TUNNEL_GRE;
} }
/* Mark packet 'b' as a tunnel packet with outer IPv4 header. */
static inline void
dp_packet_hwol_set_tx_outer_ipv4(struct dp_packet *b)
{
*dp_packet_ol_flags_ptr(b) |= DP_PACKET_OL_TX_OUTER_IPV4;
}
/* Mark packet 'b' for csum offloading in outer IPv4 header. */ /* Mark packet 'b' for csum offloading in outer IPv4 header. */
static inline void static inline void
dp_packet_hwol_set_tx_outer_ipv4_csum(struct dp_packet *b) dp_packet_hwol_set_tx_outer_ipv4_csum(struct dp_packet *b)
@ -1362,24 +1289,31 @@ dp_packet_hwol_reset_tcp_seg(struct dp_packet *p)
{ {
uint64_t ol_flags = *dp_packet_ol_flags_ptr(p) uint64_t ol_flags = *dp_packet_ol_flags_ptr(p)
| DP_PACKET_OL_TX_TCP_CKSUM; | DP_PACKET_OL_TX_TCP_CKSUM;
const struct ip_header *ip_hdr;
ol_flags = ol_flags & ~(DP_PACKET_OL_TX_TCP_SEG ol_flags = ol_flags & ~(DP_PACKET_OL_TX_TCP_SEG
| DP_PACKET_OL_RX_L4_CKSUM_GOOD | DP_PACKET_OL_RX_L4_CKSUM_GOOD
| DP_PACKET_OL_RX_IP_CKSUM_GOOD); | DP_PACKET_OL_RX_IP_CKSUM_GOOD);
if (ol_flags & DP_PACKET_OL_TX_IPV4) { if (dp_packet_hwol_is_tunnel(p)) {
ip_hdr = dp_packet_inner_l3(p);
} else {
ip_hdr = dp_packet_l3(p);
}
if (IP_VER(ip_hdr->ip_ihl_ver) == 4) {
ol_flags |= DP_PACKET_OL_TX_IP_CKSUM; ol_flags |= DP_PACKET_OL_TX_IP_CKSUM;
} }
if (ol_flags & (DP_PACKET_OL_TX_TUNNEL_VXLAN | if (dp_packet_hwol_is_tunnel(p)) {
DP_PACKET_OL_TX_TUNNEL_GENEVE)) { ip_hdr = dp_packet_l3(p);
if (ol_flags & DP_PACKET_OL_TX_OUTER_IPV4) { if (IP_VER(ip_hdr->ip_ihl_ver) == 4) {
ol_flags |= DP_PACKET_OL_TX_OUTER_IP_CKSUM; ol_flags |= DP_PACKET_OL_TX_OUTER_IP_CKSUM;
} }
ol_flags |= DP_PACKET_OL_TX_OUTER_UDP_CKSUM;
} else if (ol_flags & DP_PACKET_OL_TX_TUNNEL_GRE && if (dp_packet_hwol_is_tunnel_geneve(p)
ol_flags & DP_PACKET_OL_TX_OUTER_IPV4) { || dp_packet_hwol_is_tunnel_vxlan(p)) {
ol_flags |= DP_PACKET_OL_TX_OUTER_IP_CKSUM; ol_flags |= DP_PACKET_OL_TX_OUTER_UDP_CKSUM;
}
} }
*dp_packet_ol_flags_ptr(p) = ol_flags; *dp_packet_ol_flags_ptr(p) = ol_flags;
@ -1430,9 +1364,14 @@ dp_packet_ol_set_ip_csum_bad(struct dp_packet *p)
static inline bool static inline bool
dp_packet_hwol_l3_csum_ipv4_ol(const struct dp_packet *b) dp_packet_hwol_l3_csum_ipv4_ol(const struct dp_packet *b)
{ {
if (dp_packet_hwol_is_outer_ipv4(b)) { const struct ip_header *ip_hdr;
return dp_packet_hwol_is_outer_ipv4_cksum(b);
} else if (!dp_packet_hwol_is_outer_ipv6(b)) { if (dp_packet_hwol_is_tunnel(b)) {
ip_hdr = dp_packet_l3(b);
if (IP_VER(ip_hdr->ip_ihl_ver) == 4) {
return dp_packet_hwol_is_outer_ipv4_cksum(b);
}
} else {
return dp_packet_hwol_tx_ip_csum(b) && return dp_packet_hwol_tx_ip_csum(b) &&
!dp_packet_ip_checksum_good(b); !dp_packet_ip_checksum_good(b);
} }
@ -1446,9 +1385,12 @@ dp_packet_hwol_l3_csum_ipv4_ol(const struct dp_packet *b)
static inline bool static inline bool
dp_packet_hwol_l3_ipv4(const struct dp_packet *b) dp_packet_hwol_l3_ipv4(const struct dp_packet *b)
{ {
if (dp_packet_hwol_is_outer_ipv4(b)) { const struct ip_header *ip_hdr;
return true;
} else if (!dp_packet_hwol_is_outer_ipv6(b)) { if (dp_packet_hwol_is_tunnel(b)) {
ip_hdr = dp_packet_l3(b);
return IP_VER(ip_hdr->ip_ihl_ver) == 4;
} else {
return dp_packet_hwol_tx_ip_csum(b); return dp_packet_hwol_tx_ip_csum(b);
} }
return false; return false;

View File

@ -761,18 +761,11 @@ mfex_check_tcp_data_offset(const struct tcp_header *tcp)
static void static void
mfex_ipv4_set_hwol(struct dp_packet *pkt) mfex_ipv4_set_hwol(struct dp_packet *pkt)
{ {
dp_packet_hwol_set_tx_ipv4(pkt);
if (dp_packet_ip_checksum_good(pkt)) { if (dp_packet_ip_checksum_good(pkt)) {
dp_packet_hwol_set_tx_ip_csum(pkt); dp_packet_hwol_set_tx_ip_csum(pkt);
} }
} }
static void
mfex_ipv6_set_hwol(struct dp_packet *pkt)
{
dp_packet_hwol_set_tx_ipv6(pkt);
}
static void static void
mfex_tcp_set_hwol(struct dp_packet *pkt) mfex_tcp_set_hwol(struct dp_packet *pkt)
{ {
@ -956,7 +949,6 @@ mfex_avx512_process(struct dp_packet_batch *packets,
/* Process UDP header. */ /* Process UDP header. */
mfex_handle_ipv6_l4((void *)&pkt[54], &blocks[9]); mfex_handle_ipv6_l4((void *)&pkt[54], &blocks[9]);
dp_packet_update_rss_hash_ipv6_tcp_udp(packet); dp_packet_update_rss_hash_ipv6_tcp_udp(packet);
mfex_ipv6_set_hwol(packet);
mfex_udp_set_hwol(packet); mfex_udp_set_hwol(packet);
} break; } break;
@ -981,7 +973,6 @@ mfex_avx512_process(struct dp_packet_batch *packets,
} }
mfex_handle_tcp_flags(tcp, &blocks[9]); mfex_handle_tcp_flags(tcp, &blocks[9]);
dp_packet_update_rss_hash_ipv6_tcp_udp(packet); dp_packet_update_rss_hash_ipv6_tcp_udp(packet);
mfex_ipv6_set_hwol(packet);
mfex_tcp_set_hwol(packet); mfex_tcp_set_hwol(packet);
} break; } break;
@ -1009,7 +1000,6 @@ mfex_avx512_process(struct dp_packet_batch *packets,
} }
mfex_handle_tcp_flags(tcp, &blocks[10]); mfex_handle_tcp_flags(tcp, &blocks[10]);
dp_packet_update_rss_hash_ipv6_tcp_udp(packet); dp_packet_update_rss_hash_ipv6_tcp_udp(packet);
mfex_ipv6_set_hwol(packet);
mfex_tcp_set_hwol(packet); mfex_tcp_set_hwol(packet);
} break; } break;
@ -1032,7 +1022,6 @@ mfex_avx512_process(struct dp_packet_batch *packets,
/* Process UDP header. */ /* Process UDP header. */
mfex_handle_ipv6_l4((void *)&pkt[58], &blocks[10]); mfex_handle_ipv6_l4((void *)&pkt[58], &blocks[10]);
dp_packet_update_rss_hash_ipv6_tcp_udp(packet); dp_packet_update_rss_hash_ipv6_tcp_udp(packet);
mfex_ipv6_set_hwol(packet);
mfex_udp_set_hwol(packet); mfex_udp_set_hwol(packet);
} break; } break;

View File

@ -950,12 +950,10 @@ miniflow_extract(struct dp_packet *packet, struct miniflow *dst)
nw_frag = ipv4_get_nw_frag(nh); nw_frag = ipv4_get_nw_frag(nh);
data_pull(&data, &size, ip_len); data_pull(&data, &size, ip_len);
if (tunneling) { if (tunneling) {
dp_packet_hwol_set_tx_outer_ipv4(packet);
if (dp_packet_ip_checksum_good(packet)) { if (dp_packet_ip_checksum_good(packet)) {
dp_packet_hwol_set_tx_outer_ipv4_csum(packet); dp_packet_hwol_set_tx_outer_ipv4_csum(packet);
} }
} else { } else {
dp_packet_hwol_set_tx_ipv4(packet);
if (dp_packet_ip_checksum_good(packet)) { if (dp_packet_ip_checksum_good(packet)) {
dp_packet_hwol_set_tx_ip_csum(packet); dp_packet_hwol_set_tx_ip_csum(packet);
} }
@ -972,12 +970,6 @@ miniflow_extract(struct dp_packet *packet, struct miniflow *dst)
goto out; goto out;
} }
data_pull(&data, &size, sizeof *nh); data_pull(&data, &size, sizeof *nh);
if (tunneling) {
dp_packet_hwol_set_tx_outer_ipv6(packet);
} else {
dp_packet_hwol_set_tx_ipv6(packet);
}
plen = ntohs(nh->ip6_plen); plen = ntohs(nh->ip6_plen);
dp_packet_set_l2_pad_size(packet, size - plen); dp_packet_set_l2_pad_size(packet, size - plen);
size = plen; /* Never pull padding. */ size = plen; /* Never pull padding. */
@ -1268,7 +1260,6 @@ parse_tcp_flags(struct dp_packet *packet,
size = tot_len; /* Never pull padding. */ size = tot_len; /* Never pull padding. */
data_pull(&data, &size, ip_len); data_pull(&data, &size, ip_len);
dp_packet_hwol_set_tx_ipv4(packet);
if (dp_packet_ip_checksum_good(packet)) { if (dp_packet_ip_checksum_good(packet)) {
dp_packet_hwol_set_tx_ip_csum(packet); dp_packet_hwol_set_tx_ip_csum(packet);
} }
@ -1284,7 +1275,6 @@ parse_tcp_flags(struct dp_packet *packet,
} }
data_pull(&data, &size, sizeof *nh); data_pull(&data, &size, sizeof *nh);
dp_packet_hwol_set_tx_ipv6(packet);
plen = ntohs(nh->ip6_plen); /* Never pull padding. */ plen = ntohs(nh->ip6_plen); /* Never pull padding. */
dp_packet_set_l2_pad_size(packet, size - plen); dp_packet_set_l2_pad_size(packet, size - plen);
size = plen; size = plen;

View File

@ -2633,6 +2633,7 @@ static bool
netdev_dpdk_prep_hwol_packet(struct netdev_dpdk *dev, struct rte_mbuf *mbuf) netdev_dpdk_prep_hwol_packet(struct netdev_dpdk *dev, struct rte_mbuf *mbuf)
{ {
struct dp_packet *pkt = CONTAINER_OF(mbuf, struct dp_packet, mbuf); struct dp_packet *pkt = CONTAINER_OF(mbuf, struct dp_packet, mbuf);
const struct ip_header *ip;
void *l2; void *l2;
void *l3; void *l3;
void *l4; void *l4;
@ -2643,12 +2644,8 @@ netdev_dpdk_prep_hwol_packet(struct netdev_dpdk *dev, struct rte_mbuf *mbuf)
const uint64_t all_outer_requests = (RTE_MBUF_F_TX_OUTER_IP_CKSUM | const uint64_t all_outer_requests = (RTE_MBUF_F_TX_OUTER_IP_CKSUM |
RTE_MBUF_F_TX_OUTER_UDP_CKSUM); RTE_MBUF_F_TX_OUTER_UDP_CKSUM);
const uint64_t all_requests = all_inner_requests | all_outer_requests; const uint64_t all_requests = all_inner_requests | all_outer_requests;
const uint64_t all_inner_marks = (RTE_MBUF_F_TX_IPV4 | const uint64_t all_outer_marks = RTE_MBUF_F_TX_TUNNEL_MASK;
RTE_MBUF_F_TX_IPV6); const uint64_t all_marks = all_outer_marks;
const uint64_t all_outer_marks = (RTE_MBUF_F_TX_OUTER_IPV4 |
RTE_MBUF_F_TX_OUTER_IPV6 |
RTE_MBUF_F_TX_TUNNEL_MASK);
const uint64_t all_marks = all_inner_marks | all_outer_marks;
if (!(mbuf->ol_flags & all_requests)) { if (!(mbuf->ol_flags & all_requests)) {
/* No offloads requested, no marks should be set. */ /* No offloads requested, no marks should be set. */
@ -2684,6 +2681,11 @@ netdev_dpdk_prep_hwol_packet(struct netdev_dpdk *dev, struct rte_mbuf *mbuf)
mbuf->outer_l3_len = (char *) dp_packet_l4(pkt) - mbuf->outer_l3_len = (char *) dp_packet_l4(pkt) -
(char *) dp_packet_l3(pkt); (char *) dp_packet_l3(pkt);
ip = dp_packet_l3(pkt);
mbuf->ol_flags |= IP_VER(ip->ip_ihl_ver) == 4
? RTE_MBUF_F_TX_OUTER_IPV4
: RTE_MBUF_F_TX_OUTER_IPV6;
/* Inner L2 length must account for the tunnel header length. */ /* Inner L2 length must account for the tunnel header length. */
l2 = dp_packet_l4(pkt); l2 = dp_packet_l4(pkt);
l3 = dp_packet_inner_l3(pkt); l3 = dp_packet_inner_l3(pkt);
@ -2703,17 +2705,13 @@ netdev_dpdk_prep_hwol_packet(struct netdev_dpdk *dev, struct rte_mbuf *mbuf)
if (tunnel_type) { if (tunnel_type) {
/* No inner offload is requested, fallback to non tunnel /* No inner offload is requested, fallback to non tunnel
* checksum offloads. */ * checksum offloads. */
mbuf->ol_flags &= ~all_inner_marks;
if (mbuf->ol_flags & RTE_MBUF_F_TX_OUTER_IP_CKSUM) { if (mbuf->ol_flags & RTE_MBUF_F_TX_OUTER_IP_CKSUM) {
mbuf->ol_flags |= RTE_MBUF_F_TX_IP_CKSUM; mbuf->ol_flags |= RTE_MBUF_F_TX_IP_CKSUM;
mbuf->ol_flags |= RTE_MBUF_F_TX_IPV4;
} }
if (mbuf->ol_flags & RTE_MBUF_F_TX_OUTER_UDP_CKSUM) { if (mbuf->ol_flags & RTE_MBUF_F_TX_OUTER_UDP_CKSUM) {
mbuf->ol_flags |= RTE_MBUF_F_TX_UDP_CKSUM; mbuf->ol_flags |= RTE_MBUF_F_TX_UDP_CKSUM;
mbuf->ol_flags |= mbuf->ol_flags & RTE_MBUF_F_TX_OUTER_IPV4
? RTE_MBUF_F_TX_IPV4 : RTE_MBUF_F_TX_IPV6;
} }
mbuf->ol_flags &= ~(all_outer_requests | all_outer_marks); mbuf->ol_flags &= ~all_outer_requests;
} }
mbuf->outer_l2_len = 0; mbuf->outer_l2_len = 0;
mbuf->outer_l3_len = 0; mbuf->outer_l3_len = 0;
@ -2725,6 +2723,10 @@ netdev_dpdk_prep_hwol_packet(struct netdev_dpdk *dev, struct rte_mbuf *mbuf)
ovs_assert(l4); ovs_assert(l4);
ip = l3;
mbuf->ol_flags |= IP_VER(ip->ip_ihl_ver) == 4
? RTE_MBUF_F_TX_IPV4 : RTE_MBUF_F_TX_IPV6;
mbuf->l2_len = (char *) l3 - (char *) l2; mbuf->l2_len = (char *) l3 - (char *) l2;
mbuf->l3_len = (char *) l4 - (char *) l3; mbuf->l3_len = (char *) l4 - (char *) l3;

View File

@ -7141,10 +7141,14 @@ netdev_linux_prepend_vnet_hdr(struct dp_packet *b, int mtu)
if (dp_packet_hwol_is_tso(b)) { if (dp_packet_hwol_is_tso(b)) {
uint16_t tso_segsz = dp_packet_get_tso_segsz(b); uint16_t tso_segsz = dp_packet_get_tso_segsz(b);
struct tcp_header *tcp = dp_packet_l4(b); const struct tcp_header *tcp;
struct tcp_header *inner_tcp = dp_packet_inner_l4(b); const struct ip_header *ip;
if (inner_tcp) { if (dp_packet_inner_l4(b)) {
tcp = inner_tcp; tcp = dp_packet_inner_l4(b);
ip = dp_packet_inner_l3(b);
} else {
tcp = dp_packet_l4(b);
ip = dp_packet_l3(b);
} }
int tcp_hdr_len = TCP_OFFSET(tcp->tcp_ctl) * 4; int tcp_hdr_len = TCP_OFFSET(tcp->tcp_ctl) * 4;
int hdr_len = ((char *) tcp - (char *) dp_packet_eth(b)) int hdr_len = ((char *) tcp - (char *) dp_packet_eth(b))
@ -7160,9 +7164,9 @@ netdev_linux_prepend_vnet_hdr(struct dp_packet *b, int mtu)
vnet->hdr_len = (OVS_FORCE __virtio16)hdr_len; vnet->hdr_len = (OVS_FORCE __virtio16)hdr_len;
vnet->gso_size = (OVS_FORCE __virtio16)(tso_segsz); vnet->gso_size = (OVS_FORCE __virtio16)(tso_segsz);
if (dp_packet_hwol_is_ipv4(b)) { if (IP_VER(ip->ip_ihl_ver) == 4) {
vnet->gso_type = VIRTIO_NET_HDR_GSO_TCPV4; vnet->gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
} else if (dp_packet_hwol_tx_ipv6(b)) { } else if (IP_VER(ip->ip_ihl_ver) == 6) {
vnet->gso_type = VIRTIO_NET_HDR_GSO_TCPV6; vnet->gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
} else { } else {
VLOG_ERR_RL(&rl, "Unknown gso_type for TSO packet. " VLOG_ERR_RL(&rl, "Unknown gso_type for TSO packet. "
@ -7218,12 +7222,12 @@ netdev_linux_prepend_vnet_hdr(struct dp_packet *b, int mtu)
l4_off = dp_packet_l4(b); l4_off = dp_packet_l4(b);
} }
const struct ip_header *ip_hdr = l3_off;
struct tcp_header *tcp_hdr = l4_off; struct tcp_header *tcp_hdr = l4_off;
ovs_be16 csum = 0; ovs_be16 csum = 0;
if (dp_packet_hwol_is_ipv4(b)) { if (IP_VER(ip_hdr->ip_ihl_ver) == 4) {
const struct ip_header *ip_hdr = l3_off;
csum = ~csum_finish(packet_csum_pseudoheader(ip_hdr)); csum = ~csum_finish(packet_csum_pseudoheader(ip_hdr));
} else if (dp_packet_hwol_tx_ipv6(b)) { } else if (IP_VER(ip_hdr->ip_ihl_ver) == 6) {
const struct ovs_16aligned_ip6_hdr *ip6_hdr = l3_off; const struct ovs_16aligned_ip6_hdr *ip6_hdr = l3_off;
csum = ~csum_finish(packet_csum_pseudoheader6(ip6_hdr)); csum = ~csum_finish(packet_csum_pseudoheader6(ip6_hdr));
} }
@ -7243,14 +7247,13 @@ netdev_linux_prepend_vnet_hdr(struct dp_packet *b, int mtu)
l3_off = dp_packet_l3(b); l3_off = dp_packet_l3(b);
l4_off = dp_packet_l4(b); l4_off = dp_packet_l4(b);
} }
const struct ip_header *ip_hdr = l3_off;
struct udp_header *udp_hdr = l4_off; struct udp_header *udp_hdr = l4_off;
ovs_be16 csum = 0; ovs_be16 csum = 0;
if (IP_VER(ip_hdr->ip_ihl_ver) == 4) {
if (dp_packet_hwol_is_ipv4(b)) {
const struct ip_header *ip_hdr = l3_off;
csum = ~csum_finish(packet_csum_pseudoheader(ip_hdr)); csum = ~csum_finish(packet_csum_pseudoheader(ip_hdr));
} else if (dp_packet_hwol_tx_ipv6(b)) { } else if (IP_VER(ip_hdr->ip_ihl_ver) == 6) {
const struct ovs_16aligned_ip6_hdr *ip6_hdr = l3_off; const struct ovs_16aligned_ip6_hdr *ip6_hdr = l3_off;
csum = ~csum_finish(packet_csum_pseudoheader6(ip6_hdr)); csum = ~csum_finish(packet_csum_pseudoheader6(ip6_hdr));
} }

View File

@ -204,12 +204,6 @@ netdev_tnl_push_ip_header(struct dp_packet *packet, const void *header,
packet_set_ipv6_flow_label(&ip6->ip6_flow, ipv6_label); packet_set_ipv6_flow_label(&ip6->ip6_flow, ipv6_label);
packet->l4_ofs = dp_packet_size(packet) - *ip_tot_size; packet->l4_ofs = dp_packet_size(packet) - *ip_tot_size;
if (dp_packet_hwol_is_tunnel(packet)) {
dp_packet_hwol_set_tx_outer_ipv6(packet);
} else {
dp_packet_hwol_set_tx_ipv6(packet);
}
dp_packet_ol_reset_ip_csum_good(packet); dp_packet_ol_reset_ip_csum_good(packet);
return ip6 + 1; return ip6 + 1;
} else { } else {
@ -217,10 +211,8 @@ netdev_tnl_push_ip_header(struct dp_packet *packet, const void *header,
ip->ip_tot_len = htons(*ip_tot_size); ip->ip_tot_len = htons(*ip_tot_size);
/* Postpone checksum to when the packet is pushed to the port. */ /* Postpone checksum to when the packet is pushed to the port. */
if (dp_packet_hwol_is_tunnel(packet)) { if (dp_packet_hwol_is_tunnel(packet)) {
dp_packet_hwol_set_tx_outer_ipv4(packet);
dp_packet_hwol_set_tx_outer_ipv4_csum(packet); dp_packet_hwol_set_tx_outer_ipv4_csum(packet);
} else { } else {
dp_packet_hwol_set_tx_ipv4(packet);
dp_packet_hwol_set_tx_ip_csum(packet); dp_packet_hwol_set_tx_ip_csum(packet);
} }
@ -289,10 +281,7 @@ dp_packet_tnl_ol_process(struct dp_packet *packet,
data->tnl_type == OVS_VPORT_TYPE_IP6GRE) { data->tnl_type == OVS_VPORT_TYPE_IP6GRE) {
if (IP_VER(ip->ip_ihl_ver) == 4) { if (IP_VER(ip->ip_ihl_ver) == 4) {
dp_packet_hwol_set_tx_ipv4(packet);
dp_packet_hwol_set_tx_ip_csum(packet); dp_packet_hwol_set_tx_ip_csum(packet);
} else if (IP_VER(ip->ip_ihl_ver) == 6) {
dp_packet_hwol_set_tx_ipv6(packet);
} }
} }
} }

View File

@ -1999,7 +1999,6 @@ packet_tcp_complete_csum(struct dp_packet *p, bool inner)
struct tcp_header *tcp; struct tcp_header *tcp;
size_t tcp_sz; size_t tcp_sz;
void *ip_hdr; void *ip_hdr;
bool is_v4;
if (inner) { if (inner) {
tcp = dp_packet_inner_l4(p); tcp = dp_packet_inner_l4(p);
@ -2014,20 +2013,8 @@ packet_tcp_complete_csum(struct dp_packet *p, bool inner)
ovs_assert(tcp); ovs_assert(tcp);
ovs_assert(ip_hdr); ovs_assert(ip_hdr);
if (!inner && dp_packet_hwol_is_outer_ipv6(p)) {
is_v4 = false;
} else if (!inner && dp_packet_hwol_is_outer_ipv4(p)) {
is_v4 = true;
} else if (dp_packet_hwol_is_ipv4(p)) {
is_v4 = true;
} else if (dp_packet_hwol_tx_ipv6(p)) {
is_v4 = false;
} else {
OVS_NOT_REACHED();
}
tcp->tcp_csum = 0; tcp->tcp_csum = 0;
if (is_v4) { if (IP_VER(((const struct ip_header *) ip_hdr)->ip_ihl_ver) == 4) {
struct ip_header *ip = ip_hdr; struct ip_header *ip = ip_hdr;
tcp->tcp_csum = csum_finish(csum_continue(packet_csum_pseudoheader(ip), tcp->tcp_csum = csum_finish(csum_continue(packet_csum_pseudoheader(ip),
@ -2048,7 +2035,6 @@ packet_udp_complete_csum(struct dp_packet *p, bool inner)
struct udp_header *udp; struct udp_header *udp;
size_t udp_sz; size_t udp_sz;
void *ip_hdr; void *ip_hdr;
bool is_v4;
if (inner) { if (inner) {
udp = dp_packet_inner_l4(p); udp = dp_packet_inner_l4(p);
@ -2068,20 +2054,8 @@ packet_udp_complete_csum(struct dp_packet *p, bool inner)
return; return;
} }
if (!inner && dp_packet_hwol_is_outer_ipv6(p)) {
is_v4 = false;
} else if (!inner && dp_packet_hwol_is_outer_ipv4(p)) {
is_v4 = true;
} else if (dp_packet_hwol_is_ipv4(p)) {
is_v4 = true;
} else if (dp_packet_hwol_tx_ipv6(p)) {
is_v4 = false;
} else {
OVS_NOT_REACHED();
}
udp->udp_csum = 0; udp->udp_csum = 0;
if (is_v4) { if (IP_VER(((const struct ip_header *) ip_hdr)->ip_ihl_ver) == 4) {
struct ip_header *ip = ip_hdr; struct ip_header *ip = ip_hdr;
udp->udp_csum = csum_finish(csum_continue(packet_csum_pseudoheader(ip), udp->udp_csum = csum_finish(csum_continue(packet_csum_pseudoheader(ip),