LVS
lvs-devel
Google
 
Web LinuxVirtualServer.org

Re: [patch v2 04/12] [PATCH 04/12] IPVS: Add struct ip_vs_conn_param

To: Julian Anastasov <ja@xxxxxx>
Subject: Re: [patch v2 04/12] [PATCH 04/12] IPVS: Add struct ip_vs_conn_param
Cc: lvs-devel@xxxxxxxxxxxxxxx, netdev@xxxxxxxxxxxxxxx, netfilter@xxxxxxxxxxxxxxx, netfilter-devel@xxxxxxxxxxxxxxx, Jan Engelhardt <jengelh@xxxxxxxxxx>, Stephen Hemminger <shemminger@xxxxxxxxxx>, Wensong Zhang <wensong@xxxxxxxxxxxx>, Patrick McHardy <kaber@xxxxxxxxx>
From: Simon Horman <horms@xxxxxxxxxxxx>
Date: Sat, 2 Oct 2010 10:13:50 +0900
On Fri, Oct 01, 2010 at 11:58:04PM +0300, Julian Anastasov wrote:
> 
>       Hello,
> 
> On Fri, 1 Oct 2010, Simon Horman wrote:
> 
> >+static int
> >+ip_vs_conn_fill_param_proto(int af, const struct sk_buff *skb,
> >+                        const struct ip_vs_iphdr *iph,
> >+                        unsigned int proto_off, int inverse,
> >+                        struct ip_vs_conn_param *p)
> >+{
> >+    __be16 _ports[2], *pptr;
> >+
> >+    pptr = skb_header_pointer(skb, proto_off, sizeof(_ports), _ports);
> >+    if (pptr == NULL)
> >+            return 1;
> >+
> >+    if (likely(!inverse))
> >+            ip_vs_conn_fill_param(af, iph->protocol, &iph->saddr, pptr[0],
> >+                                  &iph->daddr, pptr[1], p);
> >+    else
> 
>       Next line is wrong for inverse=1, must be
>       &iph->daddr, pptr[1], &iph->saddr, pptr[0]

Thanks, fixed.

> >+            ip_vs_conn_fill_param(af, iph->protocol, &iph->saddr, pptr[0],
> >+                                  &iph->daddr, pptr[1], p);
> >+    return 0;
> >+}
> >+
> 
>       May be comments before ip_vs_conn_out_get should be
> changed:
> 
> >@@ -341,9 +351,7 @@ struct ip_vs_conn *ip_vs_ct_in_get
> > *   s_addr, s_port: pkt source address (inside host)
> > *   d_addr, d_port: pkt dest address (foreign host)
> > */
> >-struct ip_vs_conn *ip_vs_conn_out_get
> >-(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port,
> >- const union nf_inet_addr *d_addr, __be16 d_port)
> >+struct ip_vs_conn *ip_vs_conn_out_get(const struct ip_vs_conn_param *p)

I have updated it to:

/* Gets ip_vs_conn associated with supplied parameters in the
 * ip_vs_conn_tab.
 * Called for pkts coming from inside-to-OUTside.
 *      p->caddr, p->cport: pkt source address (inside host)
 *      p->vaddr, p->vport: pkt dest address (foreign host) */

