net: Add driver helper functions to determine checksum offloadability
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> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
9a49850d0a
commit
6ae23ad362
@@ -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
|
||||
|
Reference in New Issue
Block a user