aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/gre.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/gre.c')
-rw-r--r--net/ipv4/gre.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/net/ipv4/gre.c b/net/ipv4/gre.c
index 8b9a373890ab..1cbc46536d1f 100644
--- a/net/ipv4/gre.c
+++ b/net/ipv4/gre.c
@@ -61,6 +61,38 @@ int gre_del_protocol(const struct gre_protocol *proto, u8 version)
61} 61}
62EXPORT_SYMBOL_GPL(gre_del_protocol); 62EXPORT_SYMBOL_GPL(gre_del_protocol);
63 63
64void gre_build_header(struct sk_buff *skb, const struct tnl_ptk_info *tpi,
65 int hdr_len)
66{
67 struct gre_base_hdr *greh;
68
69 skb_push(skb, hdr_len);
70
71 greh = (struct gre_base_hdr *)skb->data;
72 greh->flags = tnl_flags_to_gre_flags(tpi->flags);
73 greh->protocol = tpi->proto;
74
75 if (tpi->flags&(TUNNEL_KEY|TUNNEL_CSUM|TUNNEL_SEQ)) {
76 __be32 *ptr = (__be32 *)(((u8 *)greh) + hdr_len - 4);
77
78 if (tpi->flags&TUNNEL_SEQ) {
79 *ptr = tpi->seq;
80 ptr--;
81 }
82 if (tpi->flags&TUNNEL_KEY) {
83 *ptr = tpi->key;
84 ptr--;
85 }
86 if (tpi->flags&TUNNEL_CSUM &&
87 !(skb_shinfo(skb)->gso_type & SKB_GSO_GRE)) {
88 *ptr = 0;
89 *(__sum16 *)ptr = csum_fold(skb_checksum(skb, 0,
90 skb->len, 0));
91 }
92 }
93}
94EXPORT_SYMBOL_GPL(gre_build_header);
95
64static __sum16 check_checksum(struct sk_buff *skb) 96static __sum16 check_checksum(struct sk_buff *skb)
65{ 97{
66 __sum16 csum = 0; 98 __sum16 csum = 0;