2 * Extension Header handling for IPv6
3 * Linux INET6 implementation
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/net.h>
31 #include <linux/netdevice.h>
32 #include <linux/in6.h>
33 #include <linux/icmpv6.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 #ifdef CONFIG_IPV6_MIP6
49 #include <asm/uaccess.h>
51 int ipv6_find_tlv(struct sk_buff *skb, int offset, int type)
53 const unsigned char *nh = skb_network_header(skb);
54 int packet_len = skb->tail - skb->network_header;
55 struct ipv6_opt_hdr *hdr;
58 if (offset + 2 > packet_len)
60 hdr = (struct ipv6_opt_hdr *)(nh + offset);
61 len = ((hdr->hdrlen + 1) << 3);
63 if (offset + len > packet_len)
70 int opttype = nh[offset];
81 optlen = nh[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_network_header(skb)[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(&ipv6_hdr(skb)->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 const unsigned char *nh = skb_network_header(skb);
146 int off = skb_network_header_len(skb);
147 int len = (skb_transport_header(skb)[1] + 1) << 3;
149 if (skb_transport_offset(skb) + len > skb_headlen(skb))
156 int optlen = nh[off + 1] + 2;
166 default: /* Other TLV code so scan list */
169 for (curr=procs; curr->type >= 0; curr++) {
170 if (curr->type == nh[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 = ipv6_hdr(skb);
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_network_header(skb) + 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);
237 struct inet6_skb_parm *opt2;
243 memcpy(opt2, opt, sizeof(*opt2));
247 /* update all variable using below by copied skbuff */
249 hao = (struct ipv6_destopt_hao *)(skb_network_header(skb2) +
251 ipv6h = ipv6_hdr(skb2);
254 if (skb->ip_summed == CHECKSUM_COMPLETE)
255 skb->ip_summed = CHECKSUM_NONE;
257 ipv6_addr_copy(&tmp_addr, &ipv6h->saddr);
258 ipv6_addr_copy(&ipv6h->saddr, &hao->addr);
259 ipv6_addr_copy(&hao->addr, &tmp_addr);
261 if (skb->tstamp.tv64 == 0)
262 __net_timestamp(skb);
272 static struct tlvtype_proc tlvprocdestopt_lst[] = {
273 #ifdef CONFIG_IPV6_MIP6
275 .type = IPV6_TLV_HAO,
276 .func = ipv6_dest_hao,
282 static int ipv6_destopt_rcv(struct sk_buff **skbp)
284 struct sk_buff *skb = *skbp;
285 struct inet6_skb_parm *opt = IP6CB(skb);
286 #ifdef CONFIG_IPV6_MIP6
289 struct dst_entry *dst;
291 if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) ||
292 !pskb_may_pull(skb, (skb_transport_offset(skb) +
293 ((skb_transport_header(skb)[1] + 1) << 3)))) {
294 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
295 IPSTATS_MIB_INHDRERRORS);
300 opt->lastopt = opt->dst1 = skb_network_header_len(skb);
301 #ifdef CONFIG_IPV6_MIP6
305 dst = dst_clone(skb->dst);
306 if (ip6_parse_tlv(tlvprocdestopt_lst, skbp)) {
309 skb->transport_header += (skb_transport_header(skb)[1] + 1) << 3;
311 #ifdef CONFIG_IPV6_MIP6
314 opt->nhoff = opt->dst1;
319 IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_INHDRERRORS);
324 static struct inet6_protocol destopt_protocol = {
325 .handler = ipv6_destopt_rcv,
326 .flags = INET6_PROTO_NOPOLICY | INET6_PROTO_GSO_EXTHDR,
329 void __init ipv6_destopt_init(void)
331 if (inet6_add_protocol(&destopt_protocol, IPPROTO_DSTOPTS) < 0)
332 printk(KERN_ERR "ipv6_destopt_init: Could not register protocol\n");
335 /********************************
336 NONE header. No data in packet.
337 ********************************/
339 static int ipv6_nodata_rcv(struct sk_buff **skbp)
341 struct sk_buff *skb = *skbp;
347 static struct inet6_protocol nodata_protocol = {
348 .handler = ipv6_nodata_rcv,
349 .flags = INET6_PROTO_NOPOLICY,
352 void __init ipv6_nodata_init(void)
354 if (inet6_add_protocol(&nodata_protocol, IPPROTO_NONE) < 0)
355 printk(KERN_ERR "ipv6_nodata_init: Could not register protocol\n");
358 /********************************
360 ********************************/
362 static int ipv6_rthdr_rcv(struct sk_buff **skbp)
364 struct sk_buff *skb = *skbp;
365 struct inet6_skb_parm *opt = IP6CB(skb);
366 struct in6_addr *addr = NULL;
367 struct in6_addr daddr;
368 struct inet6_dev *idev;
370 struct ipv6_rt_hdr *hdr;
371 struct rt0_hdr *rthdr;
372 int accept_source_route = ipv6_devconf.accept_source_route;
374 if (accept_source_route < 0 ||
375 ((idev = in6_dev_get(skb->dev)) == NULL)) {
379 if (idev->cnf.accept_source_route < 0) {
385 if (accept_source_route > idev->cnf.accept_source_route)
386 accept_source_route = idev->cnf.accept_source_route;
390 if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) ||
391 !pskb_may_pull(skb, (skb_transport_offset(skb) +
392 ((skb_transport_header(skb)[1] + 1) << 3)))) {
393 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
394 IPSTATS_MIB_INHDRERRORS);
399 hdr = (struct ipv6_rt_hdr *)skb_transport_header(skb);
402 #ifdef CONFIG_IPV6_MIP6
405 case IPV6_SRCRT_TYPE_0:
406 if (accept_source_route > 0)
411 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
412 IPSTATS_MIB_INHDRERRORS);
413 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
414 (&hdr->type) - skb_network_header(skb));
418 if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr) ||
419 skb->pkt_type != PACKET_HOST) {
420 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
421 IPSTATS_MIB_INADDRERRORS);
427 if (hdr->segments_left == 0) {
429 #ifdef CONFIG_IPV6_MIP6
430 case IPV6_SRCRT_TYPE_2:
431 /* Silently discard type 2 header unless it was
435 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
436 IPSTATS_MIB_INADDRERRORS);
446 opt->lastopt = opt->srcrt = skb_network_header_len(skb);
447 skb->transport_header += (hdr->hdrlen + 1) << 3;
448 opt->dst0 = opt->dst1;
450 opt->nhoff = (&hdr->nexthdr) - skb_network_header(skb);
455 case IPV6_SRCRT_TYPE_0:
456 if (hdr->hdrlen & 0x01) {
457 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
458 IPSTATS_MIB_INHDRERRORS);
459 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
461 skb_network_header(skb)));
465 #ifdef CONFIG_IPV6_MIP6
466 case IPV6_SRCRT_TYPE_2:
467 /* Silently discard invalid RTH type 2 */
468 if (hdr->hdrlen != 2 || hdr->segments_left != 1) {
469 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
470 IPSTATS_MIB_INHDRERRORS);
479 * This is the routing header forwarding algorithm from
483 n = hdr->hdrlen >> 1;
485 if (hdr->segments_left > n) {
486 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
487 IPSTATS_MIB_INHDRERRORS);
488 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
489 ((&hdr->segments_left) -
490 skb_network_header(skb)));
494 /* We are about to mangle packet header. Be careful!
495 Do not damage packets queued somewhere.
497 if (skb_cloned(skb)) {
498 struct sk_buff *skb2 = skb_copy(skb, GFP_ATOMIC);
499 /* the copy is a forwarded packet */
501 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
502 IPSTATS_MIB_OUTDISCARDS);
509 hdr = (struct ipv6_rt_hdr *)skb_transport_header(skb2);
512 if (skb->ip_summed == CHECKSUM_COMPLETE)
513 skb->ip_summed = CHECKSUM_NONE;
515 i = n - --hdr->segments_left;
517 rthdr = (struct rt0_hdr *) hdr;
522 #ifdef CONFIG_IPV6_MIP6
523 case IPV6_SRCRT_TYPE_2:
524 if (xfrm6_input_addr(skb, (xfrm_address_t *)addr,
525 (xfrm_address_t *)&ipv6_hdr(skb)->saddr,
526 IPPROTO_ROUTING) < 0) {
527 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
528 IPSTATS_MIB_INADDRERRORS);
532 if (!ipv6_chk_home_addr(addr)) {
533 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
534 IPSTATS_MIB_INADDRERRORS);
544 if (ipv6_addr_is_multicast(addr)) {
545 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
546 IPSTATS_MIB_INADDRERRORS);
551 ipv6_addr_copy(&daddr, addr);
552 ipv6_addr_copy(addr, &ipv6_hdr(skb)->daddr);
553 ipv6_addr_copy(&ipv6_hdr(skb)->daddr, &daddr);
555 dst_release(xchg(&skb->dst, NULL));
556 ip6_route_input(skb);
557 if (skb->dst->error) {
558 skb_push(skb, skb->data - skb_network_header(skb));
563 if (skb->dst->dev->flags&IFF_LOOPBACK) {
564 if (ipv6_hdr(skb)->hop_limit <= 1) {
565 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
566 IPSTATS_MIB_INHDRERRORS);
567 icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
572 ipv6_hdr(skb)->hop_limit--;
576 skb_push(skb, skb->data - skb_network_header(skb));
581 static struct inet6_protocol rthdr_protocol = {
582 .handler = ipv6_rthdr_rcv,
583 .flags = INET6_PROTO_NOPOLICY | INET6_PROTO_GSO_EXTHDR,
586 void __init ipv6_rthdr_init(void)
588 if (inet6_add_protocol(&rthdr_protocol, IPPROTO_ROUTING) < 0)
589 printk(KERN_ERR "ipv6_rthdr_init: Could not register protocol\n");
593 This function inverts received rthdr.
594 NOTE: specs allow to make it automatically only if
595 packet authenticated.
597 I will not discuss it here (though, I am really pissed off at
598 this stupid requirement making rthdr idea useless)
600 Actually, it creates severe problems for us.
601 Embryonic requests has no associated sockets,
602 so that user have no control over it and
603 cannot not only to set reply options, but
604 even to know, that someone wants to connect
607 For now we need to test the engine, so that I created
608 temporary (or permanent) backdoor.
609 If listening socket set IPV6_RTHDR to 2, then we invert header.
613 struct ipv6_txoptions *
614 ipv6_invert_rthdr(struct sock *sk, struct ipv6_rt_hdr *hdr)
618 [ H1 -> H2 -> ... H_prev ] daddr=ME
621 [ H_prev -> ... -> H1 ] daddr =sender
623 Note, that IP output engine will rewrite this rthdr
624 by rotating it left by one addr.
628 struct rt0_hdr *rthdr = (struct rt0_hdr*)hdr;
629 struct rt0_hdr *irthdr;
630 struct ipv6_txoptions *opt;
631 int hdrlen = ipv6_optlen(hdr);
633 if (hdr->segments_left ||
634 hdr->type != IPV6_SRCRT_TYPE_0 ||
638 n = hdr->hdrlen >> 1;
639 opt = sock_kmalloc(sk, sizeof(*opt) + hdrlen, GFP_ATOMIC);
642 memset(opt, 0, sizeof(*opt));
643 opt->tot_len = sizeof(*opt) + hdrlen;
644 opt->srcrt = (void*)(opt+1);
645 opt->opt_nflen = hdrlen;
647 memcpy(opt->srcrt, hdr, sizeof(*hdr));
648 irthdr = (struct rt0_hdr*)opt->srcrt;
649 irthdr->reserved = 0;
650 opt->srcrt->segments_left = n;
652 memcpy(irthdr->addr+i, rthdr->addr+(n-1-i), 16);
656 EXPORT_SYMBOL_GPL(ipv6_invert_rthdr);
658 /**********************************
660 **********************************/
662 /* Router Alert as of RFC 2711 */
664 static int ipv6_hop_ra(struct sk_buff **skbp, int optoff)
666 struct sk_buff *skb = *skbp;
667 const unsigned char *nh = skb_network_header(skb);
669 if (nh[optoff + 1] == 2) {
670 IP6CB(skb)->ra = optoff;
673 LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_ra: wrong RA length %d\n",
681 static int ipv6_hop_jumbo(struct sk_buff **skbp, int optoff)
683 struct sk_buff *skb = *skbp;
684 const unsigned char *nh = skb_network_header(skb);
687 if (nh[optoff + 1] != 4 || (optoff & 3) != 2) {
688 LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n",
690 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
691 IPSTATS_MIB_INHDRERRORS);
695 pkt_len = ntohl(*(__be32 *)(nh + optoff + 2));
696 if (pkt_len <= IPV6_MAXPLEN) {
697 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS);
698 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2);
701 if (ipv6_hdr(skb)->payload_len) {
702 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS);
703 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff);
707 if (pkt_len > skb->len - sizeof(struct ipv6hdr)) {
708 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INTRUNCATEDPKTS);
712 if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr)))
722 static struct tlvtype_proc tlvprochopopt_lst[] = {
724 .type = IPV6_TLV_ROUTERALERT,
728 .type = IPV6_TLV_JUMBO,
729 .func = ipv6_hop_jumbo,
734 int ipv6_parse_hopopts(struct sk_buff **skbp)
736 struct sk_buff *skb = *skbp;
737 struct inet6_skb_parm *opt = IP6CB(skb);
740 * skb_network_header(skb) is equal to skb->data, and
741 * skb_network_header_len(skb) is always equal to
742 * sizeof(struct ipv6hdr) by definition of
743 * hop-by-hop options.
745 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr) + 8) ||
746 !pskb_may_pull(skb, (sizeof(struct ipv6hdr) +
747 ((skb_transport_header(skb)[1] + 1) << 3)))) {
752 opt->hop = sizeof(struct ipv6hdr);
753 if (ip6_parse_tlv(tlvprochopopt_lst, skbp)) {
755 skb->transport_header += (skb_transport_header(skb)[1] + 1) << 3;
757 opt->nhoff = sizeof(struct ipv6hdr);
764 * Creating outbound headers.
766 * "build" functions work when skb is filled from head to tail (datagram)
767 * "push" functions work when headers are added from tail to head (tcp)
769 * In both cases we assume, that caller reserved enough room
773 static void ipv6_push_rthdr(struct sk_buff *skb, u8 *proto,
774 struct ipv6_rt_hdr *opt,
775 struct in6_addr **addr_p)
777 struct rt0_hdr *phdr, *ihdr;
780 ihdr = (struct rt0_hdr *) opt;
782 phdr = (struct rt0_hdr *) skb_push(skb, (ihdr->rt_hdr.hdrlen + 1) << 3);
783 memcpy(phdr, ihdr, sizeof(struct rt0_hdr));
785 hops = ihdr->rt_hdr.hdrlen >> 1;
788 memcpy(phdr->addr, ihdr->addr + 1,
789 (hops - 1) * sizeof(struct in6_addr));
791 ipv6_addr_copy(phdr->addr + (hops - 1), *addr_p);
792 *addr_p = ihdr->addr;
794 phdr->rt_hdr.nexthdr = *proto;
795 *proto = NEXTHDR_ROUTING;
798 static void ipv6_push_exthdr(struct sk_buff *skb, u8 *proto, u8 type, struct ipv6_opt_hdr *opt)
800 struct ipv6_opt_hdr *h = (struct ipv6_opt_hdr *)skb_push(skb, ipv6_optlen(opt));
802 memcpy(h, opt, ipv6_optlen(opt));
807 void ipv6_push_nfrag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt,
809 struct in6_addr **daddr)
812 ipv6_push_rthdr(skb, proto, opt->srcrt, daddr);
814 * IPV6_RTHDRDSTOPTS is ignored
815 * unless IPV6_RTHDR is set (RFC3542).
818 ipv6_push_exthdr(skb, proto, NEXTHDR_DEST, opt->dst0opt);
821 ipv6_push_exthdr(skb, proto, NEXTHDR_HOP, opt->hopopt);
824 EXPORT_SYMBOL(ipv6_push_nfrag_opts);
826 void ipv6_push_frag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt, u8 *proto)
829 ipv6_push_exthdr(skb, proto, NEXTHDR_DEST, opt->dst1opt);
832 struct ipv6_txoptions *
833 ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt)
835 struct ipv6_txoptions *opt2;
837 opt2 = sock_kmalloc(sk, opt->tot_len, GFP_ATOMIC);
839 long dif = (char*)opt2 - (char*)opt;
840 memcpy(opt2, opt, opt->tot_len);
842 *((char**)&opt2->hopopt) += dif;
844 *((char**)&opt2->dst0opt) += dif;
846 *((char**)&opt2->dst1opt) += dif;
848 *((char**)&opt2->srcrt) += dif;
853 EXPORT_SYMBOL_GPL(ipv6_dup_options);
855 static int ipv6_renew_option(void *ohdr,
856 struct ipv6_opt_hdr __user *newopt, int newoptlen,
858 struct ipv6_opt_hdr **hdr,
863 memcpy(*p, ohdr, ipv6_optlen((struct ipv6_opt_hdr *)ohdr));
864 *hdr = (struct ipv6_opt_hdr *)*p;
865 *p += CMSG_ALIGN(ipv6_optlen(*(struct ipv6_opt_hdr **)hdr));
869 if (copy_from_user(*p, newopt, newoptlen))
871 *hdr = (struct ipv6_opt_hdr *)*p;
872 if (ipv6_optlen(*(struct ipv6_opt_hdr **)hdr) > newoptlen)
874 *p += CMSG_ALIGN(newoptlen);
880 struct ipv6_txoptions *
881 ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt,
883 struct ipv6_opt_hdr __user *newopt, int newoptlen)
887 struct ipv6_txoptions *opt2;
891 if (newtype != IPV6_HOPOPTS && opt->hopopt)
892 tot_len += CMSG_ALIGN(ipv6_optlen(opt->hopopt));
893 if (newtype != IPV6_RTHDRDSTOPTS && opt->dst0opt)
894 tot_len += CMSG_ALIGN(ipv6_optlen(opt->dst0opt));
895 if (newtype != IPV6_RTHDR && opt->srcrt)
896 tot_len += CMSG_ALIGN(ipv6_optlen(opt->srcrt));
897 if (newtype != IPV6_DSTOPTS && opt->dst1opt)
898 tot_len += CMSG_ALIGN(ipv6_optlen(opt->dst1opt));
901 if (newopt && newoptlen)
902 tot_len += CMSG_ALIGN(newoptlen);
907 tot_len += sizeof(*opt2);
908 opt2 = sock_kmalloc(sk, tot_len, GFP_ATOMIC);
910 return ERR_PTR(-ENOBUFS);
912 memset(opt2, 0, tot_len);
914 opt2->tot_len = tot_len;
915 p = (char *)(opt2 + 1);
917 err = ipv6_renew_option(opt ? opt->hopopt : NULL, newopt, newoptlen,
918 newtype != IPV6_HOPOPTS,
923 err = ipv6_renew_option(opt ? opt->dst0opt : NULL, newopt, newoptlen,
924 newtype != IPV6_RTHDRDSTOPTS,
929 err = ipv6_renew_option(opt ? opt->srcrt : NULL, newopt, newoptlen,
930 newtype != IPV6_RTHDR,
931 (struct ipv6_opt_hdr **)&opt2->srcrt, &p);
935 err = ipv6_renew_option(opt ? opt->dst1opt : NULL, newopt, newoptlen,
936 newtype != IPV6_DSTOPTS,
941 opt2->opt_nflen = (opt2->hopopt ? ipv6_optlen(opt2->hopopt) : 0) +
942 (opt2->dst0opt ? ipv6_optlen(opt2->dst0opt) : 0) +
943 (opt2->srcrt ? ipv6_optlen(opt2->srcrt) : 0);
944 opt2->opt_flen = (opt2->dst1opt ? ipv6_optlen(opt2->dst1opt) : 0);
948 sock_kfree_s(sk, opt2, opt2->tot_len);
952 struct ipv6_txoptions *ipv6_fixup_options(struct ipv6_txoptions *opt_space,
953 struct ipv6_txoptions *opt)
956 * ignore the dest before srcrt unless srcrt is being included.
959 if (opt && opt->dst0opt && !opt->srcrt) {
960 if (opt_space != opt) {
961 memcpy(opt_space, opt, sizeof(*opt_space));
964 opt->opt_nflen -= ipv6_optlen(opt->dst0opt);