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/rawv6.h>
34#include <net/xfrm.h>
35#include <net/mip6.h>
36
37static inline unsigned int calc_padlen(unsigned int len, unsigned int n)
38{
39	return (n - len + 16) & 0x7;
40}
41
42static inline void *mip6_padn(__u8 *data, __u8 padlen)
43{
44	if (!data)
45		return NULL;
46	if (padlen == 1) {
47		data[0] = IPV6_TLV_PAD0;
48	} else if (padlen > 1) {
49		data[0] = IPV6_TLV_PADN;
50		data[1] = padlen - 2;
51		if (padlen > 2)
52			memset(data+2, 0, data[1]);
53	}
54	return data + padlen;
55}
56
57static inline void mip6_param_prob(struct sk_buff *skb, u8 code, int pos)
58{
59	icmpv6_send(skb, ICMPV6_PARAMPROB, code, pos);
60}
61
62static int mip6_mh_len(int type)
63{
64	int len = 0;
65
66	switch (type) {
67	case IP6_MH_TYPE_BRR:
68		len = 0;
69		break;
70	case IP6_MH_TYPE_HOTI:
71	case IP6_MH_TYPE_COTI:
72	case IP6_MH_TYPE_BU:
73	case IP6_MH_TYPE_BACK:
74		len = 1;
75		break;
76	case IP6_MH_TYPE_HOT:
77	case IP6_MH_TYPE_COT:
78	case IP6_MH_TYPE_BERROR:
79		len = 2;
80		break;
81	}
82	return len;
83}
84
85static int mip6_mh_filter(struct sock *sk, struct sk_buff *skb)
86{
87	struct ip6_mh *mh;
88
89	if (!pskb_may_pull(skb, (skb_transport_offset(skb)) + 8) ||
90	    !pskb_may_pull(skb, (skb_transport_offset(skb) +
91				 ((skb_transport_header(skb)[1] + 1) << 3))))
92		return -1;
93
94	mh = (struct ip6_mh *)skb_transport_header(skb);
95
96	if (mh->ip6mh_hdrlen < mip6_mh_len(mh->ip6mh_type)) {
97		LIMIT_NETDEBUG(KERN_DEBUG "mip6: MH message too short: %d vs >=%d\n",
98			       mh->ip6mh_hdrlen, mip6_mh_len(mh->ip6mh_type));
99		mip6_param_prob(skb, 0, ((&mh->ip6mh_hdrlen) -
100					 skb_network_header(skb)));
101		return -1;
102	}
103
104	if (mh->ip6mh_proto != IPPROTO_NONE) {
105		LIMIT_NETDEBUG(KERN_DEBUG "mip6: MH invalid payload proto = %d\n",
106			       mh->ip6mh_proto);
107		mip6_param_prob(skb, 0, ((&mh->ip6mh_proto) -
108					 skb_network_header(skb)));
109		return -1;
110	}
111
112	return 0;
113}
114
115struct mip6_report_rate_limiter {
116	spinlock_t lock;
117	struct timeval stamp;
118	int iif;
119	struct in6_addr src;
120	struct in6_addr dst;
121};
122
123static struct mip6_report_rate_limiter mip6_report_rl = {
124	.lock = __SPIN_LOCK_UNLOCKED(mip6_report_rl.lock)
125};
126
127static int mip6_destopt_input(struct xfrm_state *x, struct sk_buff *skb)
128{
129	struct ipv6hdr *iph = ipv6_hdr(skb);
130	struct ipv6_destopt_hdr *destopt = (struct ipv6_destopt_hdr *)skb->data;
131	int err = destopt->nexthdr;
132
133	spin_lock(&x->lock);
134	if (!ipv6_addr_equal(&iph->saddr, (struct in6_addr *)x->coaddr) &&
135	    !ipv6_addr_any((struct in6_addr *)x->coaddr))
136		err = -ENOENT;
137	spin_unlock(&x->lock);
138
139	return err;
140}
141
142/* Destination Option Header is inserted.
143 * IP Header's src address is replaced with Home Address Option in
144 * Destination Option Header.
145 */
146static int mip6_destopt_output(struct xfrm_state *x, struct sk_buff *skb)
147{
148	struct ipv6hdr *iph;
149	struct ipv6_destopt_hdr *dstopt;
150	struct ipv6_destopt_hao *hao;
151	u8 nexthdr;
152	int len;
153
154	skb_push(skb, -skb_network_offset(skb));
155	iph = ipv6_hdr(skb);
156
157	nexthdr = *skb_mac_header(skb);
158	*skb_mac_header(skb) = IPPROTO_DSTOPTS;
159
160	dstopt = (struct ipv6_destopt_hdr *)skb_transport_header(skb);
161	dstopt->nexthdr = nexthdr;
162
163	hao = mip6_padn((char *)(dstopt + 1),
164			calc_padlen(sizeof(*dstopt), 6));
165
166	hao->type = IPV6_TLV_HAO;
167	BUILD_BUG_ON(sizeof(*hao) != 18);
168	hao->length = sizeof(*hao) - 2;
169
170	len = ((char *)hao - (char *)dstopt) + sizeof(*hao);
171
172	memcpy(&hao->addr, &iph->saddr, sizeof(hao->addr));
173	spin_lock_bh(&x->lock);
174	memcpy(&iph->saddr, x->coaddr, sizeof(iph->saddr));
175	spin_unlock_bh(&x->lock);
176
177	WARN_ON(len != x->props.header_len);
178	dstopt->hdrlen = (x->props.header_len >> 3) - 1;
179
180	return 0;
181}
182
183static inline int mip6_report_rl_allow(struct timeval *stamp,
184				       struct in6_addr *dst,
185				       struct in6_addr *src, int iif)
186{
187	int allow = 0;
188
189	spin_lock_bh(&mip6_report_rl.lock);
190	if (mip6_report_rl.stamp.tv_sec != stamp->tv_sec ||
191	    mip6_report_rl.stamp.tv_usec != stamp->tv_usec ||
192	    mip6_report_rl.iif != iif ||
193	    !ipv6_addr_equal(&mip6_report_rl.src, src) ||
194	    !ipv6_addr_equal(&mip6_report_rl.dst, dst)) {
195		mip6_report_rl.stamp.tv_sec = stamp->tv_sec;
196		mip6_report_rl.stamp.tv_usec = stamp->tv_usec;
197		mip6_report_rl.iif = iif;
198		ipv6_addr_copy(&mip6_report_rl.src, src);
199		ipv6_addr_copy(&mip6_report_rl.dst, dst);
200		allow = 1;
201	}
202	spin_unlock_bh(&mip6_report_rl.lock);
203	return allow;
204}
205
206static int mip6_destopt_reject(struct xfrm_state *x, struct sk_buff *skb, struct flowi *fl)
207{
208	struct net *net = xs_net(x);
209	struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb;
210	struct ipv6_destopt_hao *hao = NULL;
211	struct xfrm_selector sel;
212	int offset;
213	struct timeval stamp;
214	int err = 0;
215
216	if (unlikely(fl->proto == IPPROTO_MH &&
217		     fl->fl_mh_type <= IP6_MH_TYPE_MAX))
218		goto out;
219
220	if (likely(opt->dsthao)) {
221		offset = ipv6_find_tlv(skb, opt->dsthao, IPV6_TLV_HAO);
222		if (likely(offset >= 0))
223			hao = (struct ipv6_destopt_hao *)
224					(skb_network_header(skb) + offset);
225	}
226
227	skb_get_timestamp(skb, &stamp);
228
229	if (!mip6_report_rl_allow(&stamp, &ipv6_hdr(skb)->daddr,
230				  hao ? &hao->addr : &ipv6_hdr(skb)->saddr,
231				  opt->iif))
232		goto out;
233
234	memset(&sel, 0, sizeof(sel));
235	memcpy(&sel.daddr, (xfrm_address_t *)&ipv6_hdr(skb)->daddr,
236	       sizeof(sel.daddr));
237	sel.prefixlen_d = 128;
238	memcpy(&sel.saddr, (xfrm_address_t *)&ipv6_hdr(skb)->saddr,
239	       sizeof(sel.saddr));
240	sel.prefixlen_s = 128;
241	sel.family = AF_INET6;
242	sel.proto = fl->proto;
243	sel.dport = xfrm_flowi_dport(fl);
244	if (sel.dport)
245		sel.dport_mask = htons(~0);
246	sel.sport = xfrm_flowi_sport(fl);
247	if (sel.sport)
248		sel.sport_mask = htons(~0);
249	sel.ifindex = fl->oif;
250
251	err = km_report(net, IPPROTO_DSTOPTS, &sel,
252			(hao ? (xfrm_address_t *)&hao->addr : NULL));
253
254 out:
255	return err;
256}
257
258static int mip6_destopt_offset(struct xfrm_state *x, struct sk_buff *skb,
259			       u8 **nexthdr)
260{
261	u16 offset = sizeof(struct ipv6hdr);
262	struct ipv6_opt_hdr *exthdr =
263				   (struct ipv6_opt_hdr *)(ipv6_hdr(skb) + 1);
264	const unsigned char *nh = skb_network_header(skb);
265	unsigned int packet_len = skb->tail - skb->network_header;
266	int found_rhdr = 0;
267
268	*nexthdr = &ipv6_hdr(skb)->nexthdr;
269
270	while (offset + 1 <= packet_len) {
271
272		switch (**nexthdr) {
273		case NEXTHDR_HOP:
274			break;
275		case NEXTHDR_ROUTING:
276			found_rhdr = 1;
277			break;
278		case NEXTHDR_DEST:
279			if (ipv6_find_tlv(skb, offset, IPV6_TLV_HAO) >= 0) {
280				LIMIT_NETDEBUG(KERN_WARNING "mip6: hao exists already, override\n");
281				return offset;
282			}
283
284			if (found_rhdr)
285				return offset;
286
287			break;
288		default:
289			return offset;
290		}
291
292		offset += ipv6_optlen(exthdr);
293		*nexthdr = &exthdr->nexthdr;
294		exthdr = (struct ipv6_opt_hdr *)(nh + offset);
295	}
296
297	return offset;
298}
299
300static int mip6_destopt_init_state(struct xfrm_state *x)
301{
302	if (x->id.spi) {
303		printk(KERN_INFO "%s: spi is not 0: %u\n", __func__,
304		       x->id.spi);
305		return -EINVAL;
306	}
307	if (x->props.mode != XFRM_MODE_ROUTEOPTIMIZATION) {
308		printk(KERN_INFO "%s: state's mode is not %u: %u\n",
309		       __func__, XFRM_MODE_ROUTEOPTIMIZATION, x->props.mode);
310		return -EINVAL;
311	}
312
313	x->props.header_len = sizeof(struct ipv6_destopt_hdr) +
314		calc_padlen(sizeof(struct ipv6_destopt_hdr), 6) +
315		sizeof(struct ipv6_destopt_hao);
316	WARN_ON(x->props.header_len != 24);
317
318	return 0;
319}
320
321/*
322 * Do nothing about destroying since it has no specific operation for
323 * destination options header unlike IPsec protocols.
324 */
325static void mip6_destopt_destroy(struct xfrm_state *x)
326{
327}
328
329static const struct xfrm_type mip6_destopt_type =
330{
331	.description	= "MIP6DESTOPT",
332	.owner		= THIS_MODULE,
333	.proto	     	= IPPROTO_DSTOPTS,
334	.flags		= XFRM_TYPE_NON_FRAGMENT | XFRM_TYPE_LOCAL_COADDR,
335	.init_state	= mip6_destopt_init_state,
336	.destructor	= mip6_destopt_destroy,
337	.input		= mip6_destopt_input,
338	.output		= mip6_destopt_output,
339	.reject		= mip6_destopt_reject,
340	.hdr_offset	= mip6_destopt_offset,
341};
342
343static int mip6_rthdr_input(struct xfrm_state *x, struct sk_buff *skb)
344{
345	struct ipv6hdr *iph = ipv6_hdr(skb);
346	struct rt2_hdr *rt2 = (struct rt2_hdr *)skb->data;
347	int err = rt2->rt_hdr.nexthdr;
348
349	spin_lock(&x->lock);
350	if (!ipv6_addr_equal(&iph->daddr, (struct in6_addr *)x->coaddr) &&
351	    !ipv6_addr_any((struct in6_addr *)x->coaddr))
352		err = -ENOENT;
353	spin_unlock(&x->lock);
354
355	return err;
356}
357
358/* Routing Header type 2 is inserted.
359 * IP Header's dst address is replaced with Routing Header's Home Address.
360 */
361static int mip6_rthdr_output(struct xfrm_state *x, struct sk_buff *skb)
362{
363	struct ipv6hdr *iph;
364	struct rt2_hdr *rt2;
365	u8 nexthdr;
366
367	skb_push(skb, -skb_network_offset(skb));
368	iph = ipv6_hdr(skb);
369
370	nexthdr = *skb_mac_header(skb);
371	*skb_mac_header(skb) = IPPROTO_ROUTING;
372
373	rt2 = (struct rt2_hdr *)skb_transport_header(skb);
374	rt2->rt_hdr.nexthdr = nexthdr;
375	rt2->rt_hdr.hdrlen = (x->props.header_len >> 3) - 1;
376	rt2->rt_hdr.type = IPV6_SRCRT_TYPE_2;
377	rt2->rt_hdr.segments_left = 1;
378	memset(&rt2->reserved, 0, sizeof(rt2->reserved));
379
380	WARN_ON(rt2->rt_hdr.hdrlen != 2);
381
382	memcpy(&rt2->addr, &iph->daddr, sizeof(rt2->addr));
383	spin_lock_bh(&x->lock);
384	memcpy(&iph->daddr, x->coaddr, sizeof(iph->daddr));
385	spin_unlock_bh(&x->lock);
386
387	return 0;
388}
389
390static int mip6_rthdr_offset(struct xfrm_state *x, struct sk_buff *skb,
391			     u8 **nexthdr)
392{
393	u16 offset = sizeof(struct ipv6hdr);
394	struct ipv6_opt_hdr *exthdr =
395				   (struct ipv6_opt_hdr *)(ipv6_hdr(skb) + 1);
396	const unsigned char *nh = skb_network_header(skb);
397	unsigned int packet_len = skb->tail - skb->network_header;
398	int found_rhdr = 0;
399
400	*nexthdr = &ipv6_hdr(skb)->nexthdr;
401
402	while (offset + 1 <= packet_len) {
403
404		switch (**nexthdr) {
405		case NEXTHDR_HOP:
406			break;
407		case NEXTHDR_ROUTING:
408			if (offset + 3 <= packet_len) {
409				struct ipv6_rt_hdr *rt;
410				rt = (struct ipv6_rt_hdr *)(nh + offset);
411				if (rt->type != 0)
412					return offset;
413			}
414			found_rhdr = 1;
415			break;
416		case NEXTHDR_DEST:
417			if (ipv6_find_tlv(skb, offset, IPV6_TLV_HAO) >= 0)
418				return offset;
419
420			if (found_rhdr)
421				return offset;
422
423			break;
424		default:
425			return offset;
426		}
427
428		offset += ipv6_optlen(exthdr);
429		*nexthdr = &exthdr->nexthdr;
430		exthdr = (struct ipv6_opt_hdr *)(nh + offset);
431	}
432
433	return offset;
434}
435
436static int mip6_rthdr_init_state(struct xfrm_state *x)
437{
438	if (x->id.spi) {
439		printk(KERN_INFO "%s: spi is not 0: %u\n", __func__,
440		       x->id.spi);
441		return -EINVAL;
442	}
443	if (x->props.mode != XFRM_MODE_ROUTEOPTIMIZATION) {
444		printk(KERN_INFO "%s: state's mode is not %u: %u\n",
445		       __func__, XFRM_MODE_ROUTEOPTIMIZATION, x->props.mode);
446		return -EINVAL;
447	}
448
449	x->props.header_len = sizeof(struct rt2_hdr);
450
451	return 0;
452}
453
454/*
455 * Do nothing about destroying since it has no specific operation for routing
456 * header type 2 unlike IPsec protocols.
457 */
458static void mip6_rthdr_destroy(struct xfrm_state *x)
459{
460}
461
462static const struct xfrm_type mip6_rthdr_type =
463{
464	.description	= "MIP6RT",
465	.owner		= THIS_MODULE,
466	.proto	     	= IPPROTO_ROUTING,
467	.flags		= XFRM_TYPE_NON_FRAGMENT | XFRM_TYPE_REMOTE_COADDR,
468	.init_state	= mip6_rthdr_init_state,
469	.destructor	= mip6_rthdr_destroy,
470	.input		= mip6_rthdr_input,
471	.output		= mip6_rthdr_output,
472	.hdr_offset	= mip6_rthdr_offset,
473};
474
475static int __init mip6_init(void)
476{
477	printk(KERN_INFO "Mobile IPv6\n");
478
479	if (xfrm_register_type(&mip6_destopt_type, AF_INET6) < 0) {
480		printk(KERN_INFO "%s: can't add xfrm type(destopt)\n", __func__);
481		goto mip6_destopt_xfrm_fail;
482	}
483	if (xfrm_register_type(&mip6_rthdr_type, AF_INET6) < 0) {
484		printk(KERN_INFO "%s: can't add xfrm type(rthdr)\n", __func__);
485		goto mip6_rthdr_xfrm_fail;
486	}
487	if (rawv6_mh_filter_register(mip6_mh_filter) < 0) {
488		printk(KERN_INFO "%s: can't add rawv6 mh filter\n", __func__);
489		goto mip6_rawv6_mh_fail;
490	}
491
492
493	return 0;
494
495 mip6_rawv6_mh_fail:
496	xfrm_unregister_type(&mip6_rthdr_type, AF_INET6);
497 mip6_rthdr_xfrm_fail:
498	xfrm_unregister_type(&mip6_destopt_type, AF_INET6);
499 mip6_destopt_xfrm_fail:
500	return -EAGAIN;
501}
502
503static void __exit mip6_fini(void)
504{
505	if (rawv6_mh_filter_unregister(mip6_mh_filter) < 0)
506		printk(KERN_INFO "%s: can't remove rawv6 mh filter\n", __func__);
507	if (xfrm_unregister_type(&mip6_rthdr_type, AF_INET6) < 0)
508		printk(KERN_INFO "%s: can't remove xfrm type(rthdr)\n", __func__);
509	if (xfrm_unregister_type(&mip6_destopt_type, AF_INET6) < 0)
510		printk(KERN_INFO "%s: can't remove xfrm type(destopt)\n", __func__);
511}
512
513module_init(mip6_init);
514module_exit(mip6_fini);
515
516MODULE_LICENSE("GPL");
517MODULE_ALIAS_XFRM_TYPE(AF_INET6, XFRM_PROTO_DSTOPTS);
518MODULE_ALIAS_XFRM_TYPE(AF_INET6, XFRM_PROTO_ROUTING);
519