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/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
403 case IPV6_SRCRT_TYPE_2:
406 case IPV6_SRCRT_TYPE_0:
407 if (accept_source_route > 0)
412 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
413 IPSTATS_MIB_INHDRERRORS);
414 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
415 (&hdr->type) - skb_network_header(skb));
419 if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr) ||
420 skb->pkt_type != PACKET_HOST) {
421 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
422 IPSTATS_MIB_INADDRERRORS);
428 if (hdr->segments_left == 0) {
430 #ifdef CONFIG_IPV6_MIP6
431 case IPV6_SRCRT_TYPE_2:
432 /* Silently discard type 2 header unless it was
436 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
437 IPSTATS_MIB_INADDRERRORS);
447 opt->lastopt = opt->srcrt = skb_network_header_len(skb);
448 skb->transport_header += (hdr->hdrlen + 1) << 3;
449 opt->dst0 = opt->dst1;
451 opt->nhoff = (&hdr->nexthdr) - skb_network_header(skb);
456 case IPV6_SRCRT_TYPE_0:
457 if (hdr->hdrlen & 0x01) {
458 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
459 IPSTATS_MIB_INHDRERRORS);
460 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
462 skb_network_header(skb)));
466 #ifdef CONFIG_IPV6_MIP6
467 case IPV6_SRCRT_TYPE_2:
468 /* Silently discard invalid RTH type 2 */
469 if (hdr->hdrlen != 2 || hdr->segments_left != 1) {
470 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
471 IPSTATS_MIB_INHDRERRORS);
480 * This is the routing header forwarding algorithm from
484 n = hdr->hdrlen >> 1;
486 if (hdr->segments_left > n) {
487 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
488 IPSTATS_MIB_INHDRERRORS);
489 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
490 ((&hdr->segments_left) -
491 skb_network_header(skb)));
495 /* We are about to mangle packet header. Be careful!
496 Do not damage packets queued somewhere.
498 if (skb_cloned(skb)) {
499 struct sk_buff *skb2 = skb_copy(skb, GFP_ATOMIC);
500 /* the copy is a forwarded packet */
502 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
503 IPSTATS_MIB_OUTDISCARDS);
510 hdr = (struct ipv6_rt_hdr *)skb_transport_header(skb2);
513 if (skb->ip_summed == CHECKSUM_COMPLETE)
514 skb->ip_summed = CHECKSUM_NONE;
516 i = n - --hdr->segments_left;
518 rthdr = (struct rt0_hdr *) hdr;
523 #ifdef CONFIG_IPV6_MIP6
524 case IPV6_SRCRT_TYPE_2:
525 if (xfrm6_input_addr(skb, (xfrm_address_t *)addr,
526 (xfrm_address_t *)&ipv6_hdr(skb)->saddr,
527 IPPROTO_ROUTING) < 0) {
528 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
529 IPSTATS_MIB_INADDRERRORS);
533 if (!ipv6_chk_home_addr(addr)) {
534 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
535 IPSTATS_MIB_INADDRERRORS);
545 if (ipv6_addr_is_multicast(addr)) {
546 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
547 IPSTATS_MIB_INADDRERRORS);
552 ipv6_addr_copy(&daddr, addr);
553 ipv6_addr_copy(addr, &ipv6_hdr(skb)->daddr);
554 ipv6_addr_copy(&ipv6_hdr(skb)->daddr, &daddr);
556 dst_release(xchg(&skb->dst, NULL));
557 ip6_route_input(skb);
558 if (skb->dst->error) {
559 skb_push(skb, skb->data - skb_network_header(skb));
564 if (skb->dst->dev->flags&IFF_LOOPBACK) {
565 if (ipv6_hdr(skb)->hop_limit <= 1) {
566 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
567 IPSTATS_MIB_INHDRERRORS);
568 icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
573 ipv6_hdr(skb)->hop_limit--;
577 skb_push(skb, skb->data - skb_network_header(skb));
582 static struct inet6_protocol rthdr_protocol = {
583 .handler = ipv6_rthdr_rcv,
584 .flags = INET6_PROTO_NOPOLICY | INET6_PROTO_GSO_EXTHDR,
587 void __init ipv6_rthdr_init(void)
589 if (inet6_add_protocol(&rthdr_protocol, IPPROTO_ROUTING) < 0)
590 printk(KERN_ERR "ipv6_rthdr_init: Could not register protocol\n");
594 This function inverts received rthdr.
595 NOTE: specs allow to make it automatically only if
596 packet authenticated.
598 I will not discuss it here (though, I am really pissed off at
599 this stupid requirement making rthdr idea useless)
601 Actually, it creates severe problems for us.
602 Embryonic requests has no associated sockets,
603 so that user have no control over it and
604 cannot not only to set reply options, but
605 even to know, that someone wants to connect
608 For now we need to test the engine, so that I created
609 temporary (or permanent) backdoor.
610 If listening socket set IPV6_RTHDR to 2, then we invert header.
614 struct ipv6_txoptions *
615 ipv6_invert_rthdr(struct sock *sk, struct ipv6_rt_hdr *hdr)
619 [ H1 -> H2 -> ... H_prev ] daddr=ME
622 [ H_prev -> ... -> H1 ] daddr =sender
624 Note, that IP output engine will rewrite this rthdr
625 by rotating it left by one addr.
629 struct rt0_hdr *rthdr = (struct rt0_hdr*)hdr;
630 struct rt0_hdr *irthdr;
631 struct ipv6_txoptions *opt;
632 int hdrlen = ipv6_optlen(hdr);
634 if (hdr->segments_left ||
635 hdr->type != IPV6_SRCRT_TYPE_0 ||
639 n = hdr->hdrlen >> 1;
640 opt = sock_kmalloc(sk, sizeof(*opt) + hdrlen, GFP_ATOMIC);
643 memset(opt, 0, sizeof(*opt));
644 opt->tot_len = sizeof(*opt) + hdrlen;
645 opt->srcrt = (void*)(opt+1);
646 opt->opt_nflen = hdrlen;
648 memcpy(opt->srcrt, hdr, sizeof(*hdr));
649 irthdr = (struct rt0_hdr*)opt->srcrt;
650 irthdr->reserved = 0;
651 opt->srcrt->segments_left = n;
653 memcpy(irthdr->addr+i, rthdr->addr+(n-1-i), 16);
657 EXPORT_SYMBOL_GPL(ipv6_invert_rthdr);
659 /**********************************
661 **********************************/
664 * Note: we cannot rely on skb->dst before we assign it in ip6_route_input().
666 static inline struct inet6_dev *ipv6_skb_idev(struct sk_buff *skb)
668 return skb->dst ? ip6_dst_idev(skb->dst) : __in6_dev_get(skb->dev);
671 /* Router Alert as of RFC 2711 */
673 static int ipv6_hop_ra(struct sk_buff **skbp, int optoff)
675 struct sk_buff *skb = *skbp;
676 const unsigned char *nh = skb_network_header(skb);
678 if (nh[optoff + 1] == 2) {
679 IP6CB(skb)->ra = optoff;
682 LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_ra: wrong RA length %d\n",
690 static int ipv6_hop_jumbo(struct sk_buff **skbp, int optoff)
692 struct sk_buff *skb = *skbp;
693 const unsigned char *nh = skb_network_header(skb);
696 if (nh[optoff + 1] != 4 || (optoff & 3) != 2) {
697 LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n",
699 IP6_INC_STATS_BH(ipv6_skb_idev(skb),
700 IPSTATS_MIB_INHDRERRORS);
704 pkt_len = ntohl(*(__be32 *)(nh + optoff + 2));
705 if (pkt_len <= IPV6_MAXPLEN) {
706 IP6_INC_STATS_BH(ipv6_skb_idev(skb), IPSTATS_MIB_INHDRERRORS);
707 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2);
710 if (ipv6_hdr(skb)->payload_len) {
711 IP6_INC_STATS_BH(ipv6_skb_idev(skb), IPSTATS_MIB_INHDRERRORS);
712 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff);
716 if (pkt_len > skb->len - sizeof(struct ipv6hdr)) {
717 IP6_INC_STATS_BH(ipv6_skb_idev(skb), IPSTATS_MIB_INTRUNCATEDPKTS);
721 if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr)))
731 static struct tlvtype_proc tlvprochopopt_lst[] = {
733 .type = IPV6_TLV_ROUTERALERT,
737 .type = IPV6_TLV_JUMBO,
738 .func = ipv6_hop_jumbo,
743 int ipv6_parse_hopopts(struct sk_buff **skbp)
745 struct sk_buff *skb = *skbp;
746 struct inet6_skb_parm *opt = IP6CB(skb);
749 * skb_network_header(skb) is equal to skb->data, and
750 * skb_network_header_len(skb) is always equal to
751 * sizeof(struct ipv6hdr) by definition of
752 * hop-by-hop options.
754 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr) + 8) ||
755 !pskb_may_pull(skb, (sizeof(struct ipv6hdr) +
756 ((skb_transport_header(skb)[1] + 1) << 3)))) {
761 opt->hop = sizeof(struct ipv6hdr);
762 if (ip6_parse_tlv(tlvprochopopt_lst, skbp)) {
764 skb->transport_header += (skb_transport_header(skb)[1] + 1) << 3;
766 opt->nhoff = sizeof(struct ipv6hdr);
773 * Creating outbound headers.
775 * "build" functions work when skb is filled from head to tail (datagram)
776 * "push" functions work when headers are added from tail to head (tcp)
778 * In both cases we assume, that caller reserved enough room
782 static void ipv6_push_rthdr(struct sk_buff *skb, u8 *proto,
783 struct ipv6_rt_hdr *opt,
784 struct in6_addr **addr_p)
786 struct rt0_hdr *phdr, *ihdr;
789 ihdr = (struct rt0_hdr *) opt;
791 phdr = (struct rt0_hdr *) skb_push(skb, (ihdr->rt_hdr.hdrlen + 1) << 3);
792 memcpy(phdr, ihdr, sizeof(struct rt0_hdr));
794 hops = ihdr->rt_hdr.hdrlen >> 1;
797 memcpy(phdr->addr, ihdr->addr + 1,
798 (hops - 1) * sizeof(struct in6_addr));
800 ipv6_addr_copy(phdr->addr + (hops - 1), *addr_p);
801 *addr_p = ihdr->addr;
803 phdr->rt_hdr.nexthdr = *proto;
804 *proto = NEXTHDR_ROUTING;
807 static void ipv6_push_exthdr(struct sk_buff *skb, u8 *proto, u8 type, struct ipv6_opt_hdr *opt)
809 struct ipv6_opt_hdr *h = (struct ipv6_opt_hdr *)skb_push(skb, ipv6_optlen(opt));
811 memcpy(h, opt, ipv6_optlen(opt));
816 void ipv6_push_nfrag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt,
818 struct in6_addr **daddr)
821 ipv6_push_rthdr(skb, proto, opt->srcrt, daddr);
823 * IPV6_RTHDRDSTOPTS is ignored
824 * unless IPV6_RTHDR is set (RFC3542).
827 ipv6_push_exthdr(skb, proto, NEXTHDR_DEST, opt->dst0opt);
830 ipv6_push_exthdr(skb, proto, NEXTHDR_HOP, opt->hopopt);
833 EXPORT_SYMBOL(ipv6_push_nfrag_opts);
835 void ipv6_push_frag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt, u8 *proto)
838 ipv6_push_exthdr(skb, proto, NEXTHDR_DEST, opt->dst1opt);
841 struct ipv6_txoptions *
842 ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt)
844 struct ipv6_txoptions *opt2;
846 opt2 = sock_kmalloc(sk, opt->tot_len, GFP_ATOMIC);
848 long dif = (char*)opt2 - (char*)opt;
849 memcpy(opt2, opt, opt->tot_len);
851 *((char**)&opt2->hopopt) += dif;
853 *((char**)&opt2->dst0opt) += dif;
855 *((char**)&opt2->dst1opt) += dif;
857 *((char**)&opt2->srcrt) += dif;
862 EXPORT_SYMBOL_GPL(ipv6_dup_options);
864 static int ipv6_renew_option(void *ohdr,
865 struct ipv6_opt_hdr __user *newopt, int newoptlen,
867 struct ipv6_opt_hdr **hdr,
872 memcpy(*p, ohdr, ipv6_optlen((struct ipv6_opt_hdr *)ohdr));
873 *hdr = (struct ipv6_opt_hdr *)*p;
874 *p += CMSG_ALIGN(ipv6_optlen(*(struct ipv6_opt_hdr **)hdr));
878 if (copy_from_user(*p, newopt, newoptlen))
880 *hdr = (struct ipv6_opt_hdr *)*p;
881 if (ipv6_optlen(*(struct ipv6_opt_hdr **)hdr) > newoptlen)
883 *p += CMSG_ALIGN(newoptlen);
889 struct ipv6_txoptions *
890 ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt,
892 struct ipv6_opt_hdr __user *newopt, int newoptlen)
896 struct ipv6_txoptions *opt2;
900 if (newtype != IPV6_HOPOPTS && opt->hopopt)
901 tot_len += CMSG_ALIGN(ipv6_optlen(opt->hopopt));
902 if (newtype != IPV6_RTHDRDSTOPTS && opt->dst0opt)
903 tot_len += CMSG_ALIGN(ipv6_optlen(opt->dst0opt));
904 if (newtype != IPV6_RTHDR && opt->srcrt)
905 tot_len += CMSG_ALIGN(ipv6_optlen(opt->srcrt));
906 if (newtype != IPV6_DSTOPTS && opt->dst1opt)
907 tot_len += CMSG_ALIGN(ipv6_optlen(opt->dst1opt));
910 if (newopt && newoptlen)
911 tot_len += CMSG_ALIGN(newoptlen);
916 tot_len += sizeof(*opt2);
917 opt2 = sock_kmalloc(sk, tot_len, GFP_ATOMIC);
919 return ERR_PTR(-ENOBUFS);
921 memset(opt2, 0, tot_len);
923 opt2->tot_len = tot_len;
924 p = (char *)(opt2 + 1);
926 err = ipv6_renew_option(opt ? opt->hopopt : NULL, newopt, newoptlen,
927 newtype != IPV6_HOPOPTS,
932 err = ipv6_renew_option(opt ? opt->dst0opt : NULL, newopt, newoptlen,
933 newtype != IPV6_RTHDRDSTOPTS,
938 err = ipv6_renew_option(opt ? opt->srcrt : NULL, newopt, newoptlen,
939 newtype != IPV6_RTHDR,
940 (struct ipv6_opt_hdr **)&opt2->srcrt, &p);
944 err = ipv6_renew_option(opt ? opt->dst1opt : NULL, newopt, newoptlen,
945 newtype != IPV6_DSTOPTS,
950 opt2->opt_nflen = (opt2->hopopt ? ipv6_optlen(opt2->hopopt) : 0) +
951 (opt2->dst0opt ? ipv6_optlen(opt2->dst0opt) : 0) +
952 (opt2->srcrt ? ipv6_optlen(opt2->srcrt) : 0);
953 opt2->opt_flen = (opt2->dst1opt ? ipv6_optlen(opt2->dst1opt) : 0);
957 sock_kfree_s(sk, opt2, opt2->tot_len);
961 struct ipv6_txoptions *ipv6_fixup_options(struct ipv6_txoptions *opt_space,
962 struct ipv6_txoptions *opt)
965 * ignore the dest before srcrt unless srcrt is being included.
968 if (opt && opt->dst0opt && !opt->srcrt) {
969 if (opt_space != opt) {
970 memcpy(opt_space, opt, sizeof(*opt_space));
973 opt->opt_nflen -= ipv6_optlen(opt->dst0opt);