#include <net/rtnetlink.h>
 #include <net/ip6_fib.h>
 
+#ifdef CONFIG_MODULES
+
+static const char *lwtunnel_encap_str(enum lwtunnel_encap_types encap_type)
+{
+       /* Only lwt encaps implemented without using an interface for
+        * the encap need to return a string here.
+        */
+       switch (encap_type) {
+       case LWTUNNEL_ENCAP_MPLS:
+               return "MPLS";
+       case LWTUNNEL_ENCAP_ILA:
+               return "ILA";
+       case LWTUNNEL_ENCAP_IP6:
+       case LWTUNNEL_ENCAP_IP:
+       case LWTUNNEL_ENCAP_NONE:
+       case __LWTUNNEL_ENCAP_MAX:
+               /* should not have got here */
+               WARN_ON(1);
+               break;
+       }
+       return NULL;
+}
+
+#endif /* CONFIG_MODULES */
+
 struct lwtunnel_state *lwtunnel_state_alloc(int encap_len)
 {
        struct lwtunnel_state *lws;
        ret = -EOPNOTSUPP;
        rcu_read_lock();
        ops = rcu_dereference(lwtun_encaps[encap_type]);
+#ifdef CONFIG_MODULES
+       if (!ops) {
+               const char *encap_type_str = lwtunnel_encap_str(encap_type);
+
+               if (encap_type_str) {
+                       rcu_read_unlock();
+                       request_module("rtnl-lwt-%s", encap_type_str);
+                       rcu_read_lock();
+                       ops = rcu_dereference(lwtun_encaps[encap_type]);
+               }
+       }
+#endif
        if (likely(ops && ops->build_state))
                ret = ops->build_state(dev, encap, family, cfg, lws);
        rcu_read_unlock();