Skip to content

Commit

Permalink
gue: TX support for using remote checksum offload option
Browse files Browse the repository at this point in the history
Add if_tunnel flag TUNNEL_ENCAP_FLAG_REMCSUM to configure
remote checksum offload on an IP tunnel. Add logic in gue_build_header
to insert remote checksum offload option.

Signed-off-by: Tom Herbert <therbert@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Tom Herbert authored and davem330 committed Nov 5, 2014
1 parent c1aa834 commit b17f709
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 4 deletions.
14 changes: 13 additions & 1 deletion include/net/fou.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,19 @@ static size_t fou_encap_hlen(struct ip_tunnel_encap *e)

static size_t gue_encap_hlen(struct ip_tunnel_encap *e)
{
return sizeof(struct udphdr) + sizeof(struct guehdr);
size_t len;
bool need_priv = false;

len = sizeof(struct udphdr) + sizeof(struct guehdr);

if (e->flags & TUNNEL_ENCAP_FLAG_REMCSUM) {
len += GUE_PLEN_REMCSUM;
need_priv = true;
}

len += need_priv ? GUE_LEN_PRIV : 0;

return len;
}

#endif
1 change: 1 addition & 0 deletions include/uapi/linux/if_tunnel.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ enum tunnel_encap_types {

#define TUNNEL_ENCAP_FLAG_CSUM (1<<0)
#define TUNNEL_ENCAP_FLAG_CSUM6 (1<<1)
#define TUNNEL_ENCAP_FLAG_REMCSUM (1<<2)

/* SIT-mode i_flags */
#define SIT_ISATAP 0x0001
Expand Down
35 changes: 32 additions & 3 deletions net/ipv4/fou.c
Original file line number Diff line number Diff line change
Expand Up @@ -562,11 +562,19 @@ int gue_build_header(struct sk_buff *skb, struct ip_tunnel_encap *e,
bool csum = !!(e->flags & TUNNEL_ENCAP_FLAG_CSUM);
int type = csum ? SKB_GSO_UDP_TUNNEL_CSUM : SKB_GSO_UDP_TUNNEL;
struct guehdr *guehdr;
size_t optlen = 0;
size_t hdrlen, optlen = 0;
__be16 sport;
void *data;
bool need_priv = false;

if ((e->flags & TUNNEL_ENCAP_FLAG_REMCSUM) &&
skb->ip_summed == CHECKSUM_PARTIAL) {
csum = false;
optlen += GUE_PLEN_REMCSUM;
type |= SKB_GSO_TUNNEL_REMCSUM;
need_priv = true;
}

optlen += need_priv ? GUE_LEN_PRIV : 0;

skb = iptunnel_handle_offloads(skb, csum, type);
Expand All @@ -578,7 +586,9 @@ int gue_build_header(struct sk_buff *skb, struct ip_tunnel_encap *e,
sport = e->sport ? : udp_flow_src_port(dev_net(skb->dev),
skb, 0, 0, false);

skb_push(skb, sizeof(struct guehdr) + optlen);
hdrlen = sizeof(struct guehdr) + optlen;

skb_push(skb, hdrlen);

guehdr = (struct guehdr *)skb->data;

Expand All @@ -597,7 +607,26 @@ int gue_build_header(struct sk_buff *skb, struct ip_tunnel_encap *e,
*flags = 0;
data += GUE_LEN_PRIV;

/* Add private flags */
if (type & SKB_GSO_TUNNEL_REMCSUM) {
u16 csum_start = skb_checksum_start_offset(skb);
__be16 *pd = data;

if (csum_start < hdrlen)
return -EINVAL;

csum_start -= hdrlen;
pd[0] = htons(csum_start);
pd[1] = htons(csum_start + skb->csum_offset);

if (!skb_is_gso(skb)) {
skb->ip_summed = CHECKSUM_NONE;
skb->encapsulation = 0;
}

*flags |= GUE_PFLAG_REMCSUM;
data += GUE_PLEN_REMCSUM;
}

}

fou_build_udp(skb, e, fl4, protocol, sport);
Expand Down

0 comments on commit b17f709

Please sign in to comment.