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: 17+ 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-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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.