SOURCES (LINUX_2_6): kernel-ipvs-nfct.patch (NEW) - http://www.ssi...
zbyniu
zbyniu at pld-linux.org
Mon Jan 28 00:16:32 CET 2008
Author: zbyniu Date: Sun Jan 27 23:16:32 2008 GMT
Module: SOURCES Tag: LINUX_2_6
---- Log message:
- http://www.ssi.bg/~ja/nfct/ipvs-nfct-2.6.24-1.diff
---- Files affected:
SOURCES:
kernel-ipvs-nfct.patch (NONE -> 1.1.4.2) (NEW)
---- Diffs:
================================================================
Index: SOURCES/kernel-ipvs-nfct.patch
diff -u /dev/null SOURCES/kernel-ipvs-nfct.patch:1.1.4.2
--- /dev/null Mon Jan 28 00:16:32 2008
+++ SOURCES/kernel-ipvs-nfct.patch Mon Jan 28 00:16:27 2008
@@ -0,0 +1,753 @@
+diff -urNp v2.6.24/linux/include/net/ip_vs.h linux/include/net/ip_vs.h
+--- v2.6.24/linux/include/net/ip_vs.h 2008-01-25 10:45:05.000000000 +0200
++++ linux/include/net/ip_vs.h 2008-01-27 17:46:03.000000000 +0200
+@@ -9,6 +9,16 @@
+ #include <asm/types.h> /* For __uXX types */
+ #include <linux/types.h> /* For __beXX types in userland */
+
++#ifdef __KERNEL__
++#include <linux/skbuff.h>
++#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
++#include <net/netfilter/nf_conntrack.h>
++#include <net/netfilter/nf_conntrack_core.h>
++#include <net/netfilter/nf_conntrack_expect.h>
++#include <net/netfilter/nf_conntrack_helper.h>
++#endif
++#endif
++
+ #define IP_VS_VERSION_CODE 0x010201
+ #define NVERSION(version) \
+ (version >> 16) & 0xFF, \
+@@ -685,6 +695,16 @@ extern void ip_vs_init_hash_table(struct
+ */
+
+ /*
++ * Netfilter connection tracking
++ * (from ip_vs_nfct.c)
++ */
++extern int ip_vs_nfct_confirm(struct sk_buff *skb, struct ip_vs_conn *cp, unsigned int hooknum);
++extern void ip_vs_nfct_expect_related(struct sk_buff *skb,
++ struct ip_vs_conn *cp,
++ __be16 port, __u16 proto, int from_rs);
++extern void ip_vs_nfct_conn_drop(struct ip_vs_conn *cp);
++
++/*
+ * IPVS connection entry hash table
+ */
+ #ifndef CONFIG_IP_VS_TAB_BITS
+@@ -855,8 +875,41 @@ extern int sysctl_ip_vs_expire_nodest_co
+ extern int sysctl_ip_vs_expire_quiescent_template;
+ extern int sysctl_ip_vs_sync_threshold[2];
+ extern int sysctl_ip_vs_nat_icmp_send;
++extern int sysctl_ip_vs_snat_reroute;
+ extern struct ip_vs_stats ip_vs_stats;
+
++#ifdef CONFIG_IP_VS_NFCT
++
++extern int sysctl_ip_vs_conntrack;
++
++static inline int ip_vs_use_conntrack(struct sk_buff *skb)
++{
++ return sysctl_ip_vs_conntrack && skb->nfct;
++}
++
++/* Returns boolean and skb is freed on failure */
++static inline int ip_vs_confirm_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp, unsigned int hooknum)
++{
++ if (!ip_vs_use_conntrack(skb))
++ return 1;
++ return nf_ct_is_confirmed((struct nf_conn *) skb->nfct) ||
++ ip_vs_nfct_confirm(skb, cp, hooknum);
++}
++
++#else
++
++static inline int ip_vs_use_conntrack(struct sk_buff *skb)
++{
++ return 0;
++}
++
++static inline int ip_vs_confirm_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp, unsigned int hooknum)
++{
++ return 1;
++}
++
++#endif
++
+ extern struct ip_vs_service *
+ ip_vs_service_get(__u32 fwmark, __u16 protocol, __be32 vaddr, __be16 vport);
+
+diff -urNp v2.6.24/linux/net/ipv4/ipvs/Kconfig linux/net/ipv4/ipvs/Kconfig
+--- v2.6.24/linux/net/ipv4/ipvs/Kconfig 2007-07-10 09:18:43.000000000 +0300
++++ linux/net/ipv4/ipvs/Kconfig 2008-01-27 17:46:03.000000000 +0200
+@@ -221,4 +221,12 @@ config IP_VS_FTP
+ If you want to compile it in kernel, say Y. To compile it as a
+ module, choose M here. If unsure, say N.
+
++config IP_VS_NFCT
++ bool "Netfilter connection tracking"
++ depends on NF_CONNTRACK
++ ---help---
++ The Netfilter connection tracking support allows the IPVS
++ connection state to be exported to the Netfilter framework
++ for filtering purposes.
++
+ endif # IP_VS
+diff -urNp v2.6.24/linux/net/ipv4/ipvs/Makefile linux/net/ipv4/ipvs/Makefile
+--- v2.6.24/linux/net/ipv4/ipvs/Makefile 2005-06-18 08:50:52.000000000 +0300
++++ linux/net/ipv4/ipvs/Makefile 2008-01-27 17:46:03.000000000 +0200
+@@ -9,10 +9,13 @@ ip_vs_proto-objs-$(CONFIG_IP_VS_PROTO_UD
+ ip_vs_proto-objs-$(CONFIG_IP_VS_PROTO_ESP) += ip_vs_proto_esp.o
+ ip_vs_proto-objs-$(CONFIG_IP_VS_PROTO_AH) += ip_vs_proto_ah.o
+
++ip_vs-extra_objs-y :=
++ip_vs-extra_objs-$(CONFIG_IP_VS_NFCT) += ip_vs_nfct.o
++
+ ip_vs-objs := ip_vs_conn.o ip_vs_core.o ip_vs_ctl.o ip_vs_sched.o \
+ ip_vs_xmit.o ip_vs_app.o ip_vs_sync.o \
+ ip_vs_est.o ip_vs_proto.o \
+- $(ip_vs_proto-objs-y)
++ $(ip_vs_proto-objs-y) $(ip_vs-extra_objs-y)
+
+
+ # IPVS core
+diff -urNp v2.6.24/linux/net/ipv4/ipvs/ip_vs_conn.c linux/net/ipv4/ipvs/ip_vs_conn.c
+--- v2.6.24/linux/net/ipv4/ipvs/ip_vs_conn.c 2008-01-25 10:45:06.000000000 +0200
++++ linux/net/ipv4/ipvs/ip_vs_conn.c 2008-01-27 17:46:03.000000000 +0200
+@@ -581,6 +581,11 @@ static void ip_vs_conn_expire(unsigned l
+ if (cp->control)
+ ip_vs_control_del(cp);
+
++#ifdef CONFIG_IP_VS_NFCT
++ if (sysctl_ip_vs_conntrack)
++ ip_vs_nfct_conn_drop(cp);
++#endif
++
+ if (unlikely(cp->app != NULL))
+ ip_vs_unbind_app(cp);
+ ip_vs_unbind_dest(cp);
+diff -urNp v2.6.24/linux/net/ipv4/ipvs/ip_vs_core.c linux/net/ipv4/ipvs/ip_vs_core.c
+--- v2.6.24/linux/net/ipv4/ipvs/ip_vs_core.c 2008-01-25 10:45:06.000000000 +0200
++++ linux/net/ipv4/ipvs/ip_vs_core.c 2008-01-27 17:56:11.000000000 +0200
+@@ -661,6 +661,8 @@ static int ip_vs_out_icmp(struct sk_buff
+
+ skb->ipvs_property = 1;
+ verdict = NF_ACCEPT;
++ if (sysctl_ip_vs_snat_reroute && ip_route_me_harder(skb, RTN_LOCAL))
++ verdict = NF_DROP;
+
+ out:
+ __ip_vs_conn_put(cp);
+@@ -761,19 +763,31 @@ ip_vs_out(unsigned int hooknum, struct s
+ if (!skb_make_writable(skb, ihl))
+ goto drop;
+
++ if (!ip_vs_confirm_conntrack(skb, cp, hooknum))
++ goto out;
++
+ /* mangle the packet */
+ if (pp->snat_handler && !pp->snat_handler(skb, pp, cp))
+ goto drop;
+ ip_hdr(skb)->saddr = cp->vaddr;
+ ip_send_check(ip_hdr(skb));
+
++ /*
++ * nf_iterate does not expect change in the skb->dst->dev.
++ * It looks like it is not fatal to enable this code for hooks
++ * where our handlers are at the end of the chain list and
++ * when all next handlers use skb->dst->dev and not outdev.
++ * It will definitely route properly the inout NAT traffic
++ * when multiple paths are used.
++ */
++
+ /* For policy routing, packets originating from this
+ * machine itself may be routed differently to packets
+ * passing through. We want this packet to be routed as
+ * if it came from this machine itself. So re-compute
+ * the routing information.
+ */
+- if (ip_route_me_harder(skb, RTN_LOCAL) != 0)
++ if (sysctl_ip_vs_snat_reroute && ip_route_me_harder(skb, RTN_LOCAL) != 0)
+ goto drop;
+
+ IP_VS_DBG_PKT(10, pp, skb, 0, "After SNAT");
+@@ -788,8 +802,11 @@ ip_vs_out(unsigned int hooknum, struct s
+ return NF_ACCEPT;
+
+ drop:
+- ip_vs_conn_put(cp);
+ kfree_skb(skb);
++
++ out:
++ ip_vs_conn_put(cp);
++ LeaveFunction(11);
+ return NF_STOLEN;
+ }
+
+diff -urNp v2.6.24/linux/net/ipv4/ipvs/ip_vs_ctl.c linux/net/ipv4/ipvs/ip_vs_ctl.c
+--- v2.6.24/linux/net/ipv4/ipvs/ip_vs_ctl.c 2008-01-25 10:45:06.000000000 +0200
++++ linux/net/ipv4/ipvs/ip_vs_ctl.c 2008-01-27 17:53:38.000000000 +0200
+@@ -81,6 +81,10 @@ int sysctl_ip_vs_expire_nodest_conn = 0;
+ int sysctl_ip_vs_expire_quiescent_template = 0;
+ int sysctl_ip_vs_sync_threshold[2] = { 3, 50 };
+ int sysctl_ip_vs_nat_icmp_send = 0;
++int sysctl_ip_vs_snat_reroute = 0;
++#ifdef CONFIG_IP_VS_NFCT
++int sysctl_ip_vs_conntrack = 0;
++#endif
+
+
+ #ifdef CONFIG_IP_VS_DEBUG
+@@ -1446,6 +1450,15 @@ static struct ctl_table vs_vars[] = {
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ },
++#ifdef CONFIG_IP_VS_NFCT
++ {
++ .procname = "conntrack",
++ .data = &sysctl_ip_vs_conntrack,
++ .maxlen = sizeof(int),
++ .mode = 0644,
++ .proc_handler = &proc_dointvec,
++ },
++#endif
+ {
+ .procname = "drop_entry",
+ .data = &sysctl_ip_vs_drop_entry,
+@@ -1467,6 +1480,13 @@ static struct ctl_table vs_vars[] = {
+ .mode = 0644,
+ .proc_handler = &proc_do_defense_mode,
+ },
++ {
++ .procname = "snat_reroute",
++ .data = &sysctl_ip_vs_snat_reroute,
++ .maxlen = sizeof(int),
++ .mode = 0644,
++ .proc_handler = &proc_dointvec,
++ },
+ #if 0
+ {
+ .procname = "timeout_established",
+diff -urNp v2.6.24/linux/net/ipv4/ipvs/ip_vs_ftp.c linux/net/ipv4/ipvs/ip_vs_ftp.c
+--- v2.6.24/linux/net/ipv4/ipvs/ip_vs_ftp.c 2008-01-25 10:45:06.000000000 +0200
++++ linux/net/ipv4/ipvs/ip_vs_ftp.c 2008-01-27 17:55:29.000000000 +0200
+@@ -195,6 +195,11 @@ static int ip_vs_ftp_out(struct ip_vs_ap
+ ip_vs_control_add(n_cp, cp);
+ }
+
++#ifdef CONFIG_IP_VS_NFCT
++ if (skb->nfct)
++ ip_vs_nfct_expect_related(skb, n_cp, 0, IPPROTO_TCP, 0);
++#endif
++
+ /*
+ * Replace the old passive address with the new one
+ */
+@@ -327,6 +332,11 @@ static int ip_vs_ftp_in(struct ip_vs_app
+ ip_vs_control_add(n_cp, cp);
+ }
+
++#ifdef CONFIG_IP_VS_NFCT
++ if (skb->nfct)
++ ip_vs_nfct_expect_related(skb, n_cp, n_cp->dport, IPPROTO_TCP, 1);
++#endif
++
+ /*
+ * Move tunnel to listen state
+ */
+diff -urNp v2.6.24/linux/net/ipv4/ipvs/ip_vs_nfct.c linux/net/ipv4/ipvs/ip_vs_nfct.c
+--- v2.6.24/linux/net/ipv4/ipvs/ip_vs_nfct.c 1970-01-01 02:00:00.000000000 +0200
++++ linux/net/ipv4/ipvs/ip_vs_nfct.c 2008-01-27 18:24:09.000000000 +0200
+@@ -0,0 +1,385 @@
++/*
++ * ip_vs_nfct.c: Netfilter connection tracking support for IPVS
++ *
++ * Portions Copyright (C) 2001-2002
++ * Antefacto Ltd, 181 Parnell St, Dublin 1, Ireland.
++ *
++ * Portions Copyright (C) 2003-2008
++ * Julian Anastasov
++ *
++ *
++ * This code is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ *
++ * Authors:
++ * Ben North <ben at redfrontdoor.org>
++ * Julian Anastasov <ja at ssi.bg> Reorganize and sync with latest kernels
++ *
++ *
++ * Current status:
++ *
++ * - provide conntrack confirmation for new and related connections, by
++ * this way we can see their proper conntrack state in all hooks
++ * - support for all forwarding methods, not only NAT
++ * - FTP support (NAT), ability to support other NAT apps with expectations
++ * - to correctly create expectations for related NAT connections the proper
++ * NF conntrack support must be already installed, eg. ip_vs_ftp requires
++ * nf_conntrack_ftp for the same ports
++ *
++ */
++
++#include <linux/module.h>
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/compiler.h>
++#include <linux/vmalloc.h>
++#include <linux/skbuff.h>
++#include <net/ip.h>
++#include <linux/netfilter.h>
++#include <linux/netfilter_ipv4.h>
++#include <net/ip_vs.h>
++
++
++EXPORT_SYMBOL(ip_vs_nfct_expect_related);
++
++
++#define FMT_TUPLE "%u.%u.%u.%u:%u->%u.%u.%u.%u:%u/%u"
++#define ARG_TUPLE(t) NIPQUAD((t)->src.u3.ip), ntohs((t)->src.u.all), \
++ NIPQUAD((t)->dst.u3.ip), ntohs((t)->dst.u.all), \
++ (t)->dst.protonum
++
++#define FMT_CONN "%u.%u.%u.%u:%u->%u.%u.%u.%u:%u->%u.%u.%u.%u:%u/%u:%u"
++#define ARG_CONN(c) NIPQUAD((c)->caddr), ntohs((c)->cport), \
++ NIPQUAD((c)->vaddr), ntohs((c)->vport), \
++ NIPQUAD((c)->daddr), ntohs((c)->dport), \
++ (c)->protocol, (c)->state
++
++/* Returns boolean and skb is freed on failure */
++static int __ip_vs_nfct_confirm(struct sk_buff *skb, struct ip_vs_conn *cp,
++ unsigned int hooknum)
++{
++ /*
++ * The assumptions:
++ * - the nfct is !NULL and is not confirmed
++ * - we are called before any mangle
++ */
++
++ struct iphdr *iph = ip_hdr(skb);
++ struct nf_conn *ct = (struct nf_conn *) skb->nfct;
++ struct nf_conntrack_tuple new_reply;
++ int ret = NF_DROP;
++ __be16 _ports[2], *pptr;
++#ifdef CONFIG_IP_VS_DEBUG
++ struct nf_conntrack_tuple *orig_tup =
++ &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
++ struct nf_conntrack_tuple *orig_rep =
++ &ct->tuplehash[IP_CT_DIR_REPLY].tuple;
++#endif
++#ifdef CONFIG_NF_NAT_NEEDED
++ int initialized = !!(ct->status & IPS_NAT_DONE_MASK);
++#else
++ int initialized = 0;
++#endif
++
++ IP_VS_DBG(7, "%s: ct=%p, init=%d, tuples=" FMT_TUPLE ", " FMT_TUPLE
++ ", cp=" FMT_CONN "\n",
++ __FUNCTION__, ct, initialized,
++ ARG_TUPLE(orig_tup), ARG_TUPLE(orig_rep), ARG_CONN(cp));
++
++#ifdef CONFIG_NF_NAT_NEEDED
++ /*
++ * This is really bad, may be we are trying to alter DNAT conn?
++ * This is not supported, avoid the confirmation.
++ */
++ if (initialized && ct->status & IPS_NAT_MASK) {
++#ifdef CONFIG_IP_VS_DEBUG
++ IP_VS_DBG(7, "%s: ct=%p, status=0x%lX, init=%d\n",
++ __FUNCTION__, ct, ct->status, initialized);
++#endif
++ return 1;
++ }
++#endif
++
++ if (IP_VS_FWD_METHOD(cp) != IP_VS_CONN_F_MASQ || NF_IP_FORWARD == hooknum)
++ goto confirm;
++
++ /*
++ * Alter reply only for IP_VS_CONN_F_MASQ in outin direction.
++ * For related connections in inout direction it is done in
++ * expectfn callback.
++ */
++
++ pptr = skb_header_pointer(skb, ip_hdrlen(skb),
++ sizeof(_ports), _ports);
++ if (!pptr)
++ goto out;
++
++ new_reply = (struct nf_conntrack_tuple) {
++ .dst = { .protonum = iph->protocol, .dir = IP_CT_DIR_REPLY }};
++
++ new_reply.src.u3.ip = cp->daddr;
++ new_reply.src.u.tcp.port = cp->dport;
++ new_reply.src.l3num = PF_INET;
++ new_reply.dst.u3.ip = iph->saddr;
++ new_reply.dst.u.tcp.port = pptr[0];
++
++ nf_conntrack_alter_reply(ct, &new_reply);
++
++ IP_VS_DBG(7, "%s: ct=%p, init=%d, orig=" FMT_TUPLE
++ ", new_reply=" FMT_TUPLE " => alter_reply\n",
++ __FUNCTION__, ct, initialized,
++ ARG_TUPLE(orig_tup), ARG_TUPLE(&new_reply));
++
++ /*
++ * No need to rehash NAT info because we don't change source
++ * address in original direction
++ */
++
++confirm:
++
++ ret = __nf_conntrack_confirm(skb);
++
++ if (ret != NF_STOLEN) {
++ IP_VS_DBG(7, "%s: ct=%p, init=%d, orig=" FMT_TUPLE " => confirm ret=%d\n",
++ __FUNCTION__, ct, initialized, ARG_TUPLE(orig_tup), ret);
++ }
++
++ if (ret != NF_ACCEPT)
++ goto out;
++ return 1;
++
++out:
++ if (ret != NF_STOLEN)
++ kfree_skb(skb);
++ return 0;
++}
++
++/*
++ * Confirm (and optionally alter) the conntrack entry if needed
++ * because the IPVS packets do not reach ipv4_confirm.
++ */
++int ip_vs_nfct_confirm(struct sk_buff *skb, struct ip_vs_conn *cp,
++ unsigned int hooknum)
++{
++ struct iphdr *iph = ip_hdr(skb);
++ struct nf_conn *ct = (struct nf_conn *) skb->nfct;
++
++ /* By the time we're sending the packet out the other
++ * side, there should be a confirmed Netfilter CT entry
++ * for this connection. This may not be the case,
++ * however, if it's a brand new connection, or if the NF
++ * entry has timed out before ours has. Either way, if
++ * the NF CT entry is unconfirmed, confirm it, and deal
++ * with reply tuple mangling at the same time.
++ */
++
++ /* We only deal with TCP or UDP packets */
++ if (iph->protocol != IPPROTO_TCP && iph->protocol != IPPROTO_UDP)
++ return 1;
++
++ if (IP_VS_FWD_METHOD(cp) != IP_VS_CONN_F_MASQ) {
++ /*
++ * Do not be surprised if non-NAT conntracks stay in SYN_SENT
++ * state, may be the replies from the real server go
++ * directly to client. In any case, keep them in REPLIED
++ * state (ESTABLISHED).
++ */
++ if (iph->protocol != IPPROTO_TCP ||
++ IP_VS_TCP_S_ESTABLISHED == cp->state) {
++ set_bit(IPS_SEEN_REPLY_BIT, &ct->status);
++ }
++ }
++
++ /*
++ * We assume the reused connections do not change their rip:rport
++ * and we do not need to alter their conntrack reply
++ */
++ return __ip_vs_nfct_confirm(skb, cp, hooknum);
++}
++
++/*
++ * We are called from init_conntrack() as expectfn handler
++ */
++
++static void ip_vs_nfct_expect_callback(struct nf_conn *ct,
++ struct nf_conntrack_expect *exp)
++{
++ struct nf_conntrack_tuple *orig, new_reply;
++ struct ip_vs_conn *cp;
++
++ if (exp->tuple.src.l3num != PF_INET)
++ return;
++
++ /*
++ * - We assume that no NF locks are held before this callback
++ * - ip_vs_conn_out_get and ip_vs_conn_in_get should match their
++ * expectations even if they use wildcard values, now we provide
++ * the actual values from the newly created original conntrack direction
++ * - the conntrack is confirmed when packet reaches IPVS hooks
++ */
++
++ /* RS->CLIENT */
++ orig = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
++ cp = ip_vs_conn_out_get(orig->dst.protonum,
++ orig->src.u3.ip, orig->src.u.tcp.port,
++ orig->dst.u3.ip, orig->dst.u.tcp.port);
++ if (cp) {
++ /* Change reply CLIENT->RS to CLIENT->VS */
++ new_reply = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
++ IP_VS_DBG(7, "%s: ct=%p, status=0x%lX, tuples=" FMT_TUPLE ", " FMT_TUPLE
++ ", found inout cp=" FMT_CONN "\n",
++ __FUNCTION__, ct, ct->status,
++ ARG_TUPLE(orig), ARG_TUPLE(&new_reply),
++ ARG_CONN(cp));
++ new_reply.dst.u3.ip = cp->vaddr;
++ new_reply.dst.u.tcp.port = cp->vport;
++ IP_VS_DBG(7, "%s: ct=%p, new tuples=" FMT_TUPLE ", " FMT_TUPLE
++ ", inout cp=" FMT_CONN "\n",
++ __FUNCTION__, ct,
++ ARG_TUPLE(orig), ARG_TUPLE(&new_reply),
++ ARG_CONN(cp));
++ goto alter;
++ }
++
++ /* CLIENT->VS */
++ cp = ip_vs_conn_in_get(orig->dst.protonum,
++ orig->src.u3.ip, orig->src.u.tcp.port,
++ orig->dst.u3.ip, orig->dst.u.tcp.port);
++ if (cp) {
++ /* Change reply VS->CLIENT to RS->CLIENT */
++ new_reply = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
++ IP_VS_DBG(7, "%s: ct=%p, status=0x%lX, tuples=" FMT_TUPLE ", " FMT_TUPLE
++ ", found outin cp=" FMT_CONN "\n",
++ __FUNCTION__, ct, ct->status,
++ ARG_TUPLE(orig), ARG_TUPLE(&new_reply),
++ ARG_CONN(cp));
++ new_reply.src.u3.ip = cp->daddr;
++ new_reply.src.u.tcp.port = cp->dport;
++ IP_VS_DBG(7, "%s: ct=%p, new tuples=" FMT_TUPLE ", " FMT_TUPLE
++ ", outin cp=" FMT_CONN "\n",
++ __FUNCTION__, ct,
++ ARG_TUPLE(orig), ARG_TUPLE(&new_reply),
++ ARG_CONN(cp));
++ goto alter;
++ }
++ IP_VS_DBG(7, "%s: ct=%p, status=0x%lX, tuple=" FMT_TUPLE " - unknown expect\n",
++ __FUNCTION__, ct, ct->status, ARG_TUPLE(orig));
++ return;
++
++alter:
++
++ /* Never alter conntrack for non-NAT conns */
++ if (IP_VS_FWD_METHOD(cp) == IP_VS_CONN_F_MASQ)
++ nf_conntrack_alter_reply(ct, &new_reply);
++ ip_vs_conn_put(cp);
++ return;
++}
++
++/*
++ * Create NF conntrack expectation with wildcard (optional) source port.
++ * Then the default callback function will alter the reply and will confirm
++ * the conntrack entry when the first packet comes.
++ */
++void ip_vs_nfct_expect_related(struct sk_buff *skb, struct ip_vs_conn *cp,
++ __be16 port, __u16 proto, int from_rs)
++{
++ struct nf_conn *ct = (struct nf_conn *) skb->nfct;
++ struct nf_conntrack_expect *e;
++
++ if (!sysctl_ip_vs_conntrack)
++ return;
++
++ if (!ct) {
++ IP_VS_DBG(7, "%s: ct=%p for cp=" FMT_CONN "\n",
++ __FUNCTION__, ct, ARG_CONN(cp));
++ return;
++ }
++
++ if (!(e = nf_ct_expect_alloc(ct)))
++ return;
++
++ e->expectfn = ip_vs_nfct_expect_callback;
++ e->helper = NULL;
++ e->flags = 0;
++ memset(&e->tuple, 0, sizeof(e->tuple));
++ e->tuple.src.u.tcp.port = port;
++ e->tuple.src.l3num = PF_INET;
++ e->tuple.dst.protonum = proto;
++ memset(&e->mask, 0, sizeof(e->mask));
++ e->mask.src.u3.ip = 0xffffffff;
++ e->mask.src.u.all = port? 0xffff : 0;
++
++ if (from_rs) {
++ e->tuple.src.u3.ip = cp->daddr;
++ e->tuple.dst.u3.ip = cp->caddr;
++ e->tuple.dst.u.tcp.port = cp->cport;
++ } else {
++ e->tuple.src.u3.ip = cp->caddr;
<<Diff was trimmed, longer than 597 lines>>
More information about the pld-cvs-commit
mailing list