diff options
| author | David S. Miller <davem@davemloft.net> | 2015-02-05 17:33:28 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2015-02-05 17:33:28 -0500 |
| commit | 6e03f896b52cd2ca88942170c5c9c407ec0ede69 (patch) | |
| tree | 48ca9a6efa5f99819667538838bab3679416f92c /net/netfilter | |
| parent | db79a621835ee91d3e10177abd97f48e0a4dcf9b (diff) | |
| parent | 9d82f5eb3376cbae96ad36a063a9390de1694546 (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts:
drivers/net/vxlan.c
drivers/vhost/net.c
include/linux/if_vlan.h
net/core/dev.c
The net/core/dev.c conflict was the overlap of one commit marking an
existing function static whilst another was adding a new function.
In the include/linux/if_vlan.h case, the type used for a local
variable was changed in 'net', whereas the function got rewritten
to fix a stacked vlan bug in 'net-next'.
In drivers/vhost/net.c, Al Viro's iov_iter conversions in 'net-next'
overlapped with an endainness fix for VHOST 1.0 in 'net'.
In drivers/net/vxlan.c, vxlan_find_vni() added a 'flags' parameter
in 'net-next' whereas in 'net' there was a bug fix to pass in the
correct network namespace pointer in calls to this function.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/netfilter')
| -rw-r--r-- | net/netfilter/ipvs/ip_vs_core.c | 33 | ||||
| -rw-r--r-- | net/netfilter/nf_tables_api.c | 28 | ||||
| -rw-r--r-- | net/netfilter/nft_masq.c | 26 | ||||
| -rw-r--r-- | net/netfilter/nft_nat.c | 40 | ||||
| -rw-r--r-- | net/netfilter/nft_redir.c | 25 |
5 files changed, 112 insertions, 40 deletions
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index 990decba1fe4..b87ca32efa0b 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c | |||
| @@ -659,16 +659,24 @@ static inline int ip_vs_gather_frags(struct sk_buff *skb, u_int32_t user) | |||
| 659 | return err; | 659 | return err; |
| 660 | } | 660 | } |
| 661 | 661 | ||
| 662 | static int ip_vs_route_me_harder(int af, struct sk_buff *skb) | 662 | static int ip_vs_route_me_harder(int af, struct sk_buff *skb, |
| 663 | unsigned int hooknum) | ||
| 663 | { | 664 | { |
| 665 | if (!sysctl_snat_reroute(skb)) | ||
| 666 | return 0; | ||
| 667 | /* Reroute replies only to remote clients (FORWARD and LOCAL_OUT) */ | ||
| 668 | if (NF_INET_LOCAL_IN == hooknum) | ||
| 669 | return 0; | ||
| 664 | #ifdef CONFIG_IP_VS_IPV6 | 670 | #ifdef CONFIG_IP_VS_IPV6 |
| 665 | if (af == AF_INET6) { | 671 | if (af == AF_INET6) { |
| 666 | if (sysctl_snat_reroute(skb) && ip6_route_me_harder(skb) != 0) | 672 | struct dst_entry *dst = skb_dst(skb); |
| 673 | |||
| 674 | if (dst->dev && !(dst->dev->flags & IFF_LOOPBACK) && | ||
| 675 | ip6_route_me_harder(skb) != 0) | ||
| 667 | return 1; | 676 | return 1; |
| 668 | } else | 677 | } else |
| 669 | #endif | 678 | #endif |
| 670 | if ((sysctl_snat_reroute(skb) || | 679 | if (!(skb_rtable(skb)->rt_flags & RTCF_LOCAL) && |
| 671 | skb_rtable(skb)->rt_flags & RTCF_LOCAL) && | ||
| 672 | ip_route_me_harder(skb, RTN_LOCAL) != 0) | 680 | ip_route_me_harder(skb, RTN_LOCAL) != 0) |
| 673 | return 1; | 681 | return 1; |
| 674 | 682 | ||
| @@ -791,7 +799,8 @@ static int handle_response_icmp(int af, struct sk_buff *skb, | |||
| 791 | union nf_inet_addr *snet, | 799 | union nf_inet_addr *snet, |
| 792 | __u8 protocol, struct ip_vs_conn *cp, | 800 | __u8 protocol, struct ip_vs_conn *cp, |
| 793 | struct ip_vs_protocol *pp, | 801 | struct ip_vs_protocol *pp, |
| 794 | unsigned int offset, unsigned int ihl) | 802 | unsigned int offset, unsigned int ihl, |
| 803 | unsigned int hooknum) | ||
| 795 | { | 804 | { |
| 796 | unsigned int verdict = NF_DROP; | 805 | unsigned int verdict = NF_DROP; |
| 797 | 806 | ||
| @@ -821,7 +830,7 @@ static int handle_response_icmp(int af, struct sk_buff *skb, | |||
| 821 | #endif | 830 | #endif |
| 822 | ip_vs_nat_icmp(skb, pp, cp, 1); | 831 | ip_vs_nat_icmp(skb, pp, cp, 1); |
| 823 | 832 | ||
| 824 | if (ip_vs_route_me_harder(af, skb)) | 833 | if (ip_vs_route_me_harder(af, skb, hooknum)) |
| 825 | goto out; | 834 | goto out; |
| 826 | 835 | ||
| 827 | /* do the statistics and put it back */ | 836 | /* do the statistics and put it back */ |
| @@ -916,7 +925,7 @@ static int ip_vs_out_icmp(struct sk_buff *skb, int *related, | |||
| 916 | 925 | ||
| 917 | snet.ip = iph->saddr; | 926 | snet.ip = iph->saddr; |
| 918 | return handle_response_icmp(AF_INET, skb, &snet, cih->protocol, cp, | 927 | return handle_response_icmp(AF_INET, skb, &snet, cih->protocol, cp, |
| 919 | pp, ciph.len, ihl); | 928 | pp, ciph.len, ihl, hooknum); |
| 920 | } | 929 | } |
| 921 | 930 | ||
| 922 | #ifdef CONFIG_IP_VS_IPV6 | 931 | #ifdef CONFIG_IP_VS_IPV6 |
| @@ -981,7 +990,8 @@ static int ip_vs_out_icmp_v6(struct sk_buff *skb, int *related, | |||
| 981 | snet.in6 = ciph.saddr.in6; | 990 | snet.in6 = ciph.saddr.in6; |
| 982 | writable = ciph.len; | 991 | writable = ciph.len; |
| 983 | return handle_response_icmp(AF_INET6, skb, &snet, ciph.protocol, cp, | 992 | return handle_response_icmp(AF_INET6, skb, &snet, ciph.protocol, cp, |
| 984 | pp, writable, sizeof(struct ipv6hdr)); | 993 | pp, writable, sizeof(struct ipv6hdr), |
| 994 | hooknum); | ||
| 985 | } | 995 | } |
| 986 | #endif | 996 | #endif |
| 987 | 997 | ||
| @@ -1040,7 +1050,8 @@ static inline bool is_new_conn(const struct sk_buff *skb, | |||
| 1040 | */ | 1050 | */ |
| 1041 | static unsigned int | 1051 | static unsigned int |
| 1042 | handle_response(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd, | 1052 | handle_response(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd, |
| 1043 | struct ip_vs_conn *cp, struct ip_vs_iphdr *iph) | 1053 | struct ip_vs_conn *cp, struct ip_vs_iphdr *iph, |
| 1054 | unsigned int hooknum) | ||
| 1044 | { | 1055 | { |
| 1045 | struct ip_vs_protocol *pp = pd->pp; | 1056 | struct ip_vs_protocol *pp = pd->pp; |
| 1046 | 1057 | ||
| @@ -1078,7 +1089,7 @@ handle_response(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd, | |||
| 1078 | * if it came from this machine itself. So re-compute | 1089 | * if it came from this machine itself. So re-compute |
| 1079 | * the routing information. | 1090 | * the routing information. |
| 1080 | */ | 1091 | */ |
| 1081 | if (ip_vs_route_me_harder(af, skb)) | 1092 | if (ip_vs_route_me_harder(af, skb, hooknum)) |
| 1082 | goto drop; | 1093 | goto drop; |
| 1083 | 1094 | ||
| 1084 | IP_VS_DBG_PKT(10, af, pp, skb, 0, "After SNAT"); | 1095 | IP_VS_DBG_PKT(10, af, pp, skb, 0, "After SNAT"); |
| @@ -1181,7 +1192,7 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, int af) | |||
| 1181 | cp = pp->conn_out_get(af, skb, &iph, 0); | 1192 | cp = pp->conn_out_get(af, skb, &iph, 0); |
| 1182 | 1193 | ||
| 1183 | if (likely(cp)) | 1194 | if (likely(cp)) |
| 1184 | return handle_response(af, skb, pd, cp, &iph); | 1195 | return handle_response(af, skb, pd, cp, &iph, hooknum); |
| 1185 | if (sysctl_nat_icmp_send(net) && | 1196 | if (sysctl_nat_icmp_send(net) && |
| 1186 | (pp->protocol == IPPROTO_TCP || | 1197 | (pp->protocol == IPPROTO_TCP || |
| 1187 | pp->protocol == IPPROTO_UDP || | 1198 | pp->protocol == IPPROTO_UDP || |
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 70f697827b9b..199fd0f27b0e 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c | |||
| @@ -1136,9 +1136,11 @@ static struct nft_stats __percpu *nft_stats_alloc(const struct nlattr *attr) | |||
| 1136 | /* Restore old counters on this cpu, no problem. Per-cpu statistics | 1136 | /* Restore old counters on this cpu, no problem. Per-cpu statistics |
| 1137 | * are not exposed to userspace. | 1137 | * are not exposed to userspace. |
| 1138 | */ | 1138 | */ |
| 1139 | preempt_disable(); | ||
| 1139 | stats = this_cpu_ptr(newstats); | 1140 | stats = this_cpu_ptr(newstats); |
| 1140 | stats->bytes = be64_to_cpu(nla_get_be64(tb[NFTA_COUNTER_BYTES])); | 1141 | stats->bytes = be64_to_cpu(nla_get_be64(tb[NFTA_COUNTER_BYTES])); |
| 1141 | stats->pkts = be64_to_cpu(nla_get_be64(tb[NFTA_COUNTER_PACKETS])); | 1142 | stats->pkts = be64_to_cpu(nla_get_be64(tb[NFTA_COUNTER_PACKETS])); |
| 1143 | preempt_enable(); | ||
| 1142 | 1144 | ||
| 1143 | return newstats; | 1145 | return newstats; |
| 1144 | } | 1146 | } |
| @@ -1264,8 +1266,10 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb, | |||
| 1264 | nft_ctx_init(&ctx, skb, nlh, afi, table, chain, nla); | 1266 | nft_ctx_init(&ctx, skb, nlh, afi, table, chain, nla); |
| 1265 | trans = nft_trans_alloc(&ctx, NFT_MSG_NEWCHAIN, | 1267 | trans = nft_trans_alloc(&ctx, NFT_MSG_NEWCHAIN, |
| 1266 | sizeof(struct nft_trans_chain)); | 1268 | sizeof(struct nft_trans_chain)); |
| 1267 | if (trans == NULL) | 1269 | if (trans == NULL) { |
| 1270 | free_percpu(stats); | ||
| 1268 | return -ENOMEM; | 1271 | return -ENOMEM; |
| 1272 | } | ||
| 1269 | 1273 | ||
| 1270 | nft_trans_chain_stats(trans) = stats; | 1274 | nft_trans_chain_stats(trans) = stats; |
| 1271 | nft_trans_chain_update(trans) = true; | 1275 | nft_trans_chain_update(trans) = true; |
| @@ -1321,8 +1325,10 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb, | |||
| 1321 | hookfn = type->hooks[hooknum]; | 1325 | hookfn = type->hooks[hooknum]; |
| 1322 | 1326 | ||
| 1323 | basechain = kzalloc(sizeof(*basechain), GFP_KERNEL); | 1327 | basechain = kzalloc(sizeof(*basechain), GFP_KERNEL); |
| 1324 | if (basechain == NULL) | 1328 | if (basechain == NULL) { |
| 1329 | module_put(type->owner); | ||
| 1325 | return -ENOMEM; | 1330 | return -ENOMEM; |
| 1331 | } | ||
| 1326 | 1332 | ||
| 1327 | if (nla[NFTA_CHAIN_COUNTERS]) { | 1333 | if (nla[NFTA_CHAIN_COUNTERS]) { |
| 1328 | stats = nft_stats_alloc(nla[NFTA_CHAIN_COUNTERS]); | 1334 | stats = nft_stats_alloc(nla[NFTA_CHAIN_COUNTERS]); |
| @@ -3759,6 +3765,24 @@ int nft_chain_validate_dependency(const struct nft_chain *chain, | |||
| 3759 | } | 3765 | } |
| 3760 | EXPORT_SYMBOL_GPL(nft_chain_validate_dependency); | 3766 | EXPORT_SYMBOL_GPL(nft_chain_validate_dependency); |
| 3761 | 3767 | ||
| 3768 | int nft_chain_validate_hooks(const struct nft_chain *chain, | ||
| 3769 | unsigned int hook_flags) | ||
| 3770 | { | ||
| 3771 | struct nft_base_chain *basechain; | ||
| 3772 | |||
| 3773 | if (chain->flags & NFT_BASE_CHAIN) { | ||
| 3774 | basechain = nft_base_chain(chain); | ||
| 3775 | |||
| 3776 | if ((1 << basechain->ops[0].hooknum) & hook_flags) | ||
| 3777 | return 0; | ||
| 3778 | |||
| 3779 | return -EOPNOTSUPP; | ||
| 3780 | } | ||
| 3781 | |||
| 3782 | return 0; | ||
| 3783 | } | ||
| 3784 | EXPORT_SYMBOL_GPL(nft_chain_validate_hooks); | ||
| 3785 | |||
| 3762 | /* | 3786 | /* |
| 3763 | * Loop detection - walk through the ruleset beginning at the destination chain | 3787 | * Loop detection - walk through the ruleset beginning at the destination chain |
| 3764 | * of a new jump until either the source chain is reached (loop) or all | 3788 | * of a new jump until either the source chain is reached (loop) or all |
diff --git a/net/netfilter/nft_masq.c b/net/netfilter/nft_masq.c index d1ffd5eb3a9b..9aea747b43ea 100644 --- a/net/netfilter/nft_masq.c +++ b/net/netfilter/nft_masq.c | |||
| @@ -21,6 +21,21 @@ const struct nla_policy nft_masq_policy[NFTA_MASQ_MAX + 1] = { | |||
| 21 | }; | 21 | }; |
| 22 | EXPORT_SYMBOL_GPL(nft_masq_policy); | 22 | EXPORT_SYMBOL_GPL(nft_masq_policy); |
| 23 | 23 | ||
| 24 | int nft_masq_validate(const struct nft_ctx *ctx, | ||
| 25 | const struct nft_expr *expr, | ||
| 26 | const struct nft_data **data) | ||
| 27 | { | ||
| 28 | int err; | ||
| 29 | |||
| 30 | err = nft_chain_validate_dependency(ctx->chain, NFT_CHAIN_T_NAT); | ||
| 31 | if (err < 0) | ||
| 32 | return err; | ||
| 33 | |||
| 34 | return nft_chain_validate_hooks(ctx->chain, | ||
| 35 | (1 << NF_INET_POST_ROUTING)); | ||
| 36 | } | ||
| 37 | EXPORT_SYMBOL_GPL(nft_masq_validate); | ||
| 38 | |||
| 24 | int nft_masq_init(const struct nft_ctx *ctx, | 39 | int nft_masq_init(const struct nft_ctx *ctx, |
| 25 | const struct nft_expr *expr, | 40 | const struct nft_expr *expr, |
| 26 | const struct nlattr * const tb[]) | 41 | const struct nlattr * const tb[]) |
| @@ -28,8 +43,8 @@ int nft_masq_init(const struct nft_ctx *ctx, | |||
| 28 | struct nft_masq *priv = nft_expr_priv(expr); | 43 | struct nft_masq *priv = nft_expr_priv(expr); |
| 29 | int err; | 44 | int err; |
| 30 | 45 | ||
| 31 | err = nft_chain_validate_dependency(ctx->chain, NFT_CHAIN_T_NAT); | 46 | err = nft_masq_validate(ctx, expr, NULL); |
| 32 | if (err < 0) | 47 | if (err) |
| 33 | return err; | 48 | return err; |
| 34 | 49 | ||
| 35 | if (tb[NFTA_MASQ_FLAGS] == NULL) | 50 | if (tb[NFTA_MASQ_FLAGS] == NULL) |
| @@ -60,12 +75,5 @@ nla_put_failure: | |||
| 60 | } | 75 | } |
| 61 | EXPORT_SYMBOL_GPL(nft_masq_dump); | 76 | EXPORT_SYMBOL_GPL(nft_masq_dump); |
| 62 | 77 | ||
| 63 | int nft_masq_validate(const struct nft_ctx *ctx, const struct nft_expr *expr, | ||
| 64 | const struct nft_data **data) | ||
| 65 | { | ||
| 66 | return nft_chain_validate_dependency(ctx->chain, NFT_CHAIN_T_NAT); | ||
| 67 | } | ||
| 68 | EXPORT_SYMBOL_GPL(nft_masq_validate); | ||
| 69 | |||
| 70 | MODULE_LICENSE("GPL"); | 78 | MODULE_LICENSE("GPL"); |
| 71 | MODULE_AUTHOR("Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>"); | 79 | MODULE_AUTHOR("Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>"); |
diff --git a/net/netfilter/nft_nat.c b/net/netfilter/nft_nat.c index aff54fb1c8a0..a0837c6c9283 100644 --- a/net/netfilter/nft_nat.c +++ b/net/netfilter/nft_nat.c | |||
| @@ -88,17 +88,40 @@ static const struct nla_policy nft_nat_policy[NFTA_NAT_MAX + 1] = { | |||
| 88 | [NFTA_NAT_FLAGS] = { .type = NLA_U32 }, | 88 | [NFTA_NAT_FLAGS] = { .type = NLA_U32 }, |
| 89 | }; | 89 | }; |
| 90 | 90 | ||
| 91 | static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr, | 91 | static int nft_nat_validate(const struct nft_ctx *ctx, |
| 92 | const struct nlattr * const tb[]) | 92 | const struct nft_expr *expr, |
| 93 | const struct nft_data **data) | ||
| 93 | { | 94 | { |
| 94 | struct nft_nat *priv = nft_expr_priv(expr); | 95 | struct nft_nat *priv = nft_expr_priv(expr); |
| 95 | u32 family; | ||
| 96 | int err; | 96 | int err; |
| 97 | 97 | ||
| 98 | err = nft_chain_validate_dependency(ctx->chain, NFT_CHAIN_T_NAT); | 98 | err = nft_chain_validate_dependency(ctx->chain, NFT_CHAIN_T_NAT); |
| 99 | if (err < 0) | 99 | if (err < 0) |
| 100 | return err; | 100 | return err; |
| 101 | 101 | ||
| 102 | switch (priv->type) { | ||
| 103 | case NFT_NAT_SNAT: | ||
| 104 | err = nft_chain_validate_hooks(ctx->chain, | ||
| 105 | (1 << NF_INET_POST_ROUTING) | | ||
| 106 | (1 << NF_INET_LOCAL_IN)); | ||
| 107 | break; | ||
| 108 | case NFT_NAT_DNAT: | ||
| 109 | err = nft_chain_validate_hooks(ctx->chain, | ||
| 110 | (1 << NF_INET_PRE_ROUTING) | | ||
| 111 | (1 << NF_INET_LOCAL_OUT)); | ||
| 112 | break; | ||
| 113 | } | ||
| 114 | |||
| 115 | return err; | ||
| 116 | } | ||
| 117 | |||
| 118 | static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr, | ||
| 119 | const struct nlattr * const tb[]) | ||
| 120 | { | ||
| 121 | struct nft_nat *priv = nft_expr_priv(expr); | ||
| 122 | u32 family; | ||
| 123 | int err; | ||
| 124 | |||
| 102 | if (tb[NFTA_NAT_TYPE] == NULL || | 125 | if (tb[NFTA_NAT_TYPE] == NULL || |
| 103 | (tb[NFTA_NAT_REG_ADDR_MIN] == NULL && | 126 | (tb[NFTA_NAT_REG_ADDR_MIN] == NULL && |
| 104 | tb[NFTA_NAT_REG_PROTO_MIN] == NULL)) | 127 | tb[NFTA_NAT_REG_PROTO_MIN] == NULL)) |
| @@ -115,6 +138,10 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr, | |||
| 115 | return -EINVAL; | 138 | return -EINVAL; |
| 116 | } | 139 | } |
| 117 | 140 | ||
| 141 | err = nft_nat_validate(ctx, expr, NULL); | ||
| 142 | if (err < 0) | ||
| 143 | return err; | ||
| 144 | |||
| 118 | if (tb[NFTA_NAT_FAMILY] == NULL) | 145 | if (tb[NFTA_NAT_FAMILY] == NULL) |
| 119 | return -EINVAL; | 146 | return -EINVAL; |
| 120 | 147 | ||
| @@ -219,13 +246,6 @@ nla_put_failure: | |||
| 219 | return -1; | 246 | return -1; |
| 220 | } | 247 | } |
| 221 | 248 | ||
| 222 | static int nft_nat_validate(const struct nft_ctx *ctx, | ||
| 223 | const struct nft_expr *expr, | ||
| 224 | const struct nft_data **data) | ||
| 225 | { | ||
| 226 | return nft_chain_validate_dependency(ctx->chain, NFT_CHAIN_T_NAT); | ||
| 227 | } | ||
| 228 | |||
| 229 | static struct nft_expr_type nft_nat_type; | 249 | static struct nft_expr_type nft_nat_type; |
| 230 | static const struct nft_expr_ops nft_nat_ops = { | 250 | static const struct nft_expr_ops nft_nat_ops = { |
| 231 | .type = &nft_nat_type, | 251 | .type = &nft_nat_type, |
diff --git a/net/netfilter/nft_redir.c b/net/netfilter/nft_redir.c index 9e8093f28311..d7e9e93a4e90 100644 --- a/net/netfilter/nft_redir.c +++ b/net/netfilter/nft_redir.c | |||
| @@ -23,6 +23,22 @@ const struct nla_policy nft_redir_policy[NFTA_REDIR_MAX + 1] = { | |||
| 23 | }; | 23 | }; |
| 24 | EXPORT_SYMBOL_GPL(nft_redir_policy); | 24 | EXPORT_SYMBOL_GPL(nft_redir_policy); |
| 25 | 25 | ||
| 26 | int nft_redir_validate(const struct nft_ctx *ctx, | ||
| 27 | const struct nft_expr *expr, | ||
| 28 | const struct nft_data **data) | ||
| 29 | { | ||
| 30 | int err; | ||
| 31 | |||
| 32 | err = nft_chain_validate_dependency(ctx->chain, NFT_CHAIN_T_NAT); | ||
| 33 | if (err < 0) | ||
| 34 | return err; | ||
| 35 | |||
| 36 | return nft_chain_validate_hooks(ctx->chain, | ||
| 37 | (1 << NF_INET_PRE_ROUTING) | | ||
| 38 | (1 << NF_INET_LOCAL_OUT)); | ||
| 39 | } | ||
| 40 | EXPORT_SYMBOL_GPL(nft_redir_validate); | ||
| 41 | |||
| 26 | int nft_redir_init(const struct nft_ctx *ctx, | 42 | int nft_redir_init(const struct nft_ctx *ctx, |
| 27 | const struct nft_expr *expr, | 43 | const struct nft_expr *expr, |
| 28 | const struct nlattr * const tb[]) | 44 | const struct nlattr * const tb[]) |
| @@ -30,7 +46,7 @@ int nft_redir_init(const struct nft_ctx *ctx, | |||
| 30 | struct nft_redir *priv = nft_expr_priv(expr); | 46 | struct nft_redir *priv = nft_expr_priv(expr); |
| 31 | int err; | 47 | int err; |
| 32 | 48 | ||
| 33 | err = nft_chain_validate_dependency(ctx->chain, NFT_CHAIN_T_NAT); | 49 | err = nft_redir_validate(ctx, expr, NULL); |
| 34 | if (err < 0) | 50 | if (err < 0) |
| 35 | return err; | 51 | return err; |
| 36 | 52 | ||
| @@ -88,12 +104,5 @@ nla_put_failure: | |||
| 88 | } | 104 | } |
| 89 | EXPORT_SYMBOL_GPL(nft_redir_dump); | 105 | EXPORT_SYMBOL_GPL(nft_redir_dump); |
| 90 | 106 | ||
| 91 | int nft_redir_validate(const struct nft_ctx *ctx, const struct nft_expr *expr, | ||
| 92 | const struct nft_data **data) | ||
| 93 | { | ||
| 94 | return nft_chain_validate_dependency(ctx->chain, NFT_CHAIN_T_NAT); | ||
| 95 | } | ||
| 96 | EXPORT_SYMBOL_GPL(nft_redir_validate); | ||
| 97 | |||
| 98 | MODULE_LICENSE("GPL"); | 107 | MODULE_LICENSE("GPL"); |
| 99 | MODULE_AUTHOR("Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>"); | 108 | MODULE_AUTHOR("Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>"); |