> >===================================================================
> >--- lvs-test-2.6.orig/net/netfilter/ipvs/ip_vs_core.c        2010-10-01 
> >22:06:23.000000000 +0900
> >+++ lvs-test-2.6/net/netfilter/ipvs/ip_vs_core.c     2010-10-01 
> >22:10:46.000000000 +0900
> >@@ -193,14 +193,11 @@ ip_vs_sched_persist(struct ip_vs_service
> >     struct ip_vs_iphdr iph;
> >     struct ip_vs_dest *dest;
> >     struct ip_vs_conn *ct;
> >-    int protocol = iph.protocol;
> >     __be16 dport = 0;               /* destination port to forward */
> >-    __be16 vport = 0;               /* virtual service port */
> >     unsigned int flags;
> >     union nf_inet_addr snet;        /* source network of the client,
> >                                        after masking */
> >-    const union nf_inet_addr fwmark = { .ip = htonl(svc->fwmark) };
> >-    const union nf_inet_addr *vaddr = &iph.daddr;
> >+    struct ip_vs_conn_param param;
> >
> >     ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph);
> >
> >@@ -232,6 +229,11 @@ ip_vs_sched_persist(struct ip_vs_service
> >      * is created for other persistent services.
> >      */
> >     {
> >+            int protocol = iph.protocol;
> >+            const union nf_inet_addr *vaddr = &iph.daddr;
> >+            const union nf_inet_addr fwmark = { .ip = htonl(svc->fwmark) };
> >+            __be16 vport = 0;
> >+
> >             if (ports[1] == svc->port) {
> >                     /* non-FTP template:
> >                      * <protocol, caddr, 0, vaddr, vport, daddr, dport>
> >@@ -253,11 +255,12 @@ ip_vs_sched_persist(struct ip_vs_service
> >                             vaddr = &fwmark;
> >                     }
> >             }
> >+            ip_vs_conn_fill_param(svc->af, protocol, &snet, 0,
> >+                                  vaddr, vport, &param);
> >     }
> >
> >     /* Check if a template already exists */
> >-    ct = ip_vs_ct_in_get(svc->af, protocol, &snet, 0, vaddr, vport);
> >-
> >+    ct = ip_vs_ct_in_get(&param);
> >     if (!ct || !ip_vs_check_template(ct)) {
> >             /* No template found or the dest of the connection
> >              * template is not available.
> >@@ -272,8 +275,7 @@ ip_vs_sched_persist(struct ip_vs_service
> >                     dport = dest->port;
> >
> >             /* Create a template */
> >-            ct = ip_vs_conn_new(svc->af, protocol, &snet, 0,vaddr, vport,
> >-                                &dest->addr, dport,
> >+            ct = ip_vs_conn_new(&param, &dest->addr, dport,
> >                                 IP_VS_CONN_F_TEMPLATE, dest);
> >             if (ct == NULL)
> >                     return NULL;
> >@@ -291,12 +293,7 @@ ip_vs_sched_persist(struct ip_vs_service
> >     /*
> >      *    Create a new connection according to the template
> >      */
> 
>       Missing ip_vs_conn_fill_param here?

Ooops, yes. I think that for some reason I thought it wasn't necessary.
I have added the following:

        ip_vs_conn_fill_param(svc->af, iph.protocol, &iph.saddr, ports[0],
                              &iph.daddr, ports[1], &param);

> >-    cp = ip_vs_conn_new(svc->af, iph.protocol,
> >-                        &iph.saddr, ports[0],
> >-                        &iph.daddr, ports[1],
> >-                        &dest->addr, dport,
> >-                        flags,
> >-                        dest);
> >+    cp = ip_vs_conn_new(&param, &dest->addr, dport, flags, dest);
> >     if (cp == NULL) {
> >             ip_vs_conn_put(ct);
> >             return NULL;
> 
> >===================================================================
> >--- lvs-test-2.6.orig/net/netfilter/ipvs/ip_vs_proto_ah_esp.c        
> >2010-10-01 21:55:19.000000000 +0900
> >+++ lvs-test-2.6/net/netfilter/ipvs/ip_vs_proto_ah_esp.c     2010-10-01 
> >22:23:33.000000000 +0900
> >@@ -40,6 +40,19 @@ struct isakmp_hdr {
> >
> >#define PORT_ISAKMP  500
> >
> >+static void
> >+ah_esp_conn_fill_param_proto(int af, const struct ip_vs_iphdr *iph,
> >+                         int inverse, struct ip_vs_conn_param *p)
> >+{
> >+    if (likely(!inverse))
> >+            ip_vs_conn_fill_param(af, IPPROTO_UDP,
> >+                                  &iph->saddr, htons(PORT_ISAKMP),
> >+                                  &iph->daddr, htons(PORT_ISAKMP), p);
> >+    else
> 
>       For inverse=1 iph->protocol must be IPPROTO_UDP
> and &iph->daddr before &iph->saddr:

Thanks, fixed.

> >+            ip_vs_conn_fill_param(af, iph->protocol,
> >+                                  &iph->saddr, htons(PORT_ISAKMP),
> >+                                  &iph->daddr, htons(PORT_ISAKMP), p);
> >+}

I will repost the entire series after addressing the concerns
you raised with several of the other patches. But for reference
here is the revised version of this patch.

>From 335c0ae2b64d8071762c50ea20b4f55bb12c2a5b Mon Sep 17 00:00:00 2001
From: Simon Horman <horms@xxxxxxxxxxxx>
Date: Sun, 22 Aug 2010 21:37:52 +0900
Subject: [patch v2.1 04/12] IPVS: Add struct ip_vs_conn_param

Signed-off-by: Simon Horman <horms@xxxxxxxxxxxx>
---

The motivation for this is to allow persistence engine modules to
fill in the parameters.

v0.3
* Add missing changes to ip_vs_ftp.c

v2
* make "union nf_inet_addr fwmark" const
* Update for the recent addition of ip_vs_nfct.c

v2.1
* As suggested by Julian Anastasov
  - Correct logic for inverse case in ip_vs_conn_fill_param_proto()
    and ah_esp_conn_fill_param_proto()
  - Update ip_vs_conn_out_get()'s comments as its parameters have changed
  - Add missing call to ip_vs_conn_fill_param() before the second
    invocation of ip_vs_conn_new() in ip_vs_sched_persist()

Index: lvs-test-2.6/include/net/ip_vs.h
===================================================================
--- lvs-test-2.6.orig/include/net/ip_vs.h       2010-10-01 21:56:39.000000000 
+0900
+++ lvs-test-2.6/include/net/ip_vs.h    2010-10-01 22:07:22.000000000 +0900
@@ -357,6 +357,15 @@ struct ip_vs_protocol {
 
 extern struct ip_vs_protocol * ip_vs_proto_get(unsigned short proto);
 
+struct ip_vs_conn_param {
+       const union nf_inet_addr        *caddr;
+       const union nf_inet_addr        *vaddr;
+       __be16                          cport;
+       __be16                          vport;
+       __u16                           protocol;
+       u16                             af;
+};
+
 /*
  *     IP_VS structure allocated for each dynamically scheduled connection
  */
@@ -626,13 +635,23 @@ enum {
        IP_VS_DIR_LAST,
 };
 
-extern struct ip_vs_conn *ip_vs_conn_in_get
-(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port,
- const union nf_inet_addr *d_addr, __be16 d_port);
-
-extern struct ip_vs_conn *ip_vs_ct_in_get
-(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port,
- const union nf_inet_addr *d_addr, __be16 d_port);
+static inline void ip_vs_conn_fill_param(int af, int protocol,
+                                        const union nf_inet_addr *caddr,
+                                        __be16 cport,
+                                        const union nf_inet_addr *vaddr,
+                                        __be16 vport,
+                                        struct ip_vs_conn_param *p)
+{
+       p->af = af;
+       p->protocol = protocol;
+       p->caddr = caddr;
+       p->cport = cport;
+       p->vaddr = vaddr;
+       p->vport = vport;
+}
+
+struct ip_vs_conn *ip_vs_conn_in_get(const struct ip_vs_conn_param *p);
+struct ip_vs_conn *ip_vs_ct_in_get(const struct ip_vs_conn_param *p);
 
 struct ip_vs_conn * ip_vs_conn_in_get_proto(int af, const struct sk_buff *skb,
                                            struct ip_vs_protocol *pp,
@@ -640,9 +659,7 @@ struct ip_vs_conn * ip_vs_conn_in_get_pr
                                            unsigned int proto_off,
                                            int inverse);
 
-extern struct ip_vs_conn *ip_vs_conn_out_get
-(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port,
- const union nf_inet_addr *d_addr, __be16 d_port);
+struct ip_vs_conn *ip_vs_conn_out_get(const struct ip_vs_conn_param *p);
 
 struct ip_vs_conn * ip_vs_conn_out_get_proto(int af, const struct sk_buff *skb,
                                             struct ip_vs_protocol *pp,
@@ -658,11 +675,10 @@ static inline void __ip_vs_conn_put(stru
 extern void ip_vs_conn_put(struct ip_vs_conn *cp);
 extern void ip_vs_conn_fill_cport(struct ip_vs_conn *cp, __be16 cport);
 
-extern struct ip_vs_conn *
-ip_vs_conn_new(int af, int proto, const union nf_inet_addr *caddr, __be16 
cport,
-              const union nf_inet_addr *vaddr, __be16 vport,
-              const union nf_inet_addr *daddr, __be16 dport, unsigned flags,
-              struct ip_vs_dest *dest);
+struct ip_vs_conn *ip_vs_conn_new(const struct ip_vs_conn_param *p,
+                                 const union nf_inet_addr *daddr,
+                                 __be16 dport, unsigned flags,
+                                 struct ip_vs_dest *dest);
 extern void ip_vs_conn_expire_now(struct ip_vs_conn *cp);
 
 extern const char * ip_vs_state_name(__u16 proto, int state);
Index: lvs-test-2.6/net/netfilter/ipvs/ip_vs_conn.c
===================================================================
--- lvs-test-2.6.orig/net/netfilter/ipvs/ip_vs_conn.c   2010-10-01 
21:56:39.000000000 +0900
+++ lvs-test-2.6/net/netfilter/ipvs/ip_vs_conn.c        2010-10-01 
22:07:22.000000000 +0900
@@ -218,27 +218,26 @@ static inline int ip_vs_conn_unhash(stru
 /*
  *  Gets ip_vs_conn associated with supplied parameters in the ip_vs_conn_tab.
  *  Called for pkts coming from OUTside-to-INside.
- *     s_addr, s_port: pkt source address (foreign host)
- *     d_addr, d_port: pkt dest address (load balancer)
+ *     p->caddr, p->cport: pkt source address (foreign host)
+ *     p->vaddr, p->vport: pkt dest address (load balancer)
  */
-static inline struct ip_vs_conn *__ip_vs_conn_in_get
-(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port,
- const union nf_inet_addr *d_addr, __be16 d_port)
+static inline struct ip_vs_conn *
+__ip_vs_conn_in_get(const struct ip_vs_conn_param *p)
 {
        unsigned hash;
        struct ip_vs_conn *cp;
 
-       hash = ip_vs_conn_hashkey(af, protocol, s_addr, s_port);
+       hash = ip_vs_conn_hashkey(p->af, p->protocol, p->caddr, p->cport);
 
        ct_read_lock(hash);
 
        list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) {
-               if (cp->af == af &&
-                   ip_vs_addr_equal(af, s_addr, &cp->caddr) &&
-                   ip_vs_addr_equal(af, d_addr, &cp->vaddr) &&
-                   s_port == cp->cport && d_port == cp->vport &&
-                   ((!s_port) ^ (!(cp->flags & IP_VS_CONN_F_NO_CPORT))) &&
-                   protocol == cp->protocol) {
+               if (cp->af == p->af &&
+                   ip_vs_addr_equal(p->af, p->caddr, &cp->caddr) &&
+                   ip_vs_addr_equal(p->af, p->vaddr, &cp->vaddr) &&
+                   p->cport == cp->cport && p->vport == cp->vport &&
+                   ((!p->cport) ^ (!(cp->flags & IP_VS_CONN_F_NO_CPORT))) &&
+                   p->protocol == cp->protocol) {
                        /* HIT */
                        atomic_inc(&cp->refcnt);
                        ct_read_unlock(hash);
@@ -251,71 +250,82 @@ static inline struct ip_vs_conn *__ip_vs
        return NULL;
 }
 
-struct ip_vs_conn *ip_vs_conn_in_get
-(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port,
- const union nf_inet_addr *d_addr, __be16 d_port)
+struct ip_vs_conn *ip_vs_conn_in_get(const struct ip_vs_conn_param *p)
 {
        struct ip_vs_conn *cp;
 
-       cp = __ip_vs_conn_in_get(af, protocol, s_addr, s_port, d_addr, d_port);
-       if (!cp && atomic_read(&ip_vs_conn_no_cport_cnt))
-               cp = __ip_vs_conn_in_get(af, protocol, s_addr, 0, d_addr,
-                                        d_port);
+       cp = __ip_vs_conn_in_get(p);
+       if (!cp && atomic_read(&ip_vs_conn_no_cport_cnt)) {
+               struct ip_vs_conn_param cport_zero_p = *p;
+               cport_zero_p.cport = 0;
+               cp = __ip_vs_conn_in_get(&cport_zero_p);
+       }
 
        IP_VS_DBG_BUF(9, "lookup/in %s %s:%d->%s:%d %s\n",
-                     ip_vs_proto_name(protocol),
-                     IP_VS_DBG_ADDR(af, s_addr), ntohs(s_port),
-                     IP_VS_DBG_ADDR(af, d_addr), ntohs(d_port),
+                     ip_vs_proto_name(p->protocol),
+                     IP_VS_DBG_ADDR(p->af, p->caddr), ntohs(p->cport),
+                     IP_VS_DBG_ADDR(p->af, p->vaddr), ntohs(p->vport),
                      cp ? "hit" : "not hit");
 
        return cp;
 }
 
+static int
+ip_vs_conn_fill_param_proto(int af, const struct sk_buff *skb,
+                           const struct ip_vs_iphdr *iph,
+                           unsigned int proto_off, int inverse,
+                           struct ip_vs_conn_param *p)
+{
+       __be16 _ports[2], *pptr;
+
+       pptr = skb_header_pointer(skb, proto_off, sizeof(_ports), _ports);
+       if (pptr == NULL)
+               return 1;
+
+       if (likely(!inverse))
+               ip_vs_conn_fill_param(af, iph->protocol, &iph->saddr, pptr[0],
+                                     &iph->daddr, pptr[1], p);
+       else
+               ip_vs_conn_fill_param(af, iph->protocol, &iph->saddr, pptr[0],
+                                     &iph->daddr, pptr[1], p);
+       return 0;
+}
+
 struct ip_vs_conn *
 ip_vs_conn_in_get_proto(int af, const struct sk_buff *skb,
                        struct ip_vs_protocol *pp,
                        const struct ip_vs_iphdr *iph,
                        unsigned int proto_off, int inverse)
 {
-       __be16 _ports[2], *pptr;
+       struct ip_vs_conn_param p;
 
-       pptr = skb_header_pointer(skb, proto_off, sizeof(_ports), _ports);
-       if (pptr == NULL)
+       if (ip_vs_conn_fill_param_proto(af, skb, iph, proto_off, inverse, &p))
                return NULL;
 
-       if (likely(!inverse))
-               return ip_vs_conn_in_get(af, iph->protocol,
-                                        &iph->saddr, pptr[0],
-                                        &iph->daddr, pptr[1]);
-       else
-               return ip_vs_conn_in_get(af, iph->protocol,
-                                        &iph->daddr, pptr[1],
-                                        &iph->saddr, pptr[0]);
+       return ip_vs_conn_in_get(&p);
 }
 EXPORT_SYMBOL_GPL(ip_vs_conn_in_get_proto);
 
 /* Get reference to connection template */
-struct ip_vs_conn *ip_vs_ct_in_get
-(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port,
- const union nf_inet_addr *d_addr, __be16 d_port)
+struct ip_vs_conn *ip_vs_ct_in_get(const struct ip_vs_conn_param *p)
 {
        unsigned hash;
        struct ip_vs_conn *cp;
 
-       hash = ip_vs_conn_hashkey(af, protocol, s_addr, s_port);
+       hash = ip_vs_conn_hashkey(p->af, p->protocol, p->caddr, p->cport);
 
        ct_read_lock(hash);
 
        list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) {
-               if (cp->af == af &&
-                   ip_vs_addr_equal(af, s_addr, &cp->caddr) &&
+               if (cp->af == p->af &&
+                   ip_vs_addr_equal(p->af, p->caddr, &cp->caddr) &&
                    /* protocol should only be IPPROTO_IP if
-                    * d_addr is a fwmark */
-                   ip_vs_addr_equal(protocol == IPPROTO_IP ? AF_UNSPEC : af,
-                                    d_addr, &cp->vaddr) &&
-                   s_port == cp->cport && d_port == cp->vport &&
+                    * p->vaddr is a fwmark */
+                   ip_vs_addr_equal(p->protocol == IPPROTO_IP ? AF_UNSPEC :
+                                    p->af, p->vaddr, &cp->vaddr) &&
+                   p->cport == cp->cport && p->vport == cp->vport &&
                    cp->flags & IP_VS_CONN_F_TEMPLATE &&
-                   protocol == cp->protocol) {
+                   p->protocol == cp->protocol) {
                        /* HIT */
                        atomic_inc(&cp->refcnt);
                        goto out;
@@ -327,9 +337,9 @@ struct ip_vs_conn *ip_vs_ct_in_get
        ct_read_unlock(hash);
 
        IP_VS_DBG_BUF(9, "template lookup/in %s %s:%d->%s:%d %s\n",
-                     ip_vs_proto_name(protocol),
-                     IP_VS_DBG_ADDR(af, s_addr), ntohs(s_port),
-                     IP_VS_DBG_ADDR(af, d_addr), ntohs(d_port),
+                     ip_vs_proto_name(p->protocol),
+                     IP_VS_DBG_ADDR(p->af, p->caddr), ntohs(p->cport),
+                     IP_VS_DBG_ADDR(p->af, p->vaddr), ntohs(p->vport),
                      cp ? "hit" : "not hit");
 
        return cp;
@@ -341,9 +351,7 @@ struct ip_vs_conn *ip_vs_ct_in_get
  *     s_addr, s_port: pkt source address (inside host)
  *     d_addr, d_port: pkt dest address (foreign host)
  */
-struct ip_vs_conn *ip_vs_conn_out_get
-(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port,
- const union nf_inet_addr *d_addr, __be16 d_port)
+struct ip_vs_conn *ip_vs_conn_out_get(const struct ip_vs_conn_param *p)
 {
        unsigned hash;
        struct ip_vs_conn *cp, *ret=NULL;
@@ -351,16 +359,16 @@ struct ip_vs_conn *ip_vs_conn_out_get
        /*
         *      Check for "full" addressed entries
         */
-       hash = ip_vs_conn_hashkey(af, protocol, d_addr, d_port);
+       hash = ip_vs_conn_hashkey(p->af, p->protocol, p->vaddr, p->vport);
 
        ct_read_lock(hash);
 
        list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) {
-               if (cp->af == af &&
-                   ip_vs_addr_equal(af, d_addr, &cp->caddr) &&
-                   ip_vs_addr_equal(af, s_addr, &cp->daddr) &&
-                   d_port == cp->cport && s_port == cp->dport &&
-                   protocol == cp->protocol) {
+               if (cp->af == p->af &&
+                   ip_vs_addr_equal(p->af, p->vaddr, &cp->caddr) &&
+                   ip_vs_addr_equal(p->af, p->caddr, &cp->daddr) &&
+                   p->vport == cp->cport && p->cport == cp->dport &&
+                   p->protocol == cp->protocol) {
                        /* HIT */
                        atomic_inc(&cp->refcnt);
                        ret = cp;
@@ -371,9 +379,9 @@ struct ip_vs_conn *ip_vs_conn_out_get
        ct_read_unlock(hash);
 
        IP_VS_DBG_BUF(9, "lookup/out %s %s:%d->%s:%d %s\n",
-                     ip_vs_proto_name(protocol),
-                     IP_VS_DBG_ADDR(af, s_addr), ntohs(s_port),
-                     IP_VS_DBG_ADDR(af, d_addr), ntohs(d_port),
+                     ip_vs_proto_name(p->protocol),
+                     IP_VS_DBG_ADDR(p->af, p->caddr), ntohs(p->cport),
+                     IP_VS_DBG_ADDR(p->af, p->vaddr), ntohs(p->vport),
                      ret ? "hit" : "not hit");
 
        return ret;
@@ -385,20 +393,12 @@ ip_vs_conn_out_get_proto(int af, const s
                         const struct ip_vs_iphdr *iph,
                         unsigned int proto_off, int inverse)
 {
-       __be16 _ports[2], *pptr;
+       struct ip_vs_conn_param p;
 
-       pptr = skb_header_pointer(skb, proto_off, sizeof(_ports), _ports);
-       if (pptr == NULL)
+       if (!ip_vs_conn_fill_param_proto(af, skb, iph, proto_off, inverse, &p))
                return NULL;
 
-       if (likely(!inverse))
-               return ip_vs_conn_out_get(af, iph->protocol,
-                                         &iph->saddr, pptr[0],
-                                         &iph->daddr, pptr[1]);
-       else
-               return ip_vs_conn_out_get(af, iph->protocol,
-                                         &iph->daddr, pptr[1],
-                                         &iph->saddr, pptr[0]);
+       return ip_vs_conn_out_get(&p);
 }
 EXPORT_SYMBOL_GPL(ip_vs_conn_out_get_proto);
 
@@ -758,13 +758,12 @@ void ip_vs_conn_expire_now(struct ip_vs_
  *     Create a new connection entry and hash it into the ip_vs_conn_tab
  */
 struct ip_vs_conn *
-ip_vs_conn_new(int af, int proto, const union nf_inet_addr *caddr, __be16 
cport,
-              const union nf_inet_addr *vaddr, __be16 vport,
+ip_vs_conn_new(const struct ip_vs_conn_param *p,
               const union nf_inet_addr *daddr, __be16 dport, unsigned flags,
               struct ip_vs_dest *dest)
 {
        struct ip_vs_conn *cp;
-       struct ip_vs_protocol *pp = ip_vs_proto_get(proto);
+       struct ip_vs_protocol *pp = ip_vs_proto_get(p->protocol);
 
        cp = kmem_cache_zalloc(ip_vs_conn_cachep, GFP_ATOMIC);
        if (cp == NULL) {
@@ -774,14 +773,14 @@ ip_vs_conn_new(int af, int proto, const
 
        INIT_LIST_HEAD(&cp->c_list);
        setup_timer(&cp->timer, ip_vs_conn_expire, (unsigned long)cp);
-       cp->af             = af;
-       cp->protocol       = proto;
-       ip_vs_addr_copy(af, &cp->caddr, caddr);
-       cp->cport          = cport;
-       ip_vs_addr_copy(af, &cp->vaddr, vaddr);
-       cp->vport          = vport;
+       cp->af             = p->af;
+       cp->protocol       = p->protocol;
+       ip_vs_addr_copy(p->af, &cp->caddr, p->caddr);
+       cp->cport          = p->cport;
+       ip_vs_addr_copy(p->af, &cp->vaddr, p->vaddr);
+       cp->vport          = p->vport;
        /* proto should only be IPPROTO_IP if d_addr is a fwmark */
-       ip_vs_addr_copy(proto == IPPROTO_IP ? AF_UNSPEC : af,
+       ip_vs_addr_copy(p->protocol == IPPROTO_IP ? AF_UNSPEC : p->af,
                        &cp->daddr, daddr);
        cp->dport          = dport;
        cp->flags          = flags;
@@ -810,7 +809,7 @@ ip_vs_conn_new(int af, int proto, const
 
        /* Bind its packet transmitter */
 #ifdef CONFIG_IP_VS_IPV6
-       if (af == AF_INET6)
+       if (p->af == AF_INET6)
                ip_vs_bind_xmit_v6(cp);
        else
 #endif
Index: lvs-test-2.6/net/netfilter/ipvs/ip_vs_core.c
===================================================================
--- lvs-test-2.6.orig/net/netfilter/ipvs/ip_vs_core.c   2010-10-01 
22:06:23.000000000 +0900
+++ lvs-test-2.6/net/netfilter/ipvs/ip_vs_core.c        2010-10-01 
22:10:46.000000000 +0900
@@ -193,14 +193,11 @@ ip_vs_sched_persist(struct ip_vs_service
        struct ip_vs_iphdr iph;
        struct ip_vs_dest *dest;
        struct ip_vs_conn *ct;
-       int protocol = iph.protocol;
        __be16 dport = 0;               /* destination port to forward */
-       __be16 vport = 0;               /* virtual service port */
        unsigned int flags;
        union nf_inet_addr snet;        /* source network of the client,
                                           after masking */
-       const union nf_inet_addr fwmark = { .ip = htonl(svc->fwmark) };
-       const union nf_inet_addr *vaddr = &iph.daddr;
+       struct ip_vs_conn_param param;
 
        ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph);
 
@@ -232,6 +229,11 @@ ip_vs_sched_persist(struct ip_vs_service
         * is created for other persistent services.
         */
        {
+               int protocol = iph.protocol;
+               const union nf_inet_addr *vaddr = &iph.daddr;
+               const union nf_inet_addr fwmark = { .ip = htonl(svc->fwmark) };
+               __be16 vport = 0;
+
                if (ports[1] == svc->port) {
                        /* non-FTP template:
                         * <protocol, caddr, 0, vaddr, vport, daddr, dport>
@@ -253,11 +255,12 @@ ip_vs_sched_persist(struct ip_vs_service
                                vaddr = &fwmark;
                        }
                }
+               ip_vs_conn_fill_param(svc->af, protocol, &snet, 0,
+                                     vaddr, vport, &param);
        }
 
        /* Check if a template already exists */
-       ct = ip_vs_ct_in_get(svc->af, protocol, &snet, 0, vaddr, vport);
-
+       ct = ip_vs_ct_in_get(&param);
        if (!ct || !ip_vs_check_template(ct)) {
                /* No template found or the dest of the connection
                 * template is not available.
@@ -272,8 +275,7 @@ ip_vs_sched_persist(struct ip_vs_service
                        dport = dest->port;
 
                /* Create a template */
-               ct = ip_vs_conn_new(svc->af, protocol, &snet, 0,vaddr, vport,
-                                   &dest->addr, dport,
+               ct = ip_vs_conn_new(&param, &dest->addr, dport,
                                    IP_VS_CONN_F_TEMPLATE, dest);
                if (ct == NULL)
                        return NULL;
@@ -291,12 +293,7 @@ ip_vs_sched_persist(struct ip_vs_service
        /*
         *    Create a new connection according to the template
         */
-       cp = ip_vs_conn_new(svc->af, iph.protocol,
-                           &iph.saddr, ports[0],
-                           &iph.daddr, ports[1],
-                           &dest->addr, dport,
-                           flags,
-                           dest);
+       cp = ip_vs_conn_new(&param, &dest->addr, dport, flags, dest);
        if (cp == NULL) {
                ip_vs_conn_put(ct);
                return NULL;
@@ -363,14 +360,16 @@ ip_vs_schedule(struct ip_vs_service *svc
        /*
         *    Create a connection entry.
         */
-       cp = ip_vs_conn_new(svc->af, iph.protocol,
-                           &iph.saddr, pptr[0],
-                           &iph.daddr, pptr[1],
-                           &dest->addr, dest->port ? dest->port : pptr[1],
-                           flags,
-                           dest);
-       if (cp == NULL)
-               return NULL;
+       {
+               struct ip_vs_conn_param p;
+               ip_vs_conn_fill_param(svc->af, iph.protocol, &iph.saddr,
+                                     pptr[0], &iph.daddr, pptr[1], &p);
+               cp = ip_vs_conn_new(&p, &dest->addr,
+                                   dest->port ? dest->port : pptr[1],
+                                   flags, dest);
+               if (!cp)
+                       return NULL;
+       }
 
        IP_VS_DBG_BUF(6, "Schedule fwd:%c c:%s:%u v:%s:%u "
                      "d:%s:%u conn->flags:%X conn->refcnt:%d\n",
@@ -426,14 +425,17 @@ int ip_vs_leave(struct ip_vs_service *sv
 
                /* create a new connection entry */
                IP_VS_DBG(6, "%s(): create a cache_bypass entry\n", __func__);
-               cp = ip_vs_conn_new(svc->af, iph.protocol,
-                                   &iph.saddr, pptr[0],
-                                   &iph.daddr, pptr[1],
-                                   &daddr, 0,
-                                   IP_VS_CONN_F_BYPASS | flags,
-                                   NULL);
-               if (cp == NULL)
-                       return NF_DROP;
+               {
+                       struct ip_vs_conn_param p;
+                       ip_vs_conn_fill_param(svc->af, iph.protocol,
+                                             &iph.saddr, pptr[0],
+                                             &iph.daddr, pptr[1], &p);
+                       cp = ip_vs_conn_new(&p, &daddr, 0,
+                                           IP_VS_CONN_F_BYPASS | flags,
+                                           NULL);
+                       if (!cp)
+                               return NF_DROP;
+               }
 
                /* statistics */
                ip_vs_in_stats(cp, skb);
Index: lvs-test-2.6/net/netfilter/ipvs/ip_vs_ftp.c
===================================================================
--- lvs-test-2.6.orig/net/netfilter/ipvs/ip_vs_ftp.c    2010-10-01 
22:14:10.000000000 +0900
+++ lvs-test-2.6/net/netfilter/ipvs/ip_vs_ftp.c 2010-10-01 22:21:09.000000000 
+0900
@@ -195,13 +195,17 @@ static int ip_vs_ftp_out(struct ip_vs_ap
                /*
                 * Now update or create an connection entry for it
                 */
-               n_cp = ip_vs_conn_out_get(AF_INET, iph->protocol, &from, port,
-                                         &cp->caddr, 0);
+               {
+                       struct ip_vs_conn_param p;
+                       ip_vs_conn_fill_param(AF_INET, iph->protocol,
+                                             &from, port, &cp->caddr, 0, &p);
+                       n_cp = ip_vs_conn_out_get(&p);
+               }
                if (!n_cp) {
-                       n_cp = ip_vs_conn_new(AF_INET, IPPROTO_TCP,
-                                             &cp->caddr, 0,
-                                             &cp->vaddr, port,
-                                             &from, port,
+                       struct ip_vs_conn_param p;
+                       ip_vs_conn_fill_param(AF_INET, IPPROTO_TCP, &cp->caddr,
+                                             0, &cp->vaddr, port, &p);
+                       n_cp = ip_vs_conn_new(&p, &from, port,
                                              IP_VS_CONN_F_NO_CPORT |
                                              IP_VS_CONN_F_NFCT,
                                              cp->dest);
@@ -347,21 +351,22 @@ static int ip_vs_ftp_in(struct ip_vs_app
                  ip_vs_proto_name(iph->protocol),
                  &to.ip, ntohs(port), &cp->vaddr.ip, 0);
 
-       n_cp = ip_vs_conn_in_get(AF_INET, iph->protocol,
-                                &to, port,
-                                &cp->vaddr, htons(ntohs(cp->vport)-1));
-       if (!n_cp) {
-               n_cp = ip_vs_conn_new(AF_INET, IPPROTO_TCP,
-                                     &to, port,
+       {
+               struct ip_vs_conn_param p;
+               ip_vs_conn_fill_param(AF_INET, iph->protocol, &to, port,
                                      &cp->vaddr, htons(ntohs(cp->vport)-1),
-                                     &cp->daddr, htons(ntohs(cp->dport)-1),
-                                     IP_VS_CONN_F_NFCT,
-                                     cp->dest);
-               if (!n_cp)
-                       return 0;
+                                     &p);
+               n_cp = ip_vs_conn_in_get(&p);
+               if (!n_cp) {
+                       n_cp = ip_vs_conn_new(&p, &cp->daddr,
+                                             htons(ntohs(cp->dport)-1),
+                                             IP_VS_CONN_F_NFCT, cp->dest);
+                       if (!n_cp)
+                               return 0;
 
-               /* add its controller */
-               ip_vs_control_add(n_cp, cp);
+                       /* add its controller */
+                       ip_vs_control_add(n_cp, cp);
+               }
        }
 
        /*
Index: lvs-test-2.6/net/netfilter/ipvs/ip_vs_nfct.c
===================================================================
--- lvs-test-2.6.orig/net/netfilter/ipvs/ip_vs_nfct.c   2010-10-01 
22:11:53.000000000 +0900
+++ lvs-test-2.6/net/netfilter/ipvs/ip_vs_nfct.c        2010-10-01 
22:24:29.000000000 +0900
@@ -140,6 +140,7 @@ static void ip_vs_nfct_expect_callback(s
 {
        struct nf_conntrack_tuple *orig, new_reply;
        struct ip_vs_conn *cp;
+       struct ip_vs_conn_param p;
 
        if (exp->tuple.src.l3num != PF_INET)
                return;
@@ -154,9 +155,10 @@ static void ip_vs_nfct_expect_callback(s
 
        /* RS->CLIENT */
        orig = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
-       cp = ip_vs_conn_out_get(exp->tuple.src.l3num, orig->dst.protonum,
-                               &orig->src.u3, orig->src.u.tcp.port,
-                               &orig->dst.u3, orig->dst.u.tcp.port);
+       ip_vs_conn_fill_param(exp->tuple.src.l3num, orig->dst.protonum,
+                             &orig->src.u3, orig->src.u.tcp.port,
+                             &orig->dst.u3, orig->dst.u.tcp.port, &p);
+       cp = ip_vs_conn_out_get(&p);
        if (cp) {
                /* Change reply CLIENT->RS to CLIENT->VS */
                new_reply = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
@@ -176,9 +178,7 @@ static void ip_vs_nfct_expect_callback(s
        }
 
        /* CLIENT->VS */
-       cp = ip_vs_conn_in_get(exp->tuple.src.l3num, orig->dst.protonum,
-                              &orig->src.u3, orig->src.u.tcp.port,
-                              &orig->dst.u3, orig->dst.u.tcp.port);
+       cp = ip_vs_conn_in_get(&p);
        if (cp) {
                /* Change reply VS->CLIENT to RS->CLIENT */
                new_reply = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
Index: lvs-test-2.6/net/netfilter/ipvs/ip_vs_proto_ah_esp.c
===================================================================
--- lvs-test-2.6.orig/net/netfilter/ipvs/ip_vs_proto_ah_esp.c   2010-10-01 
21:55:19.000000000 +0900
+++ lvs-test-2.6/net/netfilter/ipvs/ip_vs_proto_ah_esp.c        2010-10-01 
22:23:33.000000000 +0900
@@ -40,6 +40,19 @@ struct isakmp_hdr {
 
 #define PORT_ISAKMP    500
 
+static void
+ah_esp_conn_fill_param_proto(int af, const struct ip_vs_iphdr *iph,
+                            int inverse, struct ip_vs_conn_param *p)
+{
+       if (likely(!inverse))
+               ip_vs_conn_fill_param(af, IPPROTO_UDP,
+                                     &iph->saddr, htons(PORT_ISAKMP),
+                                     &iph->daddr, htons(PORT_ISAKMP), p);
+       else
+               ip_vs_conn_fill_param(af, iph->protocol,
+                                     &iph->saddr, htons(PORT_ISAKMP),
+                                     &iph->daddr, htons(PORT_ISAKMP), p);
+}
 
 static struct ip_vs_conn *
 ah_esp_conn_in_get(int af, const struct sk_buff *skb, struct ip_vs_protocol 
*pp,
@@ -47,21 +60,10 @@ ah_esp_conn_in_get(int af, const struct
                   int inverse)
 {
        struct ip_vs_conn *cp;
+       struct ip_vs_conn_param p;
 
-       if (likely(!inverse)) {
-               cp = ip_vs_conn_in_get(af, IPPROTO_UDP,
-                                      &iph->saddr,
-                                      htons(PORT_ISAKMP),
-                                      &iph->daddr,
-                                      htons(PORT_ISAKMP));
-       } else {
-               cp = ip_vs_conn_in_get(af, IPPROTO_UDP,
-                                      &iph->daddr,
-                                      htons(PORT_ISAKMP),
-                                      &iph->saddr,
-                                      htons(PORT_ISAKMP));
-       }
-
+       ah_esp_conn_fill_param_proto(af, iph, inverse, &p);
+       cp = ip_vs_conn_in_get(&p);
        if (!cp) {
                /*
                 * We are not sure if the packet is from our
@@ -87,21 +89,10 @@ ah_esp_conn_out_get(int af, const struct
                    int inverse)
 {
        struct ip_vs_conn *cp;
+       struct ip_vs_conn_param p;
 
-       if (likely(!inverse)) {
-               cp = ip_vs_conn_out_get(af, IPPROTO_UDP,
-                                       &iph->saddr,
-                                       htons(PORT_ISAKMP),
-                                       &iph->daddr,
-                                       htons(PORT_ISAKMP));
-       } else {
-               cp = ip_vs_conn_out_get(af, IPPROTO_UDP,
-                                       &iph->daddr,
-                                       htons(PORT_ISAKMP),
-                                       &iph->saddr,
-                                       htons(PORT_ISAKMP));
-       }
-
+       ah_esp_conn_fill_param_proto(af, iph, inverse, &p);
+       cp = ip_vs_conn_out_get(&p);
        if (!cp) {
                IP_VS_DBG_BUF(12, "Unknown ISAKMP entry for inout packet "
                              "%s%s %s->%s\n",
Index: lvs-test-2.6/net/netfilter/ipvs/ip_vs_sync.c
===================================================================
--- lvs-test-2.6.orig/net/netfilter/ipvs/ip_vs_sync.c   2010-10-01 
21:55:19.000000000 +0900
+++ lvs-test-2.6/net/netfilter/ipvs/ip_vs_sync.c        2010-10-01 
22:23:33.000000000 +0900
@@ -301,6 +301,7 @@ static void ip_vs_process_message(const
        struct ip_vs_conn *cp;
        struct ip_vs_protocol *pp;
        struct ip_vs_dest *dest;
+       struct ip_vs_conn_param param;
        char *p;
        int i;
 
@@ -370,18 +371,17 @@ static void ip_vs_process_message(const
                        }
                }
 
-               if (!(flags & IP_VS_CONN_F_TEMPLATE))
-                       cp = ip_vs_conn_in_get(AF_INET, s->protocol,
-                                              (union nf_inet_addr *)&s->caddr,
-                                              s->cport,
-                                              (union nf_inet_addr *)&s->vaddr,
-                                              s->vport);
-               else
-                       cp = ip_vs_ct_in_get(AF_INET, s->protocol,
-                                            (union nf_inet_addr *)&s->caddr,
-                                            s->cport,
-                                            (union nf_inet_addr *)&s->vaddr,
-                                            s->vport);
+               {
+                       ip_vs_conn_fill_param(AF_INET, s->protocol,
+                                             (union nf_inet_addr *)&s->caddr,
+                                             s->cport,
+                                             (union nf_inet_addr *)&s->vaddr,
+                                             s->vport, &param);
+                       if (!(flags & IP_VS_CONN_F_TEMPLATE))
+                               cp = ip_vs_conn_in_get(&param);
+                       else
+                               cp = ip_vs_ct_in_get(&param);
+               }
                if (!cp) {
                        /*
                         * Find the appropriate destination for the connection.
@@ -406,14 +406,9 @@ static void ip_vs_process_message(const
                                else
                                        flags &= ~IP_VS_CONN_F_INACTIVE;
                        }
-                       cp = ip_vs_conn_new(AF_INET, s->protocol,
-                                           (union nf_inet_addr *)&s->caddr,
-                                           s->cport,
-                                           (union nf_inet_addr *)&s->vaddr,
-                                           s->vport,
+                       cp = ip_vs_conn_new(&param,
                                            (union nf_inet_addr *)&s->daddr,
-                                           s->dport,
-                                           flags, dest);
+                                           s->dport, flags, dest);
                        if (dest)
                                atomic_dec(&dest->refcnt);
                        if (!cp) {
--
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>