LVS
lvs-devel
Google
 
Web LinuxVirtualServer.org

Re: [PATCH 2/2] ipvs: load balance ipv6 connections from a local process

To: "Simon Horman" <horms@xxxxxxxxxxxx>
Subject: Re: [PATCH 2/2] ipvs: load balance ipv6 connections from a local process
Cc: netdev@xxxxxxxxxxxxxxx, lvs-devel@xxxxxxxxxxxxxxx, "Malcolm Turnbull" <malcolm@xxxxxxxxxxxxxxxx>, "Siim Põder" <siim@xxxxxxxxxxxxxxx>, "Vince Busam" <vbusam@xxxxxxxxxx>
From: "Julius Volz" <juliusv@xxxxxxxxxx>
Date: Fri, 5 Sep 2008 13:40:31 +0200
Hi,

Just some minor things:

On Fri, Sep 5, 2008 at 3:37 AM, Simon Horman <horms@xxxxxxxxxxxx> wrote:
> 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@xxxxxxxxxxxxxxx>
> Cc: Malcolm Turnbull <malcolm@xxxxxxxxxxxxxxxx>
> Signed-off-by: Simon Horman <horms@xxxxxxxxxxxx>
>
> ---
>
>  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;

I've always been told to use ipv6_addr_copy() for this. I'm not sure
what the problem with the direct struct assignment is though... would
be nice if someone could explain.

> +       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;
> -                               }
> +                       }

This indents the curly brace incorrectly, probably just deleted a tab
by accident...

>                        }
>                }
>                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;

ipv6_addr_copy() again.

> +                       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,
>


-- 
Julius Volz - Corporate Operations - SysOps

Google Switzerland GmbH - Identification No.: CH-020.4.028.116-1
--
To unsubscribe from this list: send the line "unsubscribe lvs-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

<Prev in Thread] Current Thread [Next in Thread>