mirror of
https://github.com/torvalds/linux.git
synced 2026-09-12 12:34:02 +02:00
idpf: account for VLAN header when parsing RSC packet header
While parsing the header of a Receive Side Coalesced (RSC) packet, check
if a VLAN tag is present and adjust the header parsing accordingly.
Otherwise, Rx TCP traffic is completely broken for any VLAN interface
whose underlying interface has RSC (rx-gro-hw) enabled.
We only need to worry about one VLAN header since Rx packets with
multiple VLAN headers are not candidates for RSC.
Fixes: 3a8845af66 ("idpf: add RX splitq napi poll support")
Signed-off-by: Joshua Hay <joshua.a.hay@intel.com>
Reviewed-by: Emil Tantilov <emil.s.tantilov@intel.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Tested-by: Samuel Salin <Samuel.salin@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
This commit is contained in:
parent
650f197d8e
commit
cc6d60ef92
|
|
@ -3299,6 +3299,7 @@ static int idpf_rx_rsc(struct idpf_rx_queue *rxq, struct sk_buff *skb,
|
|||
struct libeth_rx_pt decoded)
|
||||
{
|
||||
u16 rsc_segments, rsc_seg_len;
|
||||
u16 l3_start = 0;
|
||||
bool ipv4, ipv6;
|
||||
int len;
|
||||
|
||||
|
|
@ -3321,7 +3322,10 @@ static int idpf_rx_rsc(struct idpf_rx_queue *rxq, struct sk_buff *skb,
|
|||
NAPI_GRO_CB(skb)->count = rsc_segments;
|
||||
skb_shinfo(skb)->gso_size = rsc_seg_len;
|
||||
|
||||
skb_reset_network_header(skb);
|
||||
if (unlikely(eth_type_vlan(skb->protocol)))
|
||||
l3_start = VLAN_HLEN;
|
||||
|
||||
skb_set_network_header(skb, l3_start);
|
||||
|
||||
if (ipv4) {
|
||||
struct iphdr *ipv4h = ip_hdr(skb);
|
||||
|
|
@ -3329,7 +3333,7 @@ static int idpf_rx_rsc(struct idpf_rx_queue *rxq, struct sk_buff *skb,
|
|||
skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
|
||||
|
||||
/* Reset and set transport header offset in skb */
|
||||
skb_set_transport_header(skb, sizeof(struct iphdr));
|
||||
skb_set_transport_header(skb, l3_start + sizeof(struct iphdr));
|
||||
len = skb->len - skb_transport_offset(skb);
|
||||
|
||||
/* Compute the TCP pseudo header checksum*/
|
||||
|
|
@ -3339,7 +3343,7 @@ static int idpf_rx_rsc(struct idpf_rx_queue *rxq, struct sk_buff *skb,
|
|||
struct ipv6hdr *ipv6h = ipv6_hdr(skb);
|
||||
|
||||
skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6;
|
||||
skb_set_transport_header(skb, sizeof(struct ipv6hdr));
|
||||
skb_set_transport_header(skb, l3_start + sizeof(struct ipv6hdr));
|
||||
len = skb->len - skb_transport_offset(skb);
|
||||
tcp_hdr(skb)->check =
|
||||
~tcp_v6_check(len, &ipv6h->saddr, &ipv6h->daddr, 0);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user