return helper;
}
+EXPORT_SYMBOL_GPL(nf_ct_helper_find_get);
void nf_ct_helper_put(struct nf_conntrack_helper *helper)
{
module_put(helper->me);
}
+EXPORT_SYMBOL_GPL(nf_ct_helper_put);
struct nf_conntrack_helper *
__nf_conntrack_helper_find_byname(const char *name)
return NULL;
}
+EXPORT_SYMBOL_GPL(__nf_conntrack_helper_find_byname);
static inline int unhelp(struct nf_conntrack_tuple_hash *i,
const struct nf_conntrack_helper *me)
return 0;
}
+EXPORT_SYMBOL_GPL(nf_conntrack_helper_register);
void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me)
{
/* Get rid of expectations */
list_for_each_entry_safe(exp, tmp, &nf_conntrack_expect_list, list) {
struct nf_conn_help *help = nfct_help(exp->master);
- if (help->helper == me && del_timer(&exp->timeout)) {
+ if ((help->helper == me || exp->helper == me) &&
+ del_timer(&exp->timeout)) {
nf_ct_unlink_expect(exp);
nf_conntrack_expect_put(exp);
}
/* Someone could be still looking at the helper in a bh. */
synchronize_net();
}
+EXPORT_SYMBOL_GPL(nf_conntrack_helper_unregister);