diff options
Diffstat (limited to 'net/core/lwtunnel.c')
-rw-r--r-- | net/core/lwtunnel.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/net/core/lwtunnel.c b/net/core/lwtunnel.c index 2f6db38..afa64f0 100644 --- a/net/core/lwtunnel.c +++ b/net/core/lwtunnel.c @@ -66,6 +66,15 @@ EXPORT_SYMBOL(lwtunnel_state_alloc); static const struct lwtunnel_encap_ops __rcu * lwtun_encaps[LWTUNNEL_ENCAP_MAX + 1] __read_mostly; +void lwtstate_free(struct lwtunnel_state *lws) +{ + const struct lwtunnel_encap_ops *ops = lwtun_encaps[lws->type]; + + kfree(lws); + module_put(ops->owner); +} +EXPORT_SYMBOL(lwtstate_free); + int lwtunnel_encap_add_ops(const struct lwtunnel_encap_ops *ops, unsigned int num) { @@ -111,8 +120,11 @@ int lwtunnel_build_state(struct net_device *dev, u16 encap_type, ret = -EOPNOTSUPP; rcu_read_lock(); ops = rcu_dereference(lwtun_encaps[encap_type]); - if (likely(ops && ops->build_state)) + if (likely(ops && ops->build_state && try_module_get(ops->owner))) { ret = ops->build_state(dev, encap, family, cfg, lws); + if (ret) + module_put(ops->owner); + } rcu_read_unlock(); return ret; |