Finally got it to work! I can access load balanced pages through ipsec.
Ken Brownfield's patch seemed to have been for an older version of
kernel/ipvs.
I've modified his patch by copying new the ip_route_me_harder function
from net/ipv4/netfiter.c (2.6.16).
Below is the patch for kernel 2.6.16 (kernel sources from FC4)
IPVS Version: $Id: ip_vs_core.c,v 1.34 2003/05/10 03:05:23 wensong
Exp
------snip--------
--- ip_vs_core.c.orig 2006-03-20 00:53:29.000000000 -0500
+++ ip_vs_core.c 2006-07-27 14:31:14.000000000 -0400
@@ -43,6 +43,7 @@
#include <net/ip_vs.h>
+#include <net/xfrm.h>
EXPORT_SYMBOL(register_ip_vs_scheduler);
EXPORT_SYMBOL(unregister_ip_vs_scheduler);
@@ -516,6 +517,76 @@
return NF_DROP;
}
+/* This code stolen from net/ipv4/netfilter.c */
+
+int ip_vs_route_me_harder(struct sk_buff **pskb)
+{
+ struct iphdr *iph = (*pskb)->nh.iph;
+ struct rtable *rt;
+ struct flowi fl = {};
+ struct dst_entry *odst;
+ unsigned int hh_len;
+
+ /* some non-standard hacks like ipt_REJECT.c:send_reset() can
cause
+ * packets with foreign saddr to appear on the NF_IP_LOCAL_OUT
hook.
+ */
+ if (inet_addr_type(iph->saddr) == RTN_LOCAL) {
+ fl.nl_u.ip4_u.daddr = iph->daddr;
+ fl.nl_u.ip4_u.saddr = iph->saddr;
+ fl.nl_u.ip4_u.tos = RT_TOS(iph->tos);
+ fl.oif = (*pskb)->sk ? (*pskb)->sk->sk_bound_dev_if :
0;
+#ifdef CONFIG_IP_ROUTE_FWMARK
+ fl.nl_u.ip4_u.fwmark = (*pskb)->nfmark;
+#endif
+ if (ip_route_output_key(&rt, &fl) != 0)
+ return -1;
+
+ /* Drop old route. */
+ dst_release((*pskb)->dst);
+ (*pskb)->dst = &rt->u.dst;
+ } else {
+ /* non-local src, find valid iif to satisfy
+ * rp-filter when calling ip_route_input. */
+ fl.nl_u.ip4_u.daddr = iph->saddr;
+ if (ip_route_output_key(&rt, &fl) != 0)
+ return -1;
+
+ odst = (*pskb)->dst;
+ if (ip_route_input(*pskb, iph->daddr, iph->saddr,
+ RT_TOS(iph->tos), rt->u.dst.dev) !=
0) {
+ dst_release(&rt->u.dst);
+ return -1;
+ }
+ dst_release(&rt->u.dst);
+ dst_release(odst);
+ }
+
+ if ((*pskb)->dst->error)
+ return -1;
+
+#ifdef CONFIG_XFRM
+ if (!(IPCB(*pskb)->flags & IPSKB_XFRM_TRANSFORMED) &&
+ xfrm_decode_session(*pskb, &fl, AF_INET) == 0)
+ if (xfrm_lookup(&(*pskb)->dst, &fl, (*pskb)->sk, 0))
+ return -1;
+#endif
+
+ /* Change in oif may mean change in hh_len. */
+ hh_len = (*pskb)->dst->dev->hard_header_len;
+ if (skb_headroom(*pskb) < hh_len) {
+ struct sk_buff *nskb;
+
+ nskb = skb_realloc_headroom(*pskb, hh_len);
+ if (!nskb)
+ return -1;
+ if ((*pskb)->sk)
+ skb_set_owner_w(nskb, (*pskb)->sk);
+ kfree_skb(*pskb);
+ *pskb = nskb;
+ }
+
+ return 0;
+}
/*
* It is hooked before NF_IP_PRI_NAT_SRC at the NF_IP_POST_ROUTING
@@ -734,6 +805,7 @@
struct ip_vs_protocol *pp;
struct ip_vs_conn *cp;
int ihl;
+ int retval;
EnterFunction(11);
@@ -821,8 +893,20 @@
skb->ipvs_property = 1;
- LeaveFunction(11);
- return NF_ACCEPT;
+ /* 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_vs_route_me_harder(pskb) == 0)
+ retval = NF_ACCEPT;
+ else
+ /* No route available; what can we do? */
+ retval = NF_DROP;
+
+ LeaveFunction(11);
+ return retval;
drop:
ip_vs_conn_put(cp);
------snip--------
-----Original Message-----
From: lvs-users-bounces@xxxxxxxxxxxxxxxxxxxxxx
[mailto:lvs-users-bounces@xxxxxxxxxxxxxxxxxxxxxx] On Behalf Of Joseph
Mack NA3T
Sent: Tuesday, July 25, 2006 8:18 PM
To: LinuxVirtualServer.org users mailing list.
Subject: Re: ipvs with ipsec
there are routing problems with LVS-NAT
http://www.austintek.com/LVS/LVS-HOWTO/HOWTO/LVS-HOWTO.LVS-NAT.html#brow
nfield
(a version of ipvs with this patch has not been released)
|