From 31be5b549c946579e322b20d2c388fae0c221bb9 Mon Sep 17 00:00:00 2001
From: Raphael Vallazza <raphael@endian.com>
Date: Sun, 13 Jan 2008 09:29:53 +0100
Subject: [PATCH] [IPVS] Add choice for connection interception method

This patch adds an option to set the position at which IPVS intercepts
incoming connections from Netfilter.

The options are:

1. INPUT (default)
Intercept incoming connections after they have traveled through
the INPUT table, only connections that have the director as
destination address will be processed.

2. FORWARD
Intercept incoming connections after they have traveled through
the INPUT or the FORWARD table. It has the same functionlity of
the "INPUT method", but also processes connections that are
routed through the director, supporting VIP-less setups.

3. PREROUTING
Intercept incoming connections before DNAT and input filtering
has been applied, this enables transparent proxying on realnodes
and localnode.

Signed-off-by: Raphael Vallazza <raphael@endian.com>
---
 net/ipv4/ipvs/Kconfig      |   44 ++++++++++++++++++++++++++++++++++++++++++++
 net/ipv4/ipvs/ip_vs_core.c |   30 +++++++++++++++++++++++++++++-
 2 files changed, 73 insertions(+), 1 deletions(-)

diff --git a/net/ipv4/ipvs/Kconfig b/net/ipv4/ipvs/Kconfig
index 09d0c3f..319f3e8 100644
--- a/net/ipv4/ipvs/Kconfig
+++ b/net/ipv4/ipvs/Kconfig
@@ -24,6 +24,50 @@ menuconfig IP_VS
 
 if IP_VS
 
+choice
+	prompt "IPVS connection interception method"
+	default IP_VS_INPUT_LOCAL_IN
+	help
+	  This option sets the position at which IPVS intercepts incoming
+	  connections from Netfilter. If in doubt select 'LOCAL_IN'.
+
+config IP_VS_INPUT_LOCAL_IN
+	bool "INPUT"
+	---help---
+	  Intercept incoming connections after they have traveled through
+	  the INPUT table, only connections that have the director as
+	  destination address will be processed.
+
+	  This method allows to apply packet filtering in the INPUT table
+	  before the connection is intercepted by IPVS.
+
+config IP_VS_INPUT_FORWARD
+	bool "FORWARD"
+	---help---
+	  Intercept incoming connections after they have traveled through
+	  the INPUT or the FORWARD table. It has the same functionlity of
+	  the "INPUT method", but also processes connections that are
+	  routed through the director, supporting VIP-less setups.
+
+	  This method allows to apply packet filtering in the INPUT or
+	  FORWARD table, before the connection is intercepted by IPVS.
+
+config IP_VS_INPUT_PRE_ROUTING
+	bool "PREROUTING"
+	---help---
+	  Intercept incoming connections before DNAT and input filtering
+	  has been applied, this allows transparent proxying on realnodes
+	  and localnode. Incoming connections are intercepted right after
+	  the mangle PREROUTING table and before the nat PREROUTING table,
+	  supporting VIP-less setups.
+
+	  WARNING: This method doesn't apply any packet filtering before
+	  packets are intercepted by IPVS. To filter the connections that
+	  should be intercepted, you have to mark the traffic in the
+	  mangle PREROUTING table.
+
+endchoice
+
 config	IP_VS_DEBUG
 	bool "IP virtual server debugging"
 	---help---
diff --git a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c
index 963981a..0da4ef6 100644
--- a/net/ipv4/ipvs/ip_vs_core.c
+++ b/net/ipv4/ipvs/ip_vs_core.c
@@ -1026,6 +1026,7 @@ ip_vs_forward_icmp(unsigned int hooknum, struct sk_buff *skb,
 
 
 static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
+#if defined(CONFIG_IP_VS_INPUT_LOCAL_IN) || defined(CONFIG_IP_VS_INPUT_FORWARD)
 	/* After packet filtering, forward packet through VS/DR, VS/TUN,
 	 * or VS/NAT(change destination), so that filtering rules can be
 	 * applied to IPVS. */
@@ -1036,6 +1037,33 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
 		.hooknum        = NF_INET_LOCAL_IN,
 		.priority       = 100,
 	},
+#endif
+#ifdef CONFIG_IP_VS_INPUT_FORWARD
+	/* Intercept incoming connections after they have traveled through
+	 * the INPUT or the FORWARD table. It has the same functionlity of
+	 * the "INPUT method", but also processes connections that are
+	 * routed through the director, supporting VIP-less setups. */
+	{
+		.hook		= ip_vs_in,
+		.owner		= THIS_MODULE,
+		.pf		= PF_INET,
+		.hooknum        = NF_INET_FORWARD,
+		.priority       = 98,
+	},
+#endif
+#ifdef CONFIG_IP_VS_INPUT_PRE_ROUTING
+	/* Intercept incoming connections before DNAT and input filtering
+	 * has been applied, this enables ransparent proxying on realnodes
+	 * and localnode. Hook right after MANGLE and before NAT_DST.
+	 */
+	{
+		.hook           = ip_vs_in,
+		.owner          = THIS_MODULE,
+		.pf             = PF_INET,
+		.hooknum        = NF_INET_PRE_ROUTING,
+		.priority       = NF_IP_PRI_NAT_DST - 1,
+	},
+#endif
 	/* After packet filtering, change source only for VS/NAT */
 	{
 		.hook		= ip_vs_out,
@@ -1059,7 +1087,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET,
 		.hooknum        = NF_INET_POST_ROUTING,
-		.priority       = NF_IP_PRI_NAT_SRC-1,
+		.priority       = NF_IP_PRI_NAT_SRC - 1,
 	},
 };
 
-- 
1.5.3.7

