struct fib_config *cfg, int nh_weight,
                struct netlink_ext_ack *extack);
 void fib_nh_release(struct net *net, struct fib_nh *fib_nh);
+int fib_nh_common_init(struct fib_nh_common *nhc, struct nlattr *fc_encap,
+                      u16 fc_encap_type, void *cfg, gfp_t gfp_flags,
+                      struct netlink_ext_ack *extack);
+void fib_nh_common_release(struct fib_nh_common *nhc);
 
 /* Exported by fib_trie.c */
 void fib_trie_init(void);
 
        free_percpu(rtp);
 }
 
+void fib_nh_common_release(struct fib_nh_common *nhc)
+{
+       if (nhc->nhc_dev)
+               dev_put(nhc->nhc_dev);
+
+       lwtstate_put(nhc->nhc_lwtstate);
+}
+EXPORT_SYMBOL_GPL(fib_nh_common_release);
+
 void fib_nh_release(struct net *net, struct fib_nh *fib_nh)
 {
 #ifdef CONFIG_IP_ROUTE_CLASSID
        if (fib_nh->nh_tclassid)
                net->ipv4.fib_num_tclassid_users--;
 #endif
-       if (fib_nh->fib_nh_dev)
-               dev_put(fib_nh->fib_nh_dev);
-
-       lwtstate_put(fib_nh->fib_nh_lws);
+       fib_nh_common_release(&fib_nh->nh_common);
        free_nh_exceptions(fib_nh);
        rt_fibinfo_free_cpus(fib_nh->nh_pcpu_rth_output);
        rt_fibinfo_free(&fib_nh->nh_rth_input);
        return 1;
 }
 
+int fib_nh_common_init(struct fib_nh_common *nhc, struct nlattr *encap,
+                      u16 encap_type, void *cfg, gfp_t gfp_flags,
+                      struct netlink_ext_ack *extack)
+{
+       if (encap) {
+               struct lwtunnel_state *lwtstate;
+               int err;
+
+               if (encap_type == LWTUNNEL_ENCAP_NONE) {
+                       NL_SET_ERR_MSG(extack, "LWT encap type not specified");
+                       return -EINVAL;
+               }
+               err = lwtunnel_build_state(encap_type, encap, nhc->nhc_family,
+                                          cfg, &lwtstate, extack);
+               if (err)
+                       return err;
+
+               nhc->nhc_lwtstate = lwtstate_get(lwtstate);
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(fib_nh_common_init);
+
 int fib_nh_init(struct net *net, struct fib_nh *nh,
                struct fib_config *cfg, int nh_weight,
                struct netlink_ext_ack *extack)
        if (!nh->nh_pcpu_rth_output)
                goto err_out;
 
-       if (cfg->fc_encap) {
-               struct lwtunnel_state *lwtstate;
-
-               err = -EINVAL;
-               if (cfg->fc_encap_type == LWTUNNEL_ENCAP_NONE) {
-                       NL_SET_ERR_MSG(extack, "LWT encap type not specified");
-                       goto lwt_failure;
-               }
-               err = lwtunnel_build_state(cfg->fc_encap_type,
-                                          cfg->fc_encap, AF_INET, cfg,
-                                          &lwtstate, extack);
-               if (err)
-                       goto lwt_failure;
-
-               nh->fib_nh_lws = lwtstate_get(lwtstate);
-       }
+       err = fib_nh_common_init(&nh->nh_common, cfg->fc_encap,
+                                cfg->fc_encap_type, cfg, GFP_KERNEL, extack);
+       if (err)
+               goto init_failure;
 
        nh->fib_nh_oif = cfg->fc_oif;
        if (cfg->fc_gw) {
 #endif
        return 0;
 
-lwt_failure:
+init_failure:
        rt_fibinfo_free_cpus(nh->nh_pcpu_rth_output);
        nh->nh_pcpu_rth_output = NULL;
 err_out:
 
                fib6_nh->fib_nh_flags |= RTNH_F_ONLINK;
        }
 
-       if (cfg->fc_encap) {
-               struct lwtunnel_state *lwtstate;
-
-               err = lwtunnel_build_state(cfg->fc_encap_type,
-                                          cfg->fc_encap, AF_INET6, cfg,
-                                          &lwtstate, extack);
-               if (err)
-                       goto out;
-
-               fib6_nh->fib_nh_lws = lwtstate_get(lwtstate);
-       }
-
        fib6_nh->fib_nh_weight = 1;
 
        /* We cannot add true routes via loopback here,
            !netif_carrier_ok(dev))
                fib6_nh->fib_nh_flags |= RTNH_F_LINKDOWN;
 
+       err = fib_nh_common_init(&fib6_nh->nh_common, cfg->fc_encap,
+                                cfg->fc_encap_type, cfg, gfp_flags, extack);
+       if (err)
+               goto out;
 set_dev:
        fib6_nh->fib_nh_dev = dev;
        fib6_nh->fib_nh_oif = dev->ifindex;
 
 void fib6_nh_release(struct fib6_nh *fib6_nh)
 {
-       lwtstate_put(fib6_nh->fib_nh_lws);
-
-       if (fib6_nh->fib_nh_dev)
-               dev_put(fib6_nh->fib_nh_dev);
+       fib_nh_common_release(&fib6_nh->nh_common);
 }
 
 static struct fib6_info *ip6_route_info_create(struct fib6_config *cfg,