* [PATCH net-next 1/8] net: Add skb_inner_transport_offset function
2015-12-14 19:19 [PATCH net-next 0/8] net: The beginning of the end for NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM Tom Herbert
@ 2015-12-14 19:19 ` Tom Herbert
2015-12-14 19:19 ` [PATCH net-next 2/8] sctp: Rename NETIF_F_SCTP_CSUM to NETIF_F_SCTP_CRC Tom Herbert
` (7 subsequent siblings)
8 siblings, 0 replies; 15+ messages in thread
From: Tom Herbert @ 2015-12-14 19:19 UTC (permalink / raw)
To: davem, netdev; +Cc: kernel-team
Same thing as skb_transport_offset but returns the offset of the inner
transport header (when skb->encpasulation is set).
Signed-off-by: Tom Herbert <tom@herbertland.com>
---
include/linux/skbuff.h | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 9b9b9ea..3f19744 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1939,6 +1939,11 @@ static inline unsigned char *skb_inner_transport_header(const struct sk_buff
return skb->head + skb->inner_transport_header;
}
+static inline int skb_inner_transport_offset(const struct sk_buff *skb)
+{
+ return skb_inner_transport_header(skb) - skb->data;
+}
+
static inline void skb_reset_inner_transport_header(struct sk_buff *skb)
{
skb->inner_transport_header = skb->data - skb->head;
--
2.4.6
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH net-next 2/8] sctp: Rename NETIF_F_SCTP_CSUM to NETIF_F_SCTP_CRC
2015-12-14 19:19 [PATCH net-next 0/8] net: The beginning of the end for NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM Tom Herbert
2015-12-14 19:19 ` [PATCH net-next 1/8] net: Add skb_inner_transport_offset function Tom Herbert
@ 2015-12-14 19:19 ` Tom Herbert
2015-12-14 19:19 ` [PATCH net-next 3/8] fcoe: Use CHECKSUM_PARTIAL to indicate CRC offload Tom Herbert
` (6 subsequent siblings)
8 siblings, 0 replies; 15+ messages in thread
From: Tom Herbert @ 2015-12-14 19:19 UTC (permalink / raw)
To: davem, netdev; +Cc: kernel-team
The SCTP checksum is really a CRC and is very different from the
standards 1's complement checksum that serves as the checksum
for IP protocols. This offload interface is also very different.
Rename NETIF_F_SCTP_CSUM to NETIF_F_SCTP_CRC to highlight these
differences. The term CSUM should be reserved in the stack to refer
to the standard 1's complement IP checksum.
Signed-off-by: Tom Herbert <tom@herbertland.com>
---
drivers/net/ethernet/intel/i40e/i40e_main.c | 2 +-
drivers/net/ethernet/intel/i40evf/i40evf_main.c | 2 +-
drivers/net/ethernet/intel/igb/igb_main.c | 4 ++--
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 4 ++--
drivers/net/loopback.c | 2 +-
include/linux/netdev_features.h | 4 ++--
net/8021q/vlan_dev.c | 2 +-
net/core/ethtool.c | 4 ++--
net/netfilter/ipvs/ip_vs_proto_sctp.c | 2 +-
net/sctp/output.c | 2 +-
10 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 2b1b655..6faa998 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -8796,7 +8796,7 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
netdev->features = NETIF_F_SG |
NETIF_F_IP_CSUM |
- NETIF_F_SCTP_CSUM |
+ NETIF_F_SCTP_CRC |
NETIF_F_HIGHDMA |
NETIF_F_GSO_UDP_TUNNEL |
NETIF_F_GSO_GRE |
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
index b4c632f..36b982c 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
@@ -2307,7 +2307,7 @@ int i40evf_process_config(struct i40evf_adapter *adapter)
netdev->features |= NETIF_F_HIGHDMA |
NETIF_F_SG |
NETIF_F_IP_CSUM |
- NETIF_F_SCTP_CSUM |
+ NETIF_F_SCTP_CRC |
NETIF_F_IPV6_CSUM |
NETIF_F_TSO |
NETIF_F_TSO6 |
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index ea7b098..1e21db3 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -2378,8 +2378,8 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
}
if (hw->mac.type >= e1000_82576) {
- netdev->hw_features |= NETIF_F_SCTP_CSUM;
- netdev->features |= NETIF_F_SCTP_CSUM;
+ netdev->hw_features |= NETIF_F_SCTP_CRC;
+ netdev->features |= NETIF_F_SCTP_CRC;
}
netdev->priv_flags |= IFF_UNICAST_FLT;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index ebd4522..62c7c8b 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -8829,8 +8829,8 @@ skip_sriov:
case ixgbe_mac_X540:
case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x:
- netdev->features |= NETIF_F_SCTP_CSUM;
- netdev->hw_features |= NETIF_F_SCTP_CSUM |
+ netdev->features |= NETIF_F_SCTP_CRC;
+ netdev->hw_features |= NETIF_F_SCTP_CRC |
NETIF_F_NTUPLE;
break;
default:
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
index dc7d970..a400288 100644
--- a/drivers/net/loopback.c
+++ b/drivers/net/loopback.c
@@ -175,7 +175,7 @@ static void loopback_setup(struct net_device *dev)
| NETIF_F_UFO
| NETIF_F_HW_CSUM
| NETIF_F_RXCSUM
- | NETIF_F_SCTP_CSUM
+ | NETIF_F_SCTP_CRC
| NETIF_F_HIGHDMA
| NETIF_F_LLTX
| NETIF_F_NETNS_LOCAL
diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h
index f0d8734..6395f83 100644
--- a/include/linux/netdev_features.h
+++ b/include/linux/netdev_features.h
@@ -52,7 +52,7 @@ enum {
NETIF_F_GSO_TUNNEL_REMCSUM_BIT,
NETIF_F_FCOE_CRC_BIT, /* FCoE CRC32 */
- NETIF_F_SCTP_CSUM_BIT, /* SCTP checksum offload */
+ NETIF_F_SCTP_CRC_BIT, /* SCTP checksum offload */
NETIF_F_FCOE_MTU_BIT, /* Supports max FCoE MTU, 2158 bytes*/
NETIF_F_NTUPLE_BIT, /* N-tuple filters supported */
NETIF_F_RXHASH_BIT, /* Receive hashing offload */
@@ -103,7 +103,7 @@ enum {
#define NETIF_F_NTUPLE __NETIF_F(NTUPLE)
#define NETIF_F_RXCSUM __NETIF_F(RXCSUM)
#define NETIF_F_RXHASH __NETIF_F(RXHASH)
-#define NETIF_F_SCTP_CSUM __NETIF_F(SCTP_CSUM)
+#define NETIF_F_SCTP_CRC __NETIF_F(SCTP_CRC)
#define NETIF_F_SG __NETIF_F(SG)
#define NETIF_F_TSO6 __NETIF_F(TSO6)
#define NETIF_F_TSO_ECN __NETIF_F(TSO_ECN)
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index fded865..c2bf37f 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -544,7 +544,7 @@ static int vlan_dev_init(struct net_device *dev)
dev->hw_features = NETIF_F_ALL_CSUM | NETIF_F_SG |
NETIF_F_FRAGLIST | NETIF_F_GSO_SOFTWARE |
- NETIF_F_HIGHDMA | NETIF_F_SCTP_CSUM |
+ NETIF_F_HIGHDMA | NETIF_F_SCTP_CRC |
NETIF_F_ALL_FCOE;
dev->features |= real_dev->vlan_features | NETIF_F_LLTX |
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 29edf74..4a0cab8 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -87,7 +87,7 @@ static const char netdev_features_strings[NETDEV_FEATURE_COUNT][ETH_GSTRING_LEN]
[NETIF_F_GSO_UDP_TUNNEL_BIT] = "tx-udp_tnl-segmentation",
[NETIF_F_FCOE_CRC_BIT] = "tx-checksum-fcoe-crc",
- [NETIF_F_SCTP_CSUM_BIT] = "tx-checksum-sctp",
+ [NETIF_F_SCTP_CRC_BIT] = "tx-checksum-sctp",
[NETIF_F_FCOE_MTU_BIT] = "fcoe-mtu",
[NETIF_F_NTUPLE_BIT] = "rx-ntuple-filter",
[NETIF_F_RXHASH_BIT] = "rx-hashing",
@@ -235,7 +235,7 @@ static netdev_features_t ethtool_get_feature_mask(u32 eth_cmd)
switch (eth_cmd) {
case ETHTOOL_GTXCSUM:
case ETHTOOL_STXCSUM:
- return NETIF_F_ALL_CSUM | NETIF_F_SCTP_CSUM;
+ return NETIF_F_ALL_CSUM | NETIF_F_SCTP_CRC;
case ETHTOOL_GRXCSUM:
case ETHTOOL_SRXCSUM:
return NETIF_F_RXCSUM;
diff --git a/net/netfilter/ipvs/ip_vs_proto_sctp.c b/net/netfilter/ipvs/ip_vs_proto_sctp.c
index 010ddee..d952d67 100644
--- a/net/netfilter/ipvs/ip_vs_proto_sctp.c
+++ b/net/netfilter/ipvs/ip_vs_proto_sctp.c
@@ -169,7 +169,7 @@ sctp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
/* Only update csum if we really have to */
if (sctph->dest != cp->dport || payload_csum ||
(skb->ip_summed == CHECKSUM_PARTIAL &&
- !(skb_dst(skb)->dev->features & NETIF_F_SCTP_CSUM))) {
+ !(skb_dst(skb)->dev->features & NETIF_F_SCTP_CRC))) {
sctph->dest = cp->dport;
sctp_nat_csum(skb, sctph, sctphoff);
} else if (skb->ip_summed != CHECKSUM_PARTIAL) {
diff --git a/net/sctp/output.c b/net/sctp/output.c
index abe7c2d..9d610ed 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -534,7 +534,7 @@ int sctp_packet_transmit(struct sctp_packet *packet)
* by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>.
*/
if (!sctp_checksum_disable) {
- if (!(dst->dev->features & NETIF_F_SCTP_CSUM) ||
+ if (!(dst->dev->features & NETIF_F_SCTP_CRC) ||
(dst_xfrm(dst) != NULL) || packet->ipfragok) {
sh->checksum = sctp_compute_cksum(nskb, 0);
} else {
--
2.4.6
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH net-next 3/8] fcoe: Use CHECKSUM_PARTIAL to indicate CRC offload
2015-12-14 19:19 [PATCH net-next 0/8] net: The beginning of the end for NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM Tom Herbert
2015-12-14 19:19 ` [PATCH net-next 1/8] net: Add skb_inner_transport_offset function Tom Herbert
2015-12-14 19:19 ` [PATCH net-next 2/8] sctp: Rename NETIF_F_SCTP_CSUM to NETIF_F_SCTP_CRC Tom Herbert
@ 2015-12-14 19:19 ` Tom Herbert
2015-12-14 19:19 ` [PATCH net-next 4/8] net: Rename NETIF_F_ALL_CSUM to NETIF_F_CSUM_MASK Tom Herbert
` (5 subsequent siblings)
8 siblings, 0 replies; 15+ messages in thread
From: Tom Herbert @ 2015-12-14 19:19 UTC (permalink / raw)
To: davem, netdev; +Cc: kernel-team
When setting up CRC offload set ip_summed to CHECKSUM_PARTIAL
instead of CHECKSUM_UNNECESSARY. This is consistent with the
definition of CHECKSUM_PARTIAL.
The only driver that seems to be advertising NETIF_F_FCOE_CRC is
ixgbe. AFICT the driver does not look at ip_summed for FCOE and
just assumes that CRC is being offloaded.
Signed-off-by: Tom Herbert <tom@herbertland.com>
---
drivers/scsi/fcoe/fcoe.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index f442406..0efe711 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -1625,7 +1625,7 @@ static int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp)
/* crc offload */
if (likely(lport->crc_offload)) {
- skb->ip_summed = CHECKSUM_UNNECESSARY;
+ skb->ip_summed = CHECKSUM_PARTIAL;
skb->csum_start = skb_headroom(skb);
skb->csum_offset = skb->len;
crc = 0;
--
2.4.6
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH net-next 4/8] net: Rename NETIF_F_ALL_CSUM to NETIF_F_CSUM_MASK
2015-12-14 19:19 [PATCH net-next 0/8] net: The beginning of the end for NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM Tom Herbert
` (2 preceding siblings ...)
2015-12-14 19:19 ` [PATCH net-next 3/8] fcoe: Use CHECKSUM_PARTIAL to indicate CRC offload Tom Herbert
@ 2015-12-14 19:19 ` Tom Herbert
2015-12-14 19:19 ` [PATCH net-next 5/8] net: Eliminate NETIF_F_GEN_CSUM and NETIF_F_V[46]_CSUM Tom Herbert
` (4 subsequent siblings)
8 siblings, 0 replies; 15+ messages in thread
From: Tom Herbert @ 2015-12-14 19:19 UTC (permalink / raw)
To: davem, netdev; +Cc: kernel-team
The name NETIF_F_ALL_CSUM is a misnomer. This does not correspond to the
set of features for offloading all checksums. This a mask of the
checksum offload related features bits. It is incorrect to set both
NETIF_F_HW_CSUM and NETIF_F_IP_CSUM or NETIF_F_IPV6 at the same time for
features of a device.
This patch:
- Changes instances of NETIF_F_ALL_CSUM to NETIF_F_CSUM_MASK (where
NETIF_F_ALL_CSUM is being used as a mask).
- Changes bonding, sfc/efx, ipvlan, macvlan, vlan, and team drivers to
use NEITF_F_HW_CSUM in features list instead of NETIF_F_ALL_CSUM.
Signed-off-by: Tom Herbert <tom@herbertland.com>
---
drivers/net/bonding/bond_main.c | 7 +++----
drivers/net/ethernet/emulex/benet/be_main.c | 2 +-
drivers/net/ethernet/ibm/ibmveth.c | 5 +++--
drivers/net/ethernet/intel/fm10k/fm10k_netdev.c | 2 +-
drivers/net/ethernet/intel/i40e/i40e_main.c | 2 +-
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 2 +-
drivers/net/ethernet/jme.c | 2 +-
drivers/net/ethernet/marvell/sky2.c | 2 +-
drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_param.c | 2 +-
drivers/net/ethernet/sfc/efx.c | 2 +-
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 ++--
drivers/net/ipvlan/ipvlan_main.c | 2 +-
drivers/net/macvlan.c | 2 +-
drivers/net/macvtap.c | 2 +-
drivers/net/team/team.c | 3 +--
drivers/net/usb/r8152.c | 2 +-
drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib.c | 2 +-
include/linux/netdev_features.h | 7 ++++++-
include/linux/netdevice.h | 6 +++---
include/net/vxlan.h | 2 +-
net/8021q/vlan_dev.c | 2 +-
net/core/dev.c | 10 +++++-----
net/core/ethtool.c | 2 +-
net/ipv4/tcp.c | 4 ++--
24 files changed, 41 insertions(+), 37 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index fe0e7a6..cab99fd 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1067,12 +1067,12 @@ static netdev_features_t bond_fix_features(struct net_device *dev,
return features;
}
-#define BOND_VLAN_FEATURES (NETIF_F_ALL_CSUM | NETIF_F_SG | \
+#define BOND_VLAN_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \
NETIF_F_FRAGLIST | NETIF_F_ALL_TSO | \
NETIF_F_HIGHDMA | NETIF_F_LRO)
-#define BOND_ENC_FEATURES (NETIF_F_ALL_CSUM | NETIF_F_SG | NETIF_F_RXCSUM |\
- NETIF_F_ALL_TSO)
+#define BOND_ENC_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \
+ NETIF_F_RXCSUM | NETIF_F_ALL_TSO)
static void bond_compute_features(struct bonding *bond)
{
@@ -4182,7 +4182,6 @@ void bond_setup(struct net_device *bond_dev)
NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_HW_VLAN_CTAG_FILTER;
- bond_dev->hw_features &= ~(NETIF_F_ALL_CSUM & ~NETIF_F_HW_CSUM);
bond_dev->hw_features |= NETIF_F_GSO_ENCAP_ALL;
bond_dev->features |= bond_dev->hw_features;
}
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 4cab887..34e324f 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -5289,7 +5289,7 @@ static netdev_features_t be_features_check(struct sk_buff *skb,
skb->inner_protocol != htons(ETH_P_TEB) ||
skb_inner_mac_header(skb) - skb_transport_header(skb) !=
sizeof(struct udphdr) + sizeof(struct vxlanhdr))
- return features & ~(NETIF_F_ALL_CSUM | NETIF_F_GSO_MASK);
+ return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
return features;
}
diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c
index 7af870a..6691b5a 100644
--- a/drivers/net/ethernet/ibm/ibmveth.c
+++ b/drivers/net/ethernet/ibm/ibmveth.c
@@ -763,7 +763,7 @@ static netdev_features_t ibmveth_fix_features(struct net_device *dev,
*/
if (!(features & NETIF_F_RXCSUM))
- features &= ~NETIF_F_ALL_CSUM;
+ features &= ~NETIF_F_CSUM_MASK;
return features;
}
@@ -928,7 +928,8 @@ static int ibmveth_set_features(struct net_device *dev,
rc1 = ibmveth_set_csum_offload(dev, rx_csum);
if (rc1 && !adapter->rx_csum)
dev->features =
- features & ~(NETIF_F_ALL_CSUM | NETIF_F_RXCSUM);
+ features & ~(NETIF_F_CSUM_MASK |
+ NETIF_F_RXCSUM);
}
if (large_send != adapter->large_send) {
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
index 79f6b7d..d4d23b3 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
@@ -1355,7 +1355,7 @@ static netdev_features_t fm10k_features_check(struct sk_buff *skb,
if (!skb->encapsulation || fm10k_tx_encap_offload(skb))
return features;
- return features & ~(NETIF_F_ALL_CSUM | NETIF_F_GSO_MASK);
+ return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
}
static const struct net_device_ops fm10k_netdev_ops = {
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 6faa998..701aa5a 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -8720,7 +8720,7 @@ static netdev_features_t i40e_features_check(struct sk_buff *skb,
if (skb->encapsulation &&
(skb_inner_mac_header(skb) - skb_transport_header(skb) >
I40E_MAX_TUNNEL_HDR_LEN))
- return features & ~(NETIF_F_ALL_CSUM | NETIF_F_GSO_MASK);
+ return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
return features;
}
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 62c7c8b..5edaec9 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -8432,7 +8432,7 @@ ixgbe_features_check(struct sk_buff *skb, struct net_device *dev,
if (unlikely(skb_inner_mac_header(skb) - skb_transport_header(skb) >
IXGBE_MAX_TUNNEL_HDR_LEN))
- return features & ~NETIF_F_ALL_CSUM;
+ return features & ~NETIF_F_CSUM_MASK;
return features;
}
diff --git a/drivers/net/ethernet/jme.c b/drivers/net/ethernet/jme.c
index 060dd39..b1de7af 100644
--- a/drivers/net/ethernet/jme.c
+++ b/drivers/net/ethernet/jme.c
@@ -2753,7 +2753,7 @@ static netdev_features_t
jme_fix_features(struct net_device *netdev, netdev_features_t features)
{
if (netdev->mtu > 1900)
- features &= ~(NETIF_F_ALL_TSO | NETIF_F_ALL_CSUM);
+ features &= ~(NETIF_F_ALL_TSO | NETIF_F_CSUM_MASK);
return features;
}
diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c
index 5606a04..ec0a221 100644
--- a/drivers/net/ethernet/marvell/sky2.c
+++ b/drivers/net/ethernet/marvell/sky2.c
@@ -4380,7 +4380,7 @@ static netdev_features_t sky2_fix_features(struct net_device *dev,
*/
if (dev->mtu > ETH_DATA_LEN && hw->chip_id == CHIP_ID_YUKON_EC_U) {
netdev_info(dev, "checksum offload not possible with jumbo frames\n");
- features &= ~(NETIF_F_TSO|NETIF_F_SG|NETIF_F_ALL_CSUM);
+ features &= ~(NETIF_F_TSO | NETIF_F_SG | NETIF_F_CSUM_MASK);
}
/* Some hardware requires receive checksum for RSS to work. */
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_param.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_param.c
index 08d4be6..e097e6b 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_param.c
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_param.c
@@ -500,7 +500,7 @@ void pch_gbe_check_options(struct pch_gbe_adapter *adapter)
val = XsumTX;
pch_gbe_validate_option(&val, &opt, adapter);
if (!val)
- dev->features &= ~NETIF_F_ALL_CSUM;
+ dev->features &= ~NETIF_F_CSUM_MASK;
}
{ /* Flow Control */
static const struct pch_gbe_option opt = {
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index b405349..1fe13c7 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -3131,7 +3131,7 @@ static int efx_pci_probe(struct pci_dev *pci_dev,
if (efx->type->offload_features & NETIF_F_V6_CSUM)
net_dev->features |= NETIF_F_TSO6;
/* Mask for features that also apply to VLAN devices */
- net_dev->vlan_features |= (NETIF_F_ALL_CSUM | NETIF_F_SG |
+ net_dev->vlan_features |= (NETIF_F_HW_CSUM | NETIF_F_SG |
NETIF_F_HIGHDMA | NETIF_F_ALL_TSO |
NETIF_F_RXCSUM);
/* All offloads can be toggled */
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 3c6549a..0b0fea7 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2402,7 +2402,7 @@ static netdev_features_t stmmac_fix_features(struct net_device *dev,
features &= ~NETIF_F_RXCSUM;
if (!priv->plat->tx_coe)
- features &= ~NETIF_F_ALL_CSUM;
+ features &= ~NETIF_F_CSUM_MASK;
/* Some GMAC devices have a bugged Jumbo frame support that
* needs to have the Tx COE disabled for oversized frames
@@ -2410,7 +2410,7 @@ static netdev_features_t stmmac_fix_features(struct net_device *dev,
* the TX csum insertionin the TDES and not use SF.
*/
if (priv->plat->bugged_jumbo && (dev->mtu > ETH_DATA_LEN))
- features &= ~NETIF_F_ALL_CSUM;
+ features &= ~NETIF_F_CSUM_MASK;
return features;
}
diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c
index a9268db..f94392d 100644
--- a/drivers/net/ipvlan/ipvlan_main.c
+++ b/drivers/net/ipvlan/ipvlan_main.c
@@ -88,7 +88,7 @@ static struct lock_class_key ipvlan_netdev_xmit_lock_key;
static struct lock_class_key ipvlan_netdev_addr_lock_key;
#define IPVLAN_FEATURES \
- (NETIF_F_SG | NETIF_F_ALL_CSUM | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | \
+ (NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | \
NETIF_F_GSO | NETIF_F_TSO | NETIF_F_UFO | NETIF_F_GSO_ROBUST | \
NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_GRO | NETIF_F_RXCSUM | \
NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_STAG_FILTER)
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 06c8bfe..ae3b486 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -762,7 +762,7 @@ static struct lock_class_key macvlan_netdev_addr_lock_key;
NETIF_F_GSO_ROBUST)
#define MACVLAN_FEATURES \
- (NETIF_F_SG | NETIF_F_ALL_CSUM | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | \
+ (NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | \
NETIF_F_GSO | NETIF_F_TSO | NETIF_F_UFO | NETIF_F_LRO | \
NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_GRO | NETIF_F_RXCSUM | \
NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_STAG_FILTER)
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
index 0fc5219..d636d05 100644
--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
@@ -388,7 +388,7 @@ static rx_handler_result_t macvtap_handle_frame(struct sk_buff **pskb)
* check, we either support them all or none.
*/
if (skb->ip_summed == CHECKSUM_PARTIAL &&
- !(features & NETIF_F_ALL_CSUM) &&
+ !(features & NETIF_F_CSUM_MASK) &&
skb_checksum_help(skb))
goto drop;
skb_queue_tail(&q->sk.sk_receive_queue, skb);
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index 059c0f6..915f60f 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -981,7 +981,7 @@ static void team_port_disable(struct team *team,
team_lower_state_changed(port);
}
-#define TEAM_VLAN_FEATURES (NETIF_F_ALL_CSUM | NETIF_F_SG | \
+#define TEAM_VLAN_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \
NETIF_F_FRAGLIST | NETIF_F_ALL_TSO | \
NETIF_F_HIGHDMA | NETIF_F_LRO)
@@ -2091,7 +2091,6 @@ static void team_setup(struct net_device *dev)
NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_HW_VLAN_CTAG_FILTER;
- dev->hw_features &= ~(NETIF_F_ALL_CSUM & ~NETIF_F_HW_CSUM);
dev->features |= dev->hw_features;
}
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index d9427ca..34642a9 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -1986,7 +1986,7 @@ rtl8152_features_check(struct sk_buff *skb, struct net_device *dev,
int offset = skb_transport_offset(skb);
if ((mss || skb->ip_summed == CHECKSUM_PARTIAL) && offset > max_offset)
- features &= ~(NETIF_F_ALL_CSUM | NETIF_F_GSO_MASK);
+ features &= ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
else if ((skb->len + sizeof(struct tx_desc)) > agg_buf_sz)
features &= ~NETIF_F_GSO_MASK;
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib.c
index 679785b..9de4f23 100644
--- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib.c
+++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib.c
@@ -69,7 +69,7 @@ ksocknal_lib_zc_capable(ksock_conn_t *conn)
/* ZC if the socket supports scatter/gather and doesn't need software
* checksums */
- return ((caps & NETIF_F_SG) != 0 && (caps & NETIF_F_ALL_CSUM) != 0);
+ return ((caps & NETIF_F_SG) != 0 && (caps & NETIF_F_CSUM_MASK) != 0);
}
int
diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h
index 6395f83..2c4e94a 100644
--- a/include/linux/netdev_features.h
+++ b/include/linux/netdev_features.h
@@ -149,7 +149,12 @@ enum {
#define NETIF_F_GEN_CSUM NETIF_F_HW_CSUM
#define NETIF_F_V4_CSUM (NETIF_F_GEN_CSUM | NETIF_F_IP_CSUM)
#define NETIF_F_V6_CSUM (NETIF_F_GEN_CSUM | NETIF_F_IPV6_CSUM)
-#define NETIF_F_ALL_CSUM (NETIF_F_V4_CSUM | NETIF_F_V6_CSUM)
+
+/* List of IP checksum features. Note that NETIF_HW_CSUM should not be
+ * set in features when NETIF_F_IP_CSUM or NETIF_F_IPV6_CSUM are set--
+ * this would be contradictory
+ */
+#define NETIF_F_CSUM_MASK (NETIF_F_V4_CSUM | NETIF_F_V6_CSUM)
#define NETIF_F_ALL_TSO (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 1bb21ff..a54223a 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -3763,12 +3763,12 @@ static inline netdev_features_t netdev_intersect_features(netdev_features_t f1,
netdev_features_t f2)
{
if (f1 & NETIF_F_GEN_CSUM)
- f1 |= (NETIF_F_ALL_CSUM & ~NETIF_F_GEN_CSUM);
+ f1 |= (NETIF_F_CSUM_MASK & ~NETIF_F_GEN_CSUM);
if (f2 & NETIF_F_GEN_CSUM)
- f2 |= (NETIF_F_ALL_CSUM & ~NETIF_F_GEN_CSUM);
+ f2 |= (NETIF_F_CSUM_MASK & ~NETIF_F_GEN_CSUM);
f1 &= f2;
if (f1 & NETIF_F_GEN_CSUM)
- f1 &= ~(NETIF_F_ALL_CSUM & ~NETIF_F_GEN_CSUM);
+ f1 &= ~(NETIF_F_CSUM_MASK & ~NETIF_F_GEN_CSUM);
return f1;
}
diff --git a/include/net/vxlan.h b/include/net/vxlan.h
index c1c899c..b5a1aec 100644
--- a/include/net/vxlan.h
+++ b/include/net/vxlan.h
@@ -232,7 +232,7 @@ static inline netdev_features_t vxlan_features_check(struct sk_buff *skb,
skb->inner_protocol != htons(ETH_P_TEB) ||
(skb_inner_mac_header(skb) - skb_transport_header(skb) !=
sizeof(struct udphdr) + sizeof(struct vxlanhdr))))
- return features & ~(NETIF_F_ALL_CSUM | NETIF_F_GSO_MASK);
+ return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
return features;
}
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index c2bf37f..58477d9 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -542,7 +542,7 @@ static int vlan_dev_init(struct net_device *dev)
(1<<__LINK_STATE_DORMANT))) |
(1<<__LINK_STATE_PRESENT);
- dev->hw_features = NETIF_F_ALL_CSUM | NETIF_F_SG |
+ dev->hw_features = NETIF_F_HW_CSUM | NETIF_F_SG |
NETIF_F_FRAGLIST | NETIF_F_GSO_SOFTWARE |
NETIF_F_HIGHDMA | NETIF_F_SCTP_CRC |
NETIF_F_ALL_FCOE;
diff --git a/net/core/dev.c b/net/core/dev.c
index 8f705fc..5a3b5a4 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2645,7 +2645,7 @@ static netdev_features_t harmonize_features(struct sk_buff *skb,
if (skb->ip_summed != CHECKSUM_NONE &&
!can_checksum_protocol(features, type)) {
- features &= ~NETIF_F_ALL_CSUM;
+ features &= ~NETIF_F_CSUM_MASK;
} else if (illegal_highdma(skb->dev, skb)) {
features &= ~NETIF_F_SG;
}
@@ -2792,7 +2792,7 @@ static struct sk_buff *validate_xmit_skb(struct sk_buff *skb, struct net_device
else
skb_set_transport_header(skb,
skb_checksum_start_offset(skb));
- if (!(features & NETIF_F_ALL_CSUM) &&
+ if (!(features & NETIF_F_CSUM_MASK) &&
skb_checksum_help(skb))
goto out_kfree_skb;
}
@@ -7572,15 +7572,15 @@ netdev_features_t netdev_increment_features(netdev_features_t all,
netdev_features_t one, netdev_features_t mask)
{
if (mask & NETIF_F_GEN_CSUM)
- mask |= NETIF_F_ALL_CSUM;
+ mask |= NETIF_F_CSUM_MASK;
mask |= NETIF_F_VLAN_CHALLENGED;
- all |= one & (NETIF_F_ONE_FOR_ALL|NETIF_F_ALL_CSUM) & mask;
+ all |= one & (NETIF_F_ONE_FOR_ALL | NETIF_F_CSUM_MASK) & mask;
all &= one | ~NETIF_F_ALL_FOR_ALL;
/* If one device supports hw checksumming, set for all. */
if (all & NETIF_F_GEN_CSUM)
- all &= ~(NETIF_F_ALL_CSUM & ~NETIF_F_GEN_CSUM);
+ all &= ~(NETIF_F_CSUM_MASK & ~NETIF_F_GEN_CSUM);
return all;
}
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 4a0cab8..09948a7 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -235,7 +235,7 @@ static netdev_features_t ethtool_get_feature_mask(u32 eth_cmd)
switch (eth_cmd) {
case ETHTOOL_GTXCSUM:
case ETHTOOL_STXCSUM:
- return NETIF_F_ALL_CSUM | NETIF_F_SCTP_CRC;
+ return NETIF_F_CSUM_MASK | NETIF_F_SCTP_CRC;
case ETHTOOL_GRXCSUM:
case ETHTOOL_SRXCSUM:
return NETIF_F_RXCSUM;
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index c82cca1..cf7ef7b 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1018,7 +1018,7 @@ int tcp_sendpage(struct sock *sk, struct page *page, int offset,
ssize_t res;
if (!(sk->sk_route_caps & NETIF_F_SG) ||
- !(sk->sk_route_caps & NETIF_F_ALL_CSUM))
+ !(sk->sk_route_caps & NETIF_F_CSUM_MASK))
return sock_no_sendpage(sk->sk_socket, page, offset, size,
flags);
@@ -1175,7 +1175,7 @@ new_segment:
/*
* Check whether we can use HW checksum.
*/
- if (sk->sk_route_caps & NETIF_F_ALL_CSUM)
+ if (sk->sk_route_caps & NETIF_F_CSUM_MASK)
skb->ip_summed = CHECKSUM_PARTIAL;
skb_entail(sk, skb);
--
2.4.6
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH net-next 5/8] net: Eliminate NETIF_F_GEN_CSUM and NETIF_F_V[46]_CSUM
2015-12-14 19:19 [PATCH net-next 0/8] net: The beginning of the end for NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM Tom Herbert
` (3 preceding siblings ...)
2015-12-14 19:19 ` [PATCH net-next 4/8] net: Rename NETIF_F_ALL_CSUM to NETIF_F_CSUM_MASK Tom Herbert
@ 2015-12-14 19:19 ` Tom Herbert
2015-12-14 19:19 ` [PATCH net-next 6/8] tcp: Fix conditions to determine checksum offload Tom Herbert
` (3 subsequent siblings)
8 siblings, 0 replies; 15+ messages in thread
From: Tom Herbert @ 2015-12-14 19:19 UTC (permalink / raw)
To: davem, netdev; +Cc: kernel-team
These netif flags are unnecessary convolutions. It is more
straightforward to just use NETIF_F_HW_CSUM, NETIF_F_IP_CSUM,
and NETIF_F_IPV6_CSUM directly.
This patch also:
- Cleans up can_checksum_protocol
- Simplifies netdev_intersect_features
Signed-off-by: Tom Herbert <tom@herbertland.com>
---
drivers/net/ethernet/sfc/efx.c | 2 +-
drivers/net/macvlan.c | 2 +-
include/linux/if_vlan.h | 2 +-
include/linux/netdev_features.h | 9 +++----
include/linux/netdevice.h | 40 ++++++++++++++++++++------------
net/core/dev.c | 12 +++++-----
net/core/pktgen.c | 4 ++--
net/ipv4/ip_output.c | 2 +-
net/ipv4/netfilter/nf_nat_l3proto_ipv4.c | 3 ++-
net/ipv4/udp.c | 3 ++-
net/ipv4/udp_offload.c | 5 ++--
net/ipv6/ip6_output.c | 2 +-
net/ipv6/netfilter/nf_nat_l3proto_ipv6.c | 3 ++-
13 files changed, 50 insertions(+), 39 deletions(-)
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index 1fe13c7..6f69743 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -3128,7 +3128,7 @@ static int efx_pci_probe(struct pci_dev *pci_dev,
net_dev->features |= (efx->type->offload_features | NETIF_F_SG |
NETIF_F_HIGHDMA | NETIF_F_TSO |
NETIF_F_RXCSUM);
- if (efx->type->offload_features & NETIF_F_V6_CSUM)
+ if (efx->type->offload_features & (NETIF_F_IPV6_CSUM | NETIF_F_HW_CSUM))
net_dev->features |= NETIF_F_TSO6;
/* Mask for features that also apply to VLAN devices */
net_dev->vlan_features |= (NETIF_F_HW_CSUM | NETIF_F_SG |
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index ae3b486..6a57a00 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -758,7 +758,7 @@ static struct lock_class_key macvlan_netdev_xmit_lock_key;
static struct lock_class_key macvlan_netdev_addr_lock_key;
#define ALWAYS_ON_FEATURES \
- (NETIF_F_SG | NETIF_F_GEN_CSUM | NETIF_F_GSO_SOFTWARE | NETIF_F_LLTX | \
+ (NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_GSO_SOFTWARE | NETIF_F_LLTX | \
NETIF_F_GSO_ROBUST)
#define MACVLAN_FEATURES \
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index 05f5879..a5f6ce6 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -621,7 +621,7 @@ static inline netdev_features_t vlan_features_check(const struct sk_buff *skb,
NETIF_F_SG |
NETIF_F_HIGHDMA |
NETIF_F_FRAGLIST |
- NETIF_F_GEN_CSUM |
+ NETIF_F_HW_CSUM |
NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_STAG_TX);
diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h
index 2c4e94a..d9654f0e 100644
--- a/include/linux/netdev_features.h
+++ b/include/linux/netdev_features.h
@@ -146,15 +146,12 @@ enum {
#define NETIF_F_GSO_SOFTWARE (NETIF_F_TSO | NETIF_F_TSO_ECN | \
NETIF_F_TSO6 | NETIF_F_UFO)
-#define NETIF_F_GEN_CSUM NETIF_F_HW_CSUM
-#define NETIF_F_V4_CSUM (NETIF_F_GEN_CSUM | NETIF_F_IP_CSUM)
-#define NETIF_F_V6_CSUM (NETIF_F_GEN_CSUM | NETIF_F_IPV6_CSUM)
-
-/* List of IP checksum features. Note that NETIF_HW_CSUM should not be
+/* List of IP checksum features. Note that NETIF_F_ HW_CSUM should not be
* set in features when NETIF_F_IP_CSUM or NETIF_F_IPV6_CSUM are set--
* this would be contradictory
*/
-#define NETIF_F_CSUM_MASK (NETIF_F_V4_CSUM | NETIF_F_V6_CSUM)
+#define NETIF_F_CSUM_MASK (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | \
+ NETIF_F_HW_CSUM)
#define NETIF_F_ALL_TSO (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index a54223a..283984b 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -3691,13 +3691,24 @@ __be16 skb_network_protocol(struct sk_buff *skb, int *depth);
static inline bool can_checksum_protocol(netdev_features_t features,
__be16 protocol)
{
- return ((features & NETIF_F_GEN_CSUM) ||
- ((features & NETIF_F_V4_CSUM) &&
- protocol == htons(ETH_P_IP)) ||
- ((features & NETIF_F_V6_CSUM) &&
- protocol == htons(ETH_P_IPV6)) ||
- ((features & NETIF_F_FCOE_CRC) &&
- protocol == htons(ETH_P_FCOE)));
+ if (protocol == htons(ETH_P_FCOE))
+ return !!(features & NETIF_F_FCOE_CRC);
+
+ /* Assume this is an IP checksum (not SCTP CRC) */
+
+ if (features & NETIF_F_HW_CSUM) {
+ /* Can checksum everything */
+ return true;
+ }
+
+ switch (protocol) {
+ case htons(ETH_P_IP):
+ return !!(features & NETIF_F_IP_CSUM);
+ case htons(ETH_P_IPV6):
+ return !!(features & NETIF_F_IPV6_CSUM);
+ default:
+ return false;
+ }
}
#ifdef CONFIG_BUG
@@ -3762,15 +3773,14 @@ void linkwatch_run_queue(void);
static inline netdev_features_t netdev_intersect_features(netdev_features_t f1,
netdev_features_t f2)
{
- if (f1 & NETIF_F_GEN_CSUM)
- f1 |= (NETIF_F_CSUM_MASK & ~NETIF_F_GEN_CSUM);
- if (f2 & NETIF_F_GEN_CSUM)
- f2 |= (NETIF_F_CSUM_MASK & ~NETIF_F_GEN_CSUM);
- f1 &= f2;
- if (f1 & NETIF_F_GEN_CSUM)
- f1 &= ~(NETIF_F_CSUM_MASK & ~NETIF_F_GEN_CSUM);
+ if ((f1 ^ f2) & NETIF_F_HW_CSUM) {
+ if (f1 & NETIF_F_HW_CSUM)
+ f1 |= (NETIF_F_IP_CSUM|NETIF_F_IP_CSUM);
+ else
+ f2 |= (NETIF_F_IP_CSUM|NETIF_F_IP_CSUM);
+ }
- return f1;
+ return f1 & f2;
}
static inline netdev_features_t netdev_get_wanted_features(
diff --git a/net/core/dev.c b/net/core/dev.c
index 5a3b5a4..45b013f 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -6467,9 +6467,9 @@ static netdev_features_t netdev_fix_features(struct net_device *dev,
/* UFO needs SG and checksumming */
if (features & NETIF_F_UFO) {
/* maybe split UFO into V4 and V6? */
- if (!((features & NETIF_F_GEN_CSUM) ||
- (features & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))
- == (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) {
+ if (!(features & NETIF_F_HW_CSUM) &&
+ ((features & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM)) !=
+ (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM))) {
netdev_dbg(dev,
"Dropping NETIF_F_UFO since no checksum offload features.\n");
features &= ~NETIF_F_UFO;
@@ -7571,7 +7571,7 @@ static int dev_cpu_callback(struct notifier_block *nfb,
netdev_features_t netdev_increment_features(netdev_features_t all,
netdev_features_t one, netdev_features_t mask)
{
- if (mask & NETIF_F_GEN_CSUM)
+ if (mask & NETIF_F_HW_CSUM)
mask |= NETIF_F_CSUM_MASK;
mask |= NETIF_F_VLAN_CHALLENGED;
@@ -7579,8 +7579,8 @@ netdev_features_t netdev_increment_features(netdev_features_t all,
all &= one | ~NETIF_F_ALL_FOR_ALL;
/* If one device supports hw checksumming, set for all. */
- if (all & NETIF_F_GEN_CSUM)
- all &= ~(NETIF_F_CSUM_MASK & ~NETIF_F_GEN_CSUM);
+ if (all & NETIF_F_HW_CSUM)
+ all &= ~(NETIF_F_CSUM_MASK & ~NETIF_F_HW_CSUM);
return all;
}
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index de8d5cc..2be1444 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -2898,7 +2898,7 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
if (!(pkt_dev->flags & F_UDPCSUM)) {
skb->ip_summed = CHECKSUM_NONE;
- } else if (odev->features & NETIF_F_V4_CSUM) {
+ } else if (odev->features & (NETIF_F_HW_CSUM | NETIF_F_IP_CSUM)) {
skb->ip_summed = CHECKSUM_PARTIAL;
skb->csum = 0;
udp4_hwcsum(skb, iph->saddr, iph->daddr);
@@ -3032,7 +3032,7 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
if (!(pkt_dev->flags & F_UDPCSUM)) {
skb->ip_summed = CHECKSUM_NONE;
- } else if (odev->features & NETIF_F_V6_CSUM) {
+ } else if (odev->features & (NETIF_F_HW_CSUM | NETIF_F_IPV6_CSUM)) {
skb->ip_summed = CHECKSUM_PARTIAL;
skb->csum_start = skb_transport_header(skb) - skb->head;
skb->csum_offset = offsetof(struct udphdr, check);
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index e0b94cd..568e2bc 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -911,7 +911,7 @@ static int __ip_append_data(struct sock *sk,
*/
if (transhdrlen &&
length + fragheaderlen <= mtu &&
- rt->dst.dev->features & NETIF_F_V4_CSUM &&
+ rt->dst.dev->features & (NETIF_F_HW_CSUM | NETIF_F_IP_CSUM) &&
!(flags & MSG_MORE) &&
!exthdrlen)
csummode = CHECKSUM_PARTIAL;
diff --git a/net/ipv4/netfilter/nf_nat_l3proto_ipv4.c b/net/ipv4/netfilter/nf_nat_l3proto_ipv4.c
index 5075b7e..61c7cc2 100644
--- a/net/ipv4/netfilter/nf_nat_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_nat_l3proto_ipv4.c
@@ -132,7 +132,8 @@ static void nf_nat_ipv4_csum_recalc(struct sk_buff *skb,
if (skb->ip_summed != CHECKSUM_PARTIAL) {
if (!(rt->rt_flags & RTCF_LOCAL) &&
- (!skb->dev || skb->dev->features & NETIF_F_V4_CSUM)) {
+ (!skb->dev || skb->dev->features &
+ (NETIF_F_IP_CSUM | NETIF_F_HW_CSUM))) {
skb->ip_summed = CHECKSUM_PARTIAL;
skb->csum_start = skb_headroom(skb) +
skb_network_offset(skb) +
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 0c7b0e6..8841e98 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -772,7 +772,8 @@ void udp_set_csum(bool nocheck, struct sk_buff *skb,
else if (skb_is_gso(skb))
uh->check = ~udp_v4_check(len, saddr, daddr, 0);
else if (skb_dst(skb) && skb_dst(skb)->dev &&
- (skb_dst(skb)->dev->features & NETIF_F_V4_CSUM)) {
+ (skb_dst(skb)->dev->features &
+ (NETIF_F_IP_CSUM | NETIF_F_HW_CSUM))) {
BUG_ON(skb->ip_summed == CHECKSUM_PARTIAL);
diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
index f938616..1300426 100644
--- a/net/ipv4/udp_offload.c
+++ b/net/ipv4/udp_offload.c
@@ -60,8 +60,9 @@ static struct sk_buff *__skb_udp_tunnel_segment(struct sk_buff *skb,
/* Try to offload checksum if possible */
offload_csum = !!(need_csum &&
- (skb->dev->features &
- (is_ipv6 ? NETIF_F_V6_CSUM : NETIF_F_V4_CSUM)));
+ ((skb->dev->features & NETIF_F_HW_CSUM) ||
+ (skb->dev->features & (is_ipv6 ?
+ NETIF_F_IPV6_CSUM : NETIF_F_IP_CSUM))));
/* segment inner packet. */
enc_features = skb->dev->hw_enc_features & features;
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index e6a7bd15..2f74845 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1322,7 +1322,7 @@ emsgsize:
headersize == sizeof(struct ipv6hdr) &&
length < mtu - headersize &&
!(flags & MSG_MORE) &&
- rt->dst.dev->features & NETIF_F_V6_CSUM)
+ rt->dst.dev->features & (NETIF_F_IPV6_CSUM | NETIF_F_HW_CSUM))
csummode = CHECKSUM_PARTIAL;
if (sk->sk_type == SOCK_DGRAM || sk->sk_type == SOCK_RAW) {
diff --git a/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c b/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c
index 238e70c..6ce3099 100644
--- a/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c
@@ -136,7 +136,8 @@ static void nf_nat_ipv6_csum_recalc(struct sk_buff *skb,
if (skb->ip_summed != CHECKSUM_PARTIAL) {
if (!(rt->rt6i_flags & RTF_LOCAL) &&
- (!skb->dev || skb->dev->features & NETIF_F_V6_CSUM)) {
+ (!skb->dev || skb->dev->features &
+ (NETIF_F_IPV6_CSUM | NETIF_F_HW_CSUM))) {
skb->ip_summed = CHECKSUM_PARTIAL;
skb->csum_start = skb_headroom(skb) +
skb_network_offset(skb) +
--
2.4.6
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH net-next 6/8] tcp: Fix conditions to determine checksum offload
2015-12-14 19:19 [PATCH net-next 0/8] net: The beginning of the end for NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM Tom Herbert
` (4 preceding siblings ...)
2015-12-14 19:19 ` [PATCH net-next 5/8] net: Eliminate NETIF_F_GEN_CSUM and NETIF_F_V[46]_CSUM Tom Herbert
@ 2015-12-14 19:19 ` Tom Herbert
2015-12-14 19:39 ` Eric Dumazet
2015-12-14 19:19 ` [PATCH net-next 7/8] net: Add driver helper functions to determine checksum offloadability Tom Herbert
` (2 subsequent siblings)
8 siblings, 1 reply; 15+ messages in thread
From: Tom Herbert @ 2015-12-14 19:19 UTC (permalink / raw)
To: davem, netdev; +Cc: kernel-team
In tcp_send_sendpage and tcp_sendmsg we check the route capabilities to
determine if checksum offload can be performed. This check currently
does not take the IP protocol into account for devices that advertise
only one of NETIF_F_IPV6_CSUM or NETIF_F_IP_CSUM. This patch adds a
function to check capabilities for checksum offload with a socket
called sk_check_csum_caps. This function checks for specific IPv4 or
IPv6 offload support based on the family of the socket.
Signed-off-by: Tom Herbert <tom@herbertland.com>
---
include/net/sock.h | 9 +++++++++
net/ipv4/tcp.c | 4 ++--
2 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/include/net/sock.h b/include/net/sock.h
index 0ca22b0..ab0269f 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1791,6 +1791,15 @@ static inline void sk_nocaps_add(struct sock *sk, netdev_features_t flags)
sk->sk_route_caps &= ~flags;
}
+static inline bool sk_check_csum_caps(struct sock *sk)
+{
+ return (sk->sk_route_caps & NETIF_F_HW_CSUM) ||
+ (sk->sk_family == PF_INET &&
+ (sk->sk_route_caps & NETIF_F_IP_CSUM)) ||
+ (sk->sk_family == PF_INET6 &&
+ (sk->sk_route_caps & NETIF_F_IPV6_CSUM));
+}
+
static inline int skb_do_copy_data_nocache(struct sock *sk, struct sk_buff *skb,
struct iov_iter *from, char *to,
int copy, int offset)
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index cf7ef7b..92b3e61 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1018,7 +1018,7 @@ int tcp_sendpage(struct sock *sk, struct page *page, int offset,
ssize_t res;
if (!(sk->sk_route_caps & NETIF_F_SG) ||
- !(sk->sk_route_caps & NETIF_F_CSUM_MASK))
+ !sk_check_csum_caps(sk))
return sock_no_sendpage(sk->sk_socket, page, offset, size,
flags);
@@ -1175,7 +1175,7 @@ new_segment:
/*
* Check whether we can use HW checksum.
*/
- if (sk->sk_route_caps & NETIF_F_CSUM_MASK)
+ if (sk_check_csum_caps(sk))
skb->ip_summed = CHECKSUM_PARTIAL;
skb_entail(sk, skb);
--
2.4.6
^ permalink raw reply related [flat|nested] 15+ messages in thread* Re: [PATCH net-next 6/8] tcp: Fix conditions to determine checksum offload
2015-12-14 19:19 ` [PATCH net-next 6/8] tcp: Fix conditions to determine checksum offload Tom Herbert
@ 2015-12-14 19:39 ` Eric Dumazet
2015-12-14 20:39 ` Tom Herbert
0 siblings, 1 reply; 15+ messages in thread
From: Eric Dumazet @ 2015-12-14 19:39 UTC (permalink / raw)
To: Tom Herbert; +Cc: davem, netdev, kernel-team
On Mon, 2015-12-14 at 11:19 -0800, Tom Herbert wrote:
> In tcp_send_sendpage and tcp_sendmsg we check the route capabilities to
> determine if checksum offload can be performed. This check currently
> does not take the IP protocol into account for devices that advertise
> only one of NETIF_F_IPV6_CSUM or NETIF_F_IP_CSUM. This patch adds a
> function to check capabilities for checksum offload with a socket
> called sk_check_csum_caps. This function checks for specific IPv4 or
> IPv6 offload support based on the family of the socket.
>
> Signed-off-by: Tom Herbert <tom@herbertland.com>
> ---
> include/net/sock.h | 9 +++++++++
> net/ipv4/tcp.c | 4 ++--
> 2 files changed, 11 insertions(+), 2 deletions(-)
>
> diff --git a/include/net/sock.h b/include/net/sock.h
> index 0ca22b0..ab0269f 100644
> --- a/include/net/sock.h
> +++ b/include/net/sock.h
> @@ -1791,6 +1791,15 @@ static inline void sk_nocaps_add(struct sock *sk, netdev_features_t flags)
> sk->sk_route_caps &= ~flags;
> }
>
> +static inline bool sk_check_csum_caps(struct sock *sk)
> +{
> + return (sk->sk_route_caps & NETIF_F_HW_CSUM) ||
> + (sk->sk_family == PF_INET &&
> + (sk->sk_route_caps & NETIF_F_IP_CSUM)) ||
> + (sk->sk_family == PF_INET6 &&
> + (sk->sk_route_caps & NETIF_F_IPV6_CSUM));
> +}
> +
Not sure this handles ipv6_mapped correctly ?
Since this is going to be called quite often, we might set a single bit
in sk_setup_caps() or elsewhere and test it here as fast as possible.
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: [PATCH net-next 6/8] tcp: Fix conditions to determine checksum offload
2015-12-14 19:39 ` Eric Dumazet
@ 2015-12-14 20:39 ` Tom Herbert
0 siblings, 0 replies; 15+ messages in thread
From: Tom Herbert @ 2015-12-14 20:39 UTC (permalink / raw)
To: Eric Dumazet
Cc: David S. Miller, Linux Kernel Network Developers, Kernel Team
On Mon, Dec 14, 2015 at 11:39 AM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> On Mon, 2015-12-14 at 11:19 -0800, Tom Herbert wrote:
>> In tcp_send_sendpage and tcp_sendmsg we check the route capabilities to
>> determine if checksum offload can be performed. This check currently
>> does not take the IP protocol into account for devices that advertise
>> only one of NETIF_F_IPV6_CSUM or NETIF_F_IP_CSUM. This patch adds a
>> function to check capabilities for checksum offload with a socket
>> called sk_check_csum_caps. This function checks for specific IPv4 or
>> IPv6 offload support based on the family of the socket.
>>
>> Signed-off-by: Tom Herbert <tom@herbertland.com>
>> ---
>> include/net/sock.h | 9 +++++++++
>> net/ipv4/tcp.c | 4 ++--
>> 2 files changed, 11 insertions(+), 2 deletions(-)
>>
>> diff --git a/include/net/sock.h b/include/net/sock.h
>> index 0ca22b0..ab0269f 100644
>> --- a/include/net/sock.h
>> +++ b/include/net/sock.h
>> @@ -1791,6 +1791,15 @@ static inline void sk_nocaps_add(struct sock *sk, netdev_features_t flags)
>> sk->sk_route_caps &= ~flags;
>> }
>>
>> +static inline bool sk_check_csum_caps(struct sock *sk)
>> +{
>> + return (sk->sk_route_caps & NETIF_F_HW_CSUM) ||
>> + (sk->sk_family == PF_INET &&
>> + (sk->sk_route_caps & NETIF_F_IP_CSUM)) ||
>> + (sk->sk_family == PF_INET6 &&
>> + (sk->sk_route_caps & NETIF_F_IPV6_CSUM));
>> +}
>> +
>
> Not sure this handles ipv6_mapped correctly ?
>
It would be handled correctly, but might be suboptimal since we could
be missing opportunities to offload. The original code would assume
that all IPv6 can be offloaded with just NETIF_F_IP_CSUM which
presumably is also suboptimal because we're missing opportunity to do
copy-csum. I don't know which is better to optimize for...
> Since this is going to be called quite often, we might set a single bit
> in sk_setup_caps() or elsewhere and test it here as fast as possible.
>
>
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH net-next 7/8] net: Add driver helper functions to determine checksum offloadability
2015-12-14 19:19 [PATCH net-next 0/8] net: The beginning of the end for NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM Tom Herbert
` (5 preceding siblings ...)
2015-12-14 19:19 ` [PATCH net-next 6/8] tcp: Fix conditions to determine checksum offload Tom Herbert
@ 2015-12-14 19:19 ` Tom Herbert
2015-12-14 19:19 ` [PATCH net-next 8/8] net: Elaborate on checksum offload interface description Tom Herbert
2015-12-15 21:32 ` [PATCH net-next 0/8] net: The beginning of the end for NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM David Miller
8 siblings, 0 replies; 15+ messages in thread
From: Tom Herbert @ 2015-12-14 19:19 UTC (permalink / raw)
To: davem, netdev; +Cc: kernel-team
Add skb_csum_offload_chk driver helper function to determine if a
device with limited checksum offload capabilities is able to offload the
checksum for a given packet.
This patch includes:
- The skb_csum_offload_chk function. Returns true if checksum is
offloadable, else false. Optionally, in the case that the checksum
is not offloable, the function can call skb_checksum_help to resolve
the checksum. skb_csum_offload_chk also returns whether the checksum
refers to an encapsulated checksum.
- Definition of skb_csum_offl_spec structure that caller uses to
indicate rules about what it can offload (e.g. IPv4/v6, TCP/UDP only,
whether encapsulated checksums can be offloaded, whether checksum with
IPv6 extension headers can be offloaded).
- Ancilary functions called skb_csum_offload_chk_help,
skb_csum_off_chk_help_cmn, skb_csum_off_chk_help_cmn_v4_only.
Signed-off-by: Tom Herbert <tom@herbertland.com>
---
include/linux/netdevice.h | 78 ++++++++++++++++++++++++++
net/core/dev.c | 136 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 214 insertions(+)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 283984b..9fb6395 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2522,6 +2522,71 @@ static inline void skb_gro_remcsum_cleanup(struct sk_buff *skb,
remcsum_unadjust((__sum16 *)ptr, grc->delta);
}
+struct skb_csum_offl_spec {
+ __u16 ipv4_okay:1,
+ ipv6_okay:1,
+ encap_okay:1,
+ ip_options_okay:1,
+ ext_hdrs_okay:1,
+ tcp_okay:1,
+ udp_okay:1,
+ sctp_okay:1,
+ vlan_okay:1,
+ no_encapped_ipv6:1,
+ no_not_encapped:1;
+};
+
+bool __skb_csum_offload_chk(struct sk_buff *skb,
+ const struct skb_csum_offl_spec *spec,
+ bool *csum_encapped,
+ bool csum_help);
+
+static inline bool skb_csum_offload_chk(struct sk_buff *skb,
+ const struct skb_csum_offl_spec *spec,
+ bool *csum_encapped,
+ bool csum_help)
+{
+ if (skb->ip_summed != CHECKSUM_PARTIAL)
+ return false;
+
+ return __skb_csum_offload_chk(skb, spec, csum_encapped, csum_help);
+}
+
+static inline bool skb_csum_offload_chk_help(struct sk_buff *skb,
+ const struct skb_csum_offl_spec *spec)
+{
+ bool csum_encapped;
+
+ return skb_csum_offload_chk(skb, spec, &csum_encapped, true);
+}
+
+static inline bool skb_csum_off_chk_help_cmn(struct sk_buff *skb)
+{
+ static const struct skb_csum_offl_spec csum_offl_spec = {
+ .ipv4_okay = 1,
+ .ip_options_okay = 1,
+ .ipv6_okay = 1,
+ .vlan_okay = 1,
+ .tcp_okay = 1,
+ .udp_okay = 1,
+ };
+
+ return skb_csum_offload_chk_help(skb, &csum_offl_spec);
+}
+
+static inline bool skb_csum_off_chk_help_cmn_v4_only(struct sk_buff *skb)
+{
+ static const struct skb_csum_offl_spec csum_offl_spec = {
+ .ipv4_okay = 1,
+ .ip_options_okay = 1,
+ .tcp_okay = 1,
+ .udp_okay = 1,
+ .vlan_okay = 1,
+ };
+
+ return skb_csum_offload_chk_help(skb, &csum_offl_spec);
+}
+
static inline int dev_hard_header(struct sk_buff *skb, struct net_device *dev,
unsigned short type,
const void *daddr, const void *saddr,
@@ -3711,6 +3776,19 @@ static inline bool can_checksum_protocol(netdev_features_t features,
}
}
+/* Map an ethertype into IP protocol if possible */
+static inline int eproto_to_ipproto(int eproto)
+{
+ switch (eproto) {
+ case htons(ETH_P_IP):
+ return IPPROTO_IP;
+ case htons(ETH_P_IPV6):
+ return IPPROTO_IPV6;
+ default:
+ return -1;
+ }
+}
+
#ifdef CONFIG_BUG
void netdev_rx_csum_fault(struct net_device *dev);
#else
diff --git a/net/core/dev.c b/net/core/dev.c
index 45b013f..914b4a2 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -138,6 +138,7 @@
#include <linux/errqueue.h>
#include <linux/hrtimer.h>
#include <linux/netfilter_ingress.h>
+#include <linux/sctp.h>
#include "net-sysfs.h"
@@ -2471,6 +2472,141 @@ out:
}
EXPORT_SYMBOL(skb_checksum_help);
+/* skb_csum_offload_check - Driver helper function to determine if a device
+ * with limited checksum offload capabilities is able to offload the checksum
+ * for a given packet.
+ *
+ * Arguments:
+ * skb - sk_buff for the packet in question
+ * spec - contains the description of what device can offload
+ * csum_encapped - returns true if the checksum being offloaded is
+ * encpasulated. That is it is checksum for the transport header
+ * in the inner headers.
+ * checksum_help - when set indicates that helper function should
+ * call skb_checksum_help if offload checks fail
+ *
+ * Returns:
+ * true: Packet has passed the checksum checks and should be offloadable to
+ * the device (a driver may still need to check for additional
+ * restrictions of its device)
+ * false: Checksum is not offloadable. If checksum_help was set then
+ * skb_checksum_help was called to resolve checksum for non-GSO
+ * packets and when IP protocol is not SCTP
+ */
+bool __skb_csum_offload_chk(struct sk_buff *skb,
+ const struct skb_csum_offl_spec *spec,
+ bool *csum_encapped,
+ bool csum_help)
+{
+ struct iphdr *iph;
+ struct ipv6hdr *ipv6;
+ void *nhdr;
+ int protocol;
+ u8 ip_proto;
+
+ if (skb->protocol == htons(ETH_P_8021Q) ||
+ skb->protocol == htons(ETH_P_8021AD)) {
+ if (!spec->vlan_okay)
+ goto need_help;
+ }
+
+ /* We check whether the checksum refers to a transport layer checksum in
+ * the outermost header or an encapsulated transport layer checksum that
+ * corresponds to the inner headers of the skb. If the checksum is for
+ * something else in the packet we need help.
+ */
+ if (skb_checksum_start_offset(skb) == skb_transport_offset(skb)) {
+ /* Non-encapsulated checksum */
+ protocol = eproto_to_ipproto(vlan_get_protocol(skb));
+ nhdr = skb_network_header(skb);
+ *csum_encapped = false;
+ if (spec->no_not_encapped)
+ goto need_help;
+ } else if (skb->encapsulation && spec->encap_okay &&
+ skb_checksum_start_offset(skb) ==
+ skb_inner_transport_offset(skb)) {
+ /* Encapsulated checksum */
+ *csum_encapped = true;
+ switch (skb->inner_protocol_type) {
+ case ENCAP_TYPE_ETHER:
+ protocol = eproto_to_ipproto(skb->inner_protocol);
+ break;
+ case ENCAP_TYPE_IPPROTO:
+ protocol = skb->inner_protocol;
+ break;
+ }
+ nhdr = skb_inner_network_header(skb);
+ } else {
+ goto need_help;
+ }
+
+ switch (protocol) {
+ case IPPROTO_IP:
+ if (!spec->ipv4_okay)
+ goto need_help;
+ iph = nhdr;
+ ip_proto = iph->protocol;
+ if (iph->ihl != 5 && !spec->ip_options_okay)
+ goto need_help;
+ break;
+ case IPPROTO_IPV6:
+ if (!spec->ipv6_okay)
+ goto need_help;
+ if (spec->no_encapped_ipv6 && *csum_encapped)
+ goto need_help;
+ ipv6 = nhdr;
+ nhdr += sizeof(*ipv6);
+ ip_proto = ipv6->nexthdr;
+ break;
+ default:
+ goto need_help;
+ }
+
+ip_proto_again:
+ switch (ip_proto) {
+ case IPPROTO_TCP:
+ if (!spec->tcp_okay ||
+ skb->csum_offset != offsetof(struct tcphdr, check))
+ goto need_help;
+ break;
+ case IPPROTO_UDP:
+ if (!spec->udp_okay ||
+ skb->csum_offset != offsetof(struct udphdr, check))
+ goto need_help;
+ break;
+ case IPPROTO_SCTP:
+ if (!spec->sctp_okay ||
+ skb->csum_offset != offsetof(struct sctphdr, checksum))
+ goto cant_help;
+ break;
+ case NEXTHDR_HOP:
+ case NEXTHDR_ROUTING:
+ case NEXTHDR_DEST: {
+ u8 *opthdr = nhdr;
+
+ if (protocol != IPPROTO_IPV6 || !spec->ext_hdrs_okay)
+ goto need_help;
+
+ ip_proto = opthdr[0];
+ nhdr += (opthdr[1] + 1) << 3;
+
+ goto ip_proto_again;
+ }
+ default:
+ goto need_help;
+ }
+
+ /* Passed the tests for offloading checksum */
+ return true;
+
+need_help:
+ if (csum_help && !skb_shinfo(skb)->gso_size)
+ skb_checksum_help(skb);
+cant_help:
+ return false;
+}
+EXPORT_SYMBOL(__skb_csum_offload_chk);
+
__be16 skb_network_protocol(struct sk_buff *skb, int *depth)
{
__be16 type = skb->protocol;
--
2.4.6
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH net-next 8/8] net: Elaborate on checksum offload interface description
2015-12-14 19:19 [PATCH net-next 0/8] net: The beginning of the end for NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM Tom Herbert
` (6 preceding siblings ...)
2015-12-14 19:19 ` [PATCH net-next 7/8] net: Add driver helper functions to determine checksum offloadability Tom Herbert
@ 2015-12-14 19:19 ` Tom Herbert
2015-12-15 21:32 ` [PATCH net-next 0/8] net: The beginning of the end for NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM David Miller
8 siblings, 0 replies; 15+ messages in thread
From: Tom Herbert @ 2015-12-14 19:19 UTC (permalink / raw)
To: davem, netdev; +Cc: kernel-team
Add specifics and details the description of the interface between
the stack and drivers for doing checksum offload. This description
is meant to be as specific and complete as possible.
Signed-off-by: Tom Herbert <tom@herbertland.com>
---
include/linux/skbuff.h | 138 ++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 109 insertions(+), 29 deletions(-)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 3f19744..123a843 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -39,11 +39,55 @@
#include <linux/in6.h>
#include <net/flow.h>
-/* A. Checksumming of received packets by device.
+/* The interface for checksum offload between the stack and networking drivers
+ * is as follows...
+ *
+ * A. IP checksum related features
+ *
+ * Drivers advertise checksum offload capabilities in the features of a device.
+ * From the stack's point of view these are capabilities offered by the driver,
+ * a driver typically only advertises features that it is capable of offloading
+ * to its device.
+ *
+ * The checksum related features are:
+ *
+ * NETIF_F_HW_CSUM - The driver (or its device) is able to compute one
+ * IP (one's complement) checksum for any combination
+ * of protocols or protocol layering. The checksum is
+ * computed and set in a packet per the CHECKSUM_PARTIAL
+ * interface (see below).
+ *
+ * NETIF_F_IP_CSUM - Driver (device) is only able to checksum plain
+ * TCP or UDP packets over IPv4. These are specifically
+ * unencapsulated packets of the form IPv4|TCP or
+ * IPv4|UDP where the Protocol field in the IPv4 header
+ * is TCP or UDP. The IPv4 header may contain IP options
+ * This feature cannot be set in features for a device
+ * with NETIF_F_HW_CSUM also set. This feature is being
+ * DEPRECATED (see below).
+ *
+ * NETIF_F_IPV6_CSUM - Driver (device) is only able to checksum plain
+ * TCP or UDP packets over IPv6. These are specifically
+ * unencapsulated packets of the form IPv6|TCP or
+ * IPv4|UDP where the Next Header field in the IPv6
+ * header is either TCP or UDP. IPv6 extension headers
+ * are not supported with this feature. This feature
+ * cannot be set in features for a device with
+ * NETIF_F_HW_CSUM also set. This feature is being
+ * DEPRECATED (see below).
+ *
+ * NETIF_F_RXCSUM - Driver (device) performs receive checksum offload.
+ * This flag is used only used to disable the RX checksum
+ * feature for a device. The stack will accept receive
+ * checksum indication in packets received on a device
+ * regardless of whether NETIF_F_RXCSUM is set.
+ *
+ * B. Checksumming of received packets by device. Indication of checksum
+ * verification is in set skb->ip_summed. Possible values are:
*
* CHECKSUM_NONE:
*
- * Device failed to checksum this packet e.g. due to lack of capabilities.
+ * Device did not checksum this packet e.g. due to lack of capabilities.
* The packet contains full (though not verified) checksum in packet but
* not in skb->csum. Thus, skb->csum is undefined in this case.
*
@@ -53,9 +97,8 @@
* (as in CHECKSUM_COMPLETE), but it does parse headers and verify checksums
* for specific protocols. For such packets it will set CHECKSUM_UNNECESSARY
* if their checksums are okay. skb->csum is still undefined in this case
- * though. It is a bad option, but, unfortunately, nowadays most vendors do
- * this. Apparently with the secret goal to sell you new devices, when you
- * will add new protocol to your host, f.e. IPv6 8)
+ * though. A driver or device must never modify the checksum field in the
+ * packet even if checksum is verified.
*
* CHECKSUM_UNNECESSARY is applicable to following protocols:
* TCP: IPv6 and IPv4.
@@ -96,40 +139,77 @@
* packet that are after the checksum being offloaded are not considered to
* be verified.
*
- * B. Checksumming on output.
- *
- * CHECKSUM_NONE:
- *
- * The skb was already checksummed by the protocol, or a checksum is not
- * required.
+ * C. Checksumming on transmit for non-GSO. The stack requests checksum offload
+ * in the skb->ip_summed for a packet. Values are:
*
* CHECKSUM_PARTIAL:
*
- * The device is required to checksum the packet as seen by hard_start_xmit()
+ * The driver is required to checksum the packet as seen by hard_start_xmit()
* from skb->csum_start up to the end, and to record/write the checksum at
- * offset skb->csum_start + skb->csum_offset.
+ * offset skb->csum_start + skb->csum_offset. A driver may verify that the
+ * csum_start and csum_offset values are valid values given the length and
+ * offset of the packet, however they should not attempt to validate that the
+ * checksum refers to a legitimate transport layer checksum-- it is the
+ * purview of the stack to validate that csum_start and csum_offset are set
+ * correctly.
+ *
+ * When the stack requests checksum offload for a packet, the driver MUST
+ * ensure that the checksum is set correctly. A driver can either offload the
+ * checksum calculation to the device, or call skb_checksum_help (in the case
+ * that the device does not support offload for a particular checksum).
+ *
+ * NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM are being deprecated in favor of
+ * NETIF_F_HW_CSUM. New devices should use NETIF_F_HW_CSUM to indicate
+ * checksum offload capability. If a device has limited checksum capabilities
+ * (for instance can only perform NETIF_F_IP_CSUM or NETIF_F_IPV6_CSUM as
+ * described above) a helper function can be called to resolve
+ * CHECKSUM_PARTIAL. The helper functions are skb_csum_off_chk*. The helper
+ * function takes a spec argument that describes the protocol layer that is
+ * supported for checksum offload and can be called for each packet. If a
+ * packet does not match the specification for offload, skb_checksum_help
+ * is called to resolve the checksum.
*
- * The device must show its capabilities in dev->features, set up at device
- * setup time, e.g. netdev_features.h:
+ * CHECKSUM_NONE:
*
- * NETIF_F_HW_CSUM - It's a clever device, it's able to checksum everything.
- * NETIF_F_IP_CSUM - Device is dumb, it's able to checksum only TCP/UDP over
- * IPv4. Sigh. Vendors like this way for an unknown reason.
- * Though, see comment above about CHECKSUM_UNNECESSARY. 8)
- * NETIF_F_IPV6_CSUM - About as dumb as the last one but does IPv6 instead.
- * NETIF_F_... - Well, you get the picture.
+ * The skb was already checksummed by the protocol, or a checksum is not
+ * required.
*
* CHECKSUM_UNNECESSARY:
*
- * Normally, the device will do per protocol specific checksumming. Protocol
- * implementations that do not want the NIC to perform the checksum
- * calculation should use this flag in their outgoing skbs.
+ * This has the same meaning on as CHECKSUM_NONE for checksum offload on
+ * output.
*
- * NETIF_F_FCOE_CRC - This indicates that the device can do FCoE FC CRC
- * offload. Correspondingly, the FCoE protocol driver
- * stack should use CHECKSUM_UNNECESSARY.
- *
- * Any questions? No questions, good. --ANK
+ * CHECKSUM_COMPLETE:
+ * Not used in checksum output. If a driver observes a packet with this value
+ * set in skbuff, if should treat as CHECKSUM_NONE being set.
+ *
+ * D. Non-IP checksum (CRC) offloads
+ *
+ * NETIF_F_SCTP_CRC - This feature indicates that a device is capable of
+ * offloading the SCTP CRC in a packet. To perform this offload the stack
+ * will set ip_summed to CHECKSUM_PARTIAL and set csum_start and csum_offset
+ * accordingly. Note the there is no indication in the skbuff that the
+ * CHECKSUM_PARTIAL refers to an SCTP checksum, a driver that supports
+ * both IP checksum offload and SCTP CRC offload must verify which offload
+ * is configured for a packet presumably by inspecting packet headers.
+ *
+ * NETIF_F_FCOE_CRC - This feature indicates that a device is capable of
+ * offloading the FCOE CRC in a packet. To perform this offload the stack
+ * will set ip_summed to CHECKSUM_PARTIAL and set csum_start and csum_offset
+ * accordingly. Note the there is no indication in the skbuff that the
+ * CHECKSUM_PARTIAL refers to an FCOE checksum, a driver that supports
+ * both IP checksum offload and FCOE CRC offload must verify which offload
+ * is configured for a packet presumably by inspecting packet headers.
+ *
+ * E. Checksumming on output with GSO.
+ *
+ * In the case of a GSO packet (skb_is_gso(skb) is true), checksum offload
+ * is implied by the SKB_GSO_* flags in gso_type. Most obviously, if the
+ * gso_type is SKB_GSO_TCPV4 or SKB_GSO_TCPV6, TCP checksum offload as
+ * part of the GSO operation is implied. If a checksum is being offloaded
+ * with GSO then ip_summed is CHECKSUM_PARTIAL, csum_start and csum_offset
+ * are set to refer to the outermost checksum being offload (two offloaded
+ * checksums are possible with UDP encapsulation).
*/
/* Don't change this without changing skb_csum_unnecessary! */
--
2.4.6
^ permalink raw reply related [flat|nested] 15+ messages in thread* Re: [PATCH net-next 0/8] net: The beginning of the end for NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM
2015-12-14 19:19 [PATCH net-next 0/8] net: The beginning of the end for NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM Tom Herbert
` (7 preceding siblings ...)
2015-12-14 19:19 ` [PATCH net-next 8/8] net: Elaborate on checksum offload interface description Tom Herbert
@ 2015-12-15 21:32 ` David Miller
2015-12-15 22:11 ` Tom Herbert
8 siblings, 1 reply; 15+ messages in thread
From: David Miller @ 2015-12-15 21:32 UTC (permalink / raw)
To: tom; +Cc: netdev, kernel-team
From: Tom Herbert <tom@herbertland.com>
Date: Mon, 14 Dec 2015 11:19:39 -0800
> This patch set starts to address one front in the battle against
> protocol ossification.
Looks good series applied, thanks.
Two things:
1) I'd ask you to reconsider passing that struct with the bit fields into
the chk routines. Some cpu ABIs pass that thing as an aggregate on
the stack. Whereas if you just use a simple bit mask and BIT(x) values
we know it's always going to be passed in as an integer or whatever.
2) As per the TCP check, it is definitely more strict now. But I seriously
doubt get ever gained anything real with the previous, looser, check.
Besides, if it bites a user segment we will get a report and can adjust
things.
Thanks!
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: [PATCH net-next 0/8] net: The beginning of the end for NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM
2015-12-15 21:32 ` [PATCH net-next 0/8] net: The beginning of the end for NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM David Miller
@ 2015-12-15 22:11 ` Tom Herbert
2015-12-15 22:18 ` Tom Herbert
2015-12-16 2:07 ` David Miller
0 siblings, 2 replies; 15+ messages in thread
From: Tom Herbert @ 2015-12-15 22:11 UTC (permalink / raw)
To: David Miller; +Cc: Linux Kernel Network Developers, Kernel Team
On Tue, Dec 15, 2015 at 1:32 PM, David Miller <davem@davemloft.net> wrote:
> From: Tom Herbert <tom@herbertland.com>
> Date: Mon, 14 Dec 2015 11:19:39 -0800
>
>> This patch set starts to address one front in the battle against
>> protocol ossification.
>
> Looks good series applied, thanks.
>
> Two things:
>
> 1) I'd ask you to reconsider passing that struct with the bit fields into
> the chk routines. Some cpu ABIs pass that thing as an aggregate on
> the stack. Whereas if you just use a simple bit mask and BIT(x) values
> we know it's always going to be passed in as an integer or whatever.
>
> 2) As per the TCP check, it is definitely more strict now. But I seriously
> doubt get ever gained anything real with the previous, looser, check.
> Besides, if it bites a user segment we will get a report and can adjust
> things.
>
> Thanks!
Looks like I may have missed a NETIF_F_ALL_CSUM in netronome driver,
will post fix shortly.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH net-next 0/8] net: The beginning of the end for NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM
2015-12-15 22:11 ` Tom Herbert
@ 2015-12-15 22:18 ` Tom Herbert
2015-12-16 2:07 ` David Miller
1 sibling, 0 replies; 15+ messages in thread
From: Tom Herbert @ 2015-12-15 22:18 UTC (permalink / raw)
To: David Miller; +Cc: Linux Kernel Network Developers, Kernel Team
On Tue, Dec 15, 2015 at 2:11 PM, Tom Herbert <tom@herbertland.com> wrote:
> On Tue, Dec 15, 2015 at 1:32 PM, David Miller <davem@davemloft.net> wrote:
>> From: Tom Herbert <tom@herbertland.com>
>> Date: Mon, 14 Dec 2015 11:19:39 -0800
>>
>>> This patch set starts to address one front in the battle against
>>> protocol ossification.
>>
>> Looks good series applied, thanks.
>>
>> Two things:
>>
>> 1) I'd ask you to reconsider passing that struct with the bit fields into
>> the chk routines. Some cpu ABIs pass that thing as an aggregate on
>> the stack. Whereas if you just use a simple bit mask and BIT(x) values
>> we know it's always going to be passed in as an integer or whatever.
>>
>> 2) As per the TCP check, it is definitely more strict now. But I seriously
>> doubt get ever gained anything real with the previous, looser, check.
>> Besides, if it bites a user segment we will get a report and can adjust
>> things.
>>
>> Thanks!
>
> Looks like I may have missed a NETIF_F_ALL_CSUM in netronome driver,
> will post fix shortly.
Actually looks okay, did you fix this up Dave?
Thanks,
Tom
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH net-next 0/8] net: The beginning of the end for NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM
2015-12-15 22:11 ` Tom Herbert
2015-12-15 22:18 ` Tom Herbert
@ 2015-12-16 2:07 ` David Miller
1 sibling, 0 replies; 15+ messages in thread
From: David Miller @ 2015-12-16 2:07 UTC (permalink / raw)
To: tom; +Cc: netdev, kernel-team
From: Tom Herbert <tom@herbertland.com>
Date: Tue, 15 Dec 2015 14:11:05 -0800
> Looks like I may have missed a NETIF_F_ALL_CSUM in netronome driver,
> will post fix shortly.
I fixed it up for you when I applied that patch.
^ permalink raw reply [flat|nested] 15+ messages in thread