* [nf_tables PATCH 1/3] netfilter: refactor NAT's redirect IPv4 code
@ 2014-10-14 17:22 Arturo Borrero Gonzalez
2014-10-14 17:22 ` [nf_tables PATCH 2/3] netfilter: refactor NAT's redirect IPv6 code Arturo Borrero Gonzalez
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Arturo Borrero Gonzalez @ 2014-10-14 17:22 UTC (permalink / raw)
To: netfilter-devel; +Cc: kaber, pablo
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.
Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
---
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
diff --git a/include/net/netfilter/ipv4/nf_nat_redirect.h b/include/net/netfilter/ipv4/nf_nat_redirect.h
new file mode 100644
index 0000000..19e1df3
--- /dev/null
+++ b/include/net/netfilter/ipv4/nf_nat_redirect.h
@@ -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_ */
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
index 4c019d5..a300e2c 100644
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -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
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
index f4cef5a..34e436c 100644
--- a/net/ipv4/netfilter/Makefile
+++ b/net/ipv4/netfilter/Makefile
@@ -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
diff --git a/net/ipv4/netfilter/nf_nat_redirect_ipv4.c b/net/ipv4/netfilter/nf_nat_redirect_ipv4.c
new file mode 100644
index 0000000..317f59c
--- /dev/null
+++ b/net/ipv4/netfilter/nf_nat_redirect_ipv4.c
@@ -0,0 +1,80 @@
+/*
+ * (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org>
+ * Copyright (c) 2011 Patrick McHardy <kaber@trash.net>
+ *
+ * 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;
+
+ 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);
+ 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 <kaber@trash.net>");
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index ae5096a..bc0726d 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -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
diff --git a/net/netfilter/xt_REDIRECT.c b/net/netfilter/xt_REDIRECT.c
index 22a1030..b4ffac5 100644
--- a/net/netfilter/xt_REDIRECT.c
+++ b/net/netfilter/xt_REDIRECT.c
@@ -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;
-
- 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);
- 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);
+ return nf_nat_redirect_ipv4(skb, par->targinfo, par->hooknum);
}
static struct xt_target redirect_tg_reg[] __read_mostly = {
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [nf_tables PATCH 2/3] netfilter: refactor NAT's redirect IPv6 code
2014-10-14 17:22 [nf_tables PATCH 1/3] netfilter: refactor NAT's redirect IPv4 code Arturo Borrero Gonzalez
@ 2014-10-14 17:22 ` Arturo Borrero Gonzalez
2014-10-14 17:22 ` [nf_tables PATCH 3/3] netfilter: nf_tables: add new expression nft_redir Arturo Borrero Gonzalez
2014-10-15 9:50 ` [nf_tables PATCH 1/3] netfilter: refactor NAT's redirect IPv4 code Pablo Neira Ayuso
2 siblings, 0 replies; 8+ messages in thread
From: Arturo Borrero Gonzalez @ 2014-10-14 17:22 UTC (permalink / raw)
To: netfilter-devel; +Cc: kaber, pablo
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.
Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
---
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
diff --git a/include/net/netfilter/ipv6/nf_nat_redirect.h b/include/net/netfilter/ipv6/nf_nat_redirect.h
new file mode 100644
index 0000000..aab7617
--- /dev/null
+++ b/include/net/netfilter/ipv6/nf_nat_redirect.h
@@ -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_ */
+
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index 6af874f..462eebb 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -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
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile
index fbb25f0..6c2baab 100644
--- a/net/ipv6/netfilter/Makefile
+++ b/net/ipv6/netfilter/Makefile
@@ -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
diff --git a/net/ipv6/netfilter/nf_nat_redirect_ipv6.c b/net/ipv6/netfilter/nf_nat_redirect_ipv6.c
new file mode 100644
index 0000000..7c8be18
--- /dev/null
+++ b/net/ipv6/netfilter/nf_nat_redirect_ipv6.c
@@ -0,0 +1,75 @@
+/*
+ * (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org>
+ * Copyright (c) 2011 Patrick McHardy <kaber@trash.net>
+ *
+ * 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_ipv6.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/ipv6/nf_nat_redirect.h>
+
+static const struct in6_addr loopback_addr = IN6ADDR_LOOPBACK_INIT;
+
+unsigned int
+nf_nat_redirect_ipv6(struct sk_buff *skb, const struct nf_nat_range *range,
+ unsigned int hooknum)
+{
+ 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 (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);
+}
+EXPORT_SYMBOL_GPL(nf_nat_redirect_ipv6);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index bc0726d..1d0131c 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -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
diff --git a/net/netfilter/xt_REDIRECT.c b/net/netfilter/xt_REDIRECT.c
index b4ffac5..b6ec67e 100644
--- a/net/netfilter/xt_REDIRECT.c
+++ b/net/netfilter/xt_REDIRECT.c
@@ -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)
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [nf_tables PATCH 3/3] netfilter: nf_tables: add new expression nft_redir
2014-10-14 17:22 [nf_tables PATCH 1/3] netfilter: refactor NAT's redirect IPv4 code Arturo Borrero Gonzalez
2014-10-14 17:22 ` [nf_tables PATCH 2/3] netfilter: refactor NAT's redirect IPv6 code Arturo Borrero Gonzalez
@ 2014-10-14 17:22 ` Arturo Borrero Gonzalez
2014-10-15 10:06 ` Pablo Neira Ayuso
2014-10-15 9:50 ` [nf_tables PATCH 1/3] netfilter: refactor NAT's redirect IPv4 code Pablo Neira Ayuso
2 siblings, 1 reply; 8+ messages in thread
From: Arturo Borrero Gonzalez @ 2014-10-14 17:22 UTC (permalink / raw)
To: netfilter-devel; +Cc: kaber, pablo
This new expression provides NAT in the redirect flavour, which is to
redirect packets to local machine.
Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
---
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
diff --git a/include/net/netfilter/nft_redir.h b/include/net/netfilter/nft_redir.h
new file mode 100644
index 0000000..b6695da
--- /dev/null
+++ b/include/net/netfilter/nft_redir.h
@@ -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_ */
diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index c26df67..8a96a36 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -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 */
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
index a300e2c..8358b2d 100644
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -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
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
index 34e436c..902bcd1 100644
--- a/net/ipv4/netfilter/Makefile
+++ b/net/ipv4/netfilter/Makefile
@@ -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
diff --git a/net/ipv4/netfilter/nft_redir_ipv4.c b/net/ipv4/netfilter/nft_redir_ipv4.c
new file mode 100644
index 0000000..d48690e
--- /dev/null
+++ b/net/ipv4/netfilter/nft_redir_ipv4.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2014 Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
+ *
+ * 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_tables.h>
+#include <net/netfilter/nf_nat.h>
+#include <net/netfilter/ipv4/nf_nat_redirect.h>
+#include <net/netfilter/nft_redir.h>
+
+static void nft_redir_ipv4_eval(const struct nft_expr *expr,
+ struct nft_data data[NFT_REG_MAX + 1],
+ const struct nft_pktinfo *pkt)
+{
+ struct nft_redir *priv = nft_expr_priv(expr);
+ struct nf_nat_ipv4_multi_range_compat mr;
+ unsigned int verdict;
+
+ memset(&mr, 0, sizeof(mr));
+ if (priv->sreg_proto_min) {
+ mr.range[0].min.all = (__force __be16)
+ data[priv->sreg_proto_min].data[0];
+ mr.range[0].max.all = (__force __be16)
+ data[priv->sreg_proto_max].data[0];
+ mr.range[0].flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
+ }
+
+ mr.range[0].flags |= priv->flags;
+
+ verdict = nf_nat_redirect_ipv4(pkt->skb, &mr, pkt->ops->hooknum);
+ data[NFT_REG_VERDICT].verdict = verdict;
+}
+
+static struct nft_expr_type nft_redir_ipv4_type;
+static const struct nft_expr_ops nft_redir_ipv4_ops = {
+ .type = &nft_redir_ipv4_type,
+ .size = NFT_EXPR_SIZE(sizeof(struct nft_redir)),
+ .eval = nft_redir_ipv4_eval,
+ .init = nft_redir_init,
+ .dump = nft_redir_dump,
+};
+
+static struct nft_expr_type nft_redir_ipv4_type __read_mostly = {
+ .family = NFPROTO_IPV4,
+ .name = "redir",
+ .ops = &nft_redir_ipv4_ops,
+ .policy = nft_redir_policy,
+ .maxattr = NFTA_REDIR_MAX,
+ .owner = THIS_MODULE,
+};
+
+static int __init nft_redir_ipv4_module_init(void)
+{
+ return nft_register_expr(&nft_redir_ipv4_type);
+}
+
+static void __exit nft_redir_ipv4_module_exit(void)
+{
+ nft_unregister_expr(&nft_redir_ipv4_type);
+}
+
+module_init(nft_redir_ipv4_module_init);
+module_exit(nft_redir_ipv4_module_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>");
+MODULE_ALIAS_NFT_AF_EXPR(AF_INET, "redir");
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index 462eebb..0dbe5c7 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -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
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile
index 6c2baab..d2ac9f5 100644
--- a/net/ipv6/netfilter/Makefile
+++ b/net/ipv6/netfilter/Makefile
@@ -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
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 1d0131c..d155799 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -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
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index a9571be..f3eb468 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -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
diff --git a/net/netfilter/nft_redir.c b/net/netfilter/nft_redir.c
new file mode 100644
index 0000000..1d414a7
--- /dev/null
+++ b/net/netfilter/nft_redir.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2014 Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
+ *
+ * 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);
+
+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]));
+ err = nft_validate_input_register(priv->sreg_proto_min);
+ if (err < 0)
+ return err;
+ }
+
+ if (tb[NFTA_REDIR_REG_PROTO_MAX]) {
+ priv->sreg_proto_max = ntohl(nla_get_be32(
+ tb[NFTA_REDIR_REG_PROTO_MAX]));
+ err = nft_validate_input_register(priv->sreg_proto_max);
+ if (err < 0)
+ return err;
+ } else
+ priv->sreg_proto_max = priv->sreg_proto_min;
+
+ if (tb[NFTA_REDIR_FLAGS]) {
+ priv->flags = ntohl(nla_get_be32(tb[NFTA_REDIR_FLAGS]));
+ if (priv->flags & ~NF_NAT_RANGE_MASK)
+ return -EINVAL;
+ }
+
+
+ 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;
+ }
+
+ 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;
+
+ return 0;
+
+nla_put_failure:
+ return -1;
+}
+EXPORT_SYMBOL_GPL(nft_redir_dump);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>");
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [nf_tables PATCH 1/3] netfilter: refactor NAT's redirect IPv4 code
2014-10-14 17:22 [nf_tables PATCH 1/3] netfilter: refactor NAT's redirect IPv4 code Arturo Borrero Gonzalez
2014-10-14 17:22 ` [nf_tables PATCH 2/3] netfilter: refactor NAT's redirect IPv6 code Arturo Borrero Gonzalez
2014-10-14 17:22 ` [nf_tables PATCH 3/3] netfilter: nf_tables: add new expression nft_redir Arturo Borrero Gonzalez
@ 2014-10-15 9:50 ` Pablo Neira Ayuso
2 siblings, 0 replies; 8+ messages in thread
From: Pablo Neira Ayuso @ 2014-10-15 9:50 UTC (permalink / raw)
To: Arturo Borrero Gonzalez; +Cc: netfilter-devel, kaber
On Tue, Oct 14, 2014 at 07:22:31PM +0200, Arturo Borrero Gonzalez wrote:
> 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.
>
> Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
> ---
> 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
>
> diff --git a/include/net/netfilter/ipv4/nf_nat_redirect.h b/include/net/netfilter/ipv4/nf_nat_redirect.h
> new file mode 100644
> index 0000000..19e1df3
> --- /dev/null
> +++ b/include/net/netfilter/ipv4/nf_nat_redirect.h
> @@ -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_ */
> diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
> index 4c019d5..a300e2c 100644
> --- a/net/ipv4/netfilter/Kconfig
> +++ b/net/ipv4/netfilter/Kconfig
> @@ -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
> diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
> index f4cef5a..34e436c 100644
> --- a/net/ipv4/netfilter/Makefile
> +++ b/net/ipv4/netfilter/Makefile
> @@ -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
> diff --git a/net/ipv4/netfilter/nf_nat_redirect_ipv4.c b/net/ipv4/netfilter/nf_nat_redirect_ipv4.c
> new file mode 100644
> index 0000000..317f59c
> --- /dev/null
> +++ b/net/ipv4/netfilter/nf_nat_redirect_ipv4.c
> @@ -0,0 +1,80 @@
> +/*
> + * (C) 1999-2001 Paul `Rusty' Russell
> + * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org>
> + * Copyright (c) 2011 Patrick McHardy <kaber@trash.net>
> + *
> + * 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;
> +
> + 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.
> + 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 <kaber@trash.net>");
> diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
> index ae5096a..bc0726d 100644
> --- a/net/netfilter/Kconfig
> +++ b/net/netfilter/Kconfig
> @@ -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.
> ---help---
> REDIRECT is a special case of NAT: all incoming connections are
> mapped onto the incoming interface's address, causing the packets to
> diff --git a/net/netfilter/xt_REDIRECT.c b/net/netfilter/xt_REDIRECT.c
> index 22a1030..b4ffac5 100644
> --- a/net/netfilter/xt_REDIRECT.c
> +++ b/net/netfilter/xt_REDIRECT.c
> @@ -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;
> -
> - 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.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [nf_tables PATCH 3/3] netfilter: nf_tables: add new expression nft_redir
2014-10-14 17:22 ` [nf_tables PATCH 3/3] netfilter: nf_tables: add new expression nft_redir Arturo Borrero Gonzalez
@ 2014-10-15 10:06 ` Pablo Neira Ayuso
2014-10-15 10:11 ` Arturo Borrero Gonzalez
2014-10-15 11:14 ` Arturo Borrero Gonzalez
0 siblings, 2 replies; 8+ messages in thread
From: Pablo Neira Ayuso @ 2014-10-15 10:06 UTC (permalink / raw)
To: Arturo Borrero Gonzalez; +Cc: netfilter-devel, kaber
On Tue, Oct 14, 2014 at 07:22:42PM +0200, Arturo Borrero Gonzalez wrote:
> This new expression provides NAT in the redirect flavour, which is to
> redirect packets to local machine.
>
> Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
> ---
> 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
>
> diff --git a/include/net/netfilter/nft_redir.h b/include/net/netfilter/nft_redir.h
> new file mode 100644
> index 0000000..b6695da
> --- /dev/null
> +++ b/include/net/netfilter/nft_redir.h
> @@ -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.
> +};
> +
> +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_ */
> diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
> index c26df67..8a96a36 100644
> --- a/include/uapi/linux/netfilter/nf_tables.h
> +++ b/include/uapi/linux/netfilter/nf_tables.h
> @@ -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)
> +
Please, place this new chunk after the masq atributes.
> #endif /* _LINUX_NF_TABLES_H */
> diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
> index a300e2c..8358b2d 100644
> --- a/net/ipv4/netfilter/Kconfig
> +++ b/net/ipv4/netfilter/Kconfig
> @@ -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
> diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
> index 34e436c..902bcd1 100644
> --- a/net/ipv4/netfilter/Makefile
> +++ b/net/ipv4/netfilter/Makefile
> @@ -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
[...]
> diff --git a/net/netfilter/nft_redir.c b/net/netfilter/nft_redir.c
> new file mode 100644
> index 0000000..1d414a7
> --- /dev/null
> +++ b/net/netfilter/nft_redir.c
> @@ -0,0 +1,93 @@
> +/*
> + * Copyright (c) 2014 Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
> + *
> + * 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);
> +
> +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]));
> + err = nft_validate_input_register(priv->sreg_proto_min);
> + if (err < 0)
> + return err;
> + }
No else here? ->sreg_proto_min is left uninitialized.
> +
> + if (tb[NFTA_REDIR_REG_PROTO_MAX]) {
> + priv->sreg_proto_max = ntohl(nla_get_be32(
> + tb[NFTA_REDIR_REG_PROTO_MAX]));
Same thing here.
> + 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'.
> +
> + 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.
> + 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;
> + }
> +
> + 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;
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [nf_tables PATCH 3/3] netfilter: nf_tables: add new expression nft_redir
2014-10-15 10:06 ` Pablo Neira Ayuso
@ 2014-10-15 10:11 ` Arturo Borrero Gonzalez
2014-10-15 11:14 ` Arturo Borrero Gonzalez
1 sibling, 0 replies; 8+ messages in thread
From: Arturo Borrero Gonzalez @ 2014-10-15 10:11 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: Netfilter Development Mailing list, Patrick McHardy
On 15 October 2014 12:06, Pablo Neira Ayuso <pablo@netfilter.org> wrote:
> On Tue, Oct 14, 2014 at 07:22:42PM +0200, Arturo Borrero Gonzalez wrote:
>> This new expression provides NAT in the redirect flavour, which is to
>> redirect packets to local machine.
>>
>> Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
>> ---
>> 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
>>
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.
--
Arturo Borrero González
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [nf_tables PATCH 3/3] netfilter: nf_tables: add new expression nft_redir
2014-10-15 10:06 ` Pablo Neira Ayuso
2014-10-15 10:11 ` Arturo Borrero Gonzalez
@ 2014-10-15 11:14 ` Arturo Borrero Gonzalez
2014-10-16 8:41 ` Pablo Neira Ayuso
1 sibling, 1 reply; 8+ messages in thread
From: Arturo Borrero Gonzalez @ 2014-10-15 11:14 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: Netfilter Development Mailing list, Patrick McHardy
On 15 October 2014 12:06, Pablo Neira Ayuso <pablo@netfilter.org> wrote:
> On Tue, Oct 14, 2014 at 07:22:42PM +0200, Arturo Borrero Gonzalez wrote:
>> This new expression provides NAT in the redirect flavour, which is to
>> redirect packets to local machine.
>>
>> Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
>> ---
>> 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
>>
>> diff --git a/include/net/netfilter/nft_redir.h b/include/net/netfilter/nft_redir.h
>> new file mode 100644
>> index 0000000..b6695da
>> --- /dev/null
>> +++ b/include/net/netfilter/nft_redir.h
>> @@ -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.
>
>> +};
>> +
>> +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_ */
>> diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
>> index c26df67..8a96a36 100644
>> --- a/include/uapi/linux/netfilter/nf_tables.h
>> +++ b/include/uapi/linux/netfilter/nf_tables.h
>> @@ -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)
>> +
>
> Please, place this new chunk after the masq atributes.
>
>> #endif /* _LINUX_NF_TABLES_H */
>> diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
>> index a300e2c..8358b2d 100644
>> --- a/net/ipv4/netfilter/Kconfig
>> +++ b/net/ipv4/netfilter/Kconfig
>> @@ -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
>> diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
>> index 34e436c..902bcd1 100644
>> --- a/net/ipv4/netfilter/Makefile
>> +++ b/net/ipv4/netfilter/Makefile
>> @@ -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
> [...]
>> diff --git a/net/netfilter/nft_redir.c b/net/netfilter/nft_redir.c
>> new file mode 100644
>> index 0000000..1d414a7
>> --- /dev/null
>> +++ b/net/netfilter/nft_redir.c
>> @@ -0,0 +1,93 @@
>> +/*
>> + * Copyright (c) 2014 Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
>> + *
>> + * 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);
>> +
>> +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]));
>
>
>> + 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.
--
Arturo Borrero González
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [nf_tables PATCH 3/3] netfilter: nf_tables: add new expression nft_redir
2014-10-15 11:14 ` Arturo Borrero Gonzalez
@ 2014-10-16 8:41 ` Pablo Neira Ayuso
0 siblings, 0 replies; 8+ messages in thread
From: Pablo Neira Ayuso @ 2014-10-16 8:41 UTC (permalink / raw)
To: Arturo Borrero Gonzalez
Cc: Netfilter Development Mailing list, Patrick McHardy
On Wed, Oct 15, 2014 at 01:14:12PM +0200, Arturo Borrero Gonzalez wrote:
> On 15 October 2014 12:06, Pablo Neira Ayuso <pablo@netfilter.org> wrote:
> >> +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]));
> >
> >
> >> + 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.
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.
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2014-10-16 8:40 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-10-14 17:22 [nf_tables PATCH 1/3] netfilter: refactor NAT's redirect IPv4 code Arturo Borrero Gonzalez
2014-10-14 17:22 ` [nf_tables PATCH 2/3] netfilter: refactor NAT's redirect IPv6 code Arturo Borrero Gonzalez
2014-10-14 17:22 ` [nf_tables PATCH 3/3] netfilter: nf_tables: add new expression nft_redir Arturo Borrero Gonzalez
2014-10-15 10:06 ` Pablo Neira Ayuso
2014-10-15 10:11 ` Arturo Borrero Gonzalez
2014-10-15 11:14 ` Arturo Borrero Gonzalez
2014-10-16 8:41 ` Pablo Neira Ayuso
2014-10-15 9:50 ` [nf_tables PATCH 1/3] netfilter: refactor NAT's redirect IPv4 code Pablo Neira Ayuso
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).