From: Simon Horman <horms@verge.net.au>
To: netdev@vger.kernel.org, lvs-devel@vger.kernel.org
Cc: "Malcolm Turnbull" <malcolm@loadbalancer.org>,
"Siim Põder" <siim@p6drad-teel.net>,
"Julius Volz" <juliusv@google.com>,
"Vince Busam" <vbusam@google.com>
Subject: [PATCH 2/2] ipvs: load balance ipv6 connections from a local process
Date: Fri, 5 Sep 2008 11:37:56 +1000 [thread overview]
Message-ID: <20080905013755.GE14128@verge.net.au> (raw)
In-Reply-To: <20080905013609.GD14128@verge.net.au>
This allows IPVS to load balance IPv6 connections made by a local process.
For example a proxy server running locally.
External client --> pound:443 -> Local:443 --> IPVS:80 --> RealServer
This is an extenstion to the IPv4 work done in this area
by Siim Põder and Malcolm Turnbull.
Cc: Siim Põder <siim@p6drad-teel.net>
Cc: Malcolm Turnbull <malcolm@loadbalancer.org>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
net/ipv4/ipvs/ip_vs_core.c | 91 +++++++++++++++++++-------------------------
1 file changed, 41 insertions(+), 50 deletions(-)
* Fri, 05 Sep 2008 11:32:38 +1000
I have applied this patch to the net-next-2.6 branck of lvs-2.6
git://git.kernel.org/pub/scm/linux/kernel/git/horms/lvs-2.6.git
Index: lvs-2.6/net/ipv4/ipvs/ip_vs_core.c
===================================================================
--- lvs-2.6.orig/net/ipv4/ipvs/ip_vs_core.c 2008-09-03 13:39:34.000000000 +1000
+++ lvs-2.6/net/ipv4/ipvs/ip_vs_core.c 2008-09-03 14:39:17.000000000 +1000
@@ -654,8 +654,9 @@ void ip_vs_nat_icmp_v6(struct sk_buff *s
/* Handle relevant response ICMP messages - forward to the right
* destination host. Used for NAT and local client.
*/
-static int handle_response_icmp(struct sk_buff *skb, struct iphdr *iph,
- struct iphdr *cih, struct ip_vs_conn *cp,
+static int handle_response_icmp(int af, struct sk_buff *skb,
+ union nf_inet_addr *snet,
+ __u8 protocol, struct ip_vs_conn *cp,
struct ip_vs_protocol *pp,
unsigned int offset, unsigned int ihl)
{
@@ -669,18 +670,22 @@ static int handle_response_icmp(struct s
/* Ensure the checksum is correct */
if (!skb_csum_unnecessary(skb) && ip_vs_checksum_complete(skb, ihl)) {
/* Failed checksum! */
- IP_VS_DBG(1,
- "Forward ICMP: failed checksum from %d.%d.%d.%d!\n",
- NIPQUAD(iph->saddr));
+ IP_VS_DBG_BUF(1, "Forward ICMP: failed checksum from %s!\n",
+ IP_VS_DBG_ADDR(af, snet));
goto out;
}
- if (IPPROTO_TCP == cih->protocol || IPPROTO_UDP == cih->protocol)
+ if (IPPROTO_TCP == protocol || IPPROTO_UDP == protocol)
offset += 2 * sizeof(__u16);
if (!skb_make_writable(skb, offset))
goto out;
- ip_vs_nat_icmp(skb, pp, cp, 1);
+#ifdef CONFIG_IP_VS_IPV6
+ if (af == AF_INET6)
+ ip_vs_nat_icmp_v6(skb, pp, cp, 1);
+ else
+#endif
+ ip_vs_nat_icmp(skb, pp, cp, 1);
/* do the statistics and put it back */
ip_vs_out_stats(cp, skb);
@@ -708,6 +713,7 @@ static int ip_vs_out_icmp(struct sk_buff
struct ip_vs_conn *cp;
struct ip_vs_protocol *pp;
unsigned int offset, ihl;
+ union nf_inet_addr snet;
*related = 1;
@@ -766,7 +772,9 @@ static int ip_vs_out_icmp(struct sk_buff
if (!cp)
return NF_ACCEPT;
- return handle_response_icmp(skb, iph, cih, cp, pp, offset, ihl);
+ snet.ip = iph->saddr;
+ return handle_response_icmp(AF_INET, skb, &snet, cih->protocol, cp,
+ pp, offset, ihl);
}
#ifdef CONFIG_IP_VS_IPV6
@@ -779,7 +787,8 @@ static int ip_vs_out_icmp_v6(struct sk_b
struct ip_vs_iphdr ciph;
struct ip_vs_conn *cp;
struct ip_vs_protocol *pp;
- unsigned int offset, verdict;
+ unsigned int offset;
+ union nf_inet_addr snet;
*related = 1;
@@ -838,40 +847,9 @@ static int ip_vs_out_icmp_v6(struct sk_b
if (!cp)
return NF_ACCEPT;
- verdict = NF_DROP;
-
- if (IP_VS_FWD_METHOD(cp) != 0) {
- IP_VS_ERR("shouldn't reach here, because the box is on the "
- "half connection in the tun/dr module.\n");
- }
-
- /* Ensure the checksum is correct */
- if (!skb_csum_unnecessary(skb)
- && ip_vs_checksum_complete(skb, sizeof(struct ipv6hdr))) {
- /* Failed checksum! */
- IP_VS_DBG(1, "Forward ICMPv6: failed checksum from "
- NIP6_FMT "!\n",
- NIP6(iph->saddr));
- goto out;
- }
-
- if (IPPROTO_TCP == cih->nexthdr || IPPROTO_UDP == cih->nexthdr)
- offset += 2 * sizeof(__u16);
- if (!skb_make_writable(skb, offset))
- goto out;
-
- ip_vs_nat_icmp_v6(skb, pp, cp, 1);
-
- /* do the statistics and put it back */
- ip_vs_out_stats(cp, skb);
-
- skb->ipvs_property = 1;
- verdict = NF_ACCEPT;
-
-out:
- __ip_vs_conn_put(cp);
-
- return verdict;
+ snet.in6 = iph->saddr;
+ return handle_response_icmp(AF_INET6, skb, &snet, cih->nexthdr, cp,
+ pp, offset, sizeof(struct ipv6hdr));
}
#endif
@@ -1055,7 +1033,7 @@ ip_vs_out(unsigned int hooknum, struct s
ICMP_DEST_UNREACH,
ICMP_PORT_UNREACH, 0);
return NF_DROP;
- }
+ }
}
}
IP_VS_DBG_PKT(12, pp, skb, 0,
@@ -1083,6 +1061,7 @@ ip_vs_in_icmp(struct sk_buff *skb, int *
struct ip_vs_conn *cp;
struct ip_vs_protocol *pp;
unsigned int offset, ihl, verdict;
+ union nf_inet_addr snet;
*related = 1;
@@ -1142,9 +1121,12 @@ ip_vs_in_icmp(struct sk_buff *skb, int *
if (!cp) {
/* The packet could also belong to a local client */
cp = pp->conn_out_get(AF_INET, skb, pp, &ciph, offset, 1);
- if (cp)
- return handle_response_icmp(skb, iph, cih, cp, pp,
+ if (cp) {
+ snet.ip = iph->saddr;
+ return handle_response_icmp(AF_INET, skb, &snet,
+ cih->protocol, cp, pp,
offset, ihl);
+ }
return NF_ACCEPT;
}
@@ -1183,6 +1165,7 @@ ip_vs_in_icmp_v6(struct sk_buff *skb, in
struct ip_vs_conn *cp;
struct ip_vs_protocol *pp;
unsigned int offset, verdict;
+ union nf_inet_addr snet;
*related = 1;
@@ -1240,8 +1223,18 @@ ip_vs_in_icmp_v6(struct sk_buff *skb, in
ip_vs_fill_iphdr(AF_INET6, cih, &ciph);
/* The embedded headers contain source and dest in reverse order */
cp = pp->conn_in_get(AF_INET6, skb, pp, &ciph, offset, 1);
- if (!cp)
+ if (!cp) {
+ /* The packet could also belong to a local client */
+ cp = pp->conn_out_get(AF_INET6, skb, pp, &ciph, offset, 1);
+ if (cp) {
+ snet.in6 = iph->saddr;
+ return handle_response_icmp(AF_INET6, skb, &snet,
+ cih->nexthdr,
+ cp, pp, offset,
+ sizeof(struct ipv6hdr));
+ }
return NF_ACCEPT;
+ }
verdict = NF_DROP;
@@ -1281,9 +1274,7 @@ ip_vs_in(unsigned int hooknum, struct sk
* Big tappo: only PACKET_HOST, including loopback for local client
* Don't handle local packets on IPv6 for now
*/
- if (unlikely(skb->pkt_type != PACKET_HOST ||
- (af == AF_INET6 || (skb->dev->flags & IFF_LOOPBACK ||
- skb->sk)))) {
+ if (unlikely(skb->pkt_type != PACKET_HOST)) {
IP_VS_DBG_BUF(12, "packet type=%d proto=%d daddr=%s ignored\n",
skb->pkt_type,
iph.protocol,
next prev parent reply other threads:[~2008-09-05 1:37 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-09-05 1:36 [PATCH 1/2] ipvs: load balance IPv4 connections from a local process Simon Horman
2008-09-05 1:37 ` Simon Horman [this message]
2008-09-05 11:40 ` [PATCH 2/2] ipvs: load balance ipv6 " Julius Volz
2008-09-05 15:55 ` Brian Haley
2008-09-05 16:37 ` Julius Volz
2008-09-06 4:14 ` Simon Horman
2008-09-06 9:26 ` Julius Volz
2008-09-08 0:30 ` Simon Horman
2008-09-08 1:48 ` Simon Horman
2008-09-08 9:30 ` Julius Volz
2008-09-08 9:50 ` Simon Horman
2008-09-05 5:12 ` [PATCH 1/2] ipvs: load balance IPv4 " Julian Anastasov
2008-09-05 5:49 ` Siim Põder
2008-09-06 7:43 ` Simon Horman
2008-09-05 11:02 ` Julius Volz
2008-09-06 3:56 ` Simon Horman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20080905013755.GE14128@verge.net.au \
--to=horms@verge.net.au \
--cc=juliusv@google.com \
--cc=lvs-devel@vger.kernel.org \
--cc=malcolm@loadbalancer.org \
--cc=netdev@vger.kernel.org \
--cc=siim@p6drad-teel.net \
--cc=vbusam@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).