mirror of
https://github.com/torvalds/linux.git
synced 2024-12-05 18:41:23 +00:00
ixgbe: ixgbe_atr() compute l4_proto only if non-paged data has network/transport headers
For some Tx paths (e.g., tpacket_snd()), ixgbe_atr may be passed down an sk_buff that has the network and transport header in the paged data, so it needs to make sure these headers are available in the headlen bytes to calculate the l4_proto. This patch expect that network and transport headers are already available in the non-paged header dat. The assumption is that the caller has set this up if l4_proto based Tx steering is desired. Signed-off-by: Sowmini Varadhan <sowmini.varadhan@oracle.com> Reviewed-by: Alexander Duyck <alexander.h.duyck@intel.com> Tested-by: Krishneil Singh <krishneil.k.singh@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
parent
520288218c
commit
9f3c7504fa
@ -54,6 +54,7 @@
|
|||||||
#include <net/pkt_cls.h>
|
#include <net/pkt_cls.h>
|
||||||
#include <net/tc_act/tc_gact.h>
|
#include <net/tc_act/tc_gact.h>
|
||||||
#include <net/tc_act/tc_mirred.h>
|
#include <net/tc_act/tc_mirred.h>
|
||||||
|
#include <net/vxlan.h>
|
||||||
|
|
||||||
#include "ixgbe.h"
|
#include "ixgbe.h"
|
||||||
#include "ixgbe_common.h"
|
#include "ixgbe_common.h"
|
||||||
@ -7660,11 +7661,17 @@ static void ixgbe_atr(struct ixgbe_ring *ring,
|
|||||||
/* snag network header to get L4 type and address */
|
/* snag network header to get L4 type and address */
|
||||||
skb = first->skb;
|
skb = first->skb;
|
||||||
hdr.network = skb_network_header(skb);
|
hdr.network = skb_network_header(skb);
|
||||||
|
if (unlikely(hdr.network <= skb->data))
|
||||||
|
return;
|
||||||
if (skb->encapsulation &&
|
if (skb->encapsulation &&
|
||||||
first->protocol == htons(ETH_P_IP) &&
|
first->protocol == htons(ETH_P_IP) &&
|
||||||
hdr.ipv4->protocol == IPPROTO_UDP) {
|
hdr.ipv4->protocol == IPPROTO_UDP) {
|
||||||
struct ixgbe_adapter *adapter = q_vector->adapter;
|
struct ixgbe_adapter *adapter = q_vector->adapter;
|
||||||
|
|
||||||
|
if (unlikely(skb_tail_pointer(skb) < hdr.network +
|
||||||
|
VXLAN_HEADROOM))
|
||||||
|
return;
|
||||||
|
|
||||||
/* verify the port is recognized as VXLAN */
|
/* verify the port is recognized as VXLAN */
|
||||||
if (adapter->vxlan_port &&
|
if (adapter->vxlan_port &&
|
||||||
udp_hdr(skb)->dest == adapter->vxlan_port)
|
udp_hdr(skb)->dest == adapter->vxlan_port)
|
||||||
@ -7675,6 +7682,12 @@ static void ixgbe_atr(struct ixgbe_ring *ring,
|
|||||||
hdr.network = skb_inner_network_header(skb);
|
hdr.network = skb_inner_network_header(skb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Make sure we have at least [minimum IPv4 header + TCP]
|
||||||
|
* or [IPv6 header] bytes
|
||||||
|
*/
|
||||||
|
if (unlikely(skb_tail_pointer(skb) < hdr.network + 40))
|
||||||
|
return;
|
||||||
|
|
||||||
/* Currently only IPv4/IPv6 with TCP is supported */
|
/* Currently only IPv4/IPv6 with TCP is supported */
|
||||||
switch (hdr.ipv4->version) {
|
switch (hdr.ipv4->version) {
|
||||||
case IPVERSION:
|
case IPVERSION:
|
||||||
@ -7694,6 +7707,10 @@ static void ixgbe_atr(struct ixgbe_ring *ring,
|
|||||||
if (l4_proto != IPPROTO_TCP)
|
if (l4_proto != IPPROTO_TCP)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (unlikely(skb_tail_pointer(skb) < hdr.network +
|
||||||
|
hlen + sizeof(struct tcphdr)))
|
||||||
|
return;
|
||||||
|
|
||||||
th = (struct tcphdr *)(hdr.network + hlen);
|
th = (struct tcphdr *)(hdr.network + hlen);
|
||||||
|
|
||||||
/* skip this packet since the socket is closing */
|
/* skip this packet since the socket is closing */
|
||||||
|
Loading…
Reference in New Issue
Block a user