diff options
Diffstat (limited to 'net/core/lwtunnel.c')
-rw-r--r-- | net/core/lwtunnel.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/net/core/lwtunnel.c b/net/core/lwtunnel.c index 299cfc24d888..669ecc9f884e 100644 --- a/net/core/lwtunnel.c +++ b/net/core/lwtunnel.c | |||
@@ -27,6 +27,31 @@ | |||
27 | #include <net/rtnetlink.h> | 27 | #include <net/rtnetlink.h> |
28 | #include <net/ip6_fib.h> | 28 | #include <net/ip6_fib.h> |
29 | 29 | ||
30 | #ifdef CONFIG_MODULES | ||
31 | |||
32 | static const char *lwtunnel_encap_str(enum lwtunnel_encap_types encap_type) | ||
33 | { | ||
34 | /* Only lwt encaps implemented without using an interface for | ||
35 | * the encap need to return a string here. | ||
36 | */ | ||
37 | switch (encap_type) { | ||
38 | case LWTUNNEL_ENCAP_MPLS: | ||
39 | return "MPLS"; | ||
40 | case LWTUNNEL_ENCAP_ILA: | ||
41 | return "ILA"; | ||
42 | case LWTUNNEL_ENCAP_IP6: | ||
43 | case LWTUNNEL_ENCAP_IP: | ||
44 | case LWTUNNEL_ENCAP_NONE: | ||
45 | case __LWTUNNEL_ENCAP_MAX: | ||
46 | /* should not have got here */ | ||
47 | WARN_ON(1); | ||
48 | break; | ||
49 | } | ||
50 | return NULL; | ||
51 | } | ||
52 | |||
53 | #endif /* CONFIG_MODULES */ | ||
54 | |||
30 | struct lwtunnel_state *lwtunnel_state_alloc(int encap_len) | 55 | struct lwtunnel_state *lwtunnel_state_alloc(int encap_len) |
31 | { | 56 | { |
32 | struct lwtunnel_state *lws; | 57 | struct lwtunnel_state *lws; |
@@ -85,6 +110,18 @@ int lwtunnel_build_state(struct net_device *dev, u16 encap_type, | |||
85 | ret = -EOPNOTSUPP; | 110 | ret = -EOPNOTSUPP; |
86 | rcu_read_lock(); | 111 | rcu_read_lock(); |
87 | ops = rcu_dereference(lwtun_encaps[encap_type]); | 112 | ops = rcu_dereference(lwtun_encaps[encap_type]); |
113 | #ifdef CONFIG_MODULES | ||
114 | if (!ops) { | ||
115 | const char *encap_type_str = lwtunnel_encap_str(encap_type); | ||
116 | |||
117 | if (encap_type_str) { | ||
118 | rcu_read_unlock(); | ||
119 | request_module("rtnl-lwt-%s", encap_type_str); | ||
120 | rcu_read_lock(); | ||
121 | ops = rcu_dereference(lwtun_encaps[encap_type]); | ||
122 | } | ||
123 | } | ||
124 | #endif | ||
88 | if (likely(ops && ops->build_state)) | 125 | if (likely(ops && ops->build_state)) |
89 | ret = ops->build_state(dev, encap, family, cfg, lws); | 126 | ret = ops->build_state(dev, encap, family, cfg, lws); |
90 | rcu_read_unlock(); | 127 | rcu_read_unlock(); |