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