aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/netfilter/nf_tables_api.c56
1 files changed, 20 insertions, 36 deletions
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 572d88dd3e5f..30fad4f6322f 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -760,22 +760,6 @@ err:
760 return err; 760 return err;
761} 761}
762 762
763static int
764nf_tables_chain_policy(struct nft_base_chain *chain, const struct nlattr *attr)
765{
766 switch (ntohl(nla_get_be32(attr))) {
767 case NF_DROP:
768 chain->policy = NF_DROP;
769 break;
770 case NF_ACCEPT:
771 chain->policy = NF_ACCEPT;
772 break;
773 default:
774 return -EINVAL;
775 }
776 return 0;
777}
778
779static const struct nla_policy nft_counter_policy[NFTA_COUNTER_MAX + 1] = { 763static const struct nla_policy nft_counter_policy[NFTA_COUNTER_MAX + 1] = {
780 [NFTA_COUNTER_PACKETS] = { .type = NLA_U64 }, 764 [NFTA_COUNTER_PACKETS] = { .type = NLA_U64 },
781 [NFTA_COUNTER_BYTES] = { .type = NLA_U64 }, 765 [NFTA_COUNTER_BYTES] = { .type = NLA_U64 },
@@ -834,6 +818,7 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
834 struct nlattr *ha[NFTA_HOOK_MAX + 1]; 818 struct nlattr *ha[NFTA_HOOK_MAX + 1];
835 struct net *net = sock_net(skb->sk); 819 struct net *net = sock_net(skb->sk);
836 int family = nfmsg->nfgen_family; 820 int family = nfmsg->nfgen_family;
821 u8 policy = NF_ACCEPT;
837 u64 handle = 0; 822 u64 handle = 0;
838 unsigned int i; 823 unsigned int i;
839 int err; 824 int err;
@@ -869,6 +854,22 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
869 } 854 }
870 } 855 }
871 856
857 if (nla[NFTA_CHAIN_POLICY]) {
858 if ((chain != NULL &&
859 !(chain->flags & NFT_BASE_CHAIN)) ||
860 nla[NFTA_CHAIN_HOOK] == NULL)
861 return -EOPNOTSUPP;
862
863 policy = nla_get_be32(nla[NFTA_CHAIN_POLICY]);
864 switch (policy) {
865 case NF_DROP:
866 case NF_ACCEPT:
867 break;
868 default:
869 return -EINVAL;
870 }
871 }
872
872 if (chain != NULL) { 873 if (chain != NULL) {
873 if (nlh->nlmsg_flags & NLM_F_EXCL) 874 if (nlh->nlmsg_flags & NLM_F_EXCL)
874 return -EEXIST; 875 return -EEXIST;
@@ -879,15 +880,8 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
879 !IS_ERR(nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME]))) 880 !IS_ERR(nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME])))
880 return -EEXIST; 881 return -EEXIST;
881 882
882 if (nla[NFTA_CHAIN_POLICY]) { 883 if (nla[NFTA_CHAIN_POLICY])
883 if (!(chain->flags & NFT_BASE_CHAIN)) 884 nft_base_chain(chain)->policy = policy;
884 return -EOPNOTSUPP;
885
886 err = nf_tables_chain_policy(nft_base_chain(chain),
887 nla[NFTA_CHAIN_POLICY]);
888 if (err < 0)
889 return err;
890 }
891 885
892 if (nla[NFTA_CHAIN_COUNTERS]) { 886 if (nla[NFTA_CHAIN_COUNTERS]) {
893 if (!(chain->flags & NFT_BASE_CHAIN)) 887 if (!(chain->flags & NFT_BASE_CHAIN))
@@ -958,17 +952,7 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
958 } 952 }
959 953
960 chain->flags |= NFT_BASE_CHAIN; 954 chain->flags |= NFT_BASE_CHAIN;
961 955 basechain->policy = policy;
962 if (nla[NFTA_CHAIN_POLICY]) {
963 err = nf_tables_chain_policy(basechain,
964 nla[NFTA_CHAIN_POLICY]);
965 if (err < 0) {
966 free_percpu(basechain->stats);
967 kfree(basechain);
968 return err;
969 }
970 } else
971 basechain->policy = NF_ACCEPT;
972 956
973 if (nla[NFTA_CHAIN_COUNTERS]) { 957 if (nla[NFTA_CHAIN_COUNTERS]) {
974 err = nf_tables_counters(basechain, 958 err = nf_tables_counters(basechain,