xref: /openbmc/linux/net/ipv6/exthdrs.c (revision ca79522c)
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)->flags |= IP6SKB_ROUTERALERT;
557 		memcpy(&IP6CB(skb)->ra, nh + optoff + 2, sizeof(IP6CB(skb)->ra));
558 		return true;
559 	}
560 	LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_ra: wrong RA length %d\n",
561 		       nh[optoff + 1]);
562 	kfree_skb(skb);
563 	return false;
564 }
565 
566 /* Jumbo payload */
567 
568 static bool ipv6_hop_jumbo(struct sk_buff *skb, int optoff)
569 {
570 	const unsigned char *nh = skb_network_header(skb);
571 	struct net *net = ipv6_skb_net(skb);
572 	u32 pkt_len;
573 
574 	if (nh[optoff + 1] != 4 || (optoff & 3) != 2) {
575 		LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n",
576 			       nh[optoff+1]);
577 		IP6_INC_STATS_BH(net, ipv6_skb_idev(skb),
578 				 IPSTATS_MIB_INHDRERRORS);
579 		goto drop;
580 	}
581 
582 	pkt_len = ntohl(*(__be32 *)(nh + optoff + 2));
583 	if (pkt_len <= IPV6_MAXPLEN) {
584 		IP6_INC_STATS_BH(net, ipv6_skb_idev(skb),
585 				 IPSTATS_MIB_INHDRERRORS);
586 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2);
587 		return false;
588 	}
589 	if (ipv6_hdr(skb)->payload_len) {
590 		IP6_INC_STATS_BH(net, ipv6_skb_idev(skb),
591 				 IPSTATS_MIB_INHDRERRORS);
592 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff);
593 		return false;
594 	}
595 
596 	if (pkt_len > skb->len - sizeof(struct ipv6hdr)) {
597 		IP6_INC_STATS_BH(net, ipv6_skb_idev(skb),
598 				 IPSTATS_MIB_INTRUNCATEDPKTS);
599 		goto drop;
600 	}
601 
602 	if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr)))
603 		goto drop;
604 
605 	return true;
606 
607 drop:
608 	kfree_skb(skb);
609 	return false;
610 }
611 
612 static const struct tlvtype_proc tlvprochopopt_lst[] = {
613 	{
614 		.type	= IPV6_TLV_ROUTERALERT,
615 		.func	= ipv6_hop_ra,
616 	},
617 	{
618 		.type	= IPV6_TLV_JUMBO,
619 		.func	= ipv6_hop_jumbo,
620 	},
621 	{ -1, }
622 };
623 
624 int ipv6_parse_hopopts(struct sk_buff *skb)
625 {
626 	struct inet6_skb_parm *opt = IP6CB(skb);
627 
628 	/*
629 	 * skb_network_header(skb) is equal to skb->data, and
630 	 * skb_network_header_len(skb) is always equal to
631 	 * sizeof(struct ipv6hdr) by definition of
632 	 * hop-by-hop options.
633 	 */
634 	if (!pskb_may_pull(skb, sizeof(struct ipv6hdr) + 8) ||
635 	    !pskb_may_pull(skb, (sizeof(struct ipv6hdr) +
636 				 ((skb_transport_header(skb)[1] + 1) << 3)))) {
637 		kfree_skb(skb);
638 		return -1;
639 	}
640 
641 	opt->hop = sizeof(struct ipv6hdr);
642 	if (ip6_parse_tlv(tlvprochopopt_lst, skb)) {
643 		skb->transport_header += (skb_transport_header(skb)[1] + 1) << 3;
644 		opt = IP6CB(skb);
645 		opt->nhoff = sizeof(struct ipv6hdr);
646 		return 1;
647 	}
648 	return -1;
649 }
650 
651 /*
652  *	Creating outbound headers.
653  *
654  *	"build" functions work when skb is filled from head to tail (datagram)
655  *	"push"	functions work when headers are added from tail to head (tcp)
656  *
657  *	In both cases we assume, that caller reserved enough room
658  *	for headers.
659  */
660 
661 static void ipv6_push_rthdr(struct sk_buff *skb, u8 *proto,
662 			    struct ipv6_rt_hdr *opt,
663 			    struct in6_addr **addr_p)
664 {
665 	struct rt0_hdr *phdr, *ihdr;
666 	int hops;
667 
668 	ihdr = (struct rt0_hdr *) opt;
669 
670 	phdr = (struct rt0_hdr *) skb_push(skb, (ihdr->rt_hdr.hdrlen + 1) << 3);
671 	memcpy(phdr, ihdr, sizeof(struct rt0_hdr));
672 
673 	hops = ihdr->rt_hdr.hdrlen >> 1;
674 
675 	if (hops > 1)
676 		memcpy(phdr->addr, ihdr->addr + 1,
677 		       (hops - 1) * sizeof(struct in6_addr));
678 
679 	phdr->addr[hops - 1] = **addr_p;
680 	*addr_p = ihdr->addr;
681 
682 	phdr->rt_hdr.nexthdr = *proto;
683 	*proto = NEXTHDR_ROUTING;
684 }
685 
686 static void ipv6_push_exthdr(struct sk_buff *skb, u8 *proto, u8 type, struct ipv6_opt_hdr *opt)
687 {
688 	struct ipv6_opt_hdr *h = (struct ipv6_opt_hdr *)skb_push(skb, ipv6_optlen(opt));
689 
690 	memcpy(h, opt, ipv6_optlen(opt));
691 	h->nexthdr = *proto;
692 	*proto = type;
693 }
694 
695 void ipv6_push_nfrag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt,
696 			  u8 *proto,
697 			  struct in6_addr **daddr)
698 {
699 	if (opt->srcrt) {
700 		ipv6_push_rthdr(skb, proto, opt->srcrt, daddr);
701 		/*
702 		 * IPV6_RTHDRDSTOPTS is ignored
703 		 * unless IPV6_RTHDR is set (RFC3542).
704 		 */
705 		if (opt->dst0opt)
706 			ipv6_push_exthdr(skb, proto, NEXTHDR_DEST, opt->dst0opt);
707 	}
708 	if (opt->hopopt)
709 		ipv6_push_exthdr(skb, proto, NEXTHDR_HOP, opt->hopopt);
710 }
711 EXPORT_SYMBOL(ipv6_push_nfrag_opts);
712 
713 void ipv6_push_frag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt, u8 *proto)
714 {
715 	if (opt->dst1opt)
716 		ipv6_push_exthdr(skb, proto, NEXTHDR_DEST, opt->dst1opt);
717 }
718 
719 struct ipv6_txoptions *
720 ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt)
721 {
722 	struct ipv6_txoptions *opt2;
723 
724 	opt2 = sock_kmalloc(sk, opt->tot_len, GFP_ATOMIC);
725 	if (opt2) {
726 		long dif = (char *)opt2 - (char *)opt;
727 		memcpy(opt2, opt, opt->tot_len);
728 		if (opt2->hopopt)
729 			*((char **)&opt2->hopopt) += dif;
730 		if (opt2->dst0opt)
731 			*((char **)&opt2->dst0opt) += dif;
732 		if (opt2->dst1opt)
733 			*((char **)&opt2->dst1opt) += dif;
734 		if (opt2->srcrt)
735 			*((char **)&opt2->srcrt) += dif;
736 	}
737 	return opt2;
738 }
739 EXPORT_SYMBOL_GPL(ipv6_dup_options);
740 
741 static int ipv6_renew_option(void *ohdr,
742 			     struct ipv6_opt_hdr __user *newopt, int newoptlen,
743 			     int inherit,
744 			     struct ipv6_opt_hdr **hdr,
745 			     char **p)
746 {
747 	if (inherit) {
748 		if (ohdr) {
749 			memcpy(*p, ohdr, ipv6_optlen((struct ipv6_opt_hdr *)ohdr));
750 			*hdr = (struct ipv6_opt_hdr *)*p;
751 			*p += CMSG_ALIGN(ipv6_optlen(*hdr));
752 		}
753 	} else {
754 		if (newopt) {
755 			if (copy_from_user(*p, newopt, newoptlen))
756 				return -EFAULT;
757 			*hdr = (struct ipv6_opt_hdr *)*p;
758 			if (ipv6_optlen(*hdr) > newoptlen)
759 				return -EINVAL;
760 			*p += CMSG_ALIGN(newoptlen);
761 		}
762 	}
763 	return 0;
764 }
765 
766 struct ipv6_txoptions *
767 ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt,
768 		   int newtype,
769 		   struct ipv6_opt_hdr __user *newopt, int newoptlen)
770 {
771 	int tot_len = 0;
772 	char *p;
773 	struct ipv6_txoptions *opt2;
774 	int err;
775 
776 	if (opt) {
777 		if (newtype != IPV6_HOPOPTS && opt->hopopt)
778 			tot_len += CMSG_ALIGN(ipv6_optlen(opt->hopopt));
779 		if (newtype != IPV6_RTHDRDSTOPTS && opt->dst0opt)
780 			tot_len += CMSG_ALIGN(ipv6_optlen(opt->dst0opt));
781 		if (newtype != IPV6_RTHDR && opt->srcrt)
782 			tot_len += CMSG_ALIGN(ipv6_optlen(opt->srcrt));
783 		if (newtype != IPV6_DSTOPTS && opt->dst1opt)
784 			tot_len += CMSG_ALIGN(ipv6_optlen(opt->dst1opt));
785 	}
786 
787 	if (newopt && newoptlen)
788 		tot_len += CMSG_ALIGN(newoptlen);
789 
790 	if (!tot_len)
791 		return NULL;
792 
793 	tot_len += sizeof(*opt2);
794 	opt2 = sock_kmalloc(sk, tot_len, GFP_ATOMIC);
795 	if (!opt2)
796 		return ERR_PTR(-ENOBUFS);
797 
798 	memset(opt2, 0, tot_len);
799 
800 	opt2->tot_len = tot_len;
801 	p = (char *)(opt2 + 1);
802 
803 	err = ipv6_renew_option(opt ? opt->hopopt : NULL, newopt, newoptlen,
804 				newtype != IPV6_HOPOPTS,
805 				&opt2->hopopt, &p);
806 	if (err)
807 		goto out;
808 
809 	err = ipv6_renew_option(opt ? opt->dst0opt : NULL, newopt, newoptlen,
810 				newtype != IPV6_RTHDRDSTOPTS,
811 				&opt2->dst0opt, &p);
812 	if (err)
813 		goto out;
814 
815 	err = ipv6_renew_option(opt ? opt->srcrt : NULL, newopt, newoptlen,
816 				newtype != IPV6_RTHDR,
817 				(struct ipv6_opt_hdr **)&opt2->srcrt, &p);
818 	if (err)
819 		goto out;
820 
821 	err = ipv6_renew_option(opt ? opt->dst1opt : NULL, newopt, newoptlen,
822 				newtype != IPV6_DSTOPTS,
823 				&opt2->dst1opt, &p);
824 	if (err)
825 		goto out;
826 
827 	opt2->opt_nflen = (opt2->hopopt ? ipv6_optlen(opt2->hopopt) : 0) +
828 			  (opt2->dst0opt ? ipv6_optlen(opt2->dst0opt) : 0) +
829 			  (opt2->srcrt ? ipv6_optlen(opt2->srcrt) : 0);
830 	opt2->opt_flen = (opt2->dst1opt ? ipv6_optlen(opt2->dst1opt) : 0);
831 
832 	return opt2;
833 out:
834 	sock_kfree_s(sk, opt2, opt2->tot_len);
835 	return ERR_PTR(err);
836 }
837 
838 struct ipv6_txoptions *ipv6_fixup_options(struct ipv6_txoptions *opt_space,
839 					  struct ipv6_txoptions *opt)
840 {
841 	/*
842 	 * ignore the dest before srcrt unless srcrt is being included.
843 	 * --yoshfuji
844 	 */
845 	if (opt && opt->dst0opt && !opt->srcrt) {
846 		if (opt_space != opt) {
847 			memcpy(opt_space, opt, sizeof(*opt_space));
848 			opt = opt_space;
849 		}
850 		opt->opt_nflen -= ipv6_optlen(opt->dst0opt);
851 		opt->dst0opt = NULL;
852 	}
853 
854 	return opt;
855 }
856 EXPORT_SYMBOL_GPL(ipv6_fixup_options);
857 
858 /**
859  * fl6_update_dst - update flowi destination address with info given
860  *                  by srcrt option, if any.
861  *
862  * @fl6: flowi6 for which daddr is to be updated
863  * @opt: struct ipv6_txoptions in which to look for srcrt opt
864  * @orig: copy of original daddr address if modified
865  *
866  * Returns NULL if no txoptions or no srcrt, otherwise returns orig
867  * and initial value of fl6->daddr set in orig
868  */
869 struct in6_addr *fl6_update_dst(struct flowi6 *fl6,
870 				const struct ipv6_txoptions *opt,
871 				struct in6_addr *orig)
872 {
873 	if (!opt || !opt->srcrt)
874 		return NULL;
875 
876 	*orig = fl6->daddr;
877 	fl6->daddr = *((struct rt0_hdr *)opt->srcrt)->addr;
878 	return orig;
879 }
880 EXPORT_SYMBOL_GPL(fl6_update_dst);
881