mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-04-02 12:47:41 +08:00
Merge branch 'tcp_v6_gso_csum_prep'
Heiner Kallweit says: ==================== net: core: add helper tcp_v6_gso_csum_prep Several network drivers for chips that support TSO6 share the same code for preparing the TCP header, so let's factor it out to a helper. A difference is that some drivers reset the payload_len whilst others don't do this. This value is overwritten by TSO anyway, therefore the new helper resets it in general. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
@@ -1416,10 +1416,7 @@ static int alx_tso(struct sk_buff *skb, struct alx_txd *first)
|
||||
0, IPPROTO_TCP, 0);
|
||||
first->word1 |= 1 << TPD_IPV4_SHIFT;
|
||||
} else if (skb_is_gso_v6(skb)) {
|
||||
ipv6_hdr(skb)->payload_len = 0;
|
||||
tcp_hdr(skb)->check = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
|
||||
&ipv6_hdr(skb)->daddr,
|
||||
0, IPPROTO_TCP, 0);
|
||||
tcp_v6_gso_csum_prep(skb);
|
||||
/* LSOv2: the first TPD only provides the packet length */
|
||||
first->adrl.l.pkt_len = skb->len;
|
||||
first->word1 |= 1 << TPD_LSO_V2_SHIFT;
|
||||
|
||||
@@ -2025,10 +2025,8 @@ static int atl1c_tso_csum(struct atl1c_adapter *adapter,
|
||||
"IPV6 tso with zero data??\n");
|
||||
goto check_sum;
|
||||
} else
|
||||
tcp_hdr(skb)->check = ~csum_ipv6_magic(
|
||||
&ipv6_hdr(skb)->saddr,
|
||||
&ipv6_hdr(skb)->daddr,
|
||||
0, IPPROTO_TCP, 0);
|
||||
tcp_v6_gso_csum_prep(skb);
|
||||
|
||||
etpd->word1 |= 1 << TPD_LSO_EN_SHIFT;
|
||||
etpd->word1 |= 1 << TPD_LSO_VER_SHIFT;
|
||||
etpd->pkt_len = cpu_to_le32(skb->len);
|
||||
|
||||
@@ -2504,12 +2504,7 @@ bnad_tso_prepare(struct bnad *bnad, struct sk_buff *skb)
|
||||
IPPROTO_TCP, 0);
|
||||
BNAD_UPDATE_CTR(bnad, tso4);
|
||||
} else {
|
||||
struct ipv6hdr *ipv6h = ipv6_hdr(skb);
|
||||
|
||||
ipv6h->payload_len = 0;
|
||||
tcp_hdr(skb)->check =
|
||||
~csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr, 0,
|
||||
IPPROTO_TCP, 0);
|
||||
tcp_v6_gso_csum_prep(skb);
|
||||
BNAD_UPDATE_CTR(bnad, tso6);
|
||||
}
|
||||
|
||||
|
||||
@@ -696,8 +696,7 @@ static void enic_preload_tcp_csum(struct sk_buff *skb)
|
||||
tcp_hdr(skb)->check = ~csum_tcpudp_magic(ip_hdr(skb)->saddr,
|
||||
ip_hdr(skb)->daddr, 0, IPPROTO_TCP, 0);
|
||||
} else if (skb->protocol == cpu_to_be16(ETH_P_IPV6)) {
|
||||
tcp_hdr(skb)->check = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
|
||||
&ipv6_hdr(skb)->daddr, 0, IPPROTO_TCP, 0);
|
||||
tcp_v6_gso_csum_prep(skb);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2715,11 +2715,7 @@ static int e1000_tso(struct e1000_adapter *adapter,
|
||||
cmd_length = E1000_TXD_CMD_IP;
|
||||
ipcse = skb_transport_offset(skb) - 1;
|
||||
} else if (skb_is_gso_v6(skb)) {
|
||||
ipv6_hdr(skb)->payload_len = 0;
|
||||
tcp_hdr(skb)->check =
|
||||
~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
|
||||
&ipv6_hdr(skb)->daddr,
|
||||
0, IPPROTO_TCP, 0);
|
||||
tcp_v6_gso_csum_prep(skb);
|
||||
ipcse = 0;
|
||||
}
|
||||
ipcss = skb_network_offset(skb);
|
||||
|
||||
@@ -5462,10 +5462,7 @@ static int e1000_tso(struct e1000_ring *tx_ring, struct sk_buff *skb,
|
||||
cmd_length = E1000_TXD_CMD_IP;
|
||||
ipcse = skb_transport_offset(skb) - 1;
|
||||
} else if (skb_is_gso_v6(skb)) {
|
||||
ipv6_hdr(skb)->payload_len = 0;
|
||||
tcp_hdr(skb)->check = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
|
||||
&ipv6_hdr(skb)->daddr,
|
||||
0, IPPROTO_TCP, 0);
|
||||
tcp_v6_gso_csum_prep(skb);
|
||||
ipcse = 0;
|
||||
}
|
||||
ipcss = skb_network_offset(skb);
|
||||
|
||||
@@ -2077,12 +2077,7 @@ jme_tx_tso(struct sk_buff *skb, __le16 *mss, u8 *flags)
|
||||
IPPROTO_TCP,
|
||||
0);
|
||||
} else {
|
||||
struct ipv6hdr *ip6h = ipv6_hdr(skb);
|
||||
|
||||
tcp_hdr(skb)->check = ~csum_ipv6_magic(&ip6h->saddr,
|
||||
&ip6h->daddr, 0,
|
||||
IPPROTO_TCP,
|
||||
0);
|
||||
tcp_v6_gso_csum_prep(skb);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -632,10 +632,7 @@ static int ionic_tx_tcp_pseudo_csum(struct sk_buff *skb)
|
||||
ip_hdr(skb)->daddr,
|
||||
0, IPPROTO_TCP, 0);
|
||||
} else if (skb->protocol == cpu_to_be16(ETH_P_IPV6)) {
|
||||
tcp_hdr(skb)->check =
|
||||
~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
|
||||
&ipv6_hdr(skb)->daddr,
|
||||
0, IPPROTO_TCP, 0);
|
||||
tcp_v6_gso_csum_prep(skb);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -1288,11 +1288,8 @@ static int emac_tso_csum(struct emac_adapter *adpt,
|
||||
memset(tpd, 0, sizeof(*tpd));
|
||||
memset(&extra_tpd, 0, sizeof(extra_tpd));
|
||||
|
||||
ipv6_hdr(skb)->payload_len = 0;
|
||||
tcp_hdr(skb)->check =
|
||||
~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
|
||||
&ipv6_hdr(skb)->daddr,
|
||||
0, IPPROTO_TCP, 0);
|
||||
tcp_v6_gso_csum_prep(skb);
|
||||
|
||||
TPD_PKT_LEN_SET(&extra_tpd, skb->len);
|
||||
TPD_LSO_SET(&extra_tpd, 1);
|
||||
TPD_LSOV_SET(&extra_tpd, 1);
|
||||
|
||||
@@ -4108,29 +4108,6 @@ static bool rtl_test_hw_pad_bug(struct rtl8169_private *tp, struct sk_buff *skb)
|
||||
return skb->len < ETH_ZLEN && tp->mac_version == RTL_GIGA_MAC_VER_34;
|
||||
}
|
||||
|
||||
/* msdn_giant_send_check()
|
||||
* According to the document of microsoft, the TCP Pseudo Header excludes the
|
||||
* packet length for IPv6 TCP large packets.
|
||||
*/
|
||||
static int msdn_giant_send_check(struct sk_buff *skb)
|
||||
{
|
||||
const struct ipv6hdr *ipv6h;
|
||||
struct tcphdr *th;
|
||||
int ret;
|
||||
|
||||
ret = skb_cow_head(skb, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ipv6h = ipv6_hdr(skb);
|
||||
th = tcp_hdr(skb);
|
||||
|
||||
th->check = 0;
|
||||
th->check = ~tcp_v6_check(0, &ipv6h->saddr, &ipv6h->daddr, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void rtl8169_tso_csum_v1(struct sk_buff *skb, u32 *opts)
|
||||
{
|
||||
u32 mss = skb_shinfo(skb)->gso_size;
|
||||
@@ -4163,9 +4140,10 @@ static bool rtl8169_tso_csum_v2(struct rtl8169_private *tp,
|
||||
break;
|
||||
|
||||
case htons(ETH_P_IPV6):
|
||||
if (msdn_giant_send_check(skb))
|
||||
if (skb_cow_head(skb, 0))
|
||||
return false;
|
||||
|
||||
tcp_v6_gso_csum_prep(skb);
|
||||
opts[0] |= TD1_GTSENV6;
|
||||
break;
|
||||
|
||||
|
||||
@@ -1148,11 +1148,7 @@ static netdev_tx_t netsec_netdev_start_xmit(struct sk_buff *skb,
|
||||
~tcp_v4_check(0, ip_hdr(skb)->saddr,
|
||||
ip_hdr(skb)->daddr, 0);
|
||||
} else {
|
||||
ipv6_hdr(skb)->payload_len = 0;
|
||||
tcp_hdr(skb)->check =
|
||||
~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
|
||||
&ipv6_hdr(skb)->daddr,
|
||||
0, IPPROTO_TCP, 0);
|
||||
tcp_v6_gso_csum_prep(skb);
|
||||
}
|
||||
|
||||
tx_ctrl.tcp_seg_offload_flag = true;
|
||||
|
||||
@@ -638,10 +638,7 @@ static int netvsc_xmit(struct sk_buff *skb, struct net_device *net, bool xdp_tx)
|
||||
} else {
|
||||
lso_info->lso_v2_transmit.ip_version =
|
||||
NDIS_TCP_LARGE_SEND_OFFLOAD_IPV6;
|
||||
ipv6_hdr(skb)->payload_len = 0;
|
||||
tcp_hdr(skb)->check =
|
||||
~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
|
||||
&ipv6_hdr(skb)->daddr, 0, IPPROTO_TCP, 0);
|
||||
tcp_v6_gso_csum_prep(skb);
|
||||
}
|
||||
lso_info->lso_v2_transmit.tcp_header_offset = skb_transport_offset(skb);
|
||||
lso_info->lso_v2_transmit.mss = skb_shinfo(skb)->gso_size;
|
||||
|
||||
@@ -1948,29 +1948,6 @@ drop:
|
||||
}
|
||||
}
|
||||
|
||||
/* msdn_giant_send_check()
|
||||
* According to the document of microsoft, the TCP Pseudo Header excludes the
|
||||
* packet length for IPv6 TCP large packets.
|
||||
*/
|
||||
static int msdn_giant_send_check(struct sk_buff *skb)
|
||||
{
|
||||
const struct ipv6hdr *ipv6h;
|
||||
struct tcphdr *th;
|
||||
int ret;
|
||||
|
||||
ret = skb_cow_head(skb, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ipv6h = ipv6_hdr(skb);
|
||||
th = tcp_hdr(skb);
|
||||
|
||||
th->check = 0;
|
||||
th->check = ~tcp_v6_check(0, &ipv6h->saddr, &ipv6h->daddr, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void rtl_tx_vlan_tag(struct tx_desc *desc, struct sk_buff *skb)
|
||||
{
|
||||
if (skb_vlan_tag_present(skb)) {
|
||||
@@ -2016,10 +1993,11 @@ static int r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc,
|
||||
break;
|
||||
|
||||
case htons(ETH_P_IPV6):
|
||||
if (msdn_giant_send_check(skb)) {
|
||||
if (skb_cow_head(skb, 0)) {
|
||||
ret = TX_CSUM_TSO;
|
||||
goto unavailable;
|
||||
}
|
||||
tcp_v6_gso_csum_prep(skb);
|
||||
opts1 |= GTSENDV6;
|
||||
break;
|
||||
|
||||
|
||||
@@ -942,10 +942,7 @@ vmxnet3_prepare_tso(struct sk_buff *skb,
|
||||
tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, 0,
|
||||
IPPROTO_TCP, 0);
|
||||
} else if (ctx->ipv6) {
|
||||
struct ipv6hdr *iph = ipv6_hdr(skb);
|
||||
|
||||
tcph->check = ~csum_ipv6_magic(&iph->saddr, &iph->daddr, 0,
|
||||
IPPROTO_TCP, 0);
|
||||
tcp_v6_gso_csum_prep(skb);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -76,6 +76,15 @@ static inline void __tcp_v6_send_check(struct sk_buff *skb,
|
||||
}
|
||||
}
|
||||
|
||||
static inline void tcp_v6_gso_csum_prep(struct sk_buff *skb)
|
||||
{
|
||||
struct ipv6hdr *ipv6h = ipv6_hdr(skb);
|
||||
struct tcphdr *th = tcp_hdr(skb);
|
||||
|
||||
ipv6h->payload_len = 0;
|
||||
th->check = ~tcp_v6_check(0, &ipv6h->saddr, &ipv6h->daddr, 0);
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
static inline void tcp_v6_send_check(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user