netfilter: refactor NAT's redirect IPv4 code
Subsystems (2)
PATCH 1/3 netfilter: refactor NAT's redirect IPv4 code
The xt_REDIRECT can be seen as a NAT flavour (like masquerade).
This patch refactors the IPv4 code so it can be usable both from xt and nf_tables.
A similar patch follows-up to handle IPv6.
--- include/net/netfilter/ipv4/nf_nat_redirect.h | 9 +++ net/ipv4/netfilter/Kconfig | 6 ++ net/ipv4/netfilter/Makefile | 1 net/ipv4/netfilter/nf_nat_redirect_ipv4.c | 80 ++++++++++++++++++++++++++ net/netfilter/Kconfig | 1 net/netfilter/xt_REDIRECT.c | 44 +------------- 6 files changed, 99 insertions(+), 42 deletions(-) create mode 100644 include/net/netfilter/ipv4/nf_nat_redirect.h create mode 100644 net/ipv4/netfilter/nf_nat_redirect_ipv4.c
include/net/netfilter/ipv4/nf_nat_redirect.h new file +9 -0
@@ -0,0 +1,9 @@ +#ifndef _NF_NAT_REDIRECT_IPV4_H_ +#define _NF_NAT_REDIRECT_IPV4_H_ + +unsigned int +nf_nat_redirect_ipv4 (struct sk_buff *skb, +const struct nf_nat_ipv4_multi_range_compat *mr, +unsigned int hooknum); + +#endif /* _NF_NAT_REDIRECT_IPV4_H_ */
net/ipv4/netfilter/Kconfig +6 -0
@@ -104,6 +104,12 @@ config NF_NAT_MASQUERADE_IPV4 This is the kernel functionality to provide NAT in the masquerade flavour (automatic source address selection). +config NF_NAT_REDIRECT_IPV4 + tristate "IPv4 redirect support" + help + This is the kernel functionality to provide NAT in the redirect + flavour (redirect packets to local machine). + config NFT_MASQ_IPV4 tristate "IPv4 masquerading support for nf_tables" depends on NF_TABLES_IPV4
net/ipv4/netfilter/Makefile +1 -0
@@ -31,6 +31,7 @@ obj-$(CONFIG_NF_NAT_H323) += nf_nat_h323.o obj-$(CONFIG_NF_NAT_PPTP) += nf_nat_pptp.o obj-$(CONFIG_NF_NAT_SNMP_BASIC) += nf_nat_snmp_basic.o obj-$(CONFIG_NF_NAT_MASQUERADE_IPV4) += nf_nat_masquerade_ipv4.o +obj-$(CONFIG_NF_NAT_REDIRECT_IPV4) += nf_nat_redirect_ipv4.o # NAT protocols (nf_nat) obj-$(CONFIG_NF_NAT_PROTO_GRE) += nf_nat_proto_gre.o
net/ipv4/netfilter/nf_nat_redirect_ipv4.c new file +80 -0
80 lines not on this page · raw message
net/netfilter/Kconfig +1 -0
@@ -835,6 +835,7 @@ config NETFILTER_XT_TARGET_RATEEST config NETFILTER_XT_TARGET_REDIRECT tristate "REDIRECT target support" depends on NF_NAT + depends on NF_NAT_REDIRECT_IPV4 ---help--- REDIRECT is a special case of NAT: all incoming connections are mapped onto the incoming interface's address, causing the packets to
net/netfilter/xt_REDIRECT.c +2 -42
56 lines not on this page · raw message
PATCH 2/3 netfilter: refactor NAT's redirect IPv6 code
The xt_REDIRECT can be seen as a NAT flavour (like masquerade).
This patch refactors the IPv6 code so it can be usable both from xt and nf_tables.
--- include/net/netfilter/ipv6/nf_nat_redirect.h | 9 +++ net/ipv6/netfilter/Kconfig | 6 ++ net/ipv6/netfilter/Makefile | 1 net/ipv6/netfilter/nf_nat_redirect_ipv6.c | 75 ++++++++++++++++++++++++++ net/netfilter/Kconfig | 1 net/netfilter/xt_REDIRECT.c | 40 +------------- 6 files changed, 94 insertions(+), 38 deletions(-) create mode 100644 include/net/netfilter/ipv6/nf_nat_redirect.h create mode 100644 net/ipv6/netfilter/nf_nat_redirect_ipv6.c
include/net/netfilter/ipv6/nf_nat_redirect.h new file +9 -0
@@ -0,0 +1,9 @@ +#ifndef _NF_NAT_REDIRECT_IPV6_H_ +#define _NF_NAT_REDIRECT_IPV6_H_ + +unsigned int +nf_nat_redirect_ipv6 (struct sk_buff *skb,const struct nf_nat_range *range, +unsigned int hooknum); + +#endif /* _NF_NAT_REDIRECT_IPV6_H_ */ +
net/ipv6/netfilter/Kconfig +6 -0
@@ -82,6 +82,12 @@ config NF_NAT_MASQUERADE_IPV6 This is the kernel functionality to provide NAT in the masquerade flavour (automatic source address selection) for IPv6. +config NF_NAT_REDIRECT_IPV6 + tristate "IPv6 redirect support" + help + This is the kernel functionality to provide NAT in the redirect + flavour (redirect packet to local machine) for IPv6. + config NFT_MASQ_IPV6 tristate "IPv6 masquerade support for nf_tables" depends on NF_TABLES_IPV6
net/ipv6/netfilter/Makefile +1 -0
@@ -19,6 +19,7 @@ obj-$(CONFIG_NF_CONNTRACK_IPV6) += nf_conntrack_ipv6.o nf_nat_ipv6-y := nf_nat_l3proto_ipv6.o nf_nat_proto_icmpv6.o obj-$(CONFIG_NF_NAT_IPV6) += nf_nat_ipv6.o obj-$(CONFIG_NF_NAT_MASQUERADE_IPV6) += nf_nat_masquerade_ipv6.o +obj-$(CONFIG_NF_NAT_REDIRECT_IPV6) += nf_nat_redirect_ipv6.o # defrag nf_defrag_ipv6-y := nf_defrag_ipv6_hooks.o nf_conntrack_reasm.o
net/ipv6/netfilter/nf_nat_redirect_ipv6.c new file +75 -0
75 lines not on this page · raw message
net/netfilter/Kconfig +1 -0
@@ -836,6 +836,7 @@ config NETFILTER_XT_TARGET_REDIRECT tristate "REDIRECT target support" depends on NF_NAT depends on NF_NAT_REDIRECT_IPV4 + depends on NF_NAT_REDIRECT_IPV6 ---help--- REDIRECT is a special case of NAT: all incoming connections are mapped onto the incoming interface's address, causing the packets to
net/netfilter/xt_REDIRECT.c +2 -38
@@ -27,48 +27,12 @@#include <net/protocol.h> #include <net/netfilter/nf_nat.h> #include <net/netfilter/ipv4/nf_nat_redirect.h> - -static const struct in6_addr loopback_addr =IN6ADDR_LOOPBACK_INIT ; +#include <net/netfilter/ipv6/nf_nat_redirect.h> static unsigned int redirect_tg6 (struct sk_buff *skb,const struct xt_action_param *par) { -const struct nf_nat_range *range = par->targinfo; -struct nf_nat_range newrange; -struct in6_addr newdst; -enum ip_conntrack_info ctinfo; -struct nf_conn *ct; - - ct =nf_ct_get (skb, &ctinfo); -if (par->hooknum ==NF_INET_LOCAL_OUT ) - newdst = loopback_addr; -else { -struct inet6_dev *idev; -struct inet6_ifaddr *ifa; -bool addr = false; - -rcu_read_lock (); - idev =__in6_dev_get (skb->dev); -if (idev !=NULL ) { -list_for_each_entry (ifa, &idev->addr_list, if_list) { - newdst = ifa->addr; - addr = true; -break ; - } - } -rcu_read_unlock (); - -if (!addr) -return NF_DROP ; - } - - newrange.flags = range->flags |NF_NAT_RANGE_MAP_IPS ; - newrange.min_addr.in6 = newdst; - newrange.max_addr.in6 = newdst; - newrange.min_proto = range->min_proto; - newrange.max_proto = range->max_proto; - -return nf_nat_setup_info (ct, &newrange,NF_NAT_MANIP_DST ); +return nf_nat_redirect_ipv6 (skb, par->targinfo, par->hooknum); }static int redirect_tg6_checkentry (const struct xt_tgchk_param *par)
PATCH 3/3 netfilter: nf_tables: add new expression nft_redir
In reply to Arturo Borrero GonzalezThis new expression provides NAT in the redirect flavour, which is to redirect packets to local machine.
--- include/net/netfilter/nft_redir.h | 18 ++++++ include/uapi/linux/netfilter/nf_tables.h | 16 +++++ net/ipv4/netfilter/Kconfig | 9 +++ net/ipv4/netfilter/Makefile | 1 net/ipv4/netfilter/nft_redir_ipv4.c | 76 +++++++++++++++++++++++++ net/ipv6/netfilter/Kconfig | 9 +++ net/ipv6/netfilter/Makefile | 1 net/netfilter/Kconfig | 9 +++ net/netfilter/Makefile | 1 net/netfilter/nft_redir.c | 93 ++++++++++++++++++++++++++++++ 10 files changed, 233 insertions(+) create mode 100644 include/net/netfilter/nft_redir.h create mode 100644 net/ipv4/netfilter/nft_redir_ipv4.c create mode 100644 net/netfilter/nft_redir.c
include/net/netfilter/nft_redir.h new file +18 -0
@@ -0,0 +1,18 @@ +#ifndef _NFT_REDIR_H_ +#define _NFT_REDIR_H_ + +struct nft_redir { +enum nft_registers sreg_proto_min:8 ; +enum nft_registers sreg_proto_max:8 ; +u32 flags; +}; + +extern const struct nla_policy nft_redir_policy[]; + +int nft_redir_init (const struct nft_ctx *ctx, +const struct nft_expr *expr, +const struct nlattr *const tb[]); + +int nft_redir_dump (struct sk_buff *skb,const struct nft_expr *expr); + +#endif /* _NFT_REDIR_H_ */
include/uapi/linux/netfilter/nf_tables.h +16 -0
@@ -849,4 +849,20 @@ enum nft_gen_attributes { };#define NFTA_GEN_MAX (__NFTA_GEN_MAX - 1) +/** +* enum nft_redir_attributes - nf_tables redirect expression netlink attributes +* +* @NFTA_REDIR_REG_PROTO_MIN: source register of proto range start (NLA_U32: nft_registers) +* @NFTA_REDIR_REG_PROTO_MAX: source register of proto range end (NLA_U32: nft_registers) +* @NFTA_REDIR_FLAGS: NAT flags (see NF_NAT_RANGE_* in linux/netfilter/nf_nat.h) (NLA_U32) +*/ +enum nft_redir_attributes { +NFTA_REDIR_UNSPEC , +NFTA_REDIR_REG_PROTO_MIN , +NFTA_REDIR_REG_PROTO_MAX , +NFTA_REDIR_FLAGS , + __NFTA_REDIR_MAX +}; +#define NFTA_REDIR_MAX (__NFTA_REDIR_MAX - 1) +#endif /* _LINUX_NF_TABLES_H */
net/ipv4/netfilter/Kconfig +9 -0
@@ -119,6 +119,15 @@ config NFT_MASQ_IPV4 This is the expression that provides IPv4 masquerading support for nf_tables. +config NFT_REDIR_IPV4 + tristate "IPv4 redirect support for nf_tables" + depends on NF_TABLES_IPV4 + depends on NFT_REDIR + select NF_NAT_REDIRECT_IPV4 + help + This is the expression that provides IPv4 redirect support for + nf_tables. + config NF_NAT_SNMP_BASIC tristate "Basic SNMP-ALG support" depends on NF_CONNTRACK_SNMP
net/ipv4/netfilter/Makefile +1 -0
@@ -41,6 +41,7 @@ obj-$(CONFIG_NFT_CHAIN_ROUTE_IPV4) += nft_chain_route_ipv4.o obj-$(CONFIG_NFT_CHAIN_NAT_IPV4) += nft_chain_nat_ipv4.o obj-$(CONFIG_NFT_REJECT_IPV4) += nft_reject_ipv4.o obj-$(CONFIG_NFT_MASQ_IPV4) += nft_masq_ipv4.o +obj-$(CONFIG_NFT_REDIR_IPV4) += nft_redir_ipv4.o obj-$(CONFIG_NF_TABLES_ARP) += nf_tables_arp.o # generic IP tables
net/ipv4/netfilter/nft_redir_ipv4.c new file +76 -0
76 lines not on this page · raw message
net/ipv6/netfilter/Kconfig +9 -0
@@ -97,6 +97,15 @@ config NFT_MASQ_IPV6 This is the expression that provides IPv4 masquerading support for nf_tables. +config NFT_REDIR_IPV6 + tristate "IPv6 redirect support for nf_tables" + depends on NF_TABLES_IPV6 + depends on NFT_REDIR + select NF_NAT_REDIRECT_IPV6 + help + This is the expression that provides IPv4 redirect support for + nf_tables. + endif # NF_NAT_IPV6 config IP6_NF_IPTABLES
net/ipv6/netfilter/Makefile +1 -0
@@ -37,6 +37,7 @@ obj-$(CONFIG_NFT_CHAIN_ROUTE_IPV6) += nft_chain_route_ipv6.o obj-$(CONFIG_NFT_CHAIN_NAT_IPV6) += nft_chain_nat_ipv6.o obj-$(CONFIG_NFT_REJECT_IPV6) += nft_reject_ipv6.o obj-$(CONFIG_NFT_MASQ_IPV6) += nft_masq_ipv6.o +obj-$(CONFIG_NFT_REDIR_IPV6) += nft_redir_ipv6.o # matches obj-$(CONFIG_IP6_NF_MATCH_AH) += ip6t_ah.o
net/netfilter/Kconfig +9 -0
@@ -505,6 +505,15 @@ config NFT_MASQ This option adds the "masquerade" expression that you can use to perform NAT in the masquerade flavour. +config NFT_REDIR + depends on NF_TABLES + depends on NF_CONNTRACK + depends on NF_NAT + tristate "Netfilter nf_tables redirect support" + help + This options adds the "redirect" expression that you can use + to perform NAT in the redirect flavour. + config NFT_NAT depends on NF_TABLES depends on NF_CONNTRACK
net/netfilter/Makefile +1 -0
@@ -88,6 +88,7 @@ obj-$(CONFIG_NFT_HASH) += nft_hash.o obj-$(CONFIG_NFT_COUNTER) += nft_counter.o obj-$(CONFIG_NFT_LOG) += nft_log.o obj-$(CONFIG_NFT_MASQ) += nft_masq.o +obj-$(CONFIG_NFT_REDIR) += nft_redir.o # generic X tables obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o
net/netfilter/nft_redir.c new file +93 -0
93 lines not on this page · raw message
Pablo Neira Ayuso
maintainerRe: [nf_tables PATCH 3/3] netfilter: nf_tables: add new expression nft_redir
Quoted 26 lines · Arturo Borrero Gonzalez
This new expression provides NAT in the redirect flavour, which is to redirect packets to local machine.
Signed-off-by Arturo Borrero Gonzalez <[email protected]>--- include/net/netfilter/nft_redir.h | 18 ++++++ include/uapi/linux/netfilter/nf_tables.h | 16 +++++ net/ipv4/netfilter/Kconfig | 9 +++ net/ipv4/netfilter/Makefile | 1 net/ipv4/netfilter/nft_redir_ipv4.c | 76 +++++++++++++++++++++++++ net/ipv6/netfilter/Kconfig | 9 +++ net/ipv6/netfilter/Makefile | 1 net/netfilter/Kconfig | 9 +++ net/netfilter/Makefile | 1 net/netfilter/nft_redir.c | 93 ++++++++++++++++++++++++++++++ 10 files changed, 233 insertions(+) create mode 100644 include/net/netfilter/nft_redir.h create mode 100644 net/ipv4/netfilter/nft_redir_ipv4.c create mode 100644 net/netfilter/nft_redir.cinclude/net/netfilter/nft_redir.h new file +0
-0
include/net/netfilter/nft_redir.h line 7
Quoted 7 lines
include/net/netfilter/nft_redir.h new file +7
-0@@ -0,0 +1,18 @@ +#ifndef _NFT_REDIR_H_ +#define _NFT_REDIR_H_ + +struct nft_redir { + enum nft_registers sreg_proto_min:8; + enum nft_registers sreg_proto_max:8; + u32 flags;
I think you can use u16 to store the flags. So this consumes only 4 bytes in 32-bits arch.
Quoted 25 lines
include/net/netfilter/nft_redir.h new file +11
-0+}; + +extern const struct nla_policy nft_redir_policy[]; + +int nft_redir_init (const struct nft_ctx *ctx, +const struct nft_expr *expr, +const struct nlattr *const tb[]); + +int nft_redir_dump (struct sk_buff *skb,const struct nft_expr *expr); + +#endif /* _NFT_REDIR_H_ */ include/uapi/linux/netfilter/nf_tables.h +6
-0@@ -849,4 +849,20 @@ enum nft_gen_attributes { };#define NFTA_GEN_MAX (__NFTA_GEN_MAX - 1) +/** +* enum nft_redir_attributes - nf_tables redirect expression netlink attributes +* +* @NFTA_REDIR_REG_PROTO_MIN: source register of proto range start (NLA_U32: nft_registers) +* @NFTA_REDIR_REG_PROTO_MAX: source register of proto range end (NLA_U32: nft_registers) +* @NFTA_REDIR_FLAGS: NAT flags (see NF_NAT_RANGE_* in linux/netfilter/nf_nat.h) (NLA_U32)
include/uapi/linux/netfilter/nf_tables.h enum nft_gen_attributes { · line 867
Quoted 10 lines
include/uapi/linux/netfilter/nf_tables.h +10
-0+*/ +enum nft_redir_attributes { +NFTA_REDIR_UNSPEC , +NFTA_REDIR_REG_PROTO_MIN , +NFTA_REDIR_REG_PROTO_MAX , +NFTA_REDIR_FLAGS , + __NFTA_REDIR_MAX +}; +#define NFTA_REDIR_MAX (__NFTA_REDIR_MAX - 1) +
Please, place this new chunk after the masq atributes.
Quoted 33 lines
include/uapi/linux/netfilter/nf_tables.h +0
-0#endif /* _LINUX_NF_TABLES_H */ net/ipv4/netfilter/Kconfig +9
-0@@ -119,6 +119,15 @@ config NFT_MASQ_IPV4 This is the expression that provides IPv4 masquerading support for nf_tables. +config NFT_REDIR_IPV4 + tristate "IPv4 redirect support for nf_tables" + depends on NF_TABLES_IPV4 + depends on NFT_REDIR + select NF_NAT_REDIRECT_IPV4 + help + This is the expression that provides IPv4 redirect support for + nf_tables. + config NF_NAT_SNMP_BASIC tristate "Basic SNMP-ALG support" depends on NF_CONNTRACK_SNMPnet/ipv4/netfilter/Makefile +1
-0@@ -41,6 +41,7 @@ obj-$(CONFIG_NFT_CHAIN_ROUTE_IPV4) += nft_chain_route_ipv4.o obj-$(CONFIG_NFT_CHAIN_NAT_IPV4) += nft_chain_nat_ipv4.o obj-$(CONFIG_NFT_REJECT_IPV4) += nft_reject_ipv4.o obj-$(CONFIG_NFT_MASQ_IPV4) += nft_masq_ipv4.o +obj-$(CONFIG_NFT_REDIR_IPV4) += nft_redir_ipv4.o obj-$(CONFIG_NF_TABLES_ARP) += nf_tables_arp.o # generic IP tables
[...]
Quoted 31 lines
net/netfilter/nft_redir.c new file +25
-0@@ -0,0 +1,93 @@ +/* +* Copyright (c) 2014 Arturo Borrero Gonzalez <[email protected]> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/module.h> +#include <linux/netlink.h> +#include <linux/netfilter.h> +#include <linux/netfilter/nf_tables.h> +#include <net/netfilter/nf_nat.h> +#include <net/netfilter/nf_tables.h> +#include <net/netfilter/nft_redir.h> + +const struct nla_policy nft_redir_policy[NFTA_REDIR_MAX +1 ] = { + [NFTA_REDIR_REG_PROTO_MIN ] = { .type =NLA_U32 }, + [NFTA_REDIR_REG_PROTO_MAX ] = { .type =NLA_U32 }, + [NFTA_REDIR_FLAGS ] = { .type =NLA_U32 }, +}; +EXPORT_SYMBOL_GPL (nft_redir_policy); +
net/netfilter/nft_redir.c line 35
Quoted 10 lines
net/netfilter/nft_redir.c new file +10
-0+int nft_redir_init (const struct nft_ctx *ctx, +const struct nft_expr *expr, +const struct nlattr *const tb[]) +{ +struct nft_redir *priv =nft_expr_priv (expr); +int err; + +if (tb[NFTA_REDIR_REG_PROTO_MIN ]) { + priv->sreg_proto_min =ntohl (nla_get_be32 ( + tb[NFTA_REDIR_REG_PROTO_MIN ]));
I prefer this:
priv->sreg_proto_min =
ntohl(nla_get_be32(tb[NFTA_REDIR_REG_PROTO_MIN]));net/netfilter/nft_redir.c line 39
Quoted 4 lines
net/netfilter/nft_redir.c new file +4
-0+ err =nft_validate_input_register (priv->sreg_proto_min); +if (err <0 ) +return err; + }
No else here? ->sreg_proto_min is left uninitialized.
net/netfilter/nft_redir.c line 43
Quoted 4 lines
net/netfilter/nft_redir.c new file +4
-0+ +if (tb[NFTA_REDIR_REG_PROTO_MAX ]) { + priv->sreg_proto_max =ntohl (nla_get_be32 ( + tb[NFTA_REDIR_REG_PROTO_MAX ]));
Same thing here.
net/netfilter/nft_redir.c line 48
Quoted 5 lines
net/netfilter/nft_redir.c new file +5
-0+ err =nft_validate_input_register (priv->sreg_proto_max); +if (err <0 ) +return err; + }else + priv->sreg_proto_max = priv->sreg_proto_min;
Missing brackets wrapping around this 'else'.
net/netfilter/nft_redir.c line 56
Quoted 8 lines
net/netfilter/nft_redir.c new file +8
-0+ +if (tb[NFTA_REDIR_FLAGS ]) { + priv->flags =ntohl (nla_get_be32 (tb[NFTA_REDIR_FLAGS ])); +if (priv->flags & ~NF_NAT_RANGE_MASK ) +return -EINVAL ; + } + +
extra line, remove it.
Quoted 17 lines
net/netfilter/nft_redir.c new file +17
-0+return 0 ; +} +EXPORT_SYMBOL_GPL (nft_redir_init); + +int nft_redir_dump (struct sk_buff *skb,const struct nft_expr *expr) +{ +const struct nft_redir *priv =nft_expr_priv (expr); + +if (priv->sreg_proto_min) { +if (nla_put_be32 (skb,NFTA_REDIR_REG_PROTO_MIN , +htonl (priv->sreg_proto_min))) + goto nla_put_failure; +if (nla_put_be32 (skb,NFTA_REDIR_REG_PROTO_MAX , +htonl (priv->sreg_proto_max))) + goto nla_put_failure; + } +
net/netfilter/nft_redir.c line 83
Quoted 10 lines
net/netfilter/nft_redir.c new file +10
-0+if (priv->flags !=0 ) { +if (nla_put_be32 (skb,NFTA_REDIR_FLAGS ,htonl (priv->flags))) + goto nla_put_failure; + } + +if (priv->flags ==0 ) +return 0 ; + +if (nla_put_be32 (skb,NFTA_REDIR_FLAGS ,htonl (priv->flags))) + goto nla_put_failure;
These 10 lines above are freak. I guess you can refactor this to:
if (priv->flags != 0 &&
nla_put_...
goto nla_put_failure;Re: [nf_tables PATCH 3/3] netfilter: nf_tables: add new expression nft_redir
Quoted 13 lines · Pablo Neira Ayuso
Quoted 12 lines · Arturo Borrero Gonzalez
This new expression provides NAT in the redirect flavour, which is to redirect packets to local machine.
Signed-off-by Arturo Borrero Gonzalez <[email protected]>--- include/net/netfilter/nft_redir.h | 18 ++++++ include/uapi/linux/netfilter/nf_tables.h | 16 +++++ net/ipv4/netfilter/Kconfig | 9 +++ net/ipv4/netfilter/Makefile | 1 net/ipv4/netfilter/nft_redir_ipv4.c | 76 +++++++++++++++++++++++++ net/ipv6/netfilter/Kconfig | 9 +++ net/ipv6/netfilter/Makefile | 1
Quoted 8 lines
Quoted 8 lines
net/netfilter/Kconfig | 9 +++ net/netfilter/Makefile | 1 net/netfilter/nft_redir.c | 93 ++++++++++++++++++++++++++++++ 10 files changed, 233 insertions(+) create mode 100644 include/net/netfilter/nft_redir.h create mode 100644 net/ipv4/netfilter/nft_redir_ipv4.c create mode 100644 net/netfilter/nft_redir.c
Hi Pablo,
thanks for your comments. I will address all of them.
BTW, the last chunk you mentioned is clearly poor code, bad reviewed by myself.
regards.
Signature · 5 lines
Arturo Borrero González -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [nf_tables PATCH 3/3] netfilter: nf_tables: add new expression nft_redir
In reply to Pablo Neira AyusoQuoted 158 lines · Pablo Neira Ayuso
Quoted 26 lines · Arturo Borrero Gonzalez
This new expression provides NAT in the redirect flavour, which is to redirect packets to local machine.
Signed-off-by Arturo Borrero Gonzalez <[email protected]>--- include/net/netfilter/nft_redir.h | 18 ++++++ include/uapi/linux/netfilter/nf_tables.h | 16 +++++ net/ipv4/netfilter/Kconfig | 9 +++ net/ipv4/netfilter/Makefile | 1 net/ipv4/netfilter/nft_redir_ipv4.c | 76 +++++++++++++++++++++++++ net/ipv6/netfilter/Kconfig | 9 +++ net/ipv6/netfilter/Makefile | 1 net/netfilter/Kconfig | 9 +++ net/netfilter/Makefile | 1 net/netfilter/nft_redir.c | 93 ++++++++++++++++++++++++++++++ 10 files changed, 233 insertions(+) create mode 100644 include/net/netfilter/nft_redir.h create mode 100644 net/ipv4/netfilter/nft_redir_ipv4.c create mode 100644 net/netfilter/nft_redir.cinclude/net/netfilter/nft_redir.h new file +0
-0include/net/netfilter/nft_redir.h line 7
Quoted 7 lines
include/net/netfilter/nft_redir.h new file +7
-0@@ -0,0 +1,18 @@ +#ifndef _NFT_REDIR_H_ +#define _NFT_REDIR_H_ + +struct nft_redir { + enum nft_registers sreg_proto_min:8; + enum nft_registers sreg_proto_max:8; + u32 flags;I think you can use u16 to store the flags. So this consumes only 4 bytes in 32-bits arch.
Quoted 25 lines
include/net/netfilter/nft_redir.h new file +11
-0+}; + +extern const struct nla_policy nft_redir_policy[]; + +int nft_redir_init (const struct nft_ctx *ctx, +const struct nft_expr *expr, +const struct nlattr *const tb[]); + +int nft_redir_dump (struct sk_buff *skb,const struct nft_expr *expr); + +#endif /* _NFT_REDIR_H_ */ include/uapi/linux/netfilter/nf_tables.h +6
-0@@ -849,4 +849,20 @@ enum nft_gen_attributes { };#define NFTA_GEN_MAX (__NFTA_GEN_MAX - 1) +/** +* enum nft_redir_attributes - nf_tables redirect expression netlink attributes +* +* @NFTA_REDIR_REG_PROTO_MIN: source register of proto range start (NLA_U32: nft_registers) +* @NFTA_REDIR_REG_PROTO_MAX: source register of proto range end (NLA_U32: nft_registers) +* @NFTA_REDIR_FLAGS: NAT flags (see NF_NAT_RANGE_* in linux/netfilter/nf_nat.h) (NLA_U32) include/uapi/linux/netfilter/nf_tables.h enum nft_gen_attributes { · line 867
Quoted 10 lines
include/uapi/linux/netfilter/nf_tables.h +10
-0+*/ +enum nft_redir_attributes { +NFTA_REDIR_UNSPEC , +NFTA_REDIR_REG_PROTO_MIN , +NFTA_REDIR_REG_PROTO_MAX , +NFTA_REDIR_FLAGS , + __NFTA_REDIR_MAX +}; +#define NFTA_REDIR_MAX (__NFTA_REDIR_MAX - 1) +Please, place this new chunk after the masq atributes.
Quoted 33 lines
include/uapi/linux/netfilter/nf_tables.h +0
-0#endif /* _LINUX_NF_TABLES_H */ net/ipv4/netfilter/Kconfig +9
-0@@ -119,6 +119,15 @@ config NFT_MASQ_IPV4 This is the expression that provides IPv4 masquerading support for nf_tables. +config NFT_REDIR_IPV4 + tristate "IPv4 redirect support for nf_tables" + depends on NF_TABLES_IPV4 + depends on NFT_REDIR + select NF_NAT_REDIRECT_IPV4 + help + This is the expression that provides IPv4 redirect support for + nf_tables. + config NF_NAT_SNMP_BASIC tristate "Basic SNMP-ALG support" depends on NF_CONNTRACK_SNMPnet/ipv4/netfilter/Makefile +1
-0@@ -41,6 +41,7 @@ obj-$(CONFIG_NFT_CHAIN_ROUTE_IPV4) += nft_chain_route_ipv4.o obj-$(CONFIG_NFT_CHAIN_NAT_IPV4) += nft_chain_nat_ipv4.o obj-$(CONFIG_NFT_REJECT_IPV4) += nft_reject_ipv4.o obj-$(CONFIG_NFT_MASQ_IPV4) += nft_masq_ipv4.o +obj-$(CONFIG_NFT_REDIR_IPV4) += nft_redir_ipv4.o obj-$(CONFIG_NF_TABLES_ARP) += nf_tables_arp.o # generic IP tables[...]
Quoted 31 lines
net/netfilter/nft_redir.c new file +25
-0@@ -0,0 +1,93 @@ +/* +* Copyright (c) 2014 Arturo Borrero Gonzalez <[email protected]> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/module.h> +#include <linux/netlink.h> +#include <linux/netfilter.h> +#include <linux/netfilter/nf_tables.h> +#include <net/netfilter/nf_nat.h> +#include <net/netfilter/nf_tables.h> +#include <net/netfilter/nft_redir.h> + +const struct nla_policy nft_redir_policy[NFTA_REDIR_MAX +1 ] = { + [NFTA_REDIR_REG_PROTO_MIN ] = { .type =NLA_U32 }, + [NFTA_REDIR_REG_PROTO_MAX ] = { .type =NLA_U32 }, + [NFTA_REDIR_FLAGS ] = { .type =NLA_U32 }, +}; +EXPORT_SYMBOL_GPL (nft_redir_policy); +net/netfilter/nft_redir.c line 35
Quoted 10 lines
net/netfilter/nft_redir.c new file +10
-0+int nft_redir_init (const struct nft_ctx *ctx, +const struct nft_expr *expr, +const struct nlattr *const tb[]) +{ +struct nft_redir *priv =nft_expr_priv (expr); +int err; + +if (tb[NFTA_REDIR_REG_PROTO_MIN ]) { + priv->sreg_proto_min =ntohl (nla_get_be32 ( + tb[NFTA_REDIR_REG_PROTO_MIN ]));I prefer this:
priv->sreg_proto_min = ntohl(nla_get_be32(tb[NFTA_REDIR_REG_PROTO_MIN]));
Quoted 7 lines
net/netfilter/nft_redir.c line 39
Quoted 4 lines
net/netfilter/nft_redir.c new file +4
-0+ err =nft_validate_input_register (priv->sreg_proto_min); +if (err <0 ) +return err; + }No else here? ->sreg_proto_min is left uninitialized.
Such behaviour is copied from nft_nat.
I'm not sure to which value I should initialize sreg_proto_min.
regards.
Signature · 5 lines
Arturo Borrero González -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Pablo Neira Ayuso
maintainerRe: [nf_tables PATCH 3/3] netfilter: nf_tables: add new expression nft_redir
Quoted 23 lines · Arturo Borrero Gonzalez
Quoted 22 lines · Pablo Neira Ayuso
net/netfilter/nft_redir.c line 35
Quoted 10 lines
net/netfilter/nft_redir.c new file +10
-0+int nft_redir_init (const struct nft_ctx *ctx, +const struct nft_expr *expr, +const struct nlattr *const tb[]) +{ +struct nft_redir *priv =nft_expr_priv (expr); +int err; + +if (tb[NFTA_REDIR_REG_PROTO_MIN ]) { + priv->sreg_proto_min =ntohl (nla_get_be32 ( + tb[NFTA_REDIR_REG_PROTO_MIN ]));I prefer this:
priv->sreg_proto_min = ntohl(nla_get_be32(tb[NFTA_REDIR_REG_PROTO_MIN]));Quoted 4 lines
net/netfilter/nft_redir.c new file +4
-0+ err =nft_validate_input_register (priv->sreg_proto_min); +if (err <0 ) +return err; + }
Quoted 5 lines
Quoted 2 lines
No else here? ->sreg_proto_min is left uninitialized.
Such behaviour is copied from
nft_nat.
I'm not sure to which value I should initializesreg_proto_min.
This seems fine for redirect as ->sreg_proto_min will be zero. Keep in mind that we have to support redirect with no port range specified. I mean, iptables supports -j REDIRECT without arguments.
Regarding nft_nat, not good. I'm going to send a patch to reject invalid configurations. At least one of the NFTA_NAT_REG_*_MIN needs to be specified.
Pablo Neira Ayuso
maintainerQuoted 107 lines · Arturo Borrero Gonzalez
The
xt_REDIRECTcan be seen as a NAT flavour (like masquerade).This patch refactors the IPv4 code so it can be usable both from xt and
nf_tables.A similar patch follows-up to handle IPv6.
Signed-off-by Arturo Borrero Gonzalez <[email protected]>--- include/net/netfilter/ipv4/nf_nat_redirect.h | 9 +++ net/ipv4/netfilter/Kconfig | 6 ++ net/ipv4/netfilter/Makefile | 1 net/ipv4/netfilter/nf_nat_redirect_ipv4.c | 80 ++++++++++++++++++++++++++ net/netfilter/Kconfig | 1 net/netfilter/xt_REDIRECT.c | 44 +------------- 6 files changed, 99 insertions(+), 42 deletions(-) create mode 100644 include/net/netfilter/ipv4/nf_nat_redirect.h create mode 100644 net/ipv4/netfilter/nf_nat_redirect_ipv4.cinclude/net/netfilter/ipv4/nf_nat_redirect.h new file +9
-0@@ -0,0 +1,9 @@ +#ifndef _NF_NAT_REDIRECT_IPV4_H_ +#define _NF_NAT_REDIRECT_IPV4_H_ + +unsigned int +nf_nat_redirect_ipv4 (struct sk_buff *skb, +const struct nf_nat_ipv4_multi_range_compat *mr, +unsigned int hooknum); + +#endif /* _NF_NAT_REDIRECT_IPV4_H_ */ net/ipv4/netfilter/Kconfig +6
-0@@ -104,6 +104,12 @@ config NF_NAT_MASQUERADE_IPV4 This is the kernel functionality to provide NAT in the masquerade flavour (automatic source address selection). +config NF_NAT_REDIRECT_IPV4 + tristate "IPv4 redirect support" + help + This is the kernel functionality to provide NAT in the redirect + flavour (redirect packets to local machine). + config NFT_MASQ_IPV4 tristate "IPv4 masquerading support for nf_tables" depends on NF_TABLES_IPV4net/ipv4/netfilter/Makefile +1
-0@@ -31,6 +31,7 @@ obj-$(CONFIG_NF_NAT_H323) += nf_nat_h323.o obj-$(CONFIG_NF_NAT_PPTP) += nf_nat_pptp.o obj-$(CONFIG_NF_NAT_SNMP_BASIC) += nf_nat_snmp_basic.o obj-$(CONFIG_NF_NAT_MASQUERADE_IPV4) += nf_nat_masquerade_ipv4.o +obj-$(CONFIG_NF_NAT_REDIRECT_IPV4) += nf_nat_redirect_ipv4.o # NAT protocols (nf_nat) obj-$(CONFIG_NF_NAT_PROTO_GRE) += nf_nat_proto_gre.onet/ipv4/netfilter/nf_nat_redirect_ipv4.c new file +38
-0@@ -0,0 +1,80 @@ +/* +* (C) 1999-2001 Paul `Rusty' Russell +* (C) 2002-2006 Netfilter Core Team <[email protected]> +* Copyright (c) 2011 Patrick McHardy <[email protected]> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +* +* Based on Rusty Russell's IPv4 REDIRECT target. Development of IPv6 +* NAT funded by Astaro. +*/ + +#include <linux/if.h> +#include <linux/inetdevice.h> +#include <linux/ip.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/netdevice.h> +#include <linux/netfilter.h> +#include <linux/types.h> +#include <linux/netfilter_ipv4.h> +#include <linux/netfilter/x_tables.h> +#include <net/addrconf.h> +#include <net/checksum.h> +#include <net/protocol.h> +#include <net/netfilter/nf_nat.h> +#include <net/netfilter/ipv4/nf_nat_redirect.h> + +unsigned int +nf_nat_redirect_ipv4 (struct sk_buff *skb, +const struct nf_nat_ipv4_multi_range_compat *mr, +unsigned int hooknum) +{ +struct nf_conn *ct; +enum ip_conntrack_info ctinfo; +__be32 newdst; +struct nf_nat_range newrange;
net/ipv4/netfilter/nf_nat_redirect_ipv4.c line 48
Quoted 10 lines
net/ipv4/netfilter/nf_nat_redirect_ipv4.c new file +10
-0+ +NF_CT_ASSERT (hooknum ==NF_INET_PRE_ROUTING || + hooknum ==NF_INET_LOCAL_OUT ); + + ct =nf_ct_get (skb, &ctinfo); +NF_CT_ASSERT (ct && (ctinfo ==IP_CT_NEW || ctinfo ==IP_CT_RELATED )); + +/* Local packets: make them go to loopback */ +if (hooknum ==NF_INET_LOCAL_OUT ) + newdst =htonl (0x7F000001 );
Please, fix coding style. This needs to be:
if (hooknum == NF_INET_LOCAL_OUT) {
newdst = htonl(0x7F000001);
} else {
...Basically, if any of the branches contains more than one line, we have to use the bracket in both.
I know this is not your fault since you're just copying and pasting this code. But I think this is a good chance to address this.
Quoted 37 lines
net/ipv4/netfilter/nf_nat_redirect_ipv4.c new file +32
-0+else { +struct in_device *indev; +struct in_ifaddr *ifa; + + newdst =0 ; + +rcu_read_lock (); + indev =__in_dev_get_rcu (skb->dev); +if (indev && (ifa = indev->ifa_list)) + newdst = ifa->ifa_local; +rcu_read_unlock (); + +if (!newdst) +return NF_DROP ; + } + +/* Transfer from original range. */ +memset (&newrange.min_addr,0 ,sizeof (newrange.min_addr)); +memset (&newrange.max_addr,0 ,sizeof (newrange.max_addr)); + newrange.flags = mr->range[0 ].flags |NF_NAT_RANGE_MAP_IPS ; + newrange.min_addr.ip = newdst; + newrange.max_addr.ip = newdst; + newrange.min_proto = mr->range[0 ].min; + newrange.max_proto = mr->range[0 ].max; + +/* Hand modified range to generic setup. */ +return nf_nat_setup_info (ct, &newrange,NF_NAT_MANIP_DST ); +} +EXPORT_SYMBOL_GPL (nf_nat_redirect_ipv4); + +MODULE_LICENSE ("GPL" ); +MODULE_AUTHOR ("Patrick McHardy <[email protected]>" );net/netfilter/Kconfig +0
-0
net/netfilter/Kconfig config NETFILTER_XT_TARGET_RATEEST · line 838
Quoted 4 lines
net/netfilter/Kconfig +1
-0@@ -835,6 +835,7 @@ config NETFILTER_XT_TARGET_RATEEST config NETFILTER_XT_TARGET_REDIRECT tristate "REDIRECT target support" depends on NF_NAT + depends on NF_NAT_REDIRECT_IPV4
This needs to be 'select NF_NAT_REDIRECT_IPV4' instead.
Quoted 24 lines
net/netfilter/Kconfig +0
-0---help--- REDIRECT is a special case of NAT: all incoming connections are mapped onto the incoming interface's address, causing the packets tonet/netfilter/xt_REDIRECT.c +1
-5@@ -26,6 +26,7 @@#include <net/checksum.h> #include <net/protocol.h> #include <net/netfilter/nf_nat.h> +#include <net/netfilter/ipv4/nf_nat_redirect.h> static const struct in6_addr loopback_addr =IN6ADDR_LOOPBACK_INIT ;@@ -98,48 +99,7 @@ static int redirect_tg4_check(const struct xt_tgchk_param *par)static unsigned int redirect_tg4 (struct sk_buff *skb,const struct xt_action_param *par) { -struct nf_conn *ct; -enum ip_conntrack_info ctinfo; -__be32 newdst; -const struct nf_nat_ipv4_multi_range_compat *mr = par->targinfo; -struct nf_nat_range newrange;
net/netfilter/xt_REDIRECT.c static int redirect_tg4_check(const struct xt_tgchk_param *par) · line 115
Quoted 10 lines
net/netfilter/xt_REDIRECT.c +0
-10- -NF_CT_ASSERT (par->hooknum ==NF_INET_PRE_ROUTING || - par->hooknum ==NF_INET_LOCAL_OUT ); - - ct =nf_ct_get (skb, &ctinfo); -NF_CT_ASSERT (ct && (ctinfo ==IP_CT_NEW || ctinfo ==IP_CT_RELATED )); - -/* Local packets: make them go to loopback */ -if (par->hooknum ==NF_INET_LOCAL_OUT ) - newdst =htonl (0x7F000001 );
Same coding style nitpick here.
Apart from those comment, this looks good to me. Thanks Arturo.