mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-25 13:14:07 +08:00
i40e: Add support for MPLS + TSO
This change adds support for TSO of MPLS packets. In my tests with tcpdump it seems to work. Note this test setup has a 9000 byte MTU: MPLS (label 100, exp 0, [S], ttl 64) IP srcip.50086 > dstip.1234: Flags [P.], seq 593345:644401, ack 0, win 420, options [nop,nop,TS val 45022534 ecr 1722291395], length 51056 IP dstip.1234 > srcip.50086: Flags [.], ack 593345, win 122, options [nop,nop,TS val 1722291395 ecr 45022534], length 0 IP dstip.1234 > srcip.50086: Flags [.], ack 602289, win 105, options [nop,nop,TS val 1722291395 ecr 45022534], length 0 IP dstip.1234 > srcip.50086: Flags [.], ack 620177, win 71, options [nop,nop,TS val 1722291395 ecr 45022534], length 0 MPLS (label 100, exp 0, [S], ttl 64) IP srcip.50086 > dstip.1234: Flags [P.], seq 644401:655953, ack 0, win 420, options [nop,nop,TS val 45022534 ecr 1722291395], length 11552 IP dstip.1234 > srcip.50086: Flags [.], ack 638065, win 37, options [nop,nop,TS val 1722291395 ecr 45022534], length 0 IP dstip.1234 > srcip.50086: Flags [.], ack 644401, win 25, options [nop,nop,TS val 1722291395 ecr 45022534], length 0 IP dstip.1234 > srcip.50086: Flags [.], ack 653345, win 8, options [nop,nop,TS val 1722291395 ecr 45022534], length 0 IP dstip.1234 > srcip.50086: Flags [.], ack 655953, win 3, options [nop,nop,TS val 1722291395 ecr 45022534], length 0 Signed-off-by: Joe Damato <jdamato@fastly.com> Co-developed-by: Mike Gallo <mgallo@fastly.com> Signed-off-by: Mike Gallo <mgallo@fastly.com> Tested-by: Gurucharan <gurucharanx.g@intel.com> (A Contingent worker at Intel) Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
This commit is contained in:
parent
590032a4d2
commit
b4fb2d3351
@ -13436,8 +13436,7 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
|
||||
np->vsi = vsi;
|
||||
|
||||
hw_enc_features = NETIF_F_SG |
|
||||
NETIF_F_IP_CSUM |
|
||||
NETIF_F_IPV6_CSUM |
|
||||
NETIF_F_HW_CSUM |
|
||||
NETIF_F_HIGHDMA |
|
||||
NETIF_F_SOFT_FEATURES |
|
||||
NETIF_F_TSO |
|
||||
@ -13468,6 +13467,23 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
|
||||
/* record features VLANs can make use of */
|
||||
netdev->vlan_features |= hw_enc_features | NETIF_F_TSO_MANGLEID;
|
||||
|
||||
#define I40E_GSO_PARTIAL_FEATURES (NETIF_F_GSO_GRE | \
|
||||
NETIF_F_GSO_GRE_CSUM | \
|
||||
NETIF_F_GSO_IPXIP4 | \
|
||||
NETIF_F_GSO_IPXIP6 | \
|
||||
NETIF_F_GSO_UDP_TUNNEL | \
|
||||
NETIF_F_GSO_UDP_TUNNEL_CSUM)
|
||||
|
||||
netdev->gso_partial_features = I40E_GSO_PARTIAL_FEATURES;
|
||||
netdev->features |= NETIF_F_GSO_PARTIAL |
|
||||
I40E_GSO_PARTIAL_FEATURES;
|
||||
|
||||
netdev->mpls_features |= NETIF_F_SG;
|
||||
netdev->mpls_features |= NETIF_F_HW_CSUM;
|
||||
netdev->mpls_features |= NETIF_F_TSO;
|
||||
netdev->mpls_features |= NETIF_F_TSO6;
|
||||
netdev->mpls_features |= I40E_GSO_PARTIAL_FEATURES;
|
||||
|
||||
/* enable macvlan offloads */
|
||||
netdev->hw_features |= NETIF_F_HW_L2FW_DOFFLOAD;
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <linux/prefetch.h>
|
||||
#include <linux/bpf_trace.h>
|
||||
#include <net/mpls.h>
|
||||
#include <net/xdp.h>
|
||||
#include "i40e.h"
|
||||
#include "i40e_trace.h"
|
||||
@ -3015,6 +3016,7 @@ static int i40e_tso(struct i40e_tx_buffer *first, u8 *hdr_len,
|
||||
{
|
||||
struct sk_buff *skb = first->skb;
|
||||
u64 cd_cmd, cd_tso_len, cd_mss;
|
||||
__be16 protocol;
|
||||
union {
|
||||
struct iphdr *v4;
|
||||
struct ipv6hdr *v6;
|
||||
@ -3026,7 +3028,7 @@ static int i40e_tso(struct i40e_tx_buffer *first, u8 *hdr_len,
|
||||
unsigned char *hdr;
|
||||
} l4;
|
||||
u32 paylen, l4_offset;
|
||||
u16 gso_segs, gso_size;
|
||||
u16 gso_size;
|
||||
int err;
|
||||
|
||||
if (skb->ip_summed != CHECKSUM_PARTIAL)
|
||||
@ -3039,15 +3041,23 @@ static int i40e_tso(struct i40e_tx_buffer *first, u8 *hdr_len,
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
ip.hdr = skb_network_header(skb);
|
||||
l4.hdr = skb_transport_header(skb);
|
||||
protocol = vlan_get_protocol(skb);
|
||||
|
||||
if (eth_p_mpls(protocol))
|
||||
ip.hdr = skb_inner_network_header(skb);
|
||||
else
|
||||
ip.hdr = skb_network_header(skb);
|
||||
l4.hdr = skb_checksum_start(skb);
|
||||
|
||||
/* initialize outer IP header fields */
|
||||
if (ip.v4->version == 4) {
|
||||
ip.v4->tot_len = 0;
|
||||
ip.v4->check = 0;
|
||||
|
||||
first->tx_flags |= I40E_TX_FLAGS_TSO;
|
||||
} else {
|
||||
ip.v6->payload_len = 0;
|
||||
first->tx_flags |= I40E_TX_FLAGS_TSO;
|
||||
}
|
||||
|
||||
if (skb_shinfo(skb)->gso_type & (SKB_GSO_GRE |
|
||||
@ -3100,10 +3110,9 @@ static int i40e_tso(struct i40e_tx_buffer *first, u8 *hdr_len,
|
||||
|
||||
/* pull values out of skb_shinfo */
|
||||
gso_size = skb_shinfo(skb)->gso_size;
|
||||
gso_segs = skb_shinfo(skb)->gso_segs;
|
||||
|
||||
/* update GSO size and bytecount with header size */
|
||||
first->gso_segs = gso_segs;
|
||||
first->gso_segs = skb_shinfo(skb)->gso_segs;
|
||||
first->bytecount += (first->gso_segs - 1) * *hdr_len;
|
||||
|
||||
/* find the field values */
|
||||
@ -3187,13 +3196,27 @@ static int i40e_tx_enable_csum(struct sk_buff *skb, u32 *tx_flags,
|
||||
unsigned char *exthdr;
|
||||
u32 offset, cmd = 0;
|
||||
__be16 frag_off;
|
||||
__be16 protocol;
|
||||
u8 l4_proto = 0;
|
||||
|
||||
if (skb->ip_summed != CHECKSUM_PARTIAL)
|
||||
return 0;
|
||||
|
||||
ip.hdr = skb_network_header(skb);
|
||||
l4.hdr = skb_transport_header(skb);
|
||||
protocol = vlan_get_protocol(skb);
|
||||
|
||||
if (eth_p_mpls(protocol))
|
||||
ip.hdr = skb_inner_network_header(skb);
|
||||
else
|
||||
ip.hdr = skb_network_header(skb);
|
||||
l4.hdr = skb_checksum_start(skb);
|
||||
|
||||
/* set the tx_flags to indicate the IP protocol type. this is
|
||||
* required so that checksum header computation below is accurate.
|
||||
*/
|
||||
if (ip.v4->version == 4)
|
||||
*tx_flags |= I40E_TX_FLAGS_IPV4;
|
||||
else
|
||||
*tx_flags |= I40E_TX_FLAGS_IPV6;
|
||||
|
||||
/* compute outer L2 header size */
|
||||
offset = ((ip.hdr - skb->data) / 2) << I40E_TX_DESC_LENGTH_MACLEN_SHIFT;
|
||||
@ -3749,7 +3772,6 @@ static netdev_tx_t i40e_xmit_frame_ring(struct sk_buff *skb,
|
||||
struct i40e_tx_buffer *first;
|
||||
u32 td_offset = 0;
|
||||
u32 tx_flags = 0;
|
||||
__be16 protocol;
|
||||
u32 td_cmd = 0;
|
||||
u8 hdr_len = 0;
|
||||
int tso, count;
|
||||
@ -3791,15 +3813,6 @@ static netdev_tx_t i40e_xmit_frame_ring(struct sk_buff *skb,
|
||||
if (i40e_tx_prepare_vlan_flags(skb, tx_ring, &tx_flags))
|
||||
goto out_drop;
|
||||
|
||||
/* obtain protocol of skb */
|
||||
protocol = vlan_get_protocol(skb);
|
||||
|
||||
/* setup IPv4/IPv6 offloads */
|
||||
if (protocol == htons(ETH_P_IP))
|
||||
tx_flags |= I40E_TX_FLAGS_IPV4;
|
||||
else if (protocol == htons(ETH_P_IPV6))
|
||||
tx_flags |= I40E_TX_FLAGS_IPV6;
|
||||
|
||||
tso = i40e_tso(first, &hdr_len, &cd_type_cmd_tso_mss);
|
||||
|
||||
if (tso < 0)
|
||||
|
Loading…
Reference in New Issue
Block a user