aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/ipv6.h2
-rw-r--r--include/net/addrconf.h2
-rw-r--r--include/net/mip6.h4
-rw-r--r--include/net/rawv6.h9
-rw-r--r--net/ipv6/Kconfig2
-rw-r--r--net/ipv6/Makefile2
-rw-r--r--net/ipv6/addrconf.c4
-rw-r--r--net/ipv6/af_inet6.c10
-rw-r--r--net/ipv6/ah6.c8
-rw-r--r--net/ipv6/datagram.c2
-rw-r--r--net/ipv6/exthdrs.c19
-rw-r--r--net/ipv6/icmp.c2
-rw-r--r--net/ipv6/ip6_output.c2
-rw-r--r--net/ipv6/ipv6_sockglue.c2
-rw-r--r--net/ipv6/mip6.c22
-rw-r--r--net/ipv6/raw.c34
-rw-r--r--net/ipv6/xfrm6_policy.c4
-rw-r--r--net/ipv6/xfrm6_state.c4
18 files changed, 88 insertions, 46 deletions
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index 648bd1f0912d..213b63be3c8f 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -247,7 +247,7 @@ struct inet6_skb_parm {
247 __u16 lastopt; 247 __u16 lastopt;
248 __u32 nhoff; 248 __u32 nhoff;
249 __u16 flags; 249 __u16 flags;
250#ifdef CONFIG_IPV6_MIP6 250#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
251 __u16 dsthao; 251 __u16 dsthao;
252#endif 252#endif
253 253
diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index f3531d0bcd05..33b593e17441 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -61,7 +61,7 @@ extern int addrconf_set_dstaddr(void __user *arg);
61extern int ipv6_chk_addr(struct in6_addr *addr, 61extern int ipv6_chk_addr(struct in6_addr *addr,
62 struct net_device *dev, 62 struct net_device *dev,
63 int strict); 63 int strict);
64#ifdef CONFIG_IPV6_MIP6 64#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
65extern int ipv6_chk_home_addr(struct in6_addr *addr); 65extern int ipv6_chk_home_addr(struct in6_addr *addr);
66#endif 66#endif
67extern struct inet6_ifaddr * ipv6_get_ifaddr(struct in6_addr *addr, 67extern struct inet6_ifaddr * ipv6_get_ifaddr(struct in6_addr *addr,
diff --git a/include/net/mip6.h b/include/net/mip6.h
index 68263c6d9996..63272610a24a 100644
--- a/include/net/mip6.h
+++ b/include/net/mip6.h
@@ -54,8 +54,4 @@ struct ip6_mh {
54#define IP6_MH_TYPE_BERROR 7 /* Binding Error */ 54#define IP6_MH_TYPE_BERROR 7 /* Binding Error */
55#define IP6_MH_TYPE_MAX IP6_MH_TYPE_BERROR 55#define IP6_MH_TYPE_MAX IP6_MH_TYPE_BERROR
56 56
57extern int mip6_init(void);
58extern void mip6_fini(void);
59extern int mip6_mh_filter(struct sock *sk, struct sk_buff *skb);
60
61#endif 57#endif
diff --git a/include/net/rawv6.h b/include/net/rawv6.h
index af8960878ef4..a5819891d525 100644
--- a/include/net/rawv6.h
+++ b/include/net/rawv6.h
@@ -3,6 +3,8 @@
3 3
4#ifdef __KERNEL__ 4#ifdef __KERNEL__
5 5
6#include <net/protocol.h>
7
6#define RAWV6_HTABLE_SIZE MAX_INET_PROTOS 8#define RAWV6_HTABLE_SIZE MAX_INET_PROTOS
7extern struct hlist_head raw_v6_htable[RAWV6_HTABLE_SIZE]; 9extern struct hlist_head raw_v6_htable[RAWV6_HTABLE_SIZE];
8extern rwlock_t raw_v6_lock; 10extern rwlock_t raw_v6_lock;
@@ -23,6 +25,13 @@ extern void rawv6_err(struct sock *sk,
23 int type, int code, 25 int type, int code,
24 int offset, __be32 info); 26 int offset, __be32 info);
25 27
28#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
29int rawv6_mh_filter_register(int (*filter)(struct sock *sock,
30 struct sk_buff *skb));
31int rawv6_mh_filter_unregister(int (*filter)(struct sock *sock,
32 struct sk_buff *skb));
33#endif
34
26#endif 35#endif
27 36
28#endif 37#endif
diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig
index 8e5d54f23b49..eb0b8085949b 100644
--- a/net/ipv6/Kconfig
+++ b/net/ipv6/Kconfig
@@ -109,7 +109,7 @@ config INET6_IPCOMP
109 If unsure, say Y. 109 If unsure, say Y.
110 110
111config IPV6_MIP6 111config IPV6_MIP6
112 bool "IPv6: Mobility (EXPERIMENTAL)" 112 tristate "IPv6: Mobility (EXPERIMENTAL)"
113 depends on IPV6 && EXPERIMENTAL 113 depends on IPV6 && EXPERIMENTAL
114 select XFRM 114 select XFRM
115 ---help--- 115 ---help---
diff --git a/net/ipv6/Makefile b/net/ipv6/Makefile
index bb33309044c9..87c23a73d284 100644
--- a/net/ipv6/Makefile
+++ b/net/ipv6/Makefile
@@ -14,7 +14,6 @@ ipv6-$(CONFIG_XFRM) += xfrm6_policy.o xfrm6_state.o xfrm6_input.o \
14 xfrm6_output.o 14 xfrm6_output.o
15ipv6-$(CONFIG_NETFILTER) += netfilter.o 15ipv6-$(CONFIG_NETFILTER) += netfilter.o
16ipv6-$(CONFIG_IPV6_MULTIPLE_TABLES) += fib6_rules.o 16ipv6-$(CONFIG_IPV6_MULTIPLE_TABLES) += fib6_rules.o
17ipv6-$(CONFIG_IPV6_MIP6) += mip6.o
18ipv6-$(CONFIG_PROC_FS) += proc.o 17ipv6-$(CONFIG_PROC_FS) += proc.o
19 18
20ipv6-objs += $(ipv6-y) 19ipv6-objs += $(ipv6-y)
@@ -28,6 +27,7 @@ obj-$(CONFIG_INET6_XFRM_MODE_TRANSPORT) += xfrm6_mode_transport.o
28obj-$(CONFIG_INET6_XFRM_MODE_TUNNEL) += xfrm6_mode_tunnel.o 27obj-$(CONFIG_INET6_XFRM_MODE_TUNNEL) += xfrm6_mode_tunnel.o
29obj-$(CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION) += xfrm6_mode_ro.o 28obj-$(CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION) += xfrm6_mode_ro.o
30obj-$(CONFIG_INET6_XFRM_MODE_BEET) += xfrm6_mode_beet.o 29obj-$(CONFIG_INET6_XFRM_MODE_BEET) += xfrm6_mode_beet.o
30obj-$(CONFIG_IPV6_MIP6) += mip6.o
31obj-$(CONFIG_NETFILTER) += netfilter/ 31obj-$(CONFIG_NETFILTER) += netfilter/
32 32
33obj-$(CONFIG_IPV6_SIT) += sit.o 33obj-$(CONFIG_IPV6_SIT) += sit.o
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 79b79f3de24c..11c0028863b0 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1034,7 +1034,7 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev,
1034 } 1034 }
1035 1035
1036 /* Rule 4: Prefer home address */ 1036 /* Rule 4: Prefer home address */
1037#ifdef CONFIG_IPV6_MIP6 1037#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
1038 if (hiscore.rule < 4) { 1038 if (hiscore.rule < 4) {
1039 if (ifa_result->flags & IFA_F_HOMEADDRESS) 1039 if (ifa_result->flags & IFA_F_HOMEADDRESS)
1040 hiscore.attrs |= IPV6_SADDR_SCORE_HOA; 1040 hiscore.attrs |= IPV6_SADDR_SCORE_HOA;
@@ -2835,7 +2835,7 @@ void if6_proc_exit(void)
2835} 2835}
2836#endif /* CONFIG_PROC_FS */ 2836#endif /* CONFIG_PROC_FS */
2837 2837
2838#ifdef CONFIG_IPV6_MIP6 2838#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
2839/* Check if address is a home address configured on any interface. */ 2839/* Check if address is a home address configured on any interface. */
2840int ipv6_chk_home_addr(struct in6_addr *addr) 2840int ipv6_chk_home_addr(struct in6_addr *addr)
2841{ 2841{
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 6dd377253cf7..eed09373a45d 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -58,9 +58,6 @@
58#ifdef CONFIG_IPV6_TUNNEL 58#ifdef CONFIG_IPV6_TUNNEL
59#include <net/ip6_tunnel.h> 59#include <net/ip6_tunnel.h>
60#endif 60#endif
61#ifdef CONFIG_IPV6_MIP6
62#include <net/mip6.h>
63#endif
64 61
65#include <asm/uaccess.h> 62#include <asm/uaccess.h>
66#include <asm/system.h> 63#include <asm/system.h>
@@ -853,9 +850,6 @@ static int __init inet6_init(void)
853 ipv6_frag_init(); 850 ipv6_frag_init();
854 ipv6_nodata_init(); 851 ipv6_nodata_init();
855 ipv6_destopt_init(); 852 ipv6_destopt_init();
856#ifdef CONFIG_IPV6_MIP6
857 mip6_init();
858#endif
859 853
860 /* Init v6 transport protocols. */ 854 /* Init v6 transport protocols. */
861 udpv6_init(); 855 udpv6_init();
@@ -921,9 +915,7 @@ static void __exit inet6_exit(void)
921 915
922 /* Cleanup code parts. */ 916 /* Cleanup code parts. */
923 ipv6_packet_cleanup(); 917 ipv6_packet_cleanup();
924#ifdef CONFIG_IPV6_MIP6 918
925 mip6_fini();
926#endif
927 addrconf_cleanup(); 919 addrconf_cleanup();
928 ip6_flowlabel_cleanup(); 920 ip6_flowlabel_cleanup();
929 ip6_route_cleanup(); 921 ip6_route_cleanup();
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index 01fa302d281e..cc6884a40be4 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -74,7 +74,7 @@ bad:
74 return 0; 74 return 0;
75} 75}
76 76
77#ifdef CONFIG_IPV6_MIP6 77#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
78/** 78/**
79 * ipv6_rearrange_destopt - rearrange IPv6 destination options header 79 * ipv6_rearrange_destopt - rearrange IPv6 destination options header
80 * @iph: IPv6 header 80 * @iph: IPv6 header
@@ -228,7 +228,7 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb)
228 u8 nexthdr; 228 u8 nexthdr;
229 char tmp_base[8]; 229 char tmp_base[8];
230 struct { 230 struct {
231#ifdef CONFIG_IPV6_MIP6 231#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
232 struct in6_addr saddr; 232 struct in6_addr saddr;
233#endif 233#endif
234 struct in6_addr daddr; 234 struct in6_addr daddr;
@@ -255,7 +255,7 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb)
255 err = -ENOMEM; 255 err = -ENOMEM;
256 goto error; 256 goto error;
257 } 257 }
258#ifdef CONFIG_IPV6_MIP6 258#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
259 memcpy(tmp_ext, &top_iph->saddr, extlen); 259 memcpy(tmp_ext, &top_iph->saddr, extlen);
260#else 260#else
261 memcpy(tmp_ext, &top_iph->daddr, extlen); 261 memcpy(tmp_ext, &top_iph->daddr, extlen);
@@ -294,7 +294,7 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb)
294 294
295 memcpy(top_iph, tmp_base, sizeof(tmp_base)); 295 memcpy(top_iph, tmp_base, sizeof(tmp_base));
296 if (tmp_ext) { 296 if (tmp_ext) {
297#ifdef CONFIG_IPV6_MIP6 297#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
298 memcpy(&top_iph->saddr, tmp_ext, extlen); 298 memcpy(&top_iph->saddr, tmp_ext, extlen);
299#else 299#else
300 memcpy(&top_iph->daddr, tmp_ext, extlen); 300 memcpy(&top_iph->daddr, tmp_ext, extlen);
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index b1fe7ac5dc90..ba1386dd4168 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -658,7 +658,7 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
658 658
659 switch (rthdr->type) { 659 switch (rthdr->type) {
660 case IPV6_SRCRT_TYPE_0: 660 case IPV6_SRCRT_TYPE_0:
661#ifdef CONFIG_IPV6_MIP6 661#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
662 case IPV6_SRCRT_TYPE_2: 662 case IPV6_SRCRT_TYPE_2:
663#endif 663#endif
664 break; 664 break;
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 14be0b9b77a5..173a4bb52255 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -42,7 +42,7 @@
42#include <net/ndisc.h> 42#include <net/ndisc.h>
43#include <net/ip6_route.h> 43#include <net/ip6_route.h>
44#include <net/addrconf.h> 44#include <net/addrconf.h>
45#ifdef CONFIG_IPV6_MIP6 45#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
46#include <net/xfrm.h> 46#include <net/xfrm.h>
47#endif 47#endif
48 48
@@ -90,6 +90,7 @@ int ipv6_find_tlv(struct sk_buff *skb, int offset, int type)
90 bad: 90 bad:
91 return -1; 91 return -1;
92} 92}
93EXPORT_SYMBOL_GPL(ipv6_find_tlv);
93 94
94/* 95/*
95 * Parsing tlv encoded headers. 96 * Parsing tlv encoded headers.
@@ -196,7 +197,7 @@ bad:
196 Destination options header. 197 Destination options header.
197 *****************************/ 198 *****************************/
198 199
199#ifdef CONFIG_IPV6_MIP6 200#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
200static int ipv6_dest_hao(struct sk_buff **skbp, int optoff) 201static int ipv6_dest_hao(struct sk_buff **skbp, int optoff)
201{ 202{
202 struct sk_buff *skb = *skbp; 203 struct sk_buff *skb = *skbp;
@@ -270,7 +271,7 @@ static int ipv6_dest_hao(struct sk_buff **skbp, int optoff)
270#endif 271#endif
271 272
272static struct tlvtype_proc tlvprocdestopt_lst[] = { 273static struct tlvtype_proc tlvprocdestopt_lst[] = {
273#ifdef CONFIG_IPV6_MIP6 274#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
274 { 275 {
275 .type = IPV6_TLV_HAO, 276 .type = IPV6_TLV_HAO,
276 .func = ipv6_dest_hao, 277 .func = ipv6_dest_hao,
@@ -283,7 +284,7 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp)
283{ 284{
284 struct sk_buff *skb = *skbp; 285 struct sk_buff *skb = *skbp;
285 struct inet6_skb_parm *opt = IP6CB(skb); 286 struct inet6_skb_parm *opt = IP6CB(skb);
286#ifdef CONFIG_IPV6_MIP6 287#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
287 __u16 dstbuf; 288 __u16 dstbuf;
288#endif 289#endif
289 struct dst_entry *dst; 290 struct dst_entry *dst;
@@ -298,7 +299,7 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp)
298 } 299 }
299 300
300 opt->lastopt = opt->dst1 = skb_network_header_len(skb); 301 opt->lastopt = opt->dst1 = skb_network_header_len(skb);
301#ifdef CONFIG_IPV6_MIP6 302#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
302 dstbuf = opt->dst1; 303 dstbuf = opt->dst1;
303#endif 304#endif
304 305
@@ -308,7 +309,7 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp)
308 skb = *skbp; 309 skb = *skbp;
309 skb->transport_header += (skb_transport_header(skb)[1] + 1) << 3; 310 skb->transport_header += (skb_transport_header(skb)[1] + 1) << 3;
310 opt = IP6CB(skb); 311 opt = IP6CB(skb);
311#ifdef CONFIG_IPV6_MIP6 312#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
312 opt->nhoff = dstbuf; 313 opt->nhoff = dstbuf;
313#else 314#else
314 opt->nhoff = opt->dst1; 315 opt->nhoff = opt->dst1;
@@ -427,7 +428,7 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp)
427looped_back: 428looped_back:
428 if (hdr->segments_left == 0) { 429 if (hdr->segments_left == 0) {
429 switch (hdr->type) { 430 switch (hdr->type) {
430#ifdef CONFIG_IPV6_MIP6 431#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
431 case IPV6_SRCRT_TYPE_2: 432 case IPV6_SRCRT_TYPE_2:
432 /* Silently discard type 2 header unless it was 433 /* Silently discard type 2 header unless it was
433 * processed by own 434 * processed by own
@@ -463,7 +464,7 @@ looped_back:
463 return -1; 464 return -1;
464 } 465 }
465 break; 466 break;
466#ifdef CONFIG_IPV6_MIP6 467#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
467 case IPV6_SRCRT_TYPE_2: 468 case IPV6_SRCRT_TYPE_2:
468 /* Silently discard invalid RTH type 2 */ 469 /* Silently discard invalid RTH type 2 */
469 if (hdr->hdrlen != 2 || hdr->segments_left != 1) { 470 if (hdr->hdrlen != 2 || hdr->segments_left != 1) {
@@ -520,7 +521,7 @@ looped_back:
520 addr += i - 1; 521 addr += i - 1;
521 522
522 switch (hdr->type) { 523 switch (hdr->type) {
523#ifdef CONFIG_IPV6_MIP6 524#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
524 case IPV6_SRCRT_TYPE_2: 525 case IPV6_SRCRT_TYPE_2:
525 if (xfrm6_input_addr(skb, (xfrm_address_t *)addr, 526 if (xfrm6_input_addr(skb, (xfrm_address_t *)addr,
526 (xfrm_address_t *)&ipv6_hdr(skb)->saddr, 527 (xfrm_address_t *)&ipv6_hdr(skb)->saddr,
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index e9bcce9e7bdf..4765a29f98a8 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -272,7 +272,7 @@ static int icmpv6_getfrag(void *from, char *to, int offset, int len, int odd, st
272 return 0; 272 return 0;
273} 273}
274 274
275#ifdef CONFIG_IPV6_MIP6 275#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
276static void mip6_addr_swap(struct sk_buff *skb) 276static void mip6_addr_swap(struct sk_buff *skb)
277{ 277{
278 struct ipv6hdr *iph = ipv6_hdr(skb); 278 struct ipv6hdr *iph = ipv6_hdr(skb);
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 4704b5fc3085..31dafaf0b652 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -543,7 +543,7 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
543 found_rhdr = 1; 543 found_rhdr = 1;
544 break; 544 break;
545 case NEXTHDR_DEST: 545 case NEXTHDR_DEST:
546#ifdef CONFIG_IPV6_MIP6 546#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
547 if (ipv6_find_tlv(skb, offset, IPV6_TLV_HAO) >= 0) 547 if (ipv6_find_tlv(skb, offset, IPV6_TLV_HAO) >= 0)
548 break; 548 break;
549#endif 549#endif
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index aa3d07c52a8f..b636c38411fb 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -417,7 +417,7 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
417 struct ipv6_rt_hdr *rthdr = opt->srcrt; 417 struct ipv6_rt_hdr *rthdr = opt->srcrt;
418 switch (rthdr->type) { 418 switch (rthdr->type) {
419 case IPV6_SRCRT_TYPE_0: 419 case IPV6_SRCRT_TYPE_0:
420#ifdef CONFIG_IPV6_MIP6 420#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
421 case IPV6_SRCRT_TYPE_2: 421 case IPV6_SRCRT_TYPE_2:
422#endif 422#endif
423 break; 423 break;
diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c
index 13b7160fb892..20c78ecff6a1 100644
--- a/net/ipv6/mip6.c
+++ b/net/ipv6/mip6.c
@@ -30,6 +30,7 @@
30#include <net/sock.h> 30#include <net/sock.h>
31#include <net/ipv6.h> 31#include <net/ipv6.h>
32#include <net/ip6_checksum.h> 32#include <net/ip6_checksum.h>
33#include <net/rawv6.h>
33#include <net/xfrm.h> 34#include <net/xfrm.h>
34#include <net/mip6.h> 35#include <net/mip6.h>
35 36
@@ -86,7 +87,7 @@ static int mip6_mh_len(int type)
86 return len; 87 return len;
87} 88}
88 89
89int mip6_mh_filter(struct sock *sk, struct sk_buff *skb) 90static int mip6_mh_filter(struct sock *sk, struct sk_buff *skb)
90{ 91{
91 struct ip6_mh *mh; 92 struct ip6_mh *mh;
92 93
@@ -471,7 +472,7 @@ static struct xfrm_type mip6_rthdr_type =
471 .remote_addr = mip6_xfrm_addr, 472 .remote_addr = mip6_xfrm_addr,
472}; 473};
473 474
474int __init mip6_init(void) 475static int __init mip6_init(void)
475{ 476{
476 printk(KERN_INFO "Mobile IPv6\n"); 477 printk(KERN_INFO "Mobile IPv6\n");
477 478
@@ -483,18 +484,33 @@ int __init mip6_init(void)
483 printk(KERN_INFO "%s: can't add xfrm type(rthdr)\n", __FUNCTION__); 484 printk(KERN_INFO "%s: can't add xfrm type(rthdr)\n", __FUNCTION__);
484 goto mip6_rthdr_xfrm_fail; 485 goto mip6_rthdr_xfrm_fail;
485 } 486 }
487 if (rawv6_mh_filter_register(mip6_mh_filter) < 0) {
488 printk(KERN_INFO "%s: can't add rawv6 mh filter\n", __FUNCTION__);
489 goto mip6_rawv6_mh_fail;
490 }
491
492
486 return 0; 493 return 0;
487 494
495 mip6_rawv6_mh_fail:
496 xfrm_unregister_type(&mip6_rthdr_type, AF_INET6);
488 mip6_rthdr_xfrm_fail: 497 mip6_rthdr_xfrm_fail:
489 xfrm_unregister_type(&mip6_destopt_type, AF_INET6); 498 xfrm_unregister_type(&mip6_destopt_type, AF_INET6);
490 mip6_destopt_xfrm_fail: 499 mip6_destopt_xfrm_fail:
491 return -EAGAIN; 500 return -EAGAIN;
492} 501}
493 502
494void __exit mip6_fini(void) 503static void __exit mip6_fini(void)
495{ 504{
505 if (rawv6_mh_filter_unregister(mip6_mh_filter) < 0)
506 printk(KERN_INFO "%s: can't remove rawv6 mh filter\n", __FUNCTION__);
496 if (xfrm_unregister_type(&mip6_rthdr_type, AF_INET6) < 0) 507 if (xfrm_unregister_type(&mip6_rthdr_type, AF_INET6) < 0)
497 printk(KERN_INFO "%s: can't remove xfrm type(rthdr)\n", __FUNCTION__); 508 printk(KERN_INFO "%s: can't remove xfrm type(rthdr)\n", __FUNCTION__);
498 if (xfrm_unregister_type(&mip6_destopt_type, AF_INET6) < 0) 509 if (xfrm_unregister_type(&mip6_destopt_type, AF_INET6) < 0)
499 printk(KERN_INFO "%s: can't remove xfrm type(destopt)\n", __FUNCTION__); 510 printk(KERN_INFO "%s: can't remove xfrm type(destopt)\n", __FUNCTION__);
500} 511}
512
513module_init(mip6_init);
514module_exit(mip6_fini);
515
516MODULE_LICENSE("GPL");
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index a22c9c93d931..aac6aeb8de8c 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -49,7 +49,7 @@
49#include <net/udp.h> 49#include <net/udp.h>
50#include <net/inet_common.h> 50#include <net/inet_common.h>
51#include <net/tcp_states.h> 51#include <net/tcp_states.h>
52#ifdef CONFIG_IPV6_MIP6 52#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
53#include <net/mip6.h> 53#include <net/mip6.h>
54#endif 54#endif
55 55
@@ -137,6 +137,28 @@ static __inline__ int icmpv6_filter(struct sock *sk, struct sk_buff *skb)
137 return 0; 137 return 0;
138} 138}
139 139
140#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
141static int (*mh_filter)(struct sock *sock, struct sk_buff *skb);
142
143int rawv6_mh_filter_register(int (*filter)(struct sock *sock,
144 struct sk_buff *skb))
145{
146 rcu_assign_pointer(mh_filter, filter);
147 return 0;
148}
149EXPORT_SYMBOL(rawv6_mh_filter_register);
150
151int rawv6_mh_filter_unregister(int (*filter)(struct sock *sock,
152 struct sk_buff *skb))
153{
154 rcu_assign_pointer(mh_filter, NULL);
155 synchronize_rcu();
156 return 0;
157}
158EXPORT_SYMBOL(rawv6_mh_filter_unregister);
159
160#endif
161
140/* 162/*
141 * demultiplex raw sockets. 163 * demultiplex raw sockets.
142 * (should consider queueing the skb in the sock receive_queue 164 * (should consider queueing the skb in the sock receive_queue
@@ -178,16 +200,22 @@ int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
178 case IPPROTO_ICMPV6: 200 case IPPROTO_ICMPV6:
179 filtered = icmpv6_filter(sk, skb); 201 filtered = icmpv6_filter(sk, skb);
180 break; 202 break;
181#ifdef CONFIG_IPV6_MIP6 203
204#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
182 case IPPROTO_MH: 205 case IPPROTO_MH:
206 {
183 /* XXX: To validate MH only once for each packet, 207 /* XXX: To validate MH only once for each packet,
184 * this is placed here. It should be after checking 208 * this is placed here. It should be after checking
185 * xfrm policy, however it doesn't. The checking xfrm 209 * xfrm policy, however it doesn't. The checking xfrm
186 * policy is placed in rawv6_rcv() because it is 210 * policy is placed in rawv6_rcv() because it is
187 * required for each socket. 211 * required for each socket.
188 */ 212 */
189 filtered = mip6_mh_filter(sk, skb); 213 int (*filter)(struct sock *sock, struct sk_buff *skb);
214
215 filter = rcu_dereference(mh_filter);
216 filtered = filter ? filter(sk, skb) : 0;
190 break; 217 break;
218 }
191#endif 219#endif
192 default: 220 default:
193 filtered = 0; 221 filtered = 0;
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 1faa2ea80afc..3ec0c4770ee3 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -18,7 +18,7 @@
18#include <net/ip.h> 18#include <net/ip.h>
19#include <net/ipv6.h> 19#include <net/ipv6.h>
20#include <net/ip6_route.h> 20#include <net/ip6_route.h>
21#ifdef CONFIG_IPV6_MIP6 21#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
22#include <net/mip6.h> 22#include <net/mip6.h>
23#endif 23#endif
24 24
@@ -318,7 +318,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl)
318 fl->proto = nexthdr; 318 fl->proto = nexthdr;
319 return; 319 return;
320 320
321#ifdef CONFIG_IPV6_MIP6 321#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
322 case IPPROTO_MH: 322 case IPPROTO_MH:
323 if (pskb_may_pull(skb, nh + offset + 3 - skb->data)) { 323 if (pskb_may_pull(skb, nh + offset + 3 - skb->data)) {
324 struct ip6_mh *mh; 324 struct ip6_mh *mh;
diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c
index baa461b9f74e..cdadb4847469 100644
--- a/net/ipv6/xfrm6_state.c
+++ b/net/ipv6/xfrm6_state.c
@@ -65,7 +65,7 @@ __xfrm6_state_sort(struct xfrm_state **dst, struct xfrm_state **src, int n)
65 goto end; 65 goto end;
66 66
67 /* Rule 2: select MIPv6 RO or inbound trigger */ 67 /* Rule 2: select MIPv6 RO or inbound trigger */
68#ifdef CONFIG_IPV6_MIP6 68#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
69 for (i = 0; i < n; i++) { 69 for (i = 0; i < n; i++) {
70 if (src[i] && 70 if (src[i] &&
71 (src[i]->props.mode == XFRM_MODE_ROUTEOPTIMIZATION || 71 (src[i]->props.mode == XFRM_MODE_ROUTEOPTIMIZATION ||
@@ -130,7 +130,7 @@ __xfrm6_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n)
130 goto end; 130 goto end;
131 131
132 /* Rule 2: select MIPv6 RO or inbound trigger */ 132 /* Rule 2: select MIPv6 RO or inbound trigger */
133#ifdef CONFIG_IPV6_MIP6 133#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
134 for (i = 0; i < n; i++) { 134 for (i = 0; i < n; i++) {
135 if (src[i] && 135 if (src[i] &&
136 (src[i]->mode == XFRM_MODE_ROUTEOPTIMIZATION || 136 (src[i]->mode == XFRM_MODE_ROUTEOPTIMIZATION ||