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;
96 * Parsing tlv encoded headers.
98 * Parsing function "func" returns 1, if parsing succeed
99 * and 0, if it failed.
100 * It MUST NOT touch skb->h.
103 struct tlvtype_proc {
105 int (*func)(struct sk_buff **skbp, int offset);
108 /*********************
110 *********************/
112 /* An unknown option is detected, decide what to do */
114 static int ip6_tlvopt_unknown(struct sk_buff **skbp, int optoff)
116 struct sk_buff *skb = *skbp;
118 switch ((skb->nh.raw[optoff] & 0xC0) >> 6) {
122 case 1: /* drop packet */
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.
129 if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr))
131 case 2: /* send ICMP PARM PROB regardless and drop packet */
132 icmpv6_param_prob(skb, ICMPV6_UNK_OPTION, optoff);
140 /* Parse tlv encoded option header (hop-by-hop or destination) */
142 static int ip6_parse_tlv(struct tlvtype_proc *procs, struct sk_buff **skbp)
144 struct sk_buff *skb = *skbp;
145 struct tlvtype_proc *curr;
146 int off = skb->h.raw - skb->nh.raw;
147 int len = ((skb->h.raw[1]+1)<<3);
149 if ((skb->h.raw + len) - skb->data > skb_headlen(skb))
156 int optlen = skb->nh.raw[off+1]+2;
158 switch (skb->nh.raw[off]) {
166 default: /* Other TLV code so scan list */
169 for (curr=procs; curr->type >= 0; curr++) {
170 if (curr->type == skb->nh.raw[off]) {
171 /* type specific length/alignment
172 checks will be performed in the
174 if (curr->func(skbp, off) == 0)
179 if (curr->type < 0) {
180 if (ip6_tlvopt_unknown(skbp, off) == 0)
195 /*****************************
196 Destination options header.
197 *****************************/
199 #ifdef CONFIG_IPV6_MIP6
200 static int ipv6_dest_hao(struct sk_buff **skbp, int optoff)
202 struct sk_buff *skb = *skbp;
203 struct ipv6_destopt_hao *hao;
204 struct inet6_skb_parm *opt = IP6CB(skb);
205 struct ipv6hdr *ipv6h = (struct ipv6hdr *)skb->nh.raw;
206 struct in6_addr tmp_addr;
210 LIMIT_NETDEBUG(KERN_DEBUG "hao duplicated\n");
213 opt->dsthao = opt->dst1;
216 hao = (struct ipv6_destopt_hao *)(skb->nh.raw + optoff);
218 if (hao->length != 16) {
220 KERN_DEBUG "hao invalid option length = %d\n", hao->length);
224 if (!(ipv6_addr_type(&hao->addr) & IPV6_ADDR_UNICAST)) {
226 KERN_DEBUG "hao is not an unicast addr: " NIP6_FMT "\n", NIP6(hao->addr));
230 ret = xfrm6_input_addr(skb, (xfrm_address_t *)&ipv6h->daddr,
231 (xfrm_address_t *)&hao->addr, IPPROTO_DSTOPTS);
232 if (unlikely(ret < 0))
235 if (skb_cloned(skb)) {
236 struct sk_buff *skb2 = skb_copy(skb, GFP_ATOMIC);
242 /* update all variable using below by copied skbuff */
244 hao = (struct ipv6_destopt_hao *)(skb2->nh.raw + optoff);
245 ipv6h = (struct ipv6hdr *)skb2->nh.raw;
248 if (skb->ip_summed == CHECKSUM_COMPLETE)
249 skb->ip_summed = CHECKSUM_NONE;
251 ipv6_addr_copy(&tmp_addr, &ipv6h->saddr);
252 ipv6_addr_copy(&ipv6h->saddr, &hao->addr);
253 ipv6_addr_copy(&hao->addr, &tmp_addr);
255 if (skb->tstamp.off_sec == 0)
256 __net_timestamp(skb);
266 static struct tlvtype_proc tlvprocdestopt_lst[] = {
267 #ifdef CONFIG_IPV6_MIP6
269 .type = IPV6_TLV_HAO,
270 .func = ipv6_dest_hao,
276 static int ipv6_destopt_rcv(struct sk_buff **skbp)
278 struct sk_buff *skb = *skbp;
279 struct inet6_skb_parm *opt = IP6CB(skb);
280 #ifdef CONFIG_IPV6_MIP6
284 if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) ||
285 !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) {
286 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
291 opt->lastopt = skb->h.raw - skb->nh.raw;
292 opt->dst1 = skb->h.raw - skb->nh.raw;
293 #ifdef CONFIG_IPV6_MIP6
297 if (ip6_parse_tlv(tlvprocdestopt_lst, skbp)) {
299 skb->h.raw += ((skb->h.raw[1]+1)<<3);
300 #ifdef CONFIG_IPV6_MIP6
303 opt->nhoff = opt->dst1;
308 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
312 static struct inet6_protocol destopt_protocol = {
313 .handler = ipv6_destopt_rcv,
314 .flags = INET6_PROTO_NOPOLICY | INET6_PROTO_GSO_EXTHDR,
317 void __init ipv6_destopt_init(void)
319 if (inet6_add_protocol(&destopt_protocol, IPPROTO_DSTOPTS) < 0)
320 printk(KERN_ERR "ipv6_destopt_init: Could not register protocol\n");
323 /********************************
324 NONE header. No data in packet.
325 ********************************/
327 static int ipv6_nodata_rcv(struct sk_buff **skbp)
329 struct sk_buff *skb = *skbp;
335 static struct inet6_protocol nodata_protocol = {
336 .handler = ipv6_nodata_rcv,
337 .flags = INET6_PROTO_NOPOLICY,
340 void __init ipv6_nodata_init(void)
342 if (inet6_add_protocol(&nodata_protocol, IPPROTO_NONE) < 0)
343 printk(KERN_ERR "ipv6_nodata_init: Could not register protocol\n");
346 /********************************
348 ********************************/
350 static int ipv6_rthdr_rcv(struct sk_buff **skbp)
352 struct sk_buff *skb = *skbp;
353 struct inet6_skb_parm *opt = IP6CB(skb);
354 struct in6_addr *addr = NULL;
355 struct in6_addr daddr;
358 struct ipv6_rt_hdr *hdr;
359 struct rt0_hdr *rthdr;
361 if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) ||
362 !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) {
363 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
368 hdr = (struct ipv6_rt_hdr *) skb->h.raw;
370 if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr) ||
371 skb->pkt_type != PACKET_HOST) {
372 IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS);
378 if (hdr->segments_left == 0) {
380 #ifdef CONFIG_IPV6_MIP6
381 case IPV6_SRCRT_TYPE_2:
382 /* Silently discard type 2 header unless it was
386 IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS);
396 opt->lastopt = skb->h.raw - skb->nh.raw;
397 opt->srcrt = skb->h.raw - skb->nh.raw;
398 skb->h.raw += (hdr->hdrlen + 1) << 3;
399 opt->dst0 = opt->dst1;
401 opt->nhoff = (&hdr->nexthdr) - skb->nh.raw;
406 case IPV6_SRCRT_TYPE_0:
407 if (hdr->hdrlen & 0x01) {
408 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
409 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->hdrlen) - skb->nh.raw);
413 #ifdef CONFIG_IPV6_MIP6
414 case IPV6_SRCRT_TYPE_2:
415 /* Silently discard invalid RTH type 2 */
416 if (hdr->hdrlen != 2 || hdr->segments_left != 1) {
417 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
424 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
425 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->type) - skb->nh.raw);
430 * This is the routing header forwarding algorithm from
434 n = hdr->hdrlen >> 1;
436 if (hdr->segments_left > n) {
437 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
438 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->segments_left) - skb->nh.raw);
442 /* We are about to mangle packet header. Be careful!
443 Do not damage packets queued somewhere.
445 if (skb_cloned(skb)) {
446 struct sk_buff *skb2 = skb_copy(skb, GFP_ATOMIC);
448 /* the copy is a forwarded packet */
450 IP6_INC_STATS_BH(IPSTATS_MIB_OUTDISCARDS);
455 hdr = (struct ipv6_rt_hdr *) skb2->h.raw;
458 if (skb->ip_summed == CHECKSUM_COMPLETE)
459 skb->ip_summed = CHECKSUM_NONE;
461 i = n - --hdr->segments_left;
463 rthdr = (struct rt0_hdr *) hdr;
468 #ifdef CONFIG_IPV6_MIP6
469 case IPV6_SRCRT_TYPE_2:
470 if (xfrm6_input_addr(skb, (xfrm_address_t *)addr,
471 (xfrm_address_t *)&skb->nh.ipv6h->saddr,
472 IPPROTO_ROUTING) < 0) {
473 IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS);
477 if (!ipv6_chk_home_addr(addr)) {
478 IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS);
488 if (ipv6_addr_is_multicast(addr)) {
489 IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS);
494 ipv6_addr_copy(&daddr, addr);
495 ipv6_addr_copy(addr, &skb->nh.ipv6h->daddr);
496 ipv6_addr_copy(&skb->nh.ipv6h->daddr, &daddr);
498 dst_release(xchg(&skb->dst, NULL));
499 ip6_route_input(skb);
500 if (skb->dst->error) {
501 skb_push(skb, skb->data - skb->nh.raw);
506 if (skb->dst->dev->flags&IFF_LOOPBACK) {
507 if (skb->nh.ipv6h->hop_limit <= 1) {
508 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
509 icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
514 skb->nh.ipv6h->hop_limit--;
518 skb_push(skb, skb->data - skb->nh.raw);
523 static struct inet6_protocol rthdr_protocol = {
524 .handler = ipv6_rthdr_rcv,
525 .flags = INET6_PROTO_NOPOLICY | INET6_PROTO_GSO_EXTHDR,
528 void __init ipv6_rthdr_init(void)
530 if (inet6_add_protocol(&rthdr_protocol, IPPROTO_ROUTING) < 0)
531 printk(KERN_ERR "ipv6_rthdr_init: Could not register protocol\n");
535 This function inverts received rthdr.
536 NOTE: specs allow to make it automatically only if
537 packet authenticated.
539 I will not discuss it here (though, I am really pissed off at
540 this stupid requirement making rthdr idea useless)
542 Actually, it creates severe problems for us.
543 Embryonic requests has no associated sockets,
544 so that user have no control over it and
545 cannot not only to set reply options, but
546 even to know, that someone wants to connect
549 For now we need to test the engine, so that I created
550 temporary (or permanent) backdoor.
551 If listening socket set IPV6_RTHDR to 2, then we invert header.
555 struct ipv6_txoptions *
556 ipv6_invert_rthdr(struct sock *sk, struct ipv6_rt_hdr *hdr)
560 [ H1 -> H2 -> ... H_prev ] daddr=ME
563 [ H_prev -> ... -> H1 ] daddr =sender
565 Note, that IP output engine will rewrite this rthdr
566 by rotating it left by one addr.
570 struct rt0_hdr *rthdr = (struct rt0_hdr*)hdr;
571 struct rt0_hdr *irthdr;
572 struct ipv6_txoptions *opt;
573 int hdrlen = ipv6_optlen(hdr);
575 if (hdr->segments_left ||
576 hdr->type != IPV6_SRCRT_TYPE_0 ||
580 n = hdr->hdrlen >> 1;
581 opt = sock_kmalloc(sk, sizeof(*opt) + hdrlen, GFP_ATOMIC);
584 memset(opt, 0, sizeof(*opt));
585 opt->tot_len = sizeof(*opt) + hdrlen;
586 opt->srcrt = (void*)(opt+1);
587 opt->opt_nflen = hdrlen;
589 memcpy(opt->srcrt, hdr, sizeof(*hdr));
590 irthdr = (struct rt0_hdr*)opt->srcrt;
591 irthdr->reserved = 0;
592 opt->srcrt->segments_left = n;
594 memcpy(irthdr->addr+i, rthdr->addr+(n-1-i), 16);
598 EXPORT_SYMBOL_GPL(ipv6_invert_rthdr);
600 /**********************************
602 **********************************/
604 /* Router Alert as of RFC 2711 */
606 static int ipv6_hop_ra(struct sk_buff **skbp, int optoff)
608 struct sk_buff *skb = *skbp;
610 if (skb->nh.raw[optoff+1] == 2) {
611 IP6CB(skb)->ra = optoff;
614 LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_ra: wrong RA length %d\n",
615 skb->nh.raw[optoff+1]);
622 static int ipv6_hop_jumbo(struct sk_buff **skbp, int optoff)
624 struct sk_buff *skb = *skbp;
627 if (skb->nh.raw[optoff+1] != 4 || (optoff&3) != 2) {
628 LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n",
629 skb->nh.raw[optoff+1]);
630 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
634 pkt_len = ntohl(*(u32*)(skb->nh.raw+optoff+2));
635 if (pkt_len <= IPV6_MAXPLEN) {
636 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
637 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2);
640 if (skb->nh.ipv6h->payload_len) {
641 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
642 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff);
646 if (pkt_len > skb->len - sizeof(struct ipv6hdr)) {
647 IP6_INC_STATS_BH(IPSTATS_MIB_INTRUNCATEDPKTS);
651 if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr)))
661 static struct tlvtype_proc tlvprochopopt_lst[] = {
663 .type = IPV6_TLV_ROUTERALERT,
667 .type = IPV6_TLV_JUMBO,
668 .func = ipv6_hop_jumbo,
673 int ipv6_parse_hopopts(struct sk_buff **skbp)
675 struct sk_buff *skb = *skbp;
676 struct inet6_skb_parm *opt = IP6CB(skb);
679 * skb->nh.raw is equal to skb->data, and
680 * skb->h.raw - skb->nh.raw is always equal to
681 * sizeof(struct ipv6hdr) by definition of
682 * hop-by-hop options.
684 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr) + 8) ||
685 !pskb_may_pull(skb, sizeof(struct ipv6hdr) + ((skb->h.raw[1] + 1) << 3))) {
690 opt->hop = sizeof(struct ipv6hdr);
691 if (ip6_parse_tlv(tlvprochopopt_lst, skbp)) {
693 skb->h.raw += (skb->h.raw[1]+1)<<3;
694 opt->nhoff = sizeof(struct ipv6hdr);
701 * Creating outbound headers.
703 * "build" functions work when skb is filled from head to tail (datagram)
704 * "push" functions work when headers are added from tail to head (tcp)
706 * In both cases we assume, that caller reserved enough room
710 static void ipv6_push_rthdr(struct sk_buff *skb, u8 *proto,
711 struct ipv6_rt_hdr *opt,
712 struct in6_addr **addr_p)
714 struct rt0_hdr *phdr, *ihdr;
717 ihdr = (struct rt0_hdr *) opt;
719 phdr = (struct rt0_hdr *) skb_push(skb, (ihdr->rt_hdr.hdrlen + 1) << 3);
720 memcpy(phdr, ihdr, sizeof(struct rt0_hdr));
722 hops = ihdr->rt_hdr.hdrlen >> 1;
725 memcpy(phdr->addr, ihdr->addr + 1,
726 (hops - 1) * sizeof(struct in6_addr));
728 ipv6_addr_copy(phdr->addr + (hops - 1), *addr_p);
729 *addr_p = ihdr->addr;
731 phdr->rt_hdr.nexthdr = *proto;
732 *proto = NEXTHDR_ROUTING;
735 static void ipv6_push_exthdr(struct sk_buff *skb, u8 *proto, u8 type, struct ipv6_opt_hdr *opt)
737 struct ipv6_opt_hdr *h = (struct ipv6_opt_hdr *)skb_push(skb, ipv6_optlen(opt));
739 memcpy(h, opt, ipv6_optlen(opt));
744 void ipv6_push_nfrag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt,
746 struct in6_addr **daddr)
749 ipv6_push_rthdr(skb, proto, opt->srcrt, daddr);
751 * IPV6_RTHDRDSTOPTS is ignored
752 * unless IPV6_RTHDR is set (RFC3542).
755 ipv6_push_exthdr(skb, proto, NEXTHDR_DEST, opt->dst0opt);
758 ipv6_push_exthdr(skb, proto, NEXTHDR_HOP, opt->hopopt);
761 void ipv6_push_frag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt, u8 *proto)
764 ipv6_push_exthdr(skb, proto, NEXTHDR_DEST, opt->dst1opt);
767 struct ipv6_txoptions *
768 ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt)
770 struct ipv6_txoptions *opt2;
772 opt2 = sock_kmalloc(sk, opt->tot_len, GFP_ATOMIC);
774 long dif = (char*)opt2 - (char*)opt;
775 memcpy(opt2, opt, opt->tot_len);
777 *((char**)&opt2->hopopt) += dif;
779 *((char**)&opt2->dst0opt) += dif;
781 *((char**)&opt2->dst1opt) += dif;
783 *((char**)&opt2->srcrt) += dif;
788 EXPORT_SYMBOL_GPL(ipv6_dup_options);
790 static int ipv6_renew_option(void *ohdr,
791 struct ipv6_opt_hdr __user *newopt, int newoptlen,
793 struct ipv6_opt_hdr **hdr,
798 memcpy(*p, ohdr, ipv6_optlen((struct ipv6_opt_hdr *)ohdr));
799 *hdr = (struct ipv6_opt_hdr *)*p;
800 *p += CMSG_ALIGN(ipv6_optlen(*(struct ipv6_opt_hdr **)hdr));
804 if (copy_from_user(*p, newopt, newoptlen))
806 *hdr = (struct ipv6_opt_hdr *)*p;
807 if (ipv6_optlen(*(struct ipv6_opt_hdr **)hdr) > newoptlen)
809 *p += CMSG_ALIGN(newoptlen);
815 struct ipv6_txoptions *
816 ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt,
818 struct ipv6_opt_hdr __user *newopt, int newoptlen)
822 struct ipv6_txoptions *opt2;
826 if (newtype != IPV6_HOPOPTS && opt->hopopt)
827 tot_len += CMSG_ALIGN(ipv6_optlen(opt->hopopt));
828 if (newtype != IPV6_RTHDRDSTOPTS && opt->dst0opt)
829 tot_len += CMSG_ALIGN(ipv6_optlen(opt->dst0opt));
830 if (newtype != IPV6_RTHDR && opt->srcrt)
831 tot_len += CMSG_ALIGN(ipv6_optlen(opt->srcrt));
832 if (newtype != IPV6_DSTOPTS && opt->dst1opt)
833 tot_len += CMSG_ALIGN(ipv6_optlen(opt->dst1opt));
836 if (newopt && newoptlen)
837 tot_len += CMSG_ALIGN(newoptlen);
842 tot_len += sizeof(*opt2);
843 opt2 = sock_kmalloc(sk, tot_len, GFP_ATOMIC);
845 return ERR_PTR(-ENOBUFS);
847 memset(opt2, 0, tot_len);
849 opt2->tot_len = tot_len;
850 p = (char *)(opt2 + 1);
852 err = ipv6_renew_option(opt ? opt->hopopt : NULL, newopt, newoptlen,
853 newtype != IPV6_HOPOPTS,
858 err = ipv6_renew_option(opt ? opt->dst0opt : NULL, newopt, newoptlen,
859 newtype != IPV6_RTHDRDSTOPTS,
864 err = ipv6_renew_option(opt ? opt->srcrt : NULL, newopt, newoptlen,
865 newtype != IPV6_RTHDR,
866 (struct ipv6_opt_hdr **)&opt2->srcrt, &p);
870 err = ipv6_renew_option(opt ? opt->dst1opt : NULL, newopt, newoptlen,
871 newtype != IPV6_DSTOPTS,
876 opt2->opt_nflen = (opt2->hopopt ? ipv6_optlen(opt2->hopopt) : 0) +
877 (opt2->dst0opt ? ipv6_optlen(opt2->dst0opt) : 0) +
878 (opt2->srcrt ? ipv6_optlen(opt2->srcrt) : 0);
879 opt2->opt_flen = (opt2->dst1opt ? ipv6_optlen(opt2->dst1opt) : 0);
883 sock_kfree_s(sk, opt2, opt2->tot_len);
887 struct ipv6_txoptions *ipv6_fixup_options(struct ipv6_txoptions *opt_space,
888 struct ipv6_txoptions *opt)
891 * ignore the dest before srcrt unless srcrt is being included.
894 if (opt && opt->dst0opt && !opt->srcrt) {
895 if (opt_space != opt) {
896 memcpy(opt_space, opt, sizeof(*opt_space));
899 opt->opt_nflen -= ipv6_optlen(opt->dst0opt);