0ff2bf12ecd1fdca3ec9dc4fc86e610d4c2bc135
[linux-2.6.git] / net / ipv6 / exthdrs.c
1 /*
2  *      Extension Header handling for IPv6
3  *      Linux INET6 implementation
4  *
5  *      Authors:
6  *      Pedro Roque             <roque@di.fc.ul.pt>
7  *      Andi Kleen              <ak@muc.de>
8  *      Alexey Kuznetsov        <kuznet@ms2.inr.ac.ru>
9  *
10  *      $Id: exthdrs.c,v 1.13 2001/06/19 15:58:56 davem Exp $
11  *
12  *      This program is free software; you can redistribute it and/or
13  *      modify it under the terms of the GNU General Public License
14  *      as published by the Free Software Foundation; either version
15  *      2 of the License, or (at your option) any later version.
16  */
17
18 /* Changes:
19  *      yoshfuji                : ensure not to overrun while parsing
20  *                                tlv options.
21  *      Mitsuru KANDA @USAGI and: Remove ipv6_parse_exthdrs().
22  *      YOSHIFUJI Hideaki @USAGI  Register inbound extension header
23  *                                handlers as inet6_protocol{}.
24  */
25
26 #include <linux/errno.h>
27 #include <linux/types.h>
28 #include <linux/socket.h>
29 #include <linux/sockios.h>
30 #include <linux/net.h>
31 #include <linux/netdevice.h>
32 #include <linux/in6.h>
33 #include <linux/icmpv6.h>
34
35 #include <net/sock.h>
36 #include <net/snmp.h>
37
38 #include <net/ipv6.h>
39 #include <net/protocol.h>
40 #include <net/transp_v6.h>
41 #include <net/rawv6.h>
42 #include <net/ndisc.h>
43 #include <net/ip6_route.h>
44 #include <net/addrconf.h>
45 #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
46 #include <net/xfrm.h>
47 #endif
48
49 #include <asm/uaccess.h>
50
51 int ipv6_find_tlv(struct sk_buff *skb, int offset, int type)
52 {
53         const unsigned char *nh = skb_network_header(skb);
54         int packet_len = skb->tail - skb->network_header;
55         struct ipv6_opt_hdr *hdr;
56         int len;
57
58         if (offset + 2 > packet_len)
59                 goto bad;
60         hdr = (struct ipv6_opt_hdr *)(nh + offset);
61         len = ((hdr->hdrlen + 1) << 3);
62
63         if (offset + len > packet_len)
64                 goto bad;
65
66         offset += 2;
67         len -= 2;
68
69         while (len > 0) {
70                 int opttype = nh[offset];
71                 int optlen;
72
73                 if (opttype == type)
74                         return offset;
75
76                 switch (opttype) {
77                 case IPV6_TLV_PAD0:
78                         optlen = 1;
79                         break;
80                 default:
81                         optlen = nh[offset + 1] + 2;
82                         if (optlen > len)
83                                 goto bad;
84                         break;
85                 }
86                 offset += optlen;
87                 len -= optlen;
88         }
89         /* not_found */
90  bad:
91         return -1;
92 }
93 EXPORT_SYMBOL_GPL(ipv6_find_tlv);
94
95 /*
96  *      Parsing tlv encoded headers.
97  *
98  *      Parsing function "func" returns 1, if parsing succeed
99  *      and 0, if it failed.
100  *      It MUST NOT touch skb->h.
101  */
102
103 struct tlvtype_proc {
104         int     type;
105         int     (*func)(struct sk_buff **skbp, int offset);
106 };
107
108 /*********************
109   Generic functions
110  *********************/
111
112 /* An unknown option is detected, decide what to do */
113
114 static int ip6_tlvopt_unknown(struct sk_buff **skbp, int optoff)
115 {
116         struct sk_buff *skb = *skbp;
117
118         switch ((skb_network_header(skb)[optoff] & 0xC0) >> 6) {
119         case 0: /* ignore */
120                 return 1;
121
122         case 1: /* drop packet */
123                 break;
124
125         case 3: /* Send ICMP if not a multicast address and drop packet */
126                 /* Actually, it is redundant check. icmp_send
127                    will recheck in any case.
128                  */
129                 if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr))
130                         break;
131         case 2: /* send ICMP PARM PROB regardless and drop packet */
132                 icmpv6_param_prob(skb, ICMPV6_UNK_OPTION, optoff);
133                 return 0;
134         }
135
136         kfree_skb(skb);
137         return 0;
138 }
139
140 /* Parse tlv encoded option header (hop-by-hop or destination) */
141
142 static int ip6_parse_tlv(struct tlvtype_proc *procs, struct sk_buff **skbp)
143 {
144         struct sk_buff *skb = *skbp;
145         struct tlvtype_proc *curr;
146         const unsigned char *nh = skb_network_header(skb);
147         int off = skb_network_header_len(skb);
148         int len = (skb_transport_header(skb)[1] + 1) << 3;
149
150         if (skb_transport_offset(skb) + len > skb_headlen(skb))
151                 goto bad;
152
153         off += 2;
154         len -= 2;
155
156         while (len > 0) {
157                 int optlen = nh[off + 1] + 2;
158
159                 switch (nh[off]) {
160                 case IPV6_TLV_PAD0:
161                         optlen = 1;
162                         break;
163
164                 case IPV6_TLV_PADN:
165                         break;
166
167                 default: /* Other TLV code so scan list */
168                         if (optlen > len)
169                                 goto bad;
170                         for (curr=procs; curr->type >= 0; curr++) {
171                                 if (curr->type == nh[off]) {
172                                         /* type specific length/alignment
173                                            checks will be performed in the
174                                            func(). */
175                                         if (curr->func(skbp, off) == 0)
176                                                 return 0;
177                                         break;
178                                 }
179                         }
180                         if (curr->type < 0) {
181                                 if (ip6_tlvopt_unknown(skbp, off) == 0)
182                                         return 0;
183                         }
184                         break;
185                 }
186                 off += optlen;
187                 len -= optlen;
188         }
189         if (len == 0)
190                 return 1;
191 bad:
192         kfree_skb(skb);
193         return 0;
194 }
195
196 /*****************************
197   Destination options header.
198  *****************************/
199
200 #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
201 static int ipv6_dest_hao(struct sk_buff **skbp, int optoff)
202 {
203         struct sk_buff *skb = *skbp;
204         struct ipv6_destopt_hao *hao;
205         struct inet6_skb_parm *opt = IP6CB(skb);
206         struct ipv6hdr *ipv6h = ipv6_hdr(skb);
207         struct in6_addr tmp_addr;
208         int ret;
209
210         if (opt->dsthao) {
211                 LIMIT_NETDEBUG(KERN_DEBUG "hao duplicated\n");
212                 goto discard;
213         }
214         opt->dsthao = opt->dst1;
215         opt->dst1 = 0;
216
217         hao = (struct ipv6_destopt_hao *)(skb_network_header(skb) + optoff);
218
219         if (hao->length != 16) {
220                 LIMIT_NETDEBUG(
221                         KERN_DEBUG "hao invalid option length = %d\n", hao->length);
222                 goto discard;
223         }
224
225         if (!(ipv6_addr_type(&hao->addr) & IPV6_ADDR_UNICAST)) {
226                 LIMIT_NETDEBUG(
227                         KERN_DEBUG "hao is not an unicast addr: " NIP6_FMT "\n", NIP6(hao->addr));
228                 goto discard;
229         }
230
231         ret = xfrm6_input_addr(skb, (xfrm_address_t *)&ipv6h->daddr,
232                                (xfrm_address_t *)&hao->addr, IPPROTO_DSTOPTS);
233         if (unlikely(ret < 0))
234                 goto discard;
235
236         if (skb_cloned(skb)) {
237                 if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
238                         goto discard;
239
240                 /* update all variable using below by copied skbuff */
241                 hao = (struct ipv6_destopt_hao *)(skb_network_header(skb) +
242                                                   optoff);
243                 ipv6h = ipv6_hdr(skb);
244         }
245
246         if (skb->ip_summed == CHECKSUM_COMPLETE)
247                 skb->ip_summed = CHECKSUM_NONE;
248
249         ipv6_addr_copy(&tmp_addr, &ipv6h->saddr);
250         ipv6_addr_copy(&ipv6h->saddr, &hao->addr);
251         ipv6_addr_copy(&hao->addr, &tmp_addr);
252
253         if (skb->tstamp.tv64 == 0)
254                 __net_timestamp(skb);
255
256         return 1;
257
258  discard:
259         kfree_skb(skb);
260         return 0;
261 }
262 #endif
263
264 static struct tlvtype_proc tlvprocdestopt_lst[] = {
265 #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
266         {
267                 .type   = IPV6_TLV_HAO,
268                 .func   = ipv6_dest_hao,
269         },
270 #endif
271         {-1,                    NULL}
272 };
273
274 static int ipv6_destopt_rcv(struct sk_buff **skbp)
275 {
276         struct sk_buff *skb = *skbp;
277         struct inet6_skb_parm *opt = IP6CB(skb);
278 #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
279         __u16 dstbuf;
280 #endif
281         struct dst_entry *dst;
282
283         if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) ||
284             !pskb_may_pull(skb, (skb_transport_offset(skb) +
285                                  ((skb_transport_header(skb)[1] + 1) << 3)))) {
286                 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
287                                  IPSTATS_MIB_INHDRERRORS);
288                 kfree_skb(skb);
289                 return -1;
290         }
291
292         opt->lastopt = opt->dst1 = skb_network_header_len(skb);
293 #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
294         dstbuf = opt->dst1;
295 #endif
296
297         dst = dst_clone(skb->dst);
298         if (ip6_parse_tlv(tlvprocdestopt_lst, skbp)) {
299                 dst_release(dst);
300                 skb = *skbp;
301                 skb->transport_header += (skb_transport_header(skb)[1] + 1) << 3;
302                 opt = IP6CB(skb);
303 #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
304                 opt->nhoff = dstbuf;
305 #else
306                 opt->nhoff = opt->dst1;
307 #endif
308                 return 1;
309         }
310
311         IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_INHDRERRORS);
312         dst_release(dst);
313         return -1;
314 }
315
316 static struct inet6_protocol destopt_protocol = {
317         .handler        =       ipv6_destopt_rcv,
318         .flags          =       INET6_PROTO_NOPOLICY | INET6_PROTO_GSO_EXTHDR,
319 };
320
321 void __init ipv6_destopt_init(void)
322 {
323         if (inet6_add_protocol(&destopt_protocol, IPPROTO_DSTOPTS) < 0)
324                 printk(KERN_ERR "ipv6_destopt_init: Could not register protocol\n");
325 }
326
327 /********************************
328   NONE header. No data in packet.
329  ********************************/
330
331 static int ipv6_nodata_rcv(struct sk_buff **skbp)
332 {
333         struct sk_buff *skb = *skbp;
334
335         kfree_skb(skb);
336         return 0;
337 }
338
339 static struct inet6_protocol nodata_protocol = {
340         .handler        =       ipv6_nodata_rcv,
341         .flags          =       INET6_PROTO_NOPOLICY,
342 };
343
344 void __init ipv6_nodata_init(void)
345 {
346         if (inet6_add_protocol(&nodata_protocol, IPPROTO_NONE) < 0)
347                 printk(KERN_ERR "ipv6_nodata_init: Could not register protocol\n");
348 }
349
350 /********************************
351   Routing header.
352  ********************************/
353
354 static int ipv6_rthdr_rcv(struct sk_buff **skbp)
355 {
356         struct sk_buff *skb = *skbp;
357         struct inet6_skb_parm *opt = IP6CB(skb);
358         struct in6_addr *addr = NULL;
359         struct in6_addr daddr;
360         struct inet6_dev *idev;
361         int n, i;
362         struct ipv6_rt_hdr *hdr;
363         struct rt0_hdr *rthdr;
364         int accept_source_route = ipv6_devconf.accept_source_route;
365
366         idev = in6_dev_get(skb->dev);
367         if (idev) {
368                 if (accept_source_route > idev->cnf.accept_source_route)
369                         accept_source_route = idev->cnf.accept_source_route;
370                 in6_dev_put(idev);
371         }
372
373         if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) ||
374             !pskb_may_pull(skb, (skb_transport_offset(skb) +
375                                  ((skb_transport_header(skb)[1] + 1) << 3)))) {
376                 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
377                                  IPSTATS_MIB_INHDRERRORS);
378                 kfree_skb(skb);
379                 return -1;
380         }
381
382         hdr = (struct ipv6_rt_hdr *)skb_transport_header(skb);
383
384         if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr) ||
385             skb->pkt_type != PACKET_HOST) {
386                 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
387                                  IPSTATS_MIB_INADDRERRORS);
388                 kfree_skb(skb);
389                 return -1;
390         }
391
392 looped_back:
393         if (hdr->segments_left == 0) {
394                 switch (hdr->type) {
395 #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
396                 case IPV6_SRCRT_TYPE_2:
397                         /* Silently discard type 2 header unless it was
398                          * processed by own
399                          */
400                         if (!addr) {
401                                 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
402                                                  IPSTATS_MIB_INADDRERRORS);
403                                 kfree_skb(skb);
404                                 return -1;
405                         }
406                         break;
407 #endif
408                 default:
409                         break;
410                 }
411
412                 opt->lastopt = opt->srcrt = skb_network_header_len(skb);
413                 skb->transport_header += (hdr->hdrlen + 1) << 3;
414                 opt->dst0 = opt->dst1;
415                 opt->dst1 = 0;
416                 opt->nhoff = (&hdr->nexthdr) - skb_network_header(skb);
417                 return 1;
418         }
419
420         switch (hdr->type) {
421 #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
422         case IPV6_SRCRT_TYPE_2:
423                 if (accept_source_route < 0)
424                         goto unknown_rh;
425                 /* Silently discard invalid RTH type 2 */
426                 if (hdr->hdrlen != 2 || hdr->segments_left != 1) {
427                         IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
428                                          IPSTATS_MIB_INHDRERRORS);
429                         kfree_skb(skb);
430                         return -1;
431                 }
432                 break;
433 #endif
434         default:
435                 goto unknown_rh;
436         }
437
438         /*
439          *      This is the routing header forwarding algorithm from
440          *      RFC 2460, page 16.
441          */
442
443         n = hdr->hdrlen >> 1;
444
445         if (hdr->segments_left > n) {
446                 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
447                                  IPSTATS_MIB_INHDRERRORS);
448                 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
449                                   ((&hdr->segments_left) -
450                                    skb_network_header(skb)));
451                 return -1;
452         }
453
454         /* We are about to mangle packet header. Be careful!
455            Do not damage packets queued somewhere.
456          */
457         if (skb_cloned(skb)) {
458                 /* the copy is a forwarded packet */
459                 if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) {
460                         IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
461                                          IPSTATS_MIB_OUTDISCARDS);
462                         kfree_skb(skb);
463                         return -1;
464                 }
465                 hdr = (struct ipv6_rt_hdr *)skb_transport_header(skb);
466         }
467
468         if (skb->ip_summed == CHECKSUM_COMPLETE)
469                 skb->ip_summed = CHECKSUM_NONE;
470
471         i = n - --hdr->segments_left;
472
473         rthdr = (struct rt0_hdr *) hdr;
474         addr = rthdr->addr;
475         addr += i - 1;
476
477         switch (hdr->type) {
478 #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
479         case IPV6_SRCRT_TYPE_2:
480                 if (xfrm6_input_addr(skb, (xfrm_address_t *)addr,
481                                      (xfrm_address_t *)&ipv6_hdr(skb)->saddr,
482                                      IPPROTO_ROUTING) < 0) {
483                         IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
484                                          IPSTATS_MIB_INADDRERRORS);
485                         kfree_skb(skb);
486                         return -1;
487                 }
488                 if (!ipv6_chk_home_addr(addr)) {
489                         IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
490                                          IPSTATS_MIB_INADDRERRORS);
491                         kfree_skb(skb);
492                         return -1;
493                 }
494                 break;
495 #endif
496         default:
497                 break;
498         }
499
500         if (ipv6_addr_is_multicast(addr)) {
501                 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
502                                  IPSTATS_MIB_INADDRERRORS);
503                 kfree_skb(skb);
504                 return -1;
505         }
506
507         ipv6_addr_copy(&daddr, addr);
508         ipv6_addr_copy(addr, &ipv6_hdr(skb)->daddr);
509         ipv6_addr_copy(&ipv6_hdr(skb)->daddr, &daddr);
510
511         dst_release(xchg(&skb->dst, NULL));
512         ip6_route_input(skb);
513         if (skb->dst->error) {
514                 skb_push(skb, skb->data - skb_network_header(skb));
515                 dst_input(skb);
516                 return -1;
517         }
518
519         if (skb->dst->dev->flags&IFF_LOOPBACK) {
520                 if (ipv6_hdr(skb)->hop_limit <= 1) {
521                         IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
522                                          IPSTATS_MIB_INHDRERRORS);
523                         icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
524                                     0, skb->dev);
525                         kfree_skb(skb);
526                         return -1;
527                 }
528                 ipv6_hdr(skb)->hop_limit--;
529                 goto looped_back;
530         }
531
532         skb_push(skb, skb->data - skb_network_header(skb));
533         dst_input(skb);
534         return -1;
535
536 unknown_rh:
537         IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS);
538         icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
539                           (&hdr->type) - skb_network_header(skb));
540         return -1;
541 }
542
543 static struct inet6_protocol rthdr_protocol = {
544         .handler        =       ipv6_rthdr_rcv,
545         .flags          =       INET6_PROTO_NOPOLICY | INET6_PROTO_GSO_EXTHDR,
546 };
547
548 void __init ipv6_rthdr_init(void)
549 {
550         if (inet6_add_protocol(&rthdr_protocol, IPPROTO_ROUTING) < 0)
551                 printk(KERN_ERR "ipv6_rthdr_init: Could not register protocol\n");
552 };
553
554 /**********************************
555   Hop-by-hop options.
556  **********************************/
557
558 /*
559  * Note: we cannot rely on skb->dst before we assign it in ip6_route_input().
560  */
561 static inline struct inet6_dev *ipv6_skb_idev(struct sk_buff *skb)
562 {
563         return skb->dst ? ip6_dst_idev(skb->dst) : __in6_dev_get(skb->dev);
564 }
565
566 /* Router Alert as of RFC 2711 */
567
568 static int ipv6_hop_ra(struct sk_buff **skbp, int optoff)
569 {
570         struct sk_buff *skb = *skbp;
571         const unsigned char *nh = skb_network_header(skb);
572
573         if (nh[optoff + 1] == 2) {
574                 IP6CB(skb)->ra = optoff;
575                 return 1;
576         }
577         LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_ra: wrong RA length %d\n",
578                        nh[optoff + 1]);
579         kfree_skb(skb);
580         return 0;
581 }
582
583 /* Jumbo payload */
584
585 static int ipv6_hop_jumbo(struct sk_buff **skbp, int optoff)
586 {
587         struct sk_buff *skb = *skbp;
588         const unsigned char *nh = skb_network_header(skb);
589         u32 pkt_len;
590
591         if (nh[optoff + 1] != 4 || (optoff & 3) != 2) {
592                 LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n",
593                                nh[optoff+1]);
594                 IP6_INC_STATS_BH(ipv6_skb_idev(skb),
595                                  IPSTATS_MIB_INHDRERRORS);
596                 goto drop;
597         }
598
599         pkt_len = ntohl(*(__be32 *)(nh + optoff + 2));
600         if (pkt_len <= IPV6_MAXPLEN) {
601                 IP6_INC_STATS_BH(ipv6_skb_idev(skb), IPSTATS_MIB_INHDRERRORS);
602                 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2);
603                 return 0;
604         }
605         if (ipv6_hdr(skb)->payload_len) {
606                 IP6_INC_STATS_BH(ipv6_skb_idev(skb), IPSTATS_MIB_INHDRERRORS);
607                 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff);
608                 return 0;
609         }
610
611         if (pkt_len > skb->len - sizeof(struct ipv6hdr)) {
612                 IP6_INC_STATS_BH(ipv6_skb_idev(skb), IPSTATS_MIB_INTRUNCATEDPKTS);
613                 goto drop;
614         }
615
616         if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr)))
617                 goto drop;
618
619         return 1;
620
621 drop:
622         kfree_skb(skb);
623         return 0;
624 }
625
626 static struct tlvtype_proc tlvprochopopt_lst[] = {
627         {
628                 .type   = IPV6_TLV_ROUTERALERT,
629                 .func   = ipv6_hop_ra,
630         },
631         {
632                 .type   = IPV6_TLV_JUMBO,
633                 .func   = ipv6_hop_jumbo,
634         },
635         { -1, }
636 };
637
638 int ipv6_parse_hopopts(struct sk_buff **skbp)
639 {
640         struct sk_buff *skb = *skbp;
641         struct inet6_skb_parm *opt = IP6CB(skb);
642
643         /*
644          * skb_network_header(skb) is equal to skb->data, and
645          * skb_network_header_len(skb) is always equal to
646          * sizeof(struct ipv6hdr) by definition of
647          * hop-by-hop options.
648          */
649         if (!pskb_may_pull(skb, sizeof(struct ipv6hdr) + 8) ||
650             !pskb_may_pull(skb, (sizeof(struct ipv6hdr) +
651                                  ((skb_transport_header(skb)[1] + 1) << 3)))) {
652                 kfree_skb(skb);
653                 return -1;
654         }
655
656         opt->hop = sizeof(struct ipv6hdr);
657         if (ip6_parse_tlv(tlvprochopopt_lst, skbp)) {
658                 skb = *skbp;
659                 skb->transport_header += (skb_transport_header(skb)[1] + 1) << 3;
660                 opt = IP6CB(skb);
661                 opt->nhoff = sizeof(struct ipv6hdr);
662                 return 1;
663         }
664         return -1;
665 }
666
667 /*
668  *      Creating outbound headers.
669  *
670  *      "build" functions work when skb is filled from head to tail (datagram)
671  *      "push"  functions work when headers are added from tail to head (tcp)
672  *
673  *      In both cases we assume, that caller reserved enough room
674  *      for headers.
675  */
676
677 static void ipv6_push_rthdr(struct sk_buff *skb, u8 *proto,
678                             struct ipv6_rt_hdr *opt,
679                             struct in6_addr **addr_p)
680 {
681         struct rt0_hdr *phdr, *ihdr;
682         int hops;
683
684         ihdr = (struct rt0_hdr *) opt;
685
686         phdr = (struct rt0_hdr *) skb_push(skb, (ihdr->rt_hdr.hdrlen + 1) << 3);
687         memcpy(phdr, ihdr, sizeof(struct rt0_hdr));
688
689         hops = ihdr->rt_hdr.hdrlen >> 1;
690
691         if (hops > 1)
692                 memcpy(phdr->addr, ihdr->addr + 1,
693                        (hops - 1) * sizeof(struct in6_addr));
694
695         ipv6_addr_copy(phdr->addr + (hops - 1), *addr_p);
696         *addr_p = ihdr->addr;
697
698         phdr->rt_hdr.nexthdr = *proto;
699         *proto = NEXTHDR_ROUTING;
700 }
701
702 static void ipv6_push_exthdr(struct sk_buff *skb, u8 *proto, u8 type, struct ipv6_opt_hdr *opt)
703 {
704         struct ipv6_opt_hdr *h = (struct ipv6_opt_hdr *)skb_push(skb, ipv6_optlen(opt));
705
706         memcpy(h, opt, ipv6_optlen(opt));
707         h->nexthdr = *proto;
708         *proto = type;
709 }
710
711 void ipv6_push_nfrag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt,
712                           u8 *proto,
713                           struct in6_addr **daddr)
714 {
715         if (opt->srcrt) {
716                 ipv6_push_rthdr(skb, proto, opt->srcrt, daddr);
717                 /*
718                  * IPV6_RTHDRDSTOPTS is ignored
719                  * unless IPV6_RTHDR is set (RFC3542).
720                  */
721                 if (opt->dst0opt)
722                         ipv6_push_exthdr(skb, proto, NEXTHDR_DEST, opt->dst0opt);
723         }
724         if (opt->hopopt)
725                 ipv6_push_exthdr(skb, proto, NEXTHDR_HOP, opt->hopopt);
726 }
727
728 EXPORT_SYMBOL(ipv6_push_nfrag_opts);
729
730 void ipv6_push_frag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt, u8 *proto)
731 {
732         if (opt->dst1opt)
733                 ipv6_push_exthdr(skb, proto, NEXTHDR_DEST, opt->dst1opt);
734 }
735
736 struct ipv6_txoptions *
737 ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt)
738 {
739         struct ipv6_txoptions *opt2;
740
741         opt2 = sock_kmalloc(sk, opt->tot_len, GFP_ATOMIC);
742         if (opt2) {
743                 long dif = (char*)opt2 - (char*)opt;
744                 memcpy(opt2, opt, opt->tot_len);
745                 if (opt2->hopopt)
746                         *((char**)&opt2->hopopt) += dif;
747                 if (opt2->dst0opt)
748                         *((char**)&opt2->dst0opt) += dif;
749                 if (opt2->dst1opt)
750                         *((char**)&opt2->dst1opt) += dif;
751                 if (opt2->srcrt)
752                         *((char**)&opt2->srcrt) += dif;
753         }
754         return opt2;
755 }
756
757 EXPORT_SYMBOL_GPL(ipv6_dup_options);
758
759 static int ipv6_renew_option(void *ohdr,
760                              struct ipv6_opt_hdr __user *newopt, int newoptlen,
761                              int inherit,
762                              struct ipv6_opt_hdr **hdr,
763                              char **p)
764 {
765         if (inherit) {
766                 if (ohdr) {
767                         memcpy(*p, ohdr, ipv6_optlen((struct ipv6_opt_hdr *)ohdr));
768                         *hdr = (struct ipv6_opt_hdr *)*p;
769                         *p += CMSG_ALIGN(ipv6_optlen(*(struct ipv6_opt_hdr **)hdr));
770                 }
771         } else {
772                 if (newopt) {
773                         if (copy_from_user(*p, newopt, newoptlen))
774                                 return -EFAULT;
775                         *hdr = (struct ipv6_opt_hdr *)*p;
776                         if (ipv6_optlen(*(struct ipv6_opt_hdr **)hdr) > newoptlen)
777                                 return -EINVAL;
778                         *p += CMSG_ALIGN(newoptlen);
779                 }
780         }
781         return 0;
782 }
783
784 struct ipv6_txoptions *
785 ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt,
786                    int newtype,
787                    struct ipv6_opt_hdr __user *newopt, int newoptlen)
788 {
789         int tot_len = 0;
790         char *p;
791         struct ipv6_txoptions *opt2;
792         int err;
793
794         if (opt) {
795                 if (newtype != IPV6_HOPOPTS && opt->hopopt)
796                         tot_len += CMSG_ALIGN(ipv6_optlen(opt->hopopt));
797                 if (newtype != IPV6_RTHDRDSTOPTS && opt->dst0opt)
798                         tot_len += CMSG_ALIGN(ipv6_optlen(opt->dst0opt));
799                 if (newtype != IPV6_RTHDR && opt->srcrt)
800                         tot_len += CMSG_ALIGN(ipv6_optlen(opt->srcrt));
801                 if (newtype != IPV6_DSTOPTS && opt->dst1opt)
802                         tot_len += CMSG_ALIGN(ipv6_optlen(opt->dst1opt));
803         }
804
805         if (newopt && newoptlen)
806                 tot_len += CMSG_ALIGN(newoptlen);
807
808         if (!tot_len)
809                 return NULL;
810
811         tot_len += sizeof(*opt2);
812         opt2 = sock_kmalloc(sk, tot_len, GFP_ATOMIC);
813         if (!opt2)
814                 return ERR_PTR(-ENOBUFS);
815
816         memset(opt2, 0, tot_len);
817
818         opt2->tot_len = tot_len;
819         p = (char *)(opt2 + 1);
820
821         err = ipv6_renew_option(opt ? opt->hopopt : NULL, newopt, newoptlen,
822                                 newtype != IPV6_HOPOPTS,
823                                 &opt2->hopopt, &p);
824         if (err)
825                 goto out;
826
827         err = ipv6_renew_option(opt ? opt->dst0opt : NULL, newopt, newoptlen,
828                                 newtype != IPV6_RTHDRDSTOPTS,
829                                 &opt2->dst0opt, &p);
830         if (err)
831                 goto out;
832
833         err = ipv6_renew_option(opt ? opt->srcrt : NULL, newopt, newoptlen,
834                                 newtype != IPV6_RTHDR,
835                                 (struct ipv6_opt_hdr **)&opt2->srcrt, &p);
836         if (err)
837                 goto out;
838
839         err = ipv6_renew_option(opt ? opt->dst1opt : NULL, newopt, newoptlen,
840                                 newtype != IPV6_DSTOPTS,
841                                 &opt2->dst1opt, &p);
842         if (err)
843                 goto out;
844
845         opt2->opt_nflen = (opt2->hopopt ? ipv6_optlen(opt2->hopopt) : 0) +
846                           (opt2->dst0opt ? ipv6_optlen(opt2->dst0opt) : 0) +
847                           (opt2->srcrt ? ipv6_optlen(opt2->srcrt) : 0);
848         opt2->opt_flen = (opt2->dst1opt ? ipv6_optlen(opt2->dst1opt) : 0);
849
850         return opt2;
851 out:
852         sock_kfree_s(sk, opt2, opt2->tot_len);
853         return ERR_PTR(err);
854 }
855
856 struct ipv6_txoptions *ipv6_fixup_options(struct ipv6_txoptions *opt_space,
857                                           struct ipv6_txoptions *opt)
858 {
859         /*
860          * ignore the dest before srcrt unless srcrt is being included.
861          * --yoshfuji
862          */
863         if (opt && opt->dst0opt && !opt->srcrt) {
864                 if (opt_space != opt) {
865                         memcpy(opt_space, opt, sizeof(*opt_space));
866                         opt = opt_space;
867                 }
868                 opt->opt_nflen -= ipv6_optlen(opt->dst0opt);
869                 opt->dst0opt = NULL;
870         }
871
872         return opt;
873 }
874