diff options
author | Masahide NAKAMURA <nakam@linux-ipv6.org> | 2007-06-27 02:56:32 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-07-11 01:15:42 -0400 |
commit | 59fbb3a61e02deaeaa4fb50792217921f3002d64 (patch) | |
tree | 7455815c2566ba9b898cd6ea2c710159bbeb624f /net/ipv6 | |
parent | 136ebf08b46f839e2dc9db34322b654e5d9b9936 (diff) |
[IPV6] MIP6: Loadable module support for MIPv6.
This patch makes MIPv6 loadable module named "mip6".
Here is a modprobe.conf(5) example to load it automatically
when user application uses XFRM state for MIPv6:
alias xfrm-type-10-43 mip6
alias xfrm-type-10-60 mip6
Some MIPv6 feature is not included by this modular, however,
it should not be affected to other features like either IPsec
or IPv6 with and without the patch.
We may discuss XFRM, MH (RAW socket) and ancillary data/sockopt
separately for future work.
Loadable features:
* MH receiving check (to send ICMP error back)
* RO header parsing and building (i.e. RH2 and HAO in DSTOPTS)
* XFRM policy/state database handling for RO
These are NOT covered as loadable:
* Home Address flags and its rule on source address selection
* XFRM sub policy (depends on its own kernel option)
* XFRM functions to receive RO as IPv6 extension header
* MH sending/receiving through raw socket if user application
opens it (since raw socket allows to do so)
* RH2 sending as ancillary data
* RH2 operation with setsockopt(2)
Signed-off-by: Masahide NAKAMURA <nakam@linux-ipv6.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/Kconfig | 2 | ||||
-rw-r--r-- | net/ipv6/Makefile | 2 | ||||
-rw-r--r-- | net/ipv6/addrconf.c | 4 | ||||
-rw-r--r-- | net/ipv6/af_inet6.c | 10 | ||||
-rw-r--r-- | net/ipv6/ah6.c | 8 | ||||
-rw-r--r-- | net/ipv6/datagram.c | 2 | ||||
-rw-r--r-- | net/ipv6/exthdrs.c | 19 | ||||
-rw-r--r-- | net/ipv6/icmp.c | 2 | ||||
-rw-r--r-- | net/ipv6/ip6_output.c | 2 | ||||
-rw-r--r-- | net/ipv6/ipv6_sockglue.c | 2 | ||||
-rw-r--r-- | net/ipv6/mip6.c | 22 | ||||
-rw-r--r-- | net/ipv6/raw.c | 34 | ||||
-rw-r--r-- | net/ipv6/xfrm6_policy.c | 4 | ||||
-rw-r--r-- | net/ipv6/xfrm6_state.c | 4 |
14 files changed, 77 insertions, 40 deletions
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 | ||
111 | config IPV6_MIP6 | 111 | config 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 |
15 | ipv6-$(CONFIG_NETFILTER) += netfilter.o | 15 | ipv6-$(CONFIG_NETFILTER) += netfilter.o |
16 | ipv6-$(CONFIG_IPV6_MULTIPLE_TABLES) += fib6_rules.o | 16 | ipv6-$(CONFIG_IPV6_MULTIPLE_TABLES) += fib6_rules.o |
17 | ipv6-$(CONFIG_IPV6_MIP6) += mip6.o | ||
18 | ipv6-$(CONFIG_PROC_FS) += proc.o | 17 | ipv6-$(CONFIG_PROC_FS) += proc.o |
19 | 18 | ||
20 | ipv6-objs += $(ipv6-y) | 19 | ipv6-objs += $(ipv6-y) |
@@ -28,6 +27,7 @@ obj-$(CONFIG_INET6_XFRM_MODE_TRANSPORT) += xfrm6_mode_transport.o | |||
28 | obj-$(CONFIG_INET6_XFRM_MODE_TUNNEL) += xfrm6_mode_tunnel.o | 27 | obj-$(CONFIG_INET6_XFRM_MODE_TUNNEL) += xfrm6_mode_tunnel.o |
29 | obj-$(CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION) += xfrm6_mode_ro.o | 28 | obj-$(CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION) += xfrm6_mode_ro.o |
30 | obj-$(CONFIG_INET6_XFRM_MODE_BEET) += xfrm6_mode_beet.o | 29 | obj-$(CONFIG_INET6_XFRM_MODE_BEET) += xfrm6_mode_beet.o |
30 | obj-$(CONFIG_IPV6_MIP6) += mip6.o | ||
31 | obj-$(CONFIG_NETFILTER) += netfilter/ | 31 | obj-$(CONFIG_NETFILTER) += netfilter/ |
32 | 32 | ||
33 | obj-$(CONFIG_IPV6_SIT) += sit.o | 33 | obj-$(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. */ |
2840 | int ipv6_chk_home_addr(struct in6_addr *addr) | 2840 | int 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 | } |
93 | EXPORT_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) |
200 | static int ipv6_dest_hao(struct sk_buff **skbp, int optoff) | 201 | static 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 | ||
272 | static struct tlvtype_proc tlvprocdestopt_lst[] = { | 273 | static 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) | |||
427 | looped_back: | 428 | looped_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) |
276 | static void mip6_addr_swap(struct sk_buff *skb) | 276 | static 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 | ||
89 | int mip6_mh_filter(struct sock *sk, struct sk_buff *skb) | 90 | static 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 | ||
474 | int __init mip6_init(void) | 475 | static 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 | ||
494 | void __exit mip6_fini(void) | 503 | static 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 | |||
513 | module_init(mip6_init); | ||
514 | module_exit(mip6_fini); | ||
515 | |||
516 | MODULE_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) | ||
141 | static int (*mh_filter)(struct sock *sock, struct sk_buff *skb); | ||
142 | |||
143 | int 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 | } | ||
149 | EXPORT_SYMBOL(rawv6_mh_filter_register); | ||
150 | |||
151 | int 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 | } | ||
158 | EXPORT_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 || |