Skip to content

Commit b17f709

Browse files
Tom Herbertdavem330
authored andcommitted
gue: TX support for using remote checksum offload option
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 <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent c1aa834 commit b17f709

File tree

3 files changed

+46
-4
lines changed

3 files changed

+46
-4
lines changed

include/net/fou.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,19 @@ static size_t fou_encap_hlen(struct ip_tunnel_encap *e)
2020

2121
static size_t gue_encap_hlen(struct ip_tunnel_encap *e)
2222
{
23-
return sizeof(struct udphdr) + sizeof(struct guehdr);
23+
size_t len;
24+
bool need_priv = false;
25+
26+
len = sizeof(struct udphdr) + sizeof(struct guehdr);
27+
28+
if (e->flags & TUNNEL_ENCAP_FLAG_REMCSUM) {
29+
len += GUE_PLEN_REMCSUM;
30+
need_priv = true;
31+
}
32+
33+
len += need_priv ? GUE_LEN_PRIV : 0;
34+
35+
return len;
2436
}
2537

2638
#endif

include/uapi/linux/if_tunnel.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ enum tunnel_encap_types {
6969

7070
#define TUNNEL_ENCAP_FLAG_CSUM (1<<0)
7171
#define TUNNEL_ENCAP_FLAG_CSUM6 (1<<1)
72+
#define TUNNEL_ENCAP_FLAG_REMCSUM (1<<2)
7273

7374
/* SIT-mode i_flags */
7475
#define SIT_ISATAP 0x0001

net/ipv4/fou.c

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -562,11 +562,19 @@ int gue_build_header(struct sk_buff *skb, struct ip_tunnel_encap *e,
562562
bool csum = !!(e->flags & TUNNEL_ENCAP_FLAG_CSUM);
563563
int type = csum ? SKB_GSO_UDP_TUNNEL_CSUM : SKB_GSO_UDP_TUNNEL;
564564
struct guehdr *guehdr;
565-
size_t optlen = 0;
565+
size_t hdrlen, optlen = 0;
566566
__be16 sport;
567567
void *data;
568568
bool need_priv = false;
569569

570+
if ((e->flags & TUNNEL_ENCAP_FLAG_REMCSUM) &&
571+
skb->ip_summed == CHECKSUM_PARTIAL) {
572+
csum = false;
573+
optlen += GUE_PLEN_REMCSUM;
574+
type |= SKB_GSO_TUNNEL_REMCSUM;
575+
need_priv = true;
576+
}
577+
570578
optlen += need_priv ? GUE_LEN_PRIV : 0;
571579

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

581-
skb_push(skb, sizeof(struct guehdr) + optlen);
589+
hdrlen = sizeof(struct guehdr) + optlen;
590+
591+
skb_push(skb, hdrlen);
582592

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

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

600-
/* Add private flags */
610+
if (type & SKB_GSO_TUNNEL_REMCSUM) {
611+
u16 csum_start = skb_checksum_start_offset(skb);
612+
__be16 *pd = data;
613+
614+
if (csum_start < hdrlen)
615+
return -EINVAL;
616+
617+
csum_start -= hdrlen;
618+
pd[0] = htons(csum_start);
619+
pd[1] = htons(csum_start + skb->csum_offset);
620+
621+
if (!skb_is_gso(skb)) {
622+
skb->ip_summed = CHECKSUM_NONE;
623+
skb->encapsulation = 0;
624+
}
625+
626+
*flags |= GUE_PFLAG_REMCSUM;
627+
data += GUE_PLEN_REMCSUM;
628+
}
629+
601630
}
602631

603632
fou_build_udp(skb, e, fl4, protocol, sport);

0 commit comments

Comments
 (0)