On Mon, Mar 20, 2017 at 9:11 PM, Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx> wrote: > On Mon, Mar 20, 2017 at 09:06:22PM +0800, Gao Feng wrote: >> On Mon, Mar 20, 2017 at 8:50 PM, Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx> wrote: >> > On Mon, Mar 20, 2017 at 11:44:42AM +0100, Pablo Neira Ayuso wrote: >> >> > diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c >> >> > index 6dc44d9..6c840af 100644 >> >> > --- a/net/netfilter/nf_conntrack_helper.c >> >> > +++ b/net/netfilter/nf_conntrack_helper.c >> >> > @@ -130,6 +130,42 @@ static unsigned int helper_hash(const struct nf_conntrack_tuple *tuple) >> >> > return NULL; >> >> > } >> >> > >> >> > +static void >> >> > +nf_ct_remove_expect_refer_dying_module(const struct module *me) >> >> > +{ >> >> > + struct nf_conntrack_expect *exp; >> >> > + const struct hlist_node *next; >> >> > + u32 i; >> >> > + >> >> > + if (!me) >> >> > + return; >> >> > + >> >> > + /* Make sure no one is still using the moudule unless >> >> > + * its a connection in the hash. >> >> > + */ >> >> > + synchronize_rcu(); >> >> > + >> >> > + /* Get rid of expectations */ >> >> > + spin_lock_bh(&nf_conntrack_expect_lock); >> >> > + for (i = 0; i < nf_ct_expect_hsize; i++) { >> >> > + hlist_for_each_entry_safe(exp, next, >> >> > + &nf_ct_expect_hash[i], hnode) { >> >> > + struct nf_conn_help *master_help = nfct_help(exp->master); >> >> > + >> >> > + if ((master_help->helper && master_help->helper->me == me) || >> >> > + (exp->helper && exp->helper->me == me) || >> >> > + exp->expectfn_module == me) { >> > >> > Are you also sure this is correct? >> > >> > me can be nf_nat_sip, while exp->helper->me points to >> > nf_conntrack_sip. >> >> I don't read the source codes of ctlink command. >> But it seems be correct from the kernel codes. >> >> Please look at the function "ctnetlink_create_expect". >> >> if (cda[CTA_EXPECT_HELP_NAME]) { >> const char *helpname = nla_data(cda[CTA_EXPECT_HELP_NAME]); >> >> helper = __nf_conntrack_helper_find(helpname, u3, >> nf_ct_protonum(ct)); >> The helper is got by cda[CTA_EXPECT_HELP_NAME]. >> >> Then go to the function ctnetlink_alloc_expect, >> >> if (cda[CTA_EXPECT_FN]) { >> const char *name = nla_data(cda[CTA_EXPECT_FN]); >> struct nf_ct_helper_expectfn *expfn; >> >> expfn = nf_ct_helper_expectfn_find_by_name(name); >> The expfn is got by cda[CTA_EXPECT_FN]. >> >> So it is possible that the helper and expfn which they belongs to >> different modules. > > ctnetlink is not the only path to create expressions. > > We can also create expectations from the packet path, from the helper > itself. Thanks, but I know the data path could create expectation from the helper. But I want to show the helper and expfn could belongs to different modules. So we need to check them when flush expect. if (master->helper->module == me || helper->module == me || expect_module == me) These three conditions are necessary. My regards Feng -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html