net: gre: move GSO functions to gre_offload
[cascardo/linux.git] / net / ipv4 / gre_demux.c
1 /*
2  *      GRE over IPv4 demultiplexer driver
3  *
4  *      Authors: Dmitry Kozlov (xeb@mail.ru)
5  *
6  *      This program is free software; you can redistribute it and/or
7  *      modify it under the terms of the GNU General Public License
8  *      as published by the Free Software Foundation; either version
9  *      2 of the License, or (at your option) any later version.
10  *
11  */
12
13 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14
15 #include <linux/module.h>
16 #include <linux/if.h>
17 #include <linux/icmp.h>
18 #include <linux/kernel.h>
19 #include <linux/kmod.h>
20 #include <linux/skbuff.h>
21 #include <linux/in.h>
22 #include <linux/ip.h>
23 #include <linux/netdevice.h>
24 #include <linux/if_tunnel.h>
25 #include <linux/spinlock.h>
26 #include <net/protocol.h>
27 #include <net/gre.h>
28
29 #include <net/icmp.h>
30 #include <net/route.h>
31 #include <net/xfrm.h>
32
33 static const struct gre_protocol __rcu *gre_proto[GREPROTO_MAX] __read_mostly;
34 static struct gre_cisco_protocol __rcu *gre_cisco_proto_list[GRE_IP_PROTO_MAX];
35
36 int gre_add_protocol(const struct gre_protocol *proto, u8 version)
37 {
38         if (version >= GREPROTO_MAX)
39                 return -EINVAL;
40
41         return (cmpxchg((const struct gre_protocol **)&gre_proto[version], NULL, proto) == NULL) ?
42                 0 : -EBUSY;
43 }
44 EXPORT_SYMBOL_GPL(gre_add_protocol);
45
46 int gre_del_protocol(const struct gre_protocol *proto, u8 version)
47 {
48         int ret;
49
50         if (version >= GREPROTO_MAX)
51                 return -EINVAL;
52
53         ret = (cmpxchg((const struct gre_protocol **)&gre_proto[version], proto, NULL) == proto) ?
54                 0 : -EBUSY;
55
56         if (ret)
57                 return ret;
58
59         synchronize_rcu();
60         return 0;
61 }
62 EXPORT_SYMBOL_GPL(gre_del_protocol);
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
96 struct sk_buff *gre_handle_offloads(struct sk_buff *skb, bool gre_csum)
97 {
98         int err;
99
100         if (likely(!skb->encapsulation)) {
101                 skb_reset_inner_headers(skb);
102                 skb->encapsulation = 1;
103         }
104
105         if (skb_is_gso(skb)) {
106                 err = skb_unclone(skb, GFP_ATOMIC);
107                 if (unlikely(err))
108                         goto error;
109                 skb_shinfo(skb)->gso_type |= SKB_GSO_GRE;
110                 return skb;
111         } else if (skb->ip_summed == CHECKSUM_PARTIAL && gre_csum) {
112                 err = skb_checksum_help(skb);
113                 if (unlikely(err))
114                         goto error;
115         } else if (skb->ip_summed != CHECKSUM_PARTIAL)
116                 skb->ip_summed = CHECKSUM_NONE;
117
118         return skb;
119 error:
120         kfree_skb(skb);
121         return ERR_PTR(err);
122 }
123 EXPORT_SYMBOL_GPL(gre_handle_offloads);
124
125 static __sum16 check_checksum(struct sk_buff *skb)
126 {
127         __sum16 csum = 0;
128
129         switch (skb->ip_summed) {
130         case CHECKSUM_COMPLETE:
131                 csum = csum_fold(skb->csum);
132
133                 if (!csum)
134                         break;
135                 /* Fall through. */
136
137         case CHECKSUM_NONE:
138                 skb->csum = 0;
139                 csum = __skb_checksum_complete(skb);
140                 skb->ip_summed = CHECKSUM_COMPLETE;
141                 break;
142         }
143
144         return csum;
145 }
146
147 static int parse_gre_header(struct sk_buff *skb, struct tnl_ptk_info *tpi,
148                             bool *csum_err)
149 {
150         unsigned int ip_hlen = ip_hdrlen(skb);
151         const struct gre_base_hdr *greh;
152         __be32 *options;
153         int hdr_len;
154
155         if (unlikely(!pskb_may_pull(skb, sizeof(struct gre_base_hdr))))
156                 return -EINVAL;
157
158         greh = (struct gre_base_hdr *)(skb_network_header(skb) + ip_hlen);
159         if (unlikely(greh->flags & (GRE_VERSION | GRE_ROUTING)))
160                 return -EINVAL;
161
162         tpi->flags = gre_flags_to_tnl_flags(greh->flags);
163         hdr_len = ip_gre_calc_hlen(tpi->flags);
164
165         if (!pskb_may_pull(skb, hdr_len))
166                 return -EINVAL;
167
168         greh = (struct gre_base_hdr *)(skb_network_header(skb) + ip_hlen);
169         tpi->proto = greh->protocol;
170
171         options = (__be32 *)(greh + 1);
172         if (greh->flags & GRE_CSUM) {
173                 if (check_checksum(skb)) {
174                         *csum_err = true;
175                         return -EINVAL;
176                 }
177                 options++;
178         }
179
180         if (greh->flags & GRE_KEY) {
181                 tpi->key = *options;
182                 options++;
183         } else
184                 tpi->key = 0;
185
186         if (unlikely(greh->flags & GRE_SEQ)) {
187                 tpi->seq = *options;
188                 options++;
189         } else
190                 tpi->seq = 0;
191
192         /* WCCP version 1 and 2 protocol decoding.
193          * - Change protocol to IP
194          * - When dealing with WCCPv2, Skip extra 4 bytes in GRE header
195          */
196         if (greh->flags == 0 && tpi->proto == htons(ETH_P_WCCP)) {
197                 tpi->proto = htons(ETH_P_IP);
198                 if ((*(u8 *)options & 0xF0) != 0x40) {
199                         hdr_len += 4;
200                         if (!pskb_may_pull(skb, hdr_len))
201                                 return -EINVAL;
202                 }
203         }
204
205         return iptunnel_pull_header(skb, hdr_len, tpi->proto);
206 }
207
208 static int gre_cisco_rcv(struct sk_buff *skb)
209 {
210         struct tnl_ptk_info tpi;
211         int i;
212         bool csum_err = false;
213
214         if (parse_gre_header(skb, &tpi, &csum_err) < 0)
215                 goto drop;
216
217         rcu_read_lock();
218         for (i = 0; i < GRE_IP_PROTO_MAX; i++) {
219                 struct gre_cisco_protocol *proto;
220                 int ret;
221
222                 proto = rcu_dereference(gre_cisco_proto_list[i]);
223                 if (!proto)
224                         continue;
225                 ret = proto->handler(skb, &tpi);
226                 if (ret == PACKET_RCVD) {
227                         rcu_read_unlock();
228                         return 0;
229                 }
230         }
231         rcu_read_unlock();
232
233         icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
234 drop:
235         kfree_skb(skb);
236         return 0;
237 }
238
239 static void gre_cisco_err(struct sk_buff *skb, u32 info)
240 {
241         /* All the routers (except for Linux) return only
242          * 8 bytes of packet payload. It means, that precise relaying of
243          * ICMP in the real Internet is absolutely infeasible.
244          *
245          * Moreover, Cisco "wise men" put GRE key to the third word
246          * in GRE header. It makes impossible maintaining even soft
247          * state for keyed
248          * GRE tunnels with enabled checksum. Tell them "thank you".
249          *
250          * Well, I wonder, rfc1812 was written by Cisco employee,
251          * what the hell these idiots break standards established
252          * by themselves???
253          */
254
255         const int type = icmp_hdr(skb)->type;
256         const int code = icmp_hdr(skb)->code;
257         struct tnl_ptk_info tpi;
258         bool csum_err = false;
259         int i;
260
261         if (parse_gre_header(skb, &tpi, &csum_err)) {
262                 if (!csum_err)          /* ignore csum errors. */
263                         return;
264         }
265
266         if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) {
267                 ipv4_update_pmtu(skb, dev_net(skb->dev), info,
268                                 skb->dev->ifindex, 0, IPPROTO_GRE, 0);
269                 return;
270         }
271         if (type == ICMP_REDIRECT) {
272                 ipv4_redirect(skb, dev_net(skb->dev), skb->dev->ifindex, 0,
273                                 IPPROTO_GRE, 0);
274                 return;
275         }
276
277         rcu_read_lock();
278         for (i = 0; i < GRE_IP_PROTO_MAX; i++) {
279                 struct gre_cisco_protocol *proto;
280
281                 proto = rcu_dereference(gre_cisco_proto_list[i]);
282                 if (!proto)
283                         continue;
284
285                 if (proto->err_handler(skb, info, &tpi) == PACKET_RCVD)
286                         goto out;
287
288         }
289 out:
290         rcu_read_unlock();
291 }
292
293 static int gre_rcv(struct sk_buff *skb)
294 {
295         const struct gre_protocol *proto;
296         u8 ver;
297         int ret;
298
299         if (!pskb_may_pull(skb, 12))
300                 goto drop;
301
302         ver = skb->data[1]&0x7f;
303         if (ver >= GREPROTO_MAX)
304                 goto drop;
305
306         rcu_read_lock();
307         proto = rcu_dereference(gre_proto[ver]);
308         if (!proto || !proto->handler)
309                 goto drop_unlock;
310         ret = proto->handler(skb);
311         rcu_read_unlock();
312         return ret;
313
314 drop_unlock:
315         rcu_read_unlock();
316 drop:
317         kfree_skb(skb);
318         return NET_RX_DROP;
319 }
320
321 static void gre_err(struct sk_buff *skb, u32 info)
322 {
323         const struct gre_protocol *proto;
324         const struct iphdr *iph = (const struct iphdr *)skb->data;
325         u8 ver = skb->data[(iph->ihl<<2) + 1]&0x7f;
326
327         if (ver >= GREPROTO_MAX)
328                 return;
329
330         rcu_read_lock();
331         proto = rcu_dereference(gre_proto[ver]);
332         if (proto && proto->err_handler)
333                 proto->err_handler(skb, info);
334         rcu_read_unlock();
335 }
336
337 static const struct net_protocol net_gre_protocol = {
338         .handler     = gre_rcv,
339         .err_handler = gre_err,
340         .netns_ok    = 1,
341 };
342
343 static const struct gre_protocol ipgre_protocol = {
344         .handler     = gre_cisco_rcv,
345         .err_handler = gre_cisco_err,
346 };
347
348 int gre_cisco_register(struct gre_cisco_protocol *newp)
349 {
350         struct gre_cisco_protocol **proto = (struct gre_cisco_protocol **)
351                                             &gre_cisco_proto_list[newp->priority];
352
353         return (cmpxchg(proto, NULL, newp) == NULL) ? 0 : -EBUSY;
354 }
355 EXPORT_SYMBOL_GPL(gre_cisco_register);
356
357 int gre_cisco_unregister(struct gre_cisco_protocol *del_proto)
358 {
359         struct gre_cisco_protocol **proto = (struct gre_cisco_protocol **)
360                                             &gre_cisco_proto_list[del_proto->priority];
361         int ret;
362
363         ret = (cmpxchg(proto, del_proto, NULL) == del_proto) ? 0 : -EINVAL;
364
365         if (ret)
366                 return ret;
367
368         synchronize_net();
369         return 0;
370 }
371 EXPORT_SYMBOL_GPL(gre_cisco_unregister);
372
373 static int __init gre_init(void)
374 {
375         pr_info("GRE over IPv4 demultiplexor driver\n");
376
377         if (inet_add_protocol(&net_gre_protocol, IPPROTO_GRE) < 0) {
378                 pr_err("can't add protocol\n");
379                 goto err;
380         }
381
382         if (gre_add_protocol(&ipgre_protocol, GREPROTO_CISCO) < 0) {
383                 pr_info("%s: can't add ipgre handler\n", __func__);
384                 goto err_gre;
385         }
386
387         if (gre_offload_init()) {
388                 pr_err("can't add protocol offload\n");
389                 goto err_gso;
390         }
391
392         return 0;
393 err_gso:
394         gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO);
395 err_gre:
396         inet_del_protocol(&net_gre_protocol, IPPROTO_GRE);
397 err:
398         return -EAGAIN;
399 }
400
401 static void __exit gre_exit(void)
402 {
403         gre_offload_exit();
404
405         gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO);
406         inet_del_protocol(&net_gre_protocol, IPPROTO_GRE);
407 }
408
409 module_init(gre_init);
410 module_exit(gre_exit);
411
412 MODULE_DESCRIPTION("GRE over IPv4 demultiplexer driver");
413 MODULE_AUTHOR("D. Kozlov (xeb@mail.ru)");
414 MODULE_LICENSE("GPL");