diff options
author | Tom Herbert <tom@herbertland.com> | 2016-04-30 02:12:19 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-05-03 01:23:31 +0200 |
commit | 182a352d2d5e0b435f7856c0cc23d467dcec55ef (patch) | |
tree | e523a1f200325dd0ec9d0b25b769f06920c65808 /include/net/gre.h | |
parent | ipv6: Create ip6_tnl_xmit (diff) | |
download | linux-182a352d2d5e0b435f7856c0cc23d467dcec55ef.tar.xz linux-182a352d2d5e0b435f7856c0cc23d467dcec55ef.zip |
gre: Create common functions for transmit
Create common functions for both IPv4 and IPv6 GRE in transmit. These
are put into gre.h.
Common functions are for:
- GRE checksum calculation. Move gre_checksum to gre.h.
- Building a GRE header. Move GRE build_header and rename
gre_build_header.
Signed-off-by: Tom Herbert <tom@herbertland.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net/gre.h')
-rw-r--r-- | include/net/gre.h | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/include/net/gre.h b/include/net/gre.h index 39591584ec92..29e37322c06e 100644 --- a/include/net/gre.h +++ b/include/net/gre.h @@ -85,4 +85,48 @@ static inline __be16 gre_tnl_flags_to_gre_flags(__be16 tflags) return flags; } +static inline __sum16 gre_checksum(struct sk_buff *skb) +{ + __wsum csum; + + if (skb->ip_summed == CHECKSUM_PARTIAL) + csum = lco_csum(skb); + else + csum = skb_checksum(skb, 0, skb->len, 0); + return csum_fold(csum); +} + +static inline void gre_build_header(struct sk_buff *skb, int hdr_len, + __be16 flags, __be16 proto, + __be32 key, __be32 seq) +{ + struct gre_base_hdr *greh; + + skb_push(skb, hdr_len); + + skb_reset_transport_header(skb); + greh = (struct gre_base_hdr *)skb->data; + greh->flags = gre_tnl_flags_to_gre_flags(flags); + greh->protocol = proto; + + if (flags & (TUNNEL_KEY | TUNNEL_CSUM | TUNNEL_SEQ)) { + __be32 *ptr = (__be32 *)(((u8 *)greh) + hdr_len - 4); + + if (flags & TUNNEL_SEQ) { + *ptr = seq; + ptr--; + } + if (flags & TUNNEL_KEY) { + *ptr = key; + ptr--; + } + if (flags & TUNNEL_CSUM && + !(skb_shinfo(skb)->gso_type & + (SKB_GSO_GRE | SKB_GSO_GRE_CSUM))) { + *ptr = 0; + *(__sum16 *)ptr = gre_checksum(skb); + } + } +} + #endif |