diff options
Diffstat (limited to 'net/ipv4/gre.c')
-rw-r--r-- | net/ipv4/gre.c | 32 |
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 | } |
62 | EXPORT_SYMBOL_GPL(gre_del_protocol); | 62 | EXPORT_SYMBOL_GPL(gre_del_protocol); |
63 | 63 | ||
64 | void 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 | } | ||
94 | EXPORT_SYMBOL_GPL(gre_build_header); | ||
95 | |||
64 | static __sum16 check_checksum(struct sk_buff *skb) | 96 | static __sum16 check_checksum(struct sk_buff *skb) |
65 | { | 97 | { |
66 | __sum16 csum = 0; | 98 | __sum16 csum = 0; |