xref: /linux/net/ipv6/mip6.c (revision c537b994505099b7197e7d3125b942ecbcc51eb6)
1 /*
2  * Copyright (C)2003-2006 Helsinki University of Technology
3  * Copyright (C)2003-2006 USAGI/WIDE Project
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19 /*
20  * Authors:
21  *	Noriaki TAKAMIYA @USAGI
22  *	Masahide NAKAMURA @USAGI
23  */
24 
25 #include <linux/module.h>
26 #include <linux/skbuff.h>
27 #include <linux/time.h>
28 #include <linux/ipv6.h>
29 #include <linux/icmpv6.h>
30 #include <net/sock.h>
31 #include <net/ipv6.h>
32 #include <net/ip6_checksum.h>
33 #include <net/xfrm.h>
34 #include <net/mip6.h>
35 
36 static xfrm_address_t *mip6_xfrm_addr(struct xfrm_state *x, xfrm_address_t *addr)
37 {
38 	return x->coaddr;
39 }
40 
41 static inline unsigned int calc_padlen(unsigned int len, unsigned int n)
42 {
43 	return (n - len + 16) & 0x7;
44 }
45 
46 static inline void *mip6_padn(__u8 *data, __u8 padlen)
47 {
48 	if (!data)
49 		return NULL;
50 	if (padlen == 1) {
51 		data[0] = MIP6_OPT_PAD_1;
52 	} else if (padlen > 1) {
53 		data[0] = MIP6_OPT_PAD_N;
54 		data[1] = padlen - 2;
55 		if (padlen > 2)
56 			memset(data+2, 0, data[1]);
57 	}
58 	return data + padlen;
59 }
60 
61 static inline void mip6_param_prob(struct sk_buff *skb, int code, int pos)
62 {
63 	icmpv6_send(skb, ICMPV6_PARAMPROB, code, pos, skb->dev);
64 }
65 
66 static int mip6_mh_len(int type)
67 {
68 	int len = 0;
69 
70 	switch (type) {
71 	case IP6_MH_TYPE_BRR:
72 		len = 0;
73 		break;
74 	case IP6_MH_TYPE_HOTI:
75 	case IP6_MH_TYPE_COTI:
76 	case IP6_MH_TYPE_BU:
77 	case IP6_MH_TYPE_BACK:
78 		len = 1;
79 		break;
80 	case IP6_MH_TYPE_HOT:
81 	case IP6_MH_TYPE_COT:
82 	case IP6_MH_TYPE_BERROR:
83 		len = 2;
84 		break;
85 	}
86 	return len;
87 }
88 
89 int mip6_mh_filter(struct sock *sk, struct sk_buff *skb)
90 {
91 	struct ip6_mh *mh;
92 
93 	if (!pskb_may_pull(skb, (skb->h.raw - skb->data) + 8) ||
94 	    !pskb_may_pull(skb, (skb->h.raw - skb->data) + ((skb->h.raw[1] + 1) << 3)))
95 		return -1;
96 
97 	mh = (struct ip6_mh *)skb->h.raw;
98 
99 	if (mh->ip6mh_hdrlen < mip6_mh_len(mh->ip6mh_type)) {
100 		LIMIT_NETDEBUG(KERN_DEBUG "mip6: MH message too short: %d vs >=%d\n",
101 			       mh->ip6mh_hdrlen, mip6_mh_len(mh->ip6mh_type));
102 		mip6_param_prob(skb, 0, (&mh->ip6mh_hdrlen) - skb->nh.raw);
103 		return -1;
104 	}
105 
106 	if (mh->ip6mh_proto != IPPROTO_NONE) {
107 		LIMIT_NETDEBUG(KERN_DEBUG "mip6: MH invalid payload proto = %d\n",
108 			       mh->ip6mh_proto);
109 		mip6_param_prob(skb, 0, (&mh->ip6mh_proto) - skb->nh.raw);
110 		return -1;
111 	}
112 
113 	return 0;
114 }
115 
116 struct mip6_report_rate_limiter {
117 	spinlock_t lock;
118 	struct timeval stamp;
119 	int iif;
120 	struct in6_addr src;
121 	struct in6_addr dst;
122 };
123 
124 static struct mip6_report_rate_limiter mip6_report_rl = {
125 	.lock = SPIN_LOCK_UNLOCKED
126 };
127 
128 static int mip6_destopt_input(struct xfrm_state *x, struct sk_buff *skb)
129 {
130 	struct ipv6hdr *iph = skb->nh.ipv6h;
131 	struct ipv6_destopt_hdr *destopt = (struct ipv6_destopt_hdr *)skb->data;
132 
133 	if (!ipv6_addr_equal(&iph->saddr, (struct in6_addr *)x->coaddr) &&
134 	    !ipv6_addr_any((struct in6_addr *)x->coaddr))
135 		return -ENOENT;
136 
137 	return destopt->nexthdr;
138 }
139 
140 /* Destination Option Header is inserted.
141  * IP Header's src address is replaced with Home Address Option in
142  * Destination Option Header.
143  */
144 static int mip6_destopt_output(struct xfrm_state *x, struct sk_buff *skb)
145 {
146 	struct ipv6hdr *iph;
147 	struct ipv6_destopt_hdr *dstopt;
148 	struct ipv6_destopt_hao *hao;
149 	u8 nexthdr;
150 	int len;
151 
152 	iph = (struct ipv6hdr *)skb->data;
153 	iph->payload_len = htons(skb->len - sizeof(*iph));
154 
155 	nexthdr = *skb->nh.raw;
156 	*skb->nh.raw = IPPROTO_DSTOPTS;
157 
158 	dstopt = (struct ipv6_destopt_hdr *)skb->h.raw;
159 	dstopt->nexthdr = nexthdr;
160 
161 	hao = mip6_padn((char *)(dstopt + 1),
162 			calc_padlen(sizeof(*dstopt), 6));
163 
164 	hao->type = IPV6_TLV_HAO;
165 	hao->length = sizeof(*hao) - 2;
166 	BUG_TRAP(hao->length == 16);
167 
168 	len = ((char *)hao - (char *)dstopt) + sizeof(*hao);
169 
170 	memcpy(&hao->addr, &iph->saddr, sizeof(hao->addr));
171 	memcpy(&iph->saddr, x->coaddr, sizeof(iph->saddr));
172 
173 	BUG_TRAP(len == x->props.header_len);
174 	dstopt->hdrlen = (x->props.header_len >> 3) - 1;
175 
176 	return 0;
177 }
178 
179 static inline int mip6_report_rl_allow(struct timeval *stamp,
180 				       struct in6_addr *dst,
181 				       struct in6_addr *src, int iif)
182 {
183 	int allow = 0;
184 
185 	spin_lock_bh(&mip6_report_rl.lock);
186 	if (mip6_report_rl.stamp.tv_sec != stamp->tv_sec ||
187 	    mip6_report_rl.stamp.tv_usec != stamp->tv_usec ||
188 	    mip6_report_rl.iif != iif ||
189 	    !ipv6_addr_equal(&mip6_report_rl.src, src) ||
190 	    !ipv6_addr_equal(&mip6_report_rl.dst, dst)) {
191 		mip6_report_rl.stamp.tv_sec = stamp->tv_sec;
192 		mip6_report_rl.stamp.tv_usec = stamp->tv_usec;
193 		mip6_report_rl.iif = iif;
194 		ipv6_addr_copy(&mip6_report_rl.src, src);
195 		ipv6_addr_copy(&mip6_report_rl.dst, dst);
196 		allow = 1;
197 	}
198 	spin_unlock_bh(&mip6_report_rl.lock);
199 	return allow;
200 }
201 
202 static int mip6_destopt_reject(struct xfrm_state *x, struct sk_buff *skb, struct flowi *fl)
203 {
204 	struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb;
205 	struct ipv6_destopt_hao *hao = NULL;
206 	struct xfrm_selector sel;
207 	int offset;
208 	struct timeval stamp;
209 	int err = 0;
210 
211 	if (unlikely(fl->proto == IPPROTO_MH &&
212 		     fl->fl_mh_type <= IP6_MH_TYPE_MAX))
213 		goto out;
214 
215 	if (likely(opt->dsthao)) {
216 		offset = ipv6_find_tlv(skb, opt->dsthao, IPV6_TLV_HAO);
217 		if (likely(offset >= 0))
218 			hao = (struct ipv6_destopt_hao *)(skb->nh.raw + offset);
219 	}
220 
221 	skb_get_timestamp(skb, &stamp);
222 
223 	if (!mip6_report_rl_allow(&stamp, &skb->nh.ipv6h->daddr,
224 				  hao ? &hao->addr : &skb->nh.ipv6h->saddr,
225 				  opt->iif))
226 		goto out;
227 
228 	memset(&sel, 0, sizeof(sel));
229 	memcpy(&sel.daddr, (xfrm_address_t *)&skb->nh.ipv6h->daddr,
230 	       sizeof(sel.daddr));
231 	sel.prefixlen_d = 128;
232 	memcpy(&sel.saddr, (xfrm_address_t *)&skb->nh.ipv6h->saddr,
233 	       sizeof(sel.saddr));
234 	sel.prefixlen_s = 128;
235 	sel.family = AF_INET6;
236 	sel.proto = fl->proto;
237 	sel.dport = xfrm_flowi_dport(fl);
238 	if (sel.dport)
239 		sel.dport_mask = htons(~0);
240 	sel.sport = xfrm_flowi_sport(fl);
241 	if (sel.sport)
242 		sel.sport_mask = htons(~0);
243 	sel.ifindex = fl->oif;
244 
245 	err = km_report(IPPROTO_DSTOPTS, &sel,
246 			(hao ? (xfrm_address_t *)&hao->addr : NULL));
247 
248  out:
249 	return err;
250 }
251 
252 static int mip6_destopt_offset(struct xfrm_state *x, struct sk_buff *skb,
253 			       u8 **nexthdr)
254 {
255 	u16 offset = sizeof(struct ipv6hdr);
256 	struct ipv6_opt_hdr *exthdr = (struct ipv6_opt_hdr*)(skb->nh.ipv6h + 1);
257 	unsigned int packet_len = skb->tail - skb->nh.raw;
258 	int found_rhdr = 0;
259 
260 	*nexthdr = &skb->nh.ipv6h->nexthdr;
261 
262 	while (offset + 1 <= packet_len) {
263 
264 		switch (**nexthdr) {
265 		case NEXTHDR_HOP:
266 			break;
267 		case NEXTHDR_ROUTING:
268 			found_rhdr = 1;
269 			break;
270 		case NEXTHDR_DEST:
271 			/*
272 			 * HAO MUST NOT appear more than once.
273 			 * XXX: It is better to try to find by the end of
274 			 * XXX: packet if HAO exists.
275 			 */
276 			if (ipv6_find_tlv(skb, offset, IPV6_TLV_HAO) >= 0) {
277 				LIMIT_NETDEBUG(KERN_WARNING "mip6: hao exists already, override\n");
278 				return offset;
279 			}
280 
281 			if (found_rhdr)
282 				return offset;
283 
284 			break;
285 		default:
286 			return offset;
287 		}
288 
289 		offset += ipv6_optlen(exthdr);
290 		*nexthdr = &exthdr->nexthdr;
291 		exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
292 	}
293 
294 	return offset;
295 }
296 
297 static int mip6_destopt_init_state(struct xfrm_state *x)
298 {
299 	if (x->id.spi) {
300 		printk(KERN_INFO "%s: spi is not 0: %u\n", __FUNCTION__,
301 		       x->id.spi);
302 		return -EINVAL;
303 	}
304 	if (x->props.mode != XFRM_MODE_ROUTEOPTIMIZATION) {
305 		printk(KERN_INFO "%s: state's mode is not %u: %u\n",
306 		       __FUNCTION__, XFRM_MODE_ROUTEOPTIMIZATION, x->props.mode);
307 		return -EINVAL;
308 	}
309 
310 	x->props.header_len = sizeof(struct ipv6_destopt_hdr) +
311 		calc_padlen(sizeof(struct ipv6_destopt_hdr), 6) +
312 		sizeof(struct ipv6_destopt_hao);
313 	BUG_TRAP(x->props.header_len == 24);
314 
315 	return 0;
316 }
317 
318 /*
319  * Do nothing about destroying since it has no specific operation for
320  * destination options header unlike IPsec protocols.
321  */
322 static void mip6_destopt_destroy(struct xfrm_state *x)
323 {
324 }
325 
326 static struct xfrm_type mip6_destopt_type =
327 {
328 	.description	= "MIP6DESTOPT",
329 	.owner		= THIS_MODULE,
330 	.proto	     	= IPPROTO_DSTOPTS,
331 	.flags		= XFRM_TYPE_NON_FRAGMENT,
332 	.init_state	= mip6_destopt_init_state,
333 	.destructor	= mip6_destopt_destroy,
334 	.input		= mip6_destopt_input,
335 	.output		= mip6_destopt_output,
336 	.reject		= mip6_destopt_reject,
337 	.hdr_offset	= mip6_destopt_offset,
338 	.local_addr	= mip6_xfrm_addr,
339 };
340 
341 static int mip6_rthdr_input(struct xfrm_state *x, struct sk_buff *skb)
342 {
343 	struct rt2_hdr *rt2 = (struct rt2_hdr *)skb->data;
344 
345 	if (!ipv6_addr_equal(&rt2->addr, (struct in6_addr *)x->coaddr) &&
346 	    !ipv6_addr_any((struct in6_addr *)x->coaddr))
347 		return -ENOENT;
348 
349 	return rt2->rt_hdr.nexthdr;
350 }
351 
352 /* Routing Header type 2 is inserted.
353  * IP Header's dst address is replaced with Routing Header's Home Address.
354  */
355 static int mip6_rthdr_output(struct xfrm_state *x, struct sk_buff *skb)
356 {
357 	struct ipv6hdr *iph;
358 	struct rt2_hdr *rt2;
359 	u8 nexthdr;
360 
361 	iph = (struct ipv6hdr *)skb->data;
362 	iph->payload_len = htons(skb->len - sizeof(*iph));
363 
364 	nexthdr = *skb->nh.raw;
365 	*skb->nh.raw = IPPROTO_ROUTING;
366 
367 	rt2 = (struct rt2_hdr *)skb->h.raw;
368 	rt2->rt_hdr.nexthdr = nexthdr;
369 	rt2->rt_hdr.hdrlen = (x->props.header_len >> 3) - 1;
370 	rt2->rt_hdr.type = IPV6_SRCRT_TYPE_2;
371 	rt2->rt_hdr.segments_left = 1;
372 	memset(&rt2->reserved, 0, sizeof(rt2->reserved));
373 
374 	BUG_TRAP(rt2->rt_hdr.hdrlen == 2);
375 
376 	memcpy(&rt2->addr, &iph->daddr, sizeof(rt2->addr));
377 	memcpy(&iph->daddr, x->coaddr, sizeof(iph->daddr));
378 
379 	return 0;
380 }
381 
382 static int mip6_rthdr_offset(struct xfrm_state *x, struct sk_buff *skb,
383 			     u8 **nexthdr)
384 {
385 	u16 offset = sizeof(struct ipv6hdr);
386 	struct ipv6_opt_hdr *exthdr = (struct ipv6_opt_hdr*)(skb->nh.ipv6h + 1);
387 	unsigned int packet_len = skb->tail - skb->nh.raw;
388 	int found_rhdr = 0;
389 
390 	*nexthdr = &skb->nh.ipv6h->nexthdr;
391 
392 	while (offset + 1 <= packet_len) {
393 
394 		switch (**nexthdr) {
395 		case NEXTHDR_HOP:
396 			break;
397 		case NEXTHDR_ROUTING:
398 			if (offset + 3 <= packet_len) {
399 				struct ipv6_rt_hdr *rt;
400 				rt = (struct ipv6_rt_hdr *)(skb->nh.raw + offset);
401 				if (rt->type != 0)
402 					return offset;
403 			}
404 			found_rhdr = 1;
405 			break;
406 		case NEXTHDR_DEST:
407 			if (ipv6_find_tlv(skb, offset, IPV6_TLV_HAO) >= 0)
408 				return offset;
409 
410 			if (found_rhdr)
411 				return offset;
412 
413 			break;
414 		default:
415 			return offset;
416 		}
417 
418 		offset += ipv6_optlen(exthdr);
419 		*nexthdr = &exthdr->nexthdr;
420 		exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
421 	}
422 
423 	return offset;
424 }
425 
426 static int mip6_rthdr_init_state(struct xfrm_state *x)
427 {
428 	if (x->id.spi) {
429 		printk(KERN_INFO "%s: spi is not 0: %u\n", __FUNCTION__,
430 		       x->id.spi);
431 		return -EINVAL;
432 	}
433 	if (x->props.mode != XFRM_MODE_ROUTEOPTIMIZATION) {
434 		printk(KERN_INFO "%s: state's mode is not %u: %u\n",
435 		       __FUNCTION__, XFRM_MODE_ROUTEOPTIMIZATION, x->props.mode);
436 		return -EINVAL;
437 	}
438 
439 	x->props.header_len = sizeof(struct rt2_hdr);
440 
441 	return 0;
442 }
443 
444 /*
445  * Do nothing about destroying since it has no specific operation for routing
446  * header type 2 unlike IPsec protocols.
447  */
448 static void mip6_rthdr_destroy(struct xfrm_state *x)
449 {
450 }
451 
452 static struct xfrm_type mip6_rthdr_type =
453 {
454 	.description	= "MIP6RT",
455 	.owner		= THIS_MODULE,
456 	.proto	     	= IPPROTO_ROUTING,
457 	.flags		= XFRM_TYPE_NON_FRAGMENT,
458 	.init_state	= mip6_rthdr_init_state,
459 	.destructor	= mip6_rthdr_destroy,
460 	.input		= mip6_rthdr_input,
461 	.output		= mip6_rthdr_output,
462 	.hdr_offset	= mip6_rthdr_offset,
463 	.remote_addr	= mip6_xfrm_addr,
464 };
465 
466 int __init mip6_init(void)
467 {
468 	printk(KERN_INFO "Mobile IPv6\n");
469 
470 	if (xfrm_register_type(&mip6_destopt_type, AF_INET6) < 0) {
471 		printk(KERN_INFO "%s: can't add xfrm type(destopt)\n", __FUNCTION__);
472 		goto mip6_destopt_xfrm_fail;
473 	}
474 	if (xfrm_register_type(&mip6_rthdr_type, AF_INET6) < 0) {
475 		printk(KERN_INFO "%s: can't add xfrm type(rthdr)\n", __FUNCTION__);
476 		goto mip6_rthdr_xfrm_fail;
477 	}
478 	return 0;
479 
480  mip6_rthdr_xfrm_fail:
481 	xfrm_unregister_type(&mip6_destopt_type, AF_INET6);
482  mip6_destopt_xfrm_fail:
483 	return -EAGAIN;
484 }
485 
486 void __exit mip6_fini(void)
487 {
488 	if (xfrm_unregister_type(&mip6_rthdr_type, AF_INET6) < 0)
489 		printk(KERN_INFO "%s: can't remove xfrm type(rthdr)\n", __FUNCTION__);
490 	if (xfrm_unregister_type(&mip6_destopt_type, AF_INET6) < 0)
491 		printk(KERN_INFO "%s: can't remove xfrm type(destopt)\n", __FUNCTION__);
492 }
493