int unregister_tcf_proto_ops(struct tcf_proto_ops *ops);
#ifdef CONFIG_NET_CLS
-struct tcf_chain *tcf_chain_get(struct tcf_block *block, u32 chain_index);
+struct tcf_chain *tcf_chain_get(struct tcf_block *block, u32 chain_index,
+ bool create);
void tcf_chain_put(struct tcf_chain *chain);
int tcf_block_get(struct tcf_block **p_block,
struct tcf_proto __rcu **p_filter_chain);
if (!tp)
return -EINVAL;
- a->goto_chain = tcf_chain_get(tp->chain->block, chain_index);
+ a->goto_chain = tcf_chain_get(tp->chain->block, chain_index, true);
if (!a->goto_chain)
return -ENOMEM;
return 0;
kfree(chain);
}
-struct tcf_chain *tcf_chain_get(struct tcf_block *block, u32 chain_index)
+struct tcf_chain *tcf_chain_get(struct tcf_block *block, u32 chain_index,
+ bool create)
{
struct tcf_chain *chain;
return chain;
}
}
- return tcf_chain_create(block, chain_index);
+ if (create)
+ return tcf_chain_create(block, chain_index);
+ else
+ return NULL;
}
EXPORT_SYMBOL(tcf_chain_get);
err = -EINVAL;
goto errout;
}
- chain = tcf_chain_get(block, chain_index);
+ chain = tcf_chain_get(block, chain_index,
+ n->nlmsg_type == RTM_NEWTFILTER);
if (!chain) {
- err = -ENOMEM;
+ err = n->nlmsg_type == RTM_NEWTFILTER ? -ENOMEM : -EINVAL;
goto errout;
}