xref: /openbmc/linux/net/ipv6/exthdrs.c (revision 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2)
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  *	$Id: exthdrs.c,v 1.13 2001/06/19 15:58:56 davem Exp $
11  *
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.
16  */
17 
18 /* Changes:
19  *	yoshfuji		: ensure not to overrun while parsing
20  *				  tlv options.
21  *	Mitsuru KANDA @USAGI and: Remove ipv6_parse_exthdrs().
22  *	YOSHIFUJI Hideaki @USAGI  Register inbound extension header
23  *				  handlers as inet6_protocol{}.
24  */
25 
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>
35 
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 
47 #include <asm/uaccess.h>
48 
49 /*
50  *	Parsing tlv encoded headers.
51  *
52  *	Parsing function "func" returns 1, if parsing succeed
53  *	and 0, if it failed.
54  *	It MUST NOT touch skb->h.
55  */
56 
57 struct tlvtype_proc {
58 	int	type;
59 	int	(*func)(struct sk_buff *skb, int offset);
60 };
61 
62 /*********************
63   Generic functions
64  *********************/
65 
66 /* An unknown option is detected, decide what to do */
67 
68 static int ip6_tlvopt_unknown(struct sk_buff *skb, int optoff)
69 {
70 	switch ((skb->nh.raw[optoff] & 0xC0) >> 6) {
71 	case 0: /* ignore */
72 		return 1;
73 
74 	case 1: /* drop packet */
75 		break;
76 
77 	case 3: /* Send ICMP if not a multicast address and drop packet */
78 		/* Actually, it is redundant check. icmp_send
79 		   will recheck in any case.
80 		 */
81 		if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr))
82 			break;
83 	case 2: /* send ICMP PARM PROB regardless and drop packet */
84 		icmpv6_param_prob(skb, ICMPV6_UNK_OPTION, optoff);
85 		return 0;
86 	};
87 
88 	kfree_skb(skb);
89 	return 0;
90 }
91 
92 /* Parse tlv encoded option header (hop-by-hop or destination) */
93 
94 static int ip6_parse_tlv(struct tlvtype_proc *procs, struct sk_buff *skb)
95 {
96 	struct tlvtype_proc *curr;
97 	int off = skb->h.raw - skb->nh.raw;
98 	int len = ((skb->h.raw[1]+1)<<3);
99 
100 	if ((skb->h.raw + len) - skb->data > skb_headlen(skb))
101 		goto bad;
102 
103 	off += 2;
104 	len -= 2;
105 
106 	while (len > 0) {
107 		int optlen = skb->nh.raw[off+1]+2;
108 
109 		switch (skb->nh.raw[off]) {
110 		case IPV6_TLV_PAD0:
111 			optlen = 1;
112 			break;
113 
114 		case IPV6_TLV_PADN:
115 			break;
116 
117 		default: /* Other TLV code so scan list */
118 			if (optlen > len)
119 				goto bad;
120 			for (curr=procs; curr->type >= 0; curr++) {
121 				if (curr->type == skb->nh.raw[off]) {
122 					/* type specific length/alignment
123 					   checks will be performed in the
124 					   func(). */
125 					if (curr->func(skb, off) == 0)
126 						return 0;
127 					break;
128 				}
129 			}
130 			if (curr->type < 0) {
131 				if (ip6_tlvopt_unknown(skb, off) == 0)
132 					return 0;
133 			}
134 			break;
135 		}
136 		off += optlen;
137 		len -= optlen;
138 	}
139 	if (len == 0)
140 		return 1;
141 bad:
142 	kfree_skb(skb);
143 	return 0;
144 }
145 
146 /*****************************
147   Destination options header.
148  *****************************/
149 
150 static struct tlvtype_proc tlvprocdestopt_lst[] = {
151 	/* No destination options are defined now */
152 	{-1,			NULL}
153 };
154 
155 static int ipv6_destopt_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
156 {
157 	struct sk_buff *skb = *skbp;
158 	struct inet6_skb_parm *opt = IP6CB(skb);
159 
160 	if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) ||
161 	    !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) {
162 		IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
163 		kfree_skb(skb);
164 		return -1;
165 	}
166 
167 	opt->dst1 = skb->h.raw - skb->nh.raw;
168 
169 	if (ip6_parse_tlv(tlvprocdestopt_lst, skb)) {
170 		skb->h.raw += ((skb->h.raw[1]+1)<<3);
171 		*nhoffp = opt->dst1;
172 		return 1;
173 	}
174 
175 	IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
176 	return -1;
177 }
178 
179 static struct inet6_protocol destopt_protocol = {
180 	.handler	=	ipv6_destopt_rcv,
181 	.flags		=	INET6_PROTO_NOPOLICY,
182 };
183 
184 void __init ipv6_destopt_init(void)
185 {
186 	if (inet6_add_protocol(&destopt_protocol, IPPROTO_DSTOPTS) < 0)
187 		printk(KERN_ERR "ipv6_destopt_init: Could not register protocol\n");
188 }
189 
190 /********************************
191   NONE header. No data in packet.
192  ********************************/
193 
194 static int ipv6_nodata_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
195 {
196 	struct sk_buff *skb = *skbp;
197 
198 	kfree_skb(skb);
199 	return 0;
200 }
201 
202 static struct inet6_protocol nodata_protocol = {
203 	.handler	=	ipv6_nodata_rcv,
204 	.flags		=	INET6_PROTO_NOPOLICY,
205 };
206 
207 void __init ipv6_nodata_init(void)
208 {
209 	if (inet6_add_protocol(&nodata_protocol, IPPROTO_NONE) < 0)
210 		printk(KERN_ERR "ipv6_nodata_init: Could not register protocol\n");
211 }
212 
213 /********************************
214   Routing header.
215  ********************************/
216 
217 static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
218 {
219 	struct sk_buff *skb = *skbp;
220 	struct inet6_skb_parm *opt = IP6CB(skb);
221 	struct in6_addr *addr;
222 	struct in6_addr daddr;
223 	int n, i;
224 
225 	struct ipv6_rt_hdr *hdr;
226 	struct rt0_hdr *rthdr;
227 
228 	if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) ||
229 	    !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) {
230 		IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
231 		kfree_skb(skb);
232 		return -1;
233 	}
234 
235 	hdr = (struct ipv6_rt_hdr *) skb->h.raw;
236 
237 	if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr) ||
238 	    skb->pkt_type != PACKET_HOST) {
239 		IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS);
240 		kfree_skb(skb);
241 		return -1;
242 	}
243 
244 looped_back:
245 	if (hdr->segments_left == 0) {
246 		opt->srcrt = skb->h.raw - skb->nh.raw;
247 		skb->h.raw += (hdr->hdrlen + 1) << 3;
248 		opt->dst0 = opt->dst1;
249 		opt->dst1 = 0;
250 		*nhoffp = (&hdr->nexthdr) - skb->nh.raw;
251 		return 1;
252 	}
253 
254 	if (hdr->type != IPV6_SRCRT_TYPE_0) {
255 		IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
256 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->type) - skb->nh.raw);
257 		return -1;
258 	}
259 
260 	if (hdr->hdrlen & 0x01) {
261 		IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
262 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->hdrlen) - skb->nh.raw);
263 		return -1;
264 	}
265 
266 	/*
267 	 *	This is the routing header forwarding algorithm from
268 	 *	RFC 2460, page 16.
269 	 */
270 
271 	n = hdr->hdrlen >> 1;
272 
273 	if (hdr->segments_left > n) {
274 		IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
275 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->segments_left) - skb->nh.raw);
276 		return -1;
277 	}
278 
279 	/* We are about to mangle packet header. Be careful!
280 	   Do not damage packets queued somewhere.
281 	 */
282 	if (skb_cloned(skb)) {
283 		struct sk_buff *skb2 = skb_copy(skb, GFP_ATOMIC);
284 		kfree_skb(skb);
285 		/* the copy is a forwarded packet */
286 		if (skb2 == NULL) {
287 			IP6_INC_STATS_BH(IPSTATS_MIB_OUTDISCARDS);
288 			return -1;
289 		}
290 		*skbp = skb = skb2;
291 		opt = IP6CB(skb2);
292 		hdr = (struct ipv6_rt_hdr *) skb2->h.raw;
293 	}
294 
295 	if (skb->ip_summed == CHECKSUM_HW)
296 		skb->ip_summed = CHECKSUM_NONE;
297 
298 	i = n - --hdr->segments_left;
299 
300 	rthdr = (struct rt0_hdr *) hdr;
301 	addr = rthdr->addr;
302 	addr += i - 1;
303 
304 	if (ipv6_addr_is_multicast(addr)) {
305 		IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS);
306 		kfree_skb(skb);
307 		return -1;
308 	}
309 
310 	ipv6_addr_copy(&daddr, addr);
311 	ipv6_addr_copy(addr, &skb->nh.ipv6h->daddr);
312 	ipv6_addr_copy(&skb->nh.ipv6h->daddr, &daddr);
313 
314 	dst_release(xchg(&skb->dst, NULL));
315 	ip6_route_input(skb);
316 	if (skb->dst->error) {
317 		skb_push(skb, skb->data - skb->nh.raw);
318 		dst_input(skb);
319 		return -1;
320 	}
321 
322 	if (skb->dst->dev->flags&IFF_LOOPBACK) {
323 		if (skb->nh.ipv6h->hop_limit <= 1) {
324 			IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
325 			icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
326 				    0, skb->dev);
327 			kfree_skb(skb);
328 			return -1;
329 		}
330 		skb->nh.ipv6h->hop_limit--;
331 		goto looped_back;
332 	}
333 
334 	skb_push(skb, skb->data - skb->nh.raw);
335 	dst_input(skb);
336 	return -1;
337 }
338 
339 static struct inet6_protocol rthdr_protocol = {
340 	.handler	=	ipv6_rthdr_rcv,
341 	.flags		=	INET6_PROTO_NOPOLICY,
342 };
343 
344 void __init ipv6_rthdr_init(void)
345 {
346 	if (inet6_add_protocol(&rthdr_protocol, IPPROTO_ROUTING) < 0)
347 		printk(KERN_ERR "ipv6_rthdr_init: Could not register protocol\n");
348 };
349 
350 /*
351    This function inverts received rthdr.
352    NOTE: specs allow to make it automatically only if
353    packet authenticated.
354 
355    I will not discuss it here (though, I am really pissed off at
356    this stupid requirement making rthdr idea useless)
357 
358    Actually, it creates severe problems  for us.
359    Embryonic requests has no associated sockets,
360    so that user have no control over it and
361    cannot not only to set reply options, but
362    even to know, that someone wants to connect
363    without success. :-(
364 
365    For now we need to test the engine, so that I created
366    temporary (or permanent) backdoor.
367    If listening socket set IPV6_RTHDR to 2, then we invert header.
368                                                    --ANK (980729)
369  */
370 
371 struct ipv6_txoptions *
372 ipv6_invert_rthdr(struct sock *sk, struct ipv6_rt_hdr *hdr)
373 {
374 	/* Received rthdr:
375 
376 	   [ H1 -> H2 -> ... H_prev ]  daddr=ME
377 
378 	   Inverted result:
379 	   [ H_prev -> ... -> H1 ] daddr =sender
380 
381 	   Note, that IP output engine will rewrite this rthdr
382 	   by rotating it left by one addr.
383 	 */
384 
385 	int n, i;
386 	struct rt0_hdr *rthdr = (struct rt0_hdr*)hdr;
387 	struct rt0_hdr *irthdr;
388 	struct ipv6_txoptions *opt;
389 	int hdrlen = ipv6_optlen(hdr);
390 
391 	if (hdr->segments_left ||
392 	    hdr->type != IPV6_SRCRT_TYPE_0 ||
393 	    hdr->hdrlen & 0x01)
394 		return NULL;
395 
396 	n = hdr->hdrlen >> 1;
397 	opt = sock_kmalloc(sk, sizeof(*opt) + hdrlen, GFP_ATOMIC);
398 	if (opt == NULL)
399 		return NULL;
400 	memset(opt, 0, sizeof(*opt));
401 	opt->tot_len = sizeof(*opt) + hdrlen;
402 	opt->srcrt = (void*)(opt+1);
403 	opt->opt_nflen = hdrlen;
404 
405 	memcpy(opt->srcrt, hdr, sizeof(*hdr));
406 	irthdr = (struct rt0_hdr*)opt->srcrt;
407 	/* Obsolete field, MBZ, when originated by us */
408 	irthdr->bitmap = 0;
409 	opt->srcrt->segments_left = n;
410 	for (i=0; i<n; i++)
411 		memcpy(irthdr->addr+i, rthdr->addr+(n-1-i), 16);
412 	return opt;
413 }
414 
415 /**********************************
416   Hop-by-hop options.
417  **********************************/
418 
419 /* Router Alert as of RFC 2711 */
420 
421 static int ipv6_hop_ra(struct sk_buff *skb, int optoff)
422 {
423 	if (skb->nh.raw[optoff+1] == 2) {
424 		IP6CB(skb)->ra = optoff;
425 		return 1;
426 	}
427 	LIMIT_NETDEBUG(
428 		 printk(KERN_DEBUG "ipv6_hop_ra: wrong RA length %d\n", skb->nh.raw[optoff+1]));
429 	kfree_skb(skb);
430 	return 0;
431 }
432 
433 /* Jumbo payload */
434 
435 static int ipv6_hop_jumbo(struct sk_buff *skb, int optoff)
436 {
437 	u32 pkt_len;
438 
439 	if (skb->nh.raw[optoff+1] != 4 || (optoff&3) != 2) {
440 		LIMIT_NETDEBUG(
441 			 printk(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n", skb->nh.raw[optoff+1]));
442 		IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
443 		goto drop;
444 	}
445 
446 	pkt_len = ntohl(*(u32*)(skb->nh.raw+optoff+2));
447 	if (pkt_len <= IPV6_MAXPLEN) {
448 		IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
449 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2);
450 		return 0;
451 	}
452 	if (skb->nh.ipv6h->payload_len) {
453 		IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
454 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff);
455 		return 0;
456 	}
457 
458 	if (pkt_len > skb->len - sizeof(struct ipv6hdr)) {
459 		IP6_INC_STATS_BH(IPSTATS_MIB_INTRUNCATEDPKTS);
460 		goto drop;
461 	}
462 	if (pkt_len + sizeof(struct ipv6hdr) < skb->len) {
463 		__pskb_trim(skb, pkt_len + sizeof(struct ipv6hdr));
464 		if (skb->ip_summed == CHECKSUM_HW)
465 			skb->ip_summed = CHECKSUM_NONE;
466 	}
467 	return 1;
468 
469 drop:
470 	kfree_skb(skb);
471 	return 0;
472 }
473 
474 static struct tlvtype_proc tlvprochopopt_lst[] = {
475 	{
476 		.type	= IPV6_TLV_ROUTERALERT,
477 		.func	= ipv6_hop_ra,
478 	},
479 	{
480 		.type	= IPV6_TLV_JUMBO,
481 		.func	= ipv6_hop_jumbo,
482 	},
483 	{ -1, }
484 };
485 
486 int ipv6_parse_hopopts(struct sk_buff *skb, int nhoff)
487 {
488 	IP6CB(skb)->hop = sizeof(struct ipv6hdr);
489 	if (ip6_parse_tlv(tlvprochopopt_lst, skb))
490 		return sizeof(struct ipv6hdr);
491 	return -1;
492 }
493 
494 /*
495  *	Creating outbound headers.
496  *
497  *	"build" functions work when skb is filled from head to tail (datagram)
498  *	"push"	functions work when headers are added from tail to head (tcp)
499  *
500  *	In both cases we assume, that caller reserved enough room
501  *	for headers.
502  */
503 
504 static void ipv6_push_rthdr(struct sk_buff *skb, u8 *proto,
505 			    struct ipv6_rt_hdr *opt,
506 			    struct in6_addr **addr_p)
507 {
508 	struct rt0_hdr *phdr, *ihdr;
509 	int hops;
510 
511 	ihdr = (struct rt0_hdr *) opt;
512 
513 	phdr = (struct rt0_hdr *) skb_push(skb, (ihdr->rt_hdr.hdrlen + 1) << 3);
514 	memcpy(phdr, ihdr, sizeof(struct rt0_hdr));
515 
516 	hops = ihdr->rt_hdr.hdrlen >> 1;
517 
518 	if (hops > 1)
519 		memcpy(phdr->addr, ihdr->addr + 1,
520 		       (hops - 1) * sizeof(struct in6_addr));
521 
522 	ipv6_addr_copy(phdr->addr + (hops - 1), *addr_p);
523 	*addr_p = ihdr->addr;
524 
525 	phdr->rt_hdr.nexthdr = *proto;
526 	*proto = NEXTHDR_ROUTING;
527 }
528 
529 static void ipv6_push_exthdr(struct sk_buff *skb, u8 *proto, u8 type, struct ipv6_opt_hdr *opt)
530 {
531 	struct ipv6_opt_hdr *h = (struct ipv6_opt_hdr *)skb_push(skb, ipv6_optlen(opt));
532 
533 	memcpy(h, opt, ipv6_optlen(opt));
534 	h->nexthdr = *proto;
535 	*proto = type;
536 }
537 
538 void ipv6_push_nfrag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt,
539 			  u8 *proto,
540 			  struct in6_addr **daddr)
541 {
542 	if (opt->srcrt)
543 		ipv6_push_rthdr(skb, proto, opt->srcrt, daddr);
544 	if (opt->dst0opt)
545 		ipv6_push_exthdr(skb, proto, NEXTHDR_DEST, opt->dst0opt);
546 	if (opt->hopopt)
547 		ipv6_push_exthdr(skb, proto, NEXTHDR_HOP, opt->hopopt);
548 }
549 
550 void ipv6_push_frag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt, u8 *proto)
551 {
552 	if (opt->dst1opt)
553 		ipv6_push_exthdr(skb, proto, NEXTHDR_DEST, opt->dst1opt);
554 }
555 
556 struct ipv6_txoptions *
557 ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt)
558 {
559 	struct ipv6_txoptions *opt2;
560 
561 	opt2 = sock_kmalloc(sk, opt->tot_len, GFP_ATOMIC);
562 	if (opt2) {
563 		long dif = (char*)opt2 - (char*)opt;
564 		memcpy(opt2, opt, opt->tot_len);
565 		if (opt2->hopopt)
566 			*((char**)&opt2->hopopt) += dif;
567 		if (opt2->dst0opt)
568 			*((char**)&opt2->dst0opt) += dif;
569 		if (opt2->dst1opt)
570 			*((char**)&opt2->dst1opt) += dif;
571 		if (opt2->srcrt)
572 			*((char**)&opt2->srcrt) += dif;
573 	}
574 	return opt2;
575 }
576