2 * Extension Header handling for IPv6
3 * Linux INET6 implementation
6 * Pedro Roque <roque@di.fc.ul.pt>
7 * Andi Kleen <ak@muc.de>
8 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
10 * $Id: exthdrs.c,v 1.13 2001/06/19 15:58:56 davem Exp $
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.
19 * yoshfuji : ensure not to overrun while parsing
21 * Mitsuru KANDA @USAGI and: Remove ipv6_parse_exthdrs().
22 * YOSHIFUJI Hideaki @USAGI Register inbound extension header
23 * handlers as inet6_protocol{}.
26 #include <linux/errno.h>
27 #include <linux/types.h>
28 #include <linux/socket.h>
29 #include <linux/sockios.h>
30 #include <linux/sched.h>
31 #include <linux/net.h>
32 #include <linux/netdevice.h>
33 #include <linux/in6.h>
34 #include <linux/icmpv6.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 #ifdef CONFIG_IPV6_MIP6
50 #include <asm/uaccess.h>
52 int ipv6_find_tlv(struct sk_buff *skb, int offset, int type)
54 int packet_len = skb->tail - skb->nh.raw;
55 struct ipv6_opt_hdr *hdr;
58 if (offset + 2 > packet_len)
60 hdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
61 len = ((hdr->hdrlen + 1) << 3);
63 if (offset + len > packet_len)
70 int opttype = skb->nh.raw[offset];
81 optlen = skb->nh.raw[offset + 1] + 2;
95 * Parsing tlv encoded headers.
97 * Parsing function "func" returns 1, if parsing succeed
98 * and 0, if it failed.
99 * It MUST NOT touch skb->h.
102 struct tlvtype_proc {
104 int (*func)(struct sk_buff **skbp, int offset);
107 /*********************
109 *********************/
111 /* An unknown option is detected, decide what to do */
113 static int ip6_tlvopt_unknown(struct sk_buff **skbp, int optoff)
115 struct sk_buff *skb = *skbp;
117 switch ((skb->nh.raw[optoff] & 0xC0) >> 6) {
121 case 1: /* drop packet */
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.
128 if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr))
130 case 2: /* send ICMP PARM PROB regardless and drop packet */
131 icmpv6_param_prob(skb, ICMPV6_UNK_OPTION, optoff);
139 /* Parse tlv encoded option header (hop-by-hop or destination) */
141 static int ip6_parse_tlv(struct tlvtype_proc *procs, struct sk_buff **skbp)
143 struct sk_buff *skb = *skbp;
144 struct tlvtype_proc *curr;
145 int off = skb->h.raw - skb->nh.raw;
146 int len = ((skb->h.raw[1]+1)<<3);
148 if ((skb->h.raw + len) - skb->data > skb_headlen(skb))
155 int optlen = skb->nh.raw[off+1]+2;
157 switch (skb->nh.raw[off]) {
165 default: /* Other TLV code so scan list */
168 for (curr=procs; curr->type >= 0; curr++) {
169 if (curr->type == skb->nh.raw[off]) {
170 /* type specific length/alignment
171 checks will be performed in the
173 if (curr->func(skbp, off) == 0)
178 if (curr->type < 0) {
179 if (ip6_tlvopt_unknown(skbp, off) == 0)
194 /*****************************
195 Destination options header.
196 *****************************/
198 #ifdef CONFIG_IPV6_MIP6
199 static int ipv6_dest_hao(struct sk_buff **skbp, int optoff)
201 struct sk_buff *skb = *skbp;
202 struct ipv6_destopt_hao *hao;
203 struct inet6_skb_parm *opt = IP6CB(skb);
204 struct ipv6hdr *ipv6h = (struct ipv6hdr *)skb->nh.raw;
205 struct in6_addr tmp_addr;
209 LIMIT_NETDEBUG(KERN_DEBUG "hao duplicated\n");
212 opt->dsthao = opt->dst1;
215 hao = (struct ipv6_destopt_hao *)(skb->nh.raw + optoff);
217 if (hao->length != 16) {
219 KERN_DEBUG "hao invalid option length = %d\n", hao->length);
223 if (!(ipv6_addr_type(&hao->addr) & IPV6_ADDR_UNICAST)) {
225 KERN_DEBUG "hao is not an unicast addr: " NIP6_FMT "\n", NIP6(hao->addr));
229 ret = xfrm6_input_addr(skb, (xfrm_address_t *)&ipv6h->daddr,
230 (xfrm_address_t *)&hao->addr, IPPROTO_DSTOPTS);
231 if (unlikely(ret < 0))
234 if (skb_cloned(skb)) {
235 struct sk_buff *skb2 = skb_copy(skb, GFP_ATOMIC);
236 struct inet6_skb_parm *opt2;
242 memcpy(opt2, opt, sizeof(*opt2));
246 /* update all variable using below by copied skbuff */
248 hao = (struct ipv6_destopt_hao *)(skb2->nh.raw + optoff);
249 ipv6h = (struct ipv6hdr *)skb2->nh.raw;
252 if (skb->ip_summed == CHECKSUM_COMPLETE)
253 skb->ip_summed = CHECKSUM_NONE;
255 ipv6_addr_copy(&tmp_addr, &ipv6h->saddr);
256 ipv6_addr_copy(&ipv6h->saddr, &hao->addr);
257 ipv6_addr_copy(&hao->addr, &tmp_addr);
259 if (skb->tstamp.off_sec == 0)
260 __net_timestamp(skb);
270 static struct tlvtype_proc tlvprocdestopt_lst[] = {
271 #ifdef CONFIG_IPV6_MIP6
273 .type = IPV6_TLV_HAO,
274 .func = ipv6_dest_hao,
280 static int ipv6_destopt_rcv(struct sk_buff **skbp)
282 struct sk_buff *skb = *skbp;
283 struct inet6_skb_parm *opt = IP6CB(skb);
284 #ifdef CONFIG_IPV6_MIP6
287 struct dst_entry *dst;
289 if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) ||
290 !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) {
291 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
292 IPSTATS_MIB_INHDRERRORS);
297 opt->lastopt = skb->h.raw - skb->nh.raw;
298 opt->dst1 = skb->h.raw - skb->nh.raw;
299 #ifdef CONFIG_IPV6_MIP6
303 dst = dst_clone(skb->dst);
304 if (ip6_parse_tlv(tlvprocdestopt_lst, skbp)) {
307 skb->h.raw += ((skb->h.raw[1]+1)<<3);
309 #ifdef CONFIG_IPV6_MIP6
312 opt->nhoff = opt->dst1;
317 IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_INHDRERRORS);
322 static struct inet6_protocol destopt_protocol = {
323 .handler = ipv6_destopt_rcv,
324 .flags = INET6_PROTO_NOPOLICY | INET6_PROTO_GSO_EXTHDR,
327 void __init ipv6_destopt_init(void)
329 if (inet6_add_protocol(&destopt_protocol, IPPROTO_DSTOPTS) < 0)
330 printk(KERN_ERR "ipv6_destopt_init: Could not register protocol\n");
333 /********************************
334 NONE header. No data in packet.
335 ********************************/
337 static int ipv6_nodata_rcv(struct sk_buff **skbp)
339 struct sk_buff *skb = *skbp;
345 static struct inet6_protocol nodata_protocol = {
346 .handler = ipv6_nodata_rcv,
347 .flags = INET6_PROTO_NOPOLICY,
350 void __init ipv6_nodata_init(void)
352 if (inet6_add_protocol(&nodata_protocol, IPPROTO_NONE) < 0)
353 printk(KERN_ERR "ipv6_nodata_init: Could not register protocol\n");
356 /********************************
358 ********************************/
360 static int ipv6_rthdr_rcv(struct sk_buff **skbp)
362 struct sk_buff *skb = *skbp;
363 struct inet6_skb_parm *opt = IP6CB(skb);
364 struct in6_addr *addr = NULL;
365 struct in6_addr daddr;
366 struct inet6_dev *idev;
368 struct ipv6_rt_hdr *hdr;
369 struct rt0_hdr *rthdr;
370 int accept_source_route = ipv6_devconf.accept_source_route;
372 if (accept_source_route < 0 ||
373 ((idev = in6_dev_get(skb->dev)) == NULL)) {
377 if (idev->cnf.accept_source_route < 0) {
383 if (accept_source_route > idev->cnf.accept_source_route)
384 accept_source_route = idev->cnf.accept_source_route;
388 if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) ||
389 !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) {
390 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
391 IPSTATS_MIB_INHDRERRORS);
396 hdr = (struct ipv6_rt_hdr *) skb->h.raw;
399 #ifdef CONFIG_IPV6_MIP6
400 case IPV6_SRCRT_TYPE_2:
403 case IPV6_SRCRT_TYPE_0:
404 if (accept_source_route > 0)
409 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
410 IPSTATS_MIB_INHDRERRORS);
411 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->type) - skb->nh.raw);
415 if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr) ||
416 skb->pkt_type != PACKET_HOST) {
417 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
418 IPSTATS_MIB_INADDRERRORS);
424 if (hdr->segments_left == 0) {
426 #ifdef CONFIG_IPV6_MIP6
427 case IPV6_SRCRT_TYPE_2:
428 /* Silently discard type 2 header unless it was
432 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
433 IPSTATS_MIB_INADDRERRORS);
443 opt->lastopt = skb->h.raw - skb->nh.raw;
444 opt->srcrt = skb->h.raw - skb->nh.raw;
445 skb->h.raw += (hdr->hdrlen + 1) << 3;
446 opt->dst0 = opt->dst1;
448 opt->nhoff = (&hdr->nexthdr) - skb->nh.raw;
453 case IPV6_SRCRT_TYPE_0:
454 if (hdr->hdrlen & 0x01) {
455 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
456 IPSTATS_MIB_INHDRERRORS);
457 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->hdrlen) - skb->nh.raw);
461 #ifdef CONFIG_IPV6_MIP6
462 case IPV6_SRCRT_TYPE_2:
463 /* Silently discard invalid RTH type 2 */
464 if (hdr->hdrlen != 2 || hdr->segments_left != 1) {
465 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
466 IPSTATS_MIB_INHDRERRORS);
475 * This is the routing header forwarding algorithm from
479 n = hdr->hdrlen >> 1;
481 if (hdr->segments_left > n) {
482 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
483 IPSTATS_MIB_INHDRERRORS);
484 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->segments_left) - skb->nh.raw);
488 /* We are about to mangle packet header. Be careful!
489 Do not damage packets queued somewhere.
491 if (skb_cloned(skb)) {
492 struct sk_buff *skb2 = skb_copy(skb, GFP_ATOMIC);
493 /* the copy is a forwarded packet */
495 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
496 IPSTATS_MIB_OUTDISCARDS);
503 hdr = (struct ipv6_rt_hdr *) skb2->h.raw;
506 if (skb->ip_summed == CHECKSUM_COMPLETE)
507 skb->ip_summed = CHECKSUM_NONE;
509 i = n - --hdr->segments_left;
511 rthdr = (struct rt0_hdr *) hdr;
516 #ifdef CONFIG_IPV6_MIP6
517 case IPV6_SRCRT_TYPE_2:
518 if (xfrm6_input_addr(skb, (xfrm_address_t *)addr,
519 (xfrm_address_t *)&skb->nh.ipv6h->saddr,
520 IPPROTO_ROUTING) < 0) {
521 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
522 IPSTATS_MIB_INADDRERRORS);
526 if (!ipv6_chk_home_addr(addr)) {
527 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
528 IPSTATS_MIB_INADDRERRORS);
538 if (ipv6_addr_is_multicast(addr)) {
539 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
540 IPSTATS_MIB_INADDRERRORS);
545 ipv6_addr_copy(&daddr, addr);
546 ipv6_addr_copy(addr, &skb->nh.ipv6h->daddr);
547 ipv6_addr_copy(&skb->nh.ipv6h->daddr, &daddr);
549 dst_release(xchg(&skb->dst, NULL));
550 ip6_route_input(skb);
551 if (skb->dst->error) {
552 skb_push(skb, skb->data - skb->nh.raw);
557 if (skb->dst->dev->flags&IFF_LOOPBACK) {
558 if (skb->nh.ipv6h->hop_limit <= 1) {
559 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
560 IPSTATS_MIB_INHDRERRORS);
561 icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
566 skb->nh.ipv6h->hop_limit--;
570 skb_push(skb, skb->data - skb->nh.raw);
575 static struct inet6_protocol rthdr_protocol = {
576 .handler = ipv6_rthdr_rcv,
577 .flags = INET6_PROTO_NOPOLICY | INET6_PROTO_GSO_EXTHDR,
580 void __init ipv6_rthdr_init(void)
582 if (inet6_add_protocol(&rthdr_protocol, IPPROTO_ROUTING) < 0)
583 printk(KERN_ERR "ipv6_rthdr_init: Could not register protocol\n");
587 This function inverts received rthdr.
588 NOTE: specs allow to make it automatically only if
589 packet authenticated.
591 I will not discuss it here (though, I am really pissed off at
592 this stupid requirement making rthdr idea useless)
594 Actually, it creates severe problems for us.
595 Embryonic requests has no associated sockets,
596 so that user have no control over it and
597 cannot not only to set reply options, but
598 even to know, that someone wants to connect
601 For now we need to test the engine, so that I created
602 temporary (or permanent) backdoor.
603 If listening socket set IPV6_RTHDR to 2, then we invert header.
607 struct ipv6_txoptions *
608 ipv6_invert_rthdr(struct sock *sk, struct ipv6_rt_hdr *hdr)
612 [ H1 -> H2 -> ... H_prev ] daddr=ME
615 [ H_prev -> ... -> H1 ] daddr =sender
617 Note, that IP output engine will rewrite this rthdr
618 by rotating it left by one addr.
622 struct rt0_hdr *rthdr = (struct rt0_hdr*)hdr;
623 struct rt0_hdr *irthdr;
624 struct ipv6_txoptions *opt;
625 int hdrlen = ipv6_optlen(hdr);
627 if (hdr->segments_left ||
628 hdr->type != IPV6_SRCRT_TYPE_0 ||
632 n = hdr->hdrlen >> 1;
633 opt = sock_kmalloc(sk, sizeof(*opt) + hdrlen, GFP_ATOMIC);
636 memset(opt, 0, sizeof(*opt));
637 opt->tot_len = sizeof(*opt) + hdrlen;
638 opt->srcrt = (void*)(opt+1);
639 opt->opt_nflen = hdrlen;
641 memcpy(opt->srcrt, hdr, sizeof(*hdr));
642 irthdr = (struct rt0_hdr*)opt->srcrt;
643 irthdr->reserved = 0;
644 opt->srcrt->segments_left = n;
646 memcpy(irthdr->addr+i, rthdr->addr+(n-1-i), 16);
650 EXPORT_SYMBOL_GPL(ipv6_invert_rthdr);
652 /**********************************
654 **********************************/
656 /* Router Alert as of RFC 2711 */
658 static int ipv6_hop_ra(struct sk_buff **skbp, int optoff)
660 struct sk_buff *skb = *skbp;
662 if (skb->nh.raw[optoff+1] == 2) {
663 IP6CB(skb)->ra = optoff;
666 LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_ra: wrong RA length %d\n",
667 skb->nh.raw[optoff+1]);
674 static int ipv6_hop_jumbo(struct sk_buff **skbp, int optoff)
676 struct sk_buff *skb = *skbp;
679 if (skb->nh.raw[optoff+1] != 4 || (optoff&3) != 2) {
680 LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n",
681 skb->nh.raw[optoff+1]);
682 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
683 IPSTATS_MIB_INHDRERRORS);
687 pkt_len = ntohl(*(__be32*)(skb->nh.raw+optoff+2));
688 if (pkt_len <= IPV6_MAXPLEN) {
689 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS);
690 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2);
693 if (skb->nh.ipv6h->payload_len) {
694 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS);
695 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff);
699 if (pkt_len > skb->len - sizeof(struct ipv6hdr)) {
700 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INTRUNCATEDPKTS);
704 if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr)))
714 static struct tlvtype_proc tlvprochopopt_lst[] = {
716 .type = IPV6_TLV_ROUTERALERT,
720 .type = IPV6_TLV_JUMBO,
721 .func = ipv6_hop_jumbo,
726 int ipv6_parse_hopopts(struct sk_buff **skbp)
728 struct sk_buff *skb = *skbp;
729 struct inet6_skb_parm *opt = IP6CB(skb);
732 * skb->nh.raw is equal to skb->data, and
733 * skb->h.raw - skb->nh.raw is always equal to
734 * sizeof(struct ipv6hdr) by definition of
735 * hop-by-hop options.
737 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr) + 8) ||
738 !pskb_may_pull(skb, sizeof(struct ipv6hdr) + ((skb->h.raw[1] + 1) << 3))) {
743 opt->hop = sizeof(struct ipv6hdr);
744 if (ip6_parse_tlv(tlvprochopopt_lst, skbp)) {
746 skb->h.raw += (skb->h.raw[1]+1)<<3;
748 opt->nhoff = sizeof(struct ipv6hdr);
755 * Creating outbound headers.
757 * "build" functions work when skb is filled from head to tail (datagram)
758 * "push" functions work when headers are added from tail to head (tcp)
760 * In both cases we assume, that caller reserved enough room
764 static void ipv6_push_rthdr(struct sk_buff *skb, u8 *proto,
765 struct ipv6_rt_hdr *opt,
766 struct in6_addr **addr_p)
768 struct rt0_hdr *phdr, *ihdr;
771 ihdr = (struct rt0_hdr *) opt;
773 phdr = (struct rt0_hdr *) skb_push(skb, (ihdr->rt_hdr.hdrlen + 1) << 3);
774 memcpy(phdr, ihdr, sizeof(struct rt0_hdr));
776 hops = ihdr->rt_hdr.hdrlen >> 1;
779 memcpy(phdr->addr, ihdr->addr + 1,
780 (hops - 1) * sizeof(struct in6_addr));
782 ipv6_addr_copy(phdr->addr + (hops - 1), *addr_p);
783 *addr_p = ihdr->addr;
785 phdr->rt_hdr.nexthdr = *proto;
786 *proto = NEXTHDR_ROUTING;
789 static void ipv6_push_exthdr(struct sk_buff *skb, u8 *proto, u8 type, struct ipv6_opt_hdr *opt)
791 struct ipv6_opt_hdr *h = (struct ipv6_opt_hdr *)skb_push(skb, ipv6_optlen(opt));
793 memcpy(h, opt, ipv6_optlen(opt));
798 void ipv6_push_nfrag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt,
800 struct in6_addr **daddr)
803 ipv6_push_rthdr(skb, proto, opt->srcrt, daddr);
805 * IPV6_RTHDRDSTOPTS is ignored
806 * unless IPV6_RTHDR is set (RFC3542).
809 ipv6_push_exthdr(skb, proto, NEXTHDR_DEST, opt->dst0opt);
812 ipv6_push_exthdr(skb, proto, NEXTHDR_HOP, opt->hopopt);
815 void ipv6_push_frag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt, u8 *proto)
818 ipv6_push_exthdr(skb, proto, NEXTHDR_DEST, opt->dst1opt);
821 struct ipv6_txoptions *
822 ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt)
824 struct ipv6_txoptions *opt2;
826 opt2 = sock_kmalloc(sk, opt->tot_len, GFP_ATOMIC);
828 long dif = (char*)opt2 - (char*)opt;
829 memcpy(opt2, opt, opt->tot_len);
831 *((char**)&opt2->hopopt) += dif;
833 *((char**)&opt2->dst0opt) += dif;
835 *((char**)&opt2->dst1opt) += dif;
837 *((char**)&opt2->srcrt) += dif;
842 EXPORT_SYMBOL_GPL(ipv6_dup_options);
844 static int ipv6_renew_option(void *ohdr,
845 struct ipv6_opt_hdr __user *newopt, int newoptlen,
847 struct ipv6_opt_hdr **hdr,
852 memcpy(*p, ohdr, ipv6_optlen((struct ipv6_opt_hdr *)ohdr));
853 *hdr = (struct ipv6_opt_hdr *)*p;
854 *p += CMSG_ALIGN(ipv6_optlen(*(struct ipv6_opt_hdr **)hdr));
858 if (copy_from_user(*p, newopt, newoptlen))
860 *hdr = (struct ipv6_opt_hdr *)*p;
861 if (ipv6_optlen(*(struct ipv6_opt_hdr **)hdr) > newoptlen)
863 *p += CMSG_ALIGN(newoptlen);
869 struct ipv6_txoptions *
870 ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt,
872 struct ipv6_opt_hdr __user *newopt, int newoptlen)
876 struct ipv6_txoptions *opt2;
880 if (newtype != IPV6_HOPOPTS && opt->hopopt)
881 tot_len += CMSG_ALIGN(ipv6_optlen(opt->hopopt));
882 if (newtype != IPV6_RTHDRDSTOPTS && opt->dst0opt)
883 tot_len += CMSG_ALIGN(ipv6_optlen(opt->dst0opt));
884 if (newtype != IPV6_RTHDR && opt->srcrt)
885 tot_len += CMSG_ALIGN(ipv6_optlen(opt->srcrt));
886 if (newtype != IPV6_DSTOPTS && opt->dst1opt)
887 tot_len += CMSG_ALIGN(ipv6_optlen(opt->dst1opt));
890 if (newopt && newoptlen)
891 tot_len += CMSG_ALIGN(newoptlen);
896 tot_len += sizeof(*opt2);
897 opt2 = sock_kmalloc(sk, tot_len, GFP_ATOMIC);
899 return ERR_PTR(-ENOBUFS);
901 memset(opt2, 0, tot_len);
903 opt2->tot_len = tot_len;
904 p = (char *)(opt2 + 1);
906 err = ipv6_renew_option(opt ? opt->hopopt : NULL, newopt, newoptlen,
907 newtype != IPV6_HOPOPTS,
912 err = ipv6_renew_option(opt ? opt->dst0opt : NULL, newopt, newoptlen,
913 newtype != IPV6_RTHDRDSTOPTS,
918 err = ipv6_renew_option(opt ? opt->srcrt : NULL, newopt, newoptlen,
919 newtype != IPV6_RTHDR,
920 (struct ipv6_opt_hdr **)&opt2->srcrt, &p);
924 err = ipv6_renew_option(opt ? opt->dst1opt : NULL, newopt, newoptlen,
925 newtype != IPV6_DSTOPTS,
930 opt2->opt_nflen = (opt2->hopopt ? ipv6_optlen(opt2->hopopt) : 0) +
931 (opt2->dst0opt ? ipv6_optlen(opt2->dst0opt) : 0) +
932 (opt2->srcrt ? ipv6_optlen(opt2->srcrt) : 0);
933 opt2->opt_flen = (opt2->dst1opt ? ipv6_optlen(opt2->dst1opt) : 0);
937 sock_kfree_s(sk, opt2, opt2->tot_len);
941 struct ipv6_txoptions *ipv6_fixup_options(struct ipv6_txoptions *opt_space,
942 struct ipv6_txoptions *opt)
945 * ignore the dest before srcrt unless srcrt is being included.
948 if (opt && opt->dst0opt && !opt->srcrt) {
949 if (opt_space != opt) {
950 memcpy(opt_space, opt, sizeof(*opt_space));
953 opt->opt_nflen -= ipv6_optlen(opt->dst0opt);