]> err.no Git - linux-2.6/commitdiff
[IPV6] MIP6: Loadable module support for MIPv6.
authorMasahide NAKAMURA <nakam@linux-ipv6.org>
Wed, 27 Jun 2007 06:56:32 +0000 (23:56 -0700)
committerDavid S. Miller <davem@sunset.davemloft.net>
Wed, 11 Jul 2007 05:15:42 +0000 (22:15 -0700)
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>
18 files changed:
include/linux/ipv6.h
include/net/addrconf.h
include/net/mip6.h
include/net/rawv6.h
net/ipv6/Kconfig
net/ipv6/Makefile
net/ipv6/addrconf.c
net/ipv6/af_inet6.c
net/ipv6/ah6.c
net/ipv6/datagram.c
net/ipv6/exthdrs.c
net/ipv6/icmp.c
net/ipv6/ip6_output.c
net/ipv6/ipv6_sockglue.c
net/ipv6/mip6.c
net/ipv6/raw.c
net/ipv6/xfrm6_policy.c
net/ipv6/xfrm6_state.c

index 648bd1f0912d3cbbba77b9276d34309f1f1700d5..213b63be3c8f0ec8c1b4ec355eb13bee9a00399b 100644 (file)
@@ -247,7 +247,7 @@ struct inet6_skb_parm {
        __u16                   lastopt;
        __u32                   nhoff;
        __u16                   flags;
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
        __u16                   dsthao;
 #endif
 
index f3531d0bcd051ae62bb31e655d197877e27b2122..33b593e174412792347be0d366a1f036e963430e 100644 (file)
@@ -61,7 +61,7 @@ extern int                    addrconf_set_dstaddr(void __user *arg);
 extern int                     ipv6_chk_addr(struct in6_addr *addr,
                                              struct net_device *dev,
                                              int strict);
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 extern int                     ipv6_chk_home_addr(struct in6_addr *addr);
 #endif
 extern struct inet6_ifaddr *   ipv6_get_ifaddr(struct in6_addr *addr,
index 68263c6d99960210138aed30aac13242c367ff15..63272610a24a4cd3c9f32951c78174189d5d3529 100644 (file)
@@ -54,8 +54,4 @@ struct ip6_mh {
 #define IP6_MH_TYPE_BERROR     7   /* Binding Error */
 #define IP6_MH_TYPE_MAX                IP6_MH_TYPE_BERROR
 
-extern int mip6_init(void);
-extern void mip6_fini(void);
-extern int mip6_mh_filter(struct sock *sk, struct sk_buff *skb);
-
 #endif
index af8960878ef41c72df5238a2304fc6bca643ef94..a5819891d52518a25b8430ba1f90cdad6ab0b403 100644 (file)
@@ -3,6 +3,8 @@
 
 #ifdef __KERNEL__
 
+#include <net/protocol.h>
+
 #define RAWV6_HTABLE_SIZE      MAX_INET_PROTOS
 extern struct hlist_head raw_v6_htable[RAWV6_HTABLE_SIZE];
 extern rwlock_t raw_v6_lock;
@@ -23,6 +25,13 @@ extern void                  rawv6_err(struct sock *sk,
                                          int type, int code, 
                                          int offset, __be32 info);
 
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+int rawv6_mh_filter_register(int (*filter)(struct sock *sock,
+                                          struct sk_buff *skb));
+int rawv6_mh_filter_unregister(int (*filter)(struct sock *sock,
+                                            struct sk_buff *skb));
+#endif
+
 #endif
 
 #endif
index 8e5d54f23b49398465b34797d2a20a919c947119..eb0b8085949b64620241de94be4815a1a303887d 100644 (file)
@@ -109,7 +109,7 @@ config INET6_IPCOMP
          If unsure, say Y.
 
 config IPV6_MIP6
-       bool "IPv6: Mobility (EXPERIMENTAL)"
+       tristate "IPv6: Mobility (EXPERIMENTAL)"
        depends on IPV6 && EXPERIMENTAL
        select XFRM
        ---help---
index bb33309044c9d01830f0b5ae323ae2efe966f326..87c23a73d28426f8d3dba9d5cdbfa1303835609f 100644 (file)
@@ -14,7 +14,6 @@ ipv6-$(CONFIG_XFRM) += xfrm6_policy.o xfrm6_state.o xfrm6_input.o \
        xfrm6_output.o
 ipv6-$(CONFIG_NETFILTER) += netfilter.o
 ipv6-$(CONFIG_IPV6_MULTIPLE_TABLES) += fib6_rules.o
-ipv6-$(CONFIG_IPV6_MIP6) += mip6.o
 ipv6-$(CONFIG_PROC_FS) += proc.o
 
 ipv6-objs += $(ipv6-y)
@@ -28,6 +27,7 @@ obj-$(CONFIG_INET6_XFRM_MODE_TRANSPORT) += xfrm6_mode_transport.o
 obj-$(CONFIG_INET6_XFRM_MODE_TUNNEL) += xfrm6_mode_tunnel.o
 obj-$(CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION) += xfrm6_mode_ro.o
 obj-$(CONFIG_INET6_XFRM_MODE_BEET) += xfrm6_mode_beet.o
+obj-$(CONFIG_IPV6_MIP6) += mip6.o
 obj-$(CONFIG_NETFILTER)        += netfilter/
 
 obj-$(CONFIG_IPV6_SIT) += sit.o
index 79b79f3de24ce263e79c6e478c07f705d31d11fe..11c0028863b0935e26ab31504a566fba2b39d836 100644 (file)
@@ -1034,7 +1034,7 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev,
                        }
 
                        /* Rule 4: Prefer home address */
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
                        if (hiscore.rule < 4) {
                                if (ifa_result->flags & IFA_F_HOMEADDRESS)
                                        hiscore.attrs |= IPV6_SADDR_SCORE_HOA;
@@ -2835,7 +2835,7 @@ void if6_proc_exit(void)
 }
 #endif /* CONFIG_PROC_FS */
 
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 /* Check if address is a home address configured on any interface. */
 int ipv6_chk_home_addr(struct in6_addr *addr)
 {
index 6dd377253cf77dbc615d436ef123e7323d3ee1cc..eed09373a45d8cb9685ae28eebcaa761b5ef557e 100644 (file)
@@ -58,9 +58,6 @@
 #ifdef CONFIG_IPV6_TUNNEL
 #include <net/ip6_tunnel.h>
 #endif
-#ifdef CONFIG_IPV6_MIP6
-#include <net/mip6.h>
-#endif
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -853,9 +850,6 @@ static int __init inet6_init(void)
        ipv6_frag_init();
        ipv6_nodata_init();
        ipv6_destopt_init();
-#ifdef CONFIG_IPV6_MIP6
-       mip6_init();
-#endif
 
        /* Init v6 transport protocols. */
        udpv6_init();
@@ -921,9 +915,7 @@ static void __exit inet6_exit(void)
 
        /* Cleanup code parts. */
        ipv6_packet_cleanup();
-#ifdef CONFIG_IPV6_MIP6
-       mip6_fini();
-#endif
+
        addrconf_cleanup();
        ip6_flowlabel_cleanup();
        ip6_route_cleanup();
index 01fa302d281e068dbd0a27a5c084a520a0790fea..cc6884a40be4e459ce569e033de179774ba6b3a8 100644 (file)
@@ -74,7 +74,7 @@ bad:
        return 0;
 }
 
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 /**
  *     ipv6_rearrange_destopt - rearrange IPv6 destination options header
  *     @iph: IPv6 header
@@ -228,7 +228,7 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb)
        u8 nexthdr;
        char tmp_base[8];
        struct {
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
                struct in6_addr saddr;
 #endif
                struct in6_addr daddr;
@@ -255,7 +255,7 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb)
                        err = -ENOMEM;
                        goto error;
                }
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
                memcpy(tmp_ext, &top_iph->saddr, extlen);
 #else
                memcpy(tmp_ext, &top_iph->daddr, extlen);
@@ -294,7 +294,7 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb)
 
        memcpy(top_iph, tmp_base, sizeof(tmp_base));
        if (tmp_ext) {
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
                memcpy(&top_iph->saddr, tmp_ext, extlen);
 #else
                memcpy(&top_iph->daddr, tmp_ext, extlen);
index b1fe7ac5dc9006795e871621179bf4d20f58cd9b..ba1386dd41684a2257fb0a63ddc856d94760f4db 100644 (file)
@@ -658,7 +658,7 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
 
                        switch (rthdr->type) {
                        case IPV6_SRCRT_TYPE_0:
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
                        case IPV6_SRCRT_TYPE_2:
 #endif
                                break;
index 14be0b9b77a5f998614351e1c5dbc92a31f94df0..173a4bb52255d57a9e7f2b105b95a52c32f1cda2 100644 (file)
@@ -42,7 +42,7 @@
 #include <net/ndisc.h>
 #include <net/ip6_route.h>
 #include <net/addrconf.h>
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 #include <net/xfrm.h>
 #endif
 
@@ -90,6 +90,7 @@ int ipv6_find_tlv(struct sk_buff *skb, int offset, int type)
  bad:
        return -1;
 }
+EXPORT_SYMBOL_GPL(ipv6_find_tlv);
 
 /*
  *     Parsing tlv encoded headers.
@@ -196,7 +197,7 @@ bad:
   Destination options header.
  *****************************/
 
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 static int ipv6_dest_hao(struct sk_buff **skbp, int optoff)
 {
        struct sk_buff *skb = *skbp;
@@ -270,7 +271,7 @@ static int ipv6_dest_hao(struct sk_buff **skbp, int optoff)
 #endif
 
 static struct tlvtype_proc tlvprocdestopt_lst[] = {
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
        {
                .type   = IPV6_TLV_HAO,
                .func   = ipv6_dest_hao,
@@ -283,7 +284,7 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp)
 {
        struct sk_buff *skb = *skbp;
        struct inet6_skb_parm *opt = IP6CB(skb);
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
        __u16 dstbuf;
 #endif
        struct dst_entry *dst;
@@ -298,7 +299,7 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp)
        }
 
        opt->lastopt = opt->dst1 = skb_network_header_len(skb);
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
        dstbuf = opt->dst1;
 #endif
 
@@ -308,7 +309,7 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp)
                skb = *skbp;
                skb->transport_header += (skb_transport_header(skb)[1] + 1) << 3;
                opt = IP6CB(skb);
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
                opt->nhoff = dstbuf;
 #else
                opt->nhoff = opt->dst1;
@@ -427,7 +428,7 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp)
 looped_back:
        if (hdr->segments_left == 0) {
                switch (hdr->type) {
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
                case IPV6_SRCRT_TYPE_2:
                        /* Silently discard type 2 header unless it was
                         * processed by own
@@ -463,7 +464,7 @@ looped_back:
                        return -1;
                }
                break;
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
        case IPV6_SRCRT_TYPE_2:
                /* Silently discard invalid RTH type 2 */
                if (hdr->hdrlen != 2 || hdr->segments_left != 1) {
@@ -520,7 +521,7 @@ looped_back:
        addr += i - 1;
 
        switch (hdr->type) {
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
        case IPV6_SRCRT_TYPE_2:
                if (xfrm6_input_addr(skb, (xfrm_address_t *)addr,
                                     (xfrm_address_t *)&ipv6_hdr(skb)->saddr,
index e9bcce9e7bdfb8bf59b74cf199fa16ac8c7a960e..4765a29f98a8e003b535ed7aedcf1b97d63b98e5 100644 (file)
@@ -272,7 +272,7 @@ static int icmpv6_getfrag(void *from, char *to, int offset, int len, int odd, st
        return 0;
 }
 
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 static void mip6_addr_swap(struct sk_buff *skb)
 {
        struct ipv6hdr *iph = ipv6_hdr(skb);
index 4704b5fc3085b9f8dab20bd5d1d36ea0b2d062a3..31dafaf0b652d7fc1ff965a092884bb43748d1fe 100644 (file)
@@ -543,7 +543,7 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
                        found_rhdr = 1;
                        break;
                case NEXTHDR_DEST:
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
                        if (ipv6_find_tlv(skb, offset, IPV6_TLV_HAO) >= 0)
                                break;
 #endif
index aa3d07c52a8fd18d44361d4a6f5fa2fd2d5c1612..b636c38411fbff749f4322c26ddf97ef0c4a22dd 100644 (file)
@@ -417,7 +417,7 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
                        struct ipv6_rt_hdr *rthdr = opt->srcrt;
                        switch (rthdr->type) {
                        case IPV6_SRCRT_TYPE_0:
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
                        case IPV6_SRCRT_TYPE_2:
 #endif
                                break;
index 13b7160fb8927b77b30bd6826f295169c71154e8..20c78ecff6a199b55eade55ccc03aec69a2f827a 100644 (file)
@@ -30,6 +30,7 @@
 #include <net/sock.h>
 #include <net/ipv6.h>
 #include <net/ip6_checksum.h>
+#include <net/rawv6.h>
 #include <net/xfrm.h>
 #include <net/mip6.h>
 
@@ -86,7 +87,7 @@ static int mip6_mh_len(int type)
        return len;
 }
 
-int mip6_mh_filter(struct sock *sk, struct sk_buff *skb)
+static int mip6_mh_filter(struct sock *sk, struct sk_buff *skb)
 {
        struct ip6_mh *mh;
 
@@ -471,7 +472,7 @@ static struct xfrm_type mip6_rthdr_type =
        .remote_addr    = mip6_xfrm_addr,
 };
 
-int __init mip6_init(void)
+static int __init mip6_init(void)
 {
        printk(KERN_INFO "Mobile IPv6\n");
 
@@ -483,18 +484,33 @@ int __init mip6_init(void)
                printk(KERN_INFO "%s: can't add xfrm type(rthdr)\n", __FUNCTION__);
                goto mip6_rthdr_xfrm_fail;
        }
+       if (rawv6_mh_filter_register(mip6_mh_filter) < 0) {
+               printk(KERN_INFO "%s: can't add rawv6 mh filter\n", __FUNCTION__);
+               goto mip6_rawv6_mh_fail;
+       }
+
+
        return 0;
 
+ mip6_rawv6_mh_fail:
+       xfrm_unregister_type(&mip6_rthdr_type, AF_INET6);
  mip6_rthdr_xfrm_fail:
        xfrm_unregister_type(&mip6_destopt_type, AF_INET6);
  mip6_destopt_xfrm_fail:
        return -EAGAIN;
 }
 
-void __exit mip6_fini(void)
+static void __exit mip6_fini(void)
 {
+       if (rawv6_mh_filter_unregister(mip6_mh_filter) < 0)
+               printk(KERN_INFO "%s: can't remove rawv6 mh filter\n", __FUNCTION__);
        if (xfrm_unregister_type(&mip6_rthdr_type, AF_INET6) < 0)
                printk(KERN_INFO "%s: can't remove xfrm type(rthdr)\n", __FUNCTION__);
        if (xfrm_unregister_type(&mip6_destopt_type, AF_INET6) < 0)
                printk(KERN_INFO "%s: can't remove xfrm type(destopt)\n", __FUNCTION__);
 }
+
+module_init(mip6_init);
+module_exit(mip6_fini);
+
+MODULE_LICENSE("GPL");
index a22c9c93d931148675d0ca8ea600cf430c53c75b..aac6aeb8de8c85f1b3d8099959e5f672a578e746 100644 (file)
@@ -49,7 +49,7 @@
 #include <net/udp.h>
 #include <net/inet_common.h>
 #include <net/tcp_states.h>
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 #include <net/mip6.h>
 #endif
 
@@ -137,6 +137,28 @@ static __inline__ int icmpv6_filter(struct sock *sk, struct sk_buff *skb)
        return 0;
 }
 
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+static int (*mh_filter)(struct sock *sock, struct sk_buff *skb);
+
+int rawv6_mh_filter_register(int (*filter)(struct sock *sock,
+                                          struct sk_buff *skb))
+{
+       rcu_assign_pointer(mh_filter, filter);
+       return 0;
+}
+EXPORT_SYMBOL(rawv6_mh_filter_register);
+
+int rawv6_mh_filter_unregister(int (*filter)(struct sock *sock,
+                                            struct sk_buff *skb))
+{
+       rcu_assign_pointer(mh_filter, NULL);
+       synchronize_rcu();
+       return 0;
+}
+EXPORT_SYMBOL(rawv6_mh_filter_unregister);
+
+#endif
+
 /*
  *     demultiplex raw sockets.
  *     (should consider queueing the skb in the sock receive_queue
@@ -178,16 +200,22 @@ int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
                case IPPROTO_ICMPV6:
                        filtered = icmpv6_filter(sk, skb);
                        break;
-#ifdef CONFIG_IPV6_MIP6
+
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
                case IPPROTO_MH:
+               {
                        /* XXX: To validate MH only once for each packet,
                         * this is placed here. It should be after checking
                         * xfrm policy, however it doesn't. The checking xfrm
                         * policy is placed in rawv6_rcv() because it is
                         * required for each socket.
                         */
-                       filtered = mip6_mh_filter(sk, skb);
+                       int (*filter)(struct sock *sock, struct sk_buff *skb);
+
+                       filter = rcu_dereference(mh_filter);
+                       filtered = filter ? filter(sk, skb) : 0;
                        break;
+               }
 #endif
                default:
                        filtered = 0;
index 1faa2ea80afc19e2ef246768388604ef616dde40..3ec0c4770ee35346693bc52ea35d434aea28d815 100644 (file)
@@ -18,7 +18,7 @@
 #include <net/ip.h>
 #include <net/ipv6.h>
 #include <net/ip6_route.h>
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 #include <net/mip6.h>
 #endif
 
@@ -318,7 +318,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl)
                        fl->proto = nexthdr;
                        return;
 
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
                case IPPROTO_MH:
                        if (pskb_may_pull(skb, nh + offset + 3 - skb->data)) {
                                struct ip6_mh *mh;
index baa461b9f74eebf97c654aa858203dcf010aa7e8..cdadb4847469f21e52237c75d5f12abaac9a5ffb 100644 (file)
@@ -65,7 +65,7 @@ __xfrm6_state_sort(struct xfrm_state **dst, struct xfrm_state **src, int n)
                goto end;
 
        /* Rule 2: select MIPv6 RO or inbound trigger */
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
        for (i = 0; i < n; i++) {
                if (src[i] &&
                    (src[i]->props.mode == XFRM_MODE_ROUTEOPTIMIZATION ||
@@ -130,7 +130,7 @@ __xfrm6_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n)
                goto end;
 
        /* Rule 2: select MIPv6 RO or inbound trigger */
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
        for (i = 0; i < n; i++) {
                if (src[i] &&
                    (src[i]->mode == XFRM_MODE_ROUTEOPTIMIZATION ||