net: ipv6: add support for UL checksum offload for IPv6 over UDP

For IPv6 over UDP packets, uplink UDP checksum offloading to HW is not
supported since there is no check whether the device features are
configured with tx checksumming.
Add a new flag NETIF_F_IPV6_UDP_CSUM for tx checksumming for IPv6
over UDP packets. When a network device has this flag configured
as one of its features, UDP checksum will be offloaded for IPv6 over
UDP packets on uplink as well.

CRs-fixed: 731693
Change-Id: Ifd89d569d211f8bed9cf57bca101560c4ca7e9eb
Signed-off-by: Sivan Reinstein <sivanr@codeaurora.org>
This commit is contained in:
Sivan Reinstein 2014-09-30 15:50:55 +03:00
parent 6b9a08570c
commit b890bfe609
3 changed files with 19 additions and 3 deletions

View File

@ -59,6 +59,7 @@ enum {
NETIF_F_HW_VLAN_STAG_TX_BIT, /* Transmit VLAN STAG HW acceleration */
NETIF_F_HW_VLAN_STAG_RX_BIT, /* Receive VLAN STAG HW acceleration */
NETIF_F_HW_VLAN_STAG_FILTER_BIT,/* Receive filtering on VLAN STAGs */
NETIF_F_IPV6_UDP_CSUM_BIT, /* Can checksum UDP over IPV6 */
/*
* Add your fresh new feature above and remember to update
@ -110,6 +111,7 @@ enum {
#define NETIF_F_HW_VLAN_STAG_FILTER __NETIF_F(HW_VLAN_STAG_FILTER)
#define NETIF_F_HW_VLAN_STAG_RX __NETIF_F(HW_VLAN_STAG_RX)
#define NETIF_F_HW_VLAN_STAG_TX __NETIF_F(HW_VLAN_STAG_TX)
#define NETIF_F_IPV6_UDP_CSUM __NETIF_F(IPV6_UDP_CSUM)
/* Features valid for ethtool to change */
/* = all defined minus driver/device-class-related */

View File

@ -58,6 +58,7 @@ static const char netdev_features_strings[NETDEV_FEATURE_COUNT][ETH_GSTRING_LEN]
[NETIF_F_IP_CSUM_BIT] = "tx-checksum-ipv4",
[NETIF_F_HW_CSUM_BIT] = "tx-checksum-ip-generic",
[NETIF_F_IPV6_CSUM_BIT] = "tx-checksum-ipv6",
[NETIF_F_IPV6_UDP_CSUM_BIT] = "tx-checksum-ipv6-udp",
[NETIF_F_HIGHDMA_BIT] = "highdma",
[NETIF_F_FRAGLIST_BIT] = "tx-scatter-gather-fraglist",
[NETIF_F_HW_VLAN_CTAG_TX_BIT] = "tx-vlan-hw-insert",
@ -206,7 +207,8 @@ 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_CSUM |
NETIF_F_IPV6_UDP_CSUM;
case ETHTOOL_GRXCSUM:
case ETHTOOL_SRXCSUM:
return NETIF_F_RXCSUM;

View File

@ -1367,8 +1367,20 @@ alloc_new_skb:
/*
* Fill in the control structures
*/
skb->ip_summed = CHECKSUM_NONE;
skb->csum = 0;
/* offload UDP checksum in case the packet is not
* a fragment (length <= mtu && transhdrlen) and the
* device supports it in its features.
*/
if ((rt->dst.dev->features &
NETIF_F_IPV6_UDP_CSUM) &&
(length <= mtu) && transhdrlen &&
(sk->sk_protocol == IPPROTO_UDP)) {
skb->ip_summed = CHECKSUM_PARTIAL;
} else {
skb->ip_summed = CHECKSUM_NONE;
skb->csum = 0;
}
/* reserve for fragmentation and ipsec header */
skb_reserve(skb, hh_len + sizeof(struct frag_hdr) +
dst_exthdrlen);