On Tue, Jul 24, 2018 at 3:30 PM Cong Wang <xiyou.wangc...@gmail.com> wrote: > > On Mon, Jul 23, 2018 at 12:25 AM Jiri Pirko <j...@resnulli.us> wrote: > > + switch (n->nlmsg_type) { > > + case RTM_NEWCHAIN: > > + /* In case the chain was successfully added, take a > > reference > > + * to the chain. This ensures that an empty chain > > + * does not disappear at the end of this function. > > + */ > > + tcf_chain_hold(chain); > > + chain->explicitly_created = true; > > + tc_chain_notify(chain, NULL, 0, NLM_F_CREATE | NLM_F_EXCL, > > + RTM_NEWCHAIN, false); > > + break; > > + case RTM_DELCHAIN: > > + /* Flush the chain first as the user requested chain > > removal. */ > > + tcf_chain_flush(chain); > > + /* In case the chain was successfully deleted, put a > > reference > > + * to the chain previously taken during addition. > > + */ > > + tcf_chain_put_explicitly_created(chain); > > + break; > > I don't see you send notification to user-space when deleting a chain, > am I missing anything?
Oh, it is hidden in tcf_chain_put(): void tcf_chain_put(struct tcf_chain *chain) { if (--chain->refcnt == 0) { tc_chain_notify(chain, NULL, 0, 0, RTM_DELCHAIN, false); tc_chain_tmplt_del(chain); tcf_chain_destroy(chain); } } So, you only send out notification when the last refcnt is gone. If the chain that is being deleted by a user is still used by an action, you return 0 or -EPERM?