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