|
@@ -1348,6 +1348,37 @@ static int nf_tables_newchain(struct net *net, struct sock *nlsk,
|
|
|
if (nlh->nlmsg_flags & NLM_F_REPLACE)
|
|
|
return -EOPNOTSUPP;
|
|
|
|
|
|
+ if (nla[NFTA_CHAIN_HOOK]) {
|
|
|
+ struct nft_base_chain *basechain;
|
|
|
+ struct nft_chain_hook hook;
|
|
|
+ struct nf_hook_ops *ops;
|
|
|
+
|
|
|
+ if (!(chain->flags & NFT_BASE_CHAIN))
|
|
|
+ return -EBUSY;
|
|
|
+
|
|
|
+ err = nft_chain_parse_hook(net, nla, afi, &hook,
|
|
|
+ create);
|
|
|
+ if (err < 0)
|
|
|
+ return err;
|
|
|
+
|
|
|
+ basechain = nft_base_chain(chain);
|
|
|
+ if (basechain->type != hook.type) {
|
|
|
+ nft_chain_release_hook(&hook);
|
|
|
+ return -EBUSY;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (i = 0; i < afi->nops; i++) {
|
|
|
+ ops = &basechain->ops[i];
|
|
|
+ if (ops->hooknum != hook.num ||
|
|
|
+ ops->priority != hook.priority ||
|
|
|
+ ops->dev != hook.dev) {
|
|
|
+ nft_chain_release_hook(&hook);
|
|
|
+ return -EBUSY;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ nft_chain_release_hook(&hook);
|
|
|
+ }
|
|
|
+
|
|
|
if (nla[NFTA_CHAIN_HANDLE] && name) {
|
|
|
struct nft_chain *chain2;
|
|
|
|