LVS
lvs-devel
Google
 
Web LinuxVirtualServer.org

Re: [PATCHv2 RFC 17/25] IPVS: Convert real server lookup functions

To: Julius Volz <juliusv@xxxxxxxxxx>
Subject: Re: [PATCHv2 RFC 17/25] IPVS: Convert real server lookup functions
Cc: netdev@xxxxxxxxxxxxxxx, lvs-devel@xxxxxxxxxxxxxxx, kaber@xxxxxxxxx, vbusam@xxxxxxxxxx
From: Simon Horman <horms@xxxxxxxxxxxx>
Date: Tue, 2 Sep 2008 17:46:37 +1000
On Mon, Sep 01, 2008 at 02:56:14PM +0200, Julius Volz wrote:
> Convert functions for looking up destinations (real servers) to support
> IPv6 services/dests.
> 
> Signed-off-by: Julius Volz <juliusv@xxxxxxxxxx>
> 
>  5 files changed, 66 insertions(+), 37 deletions(-)
> 
> diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
> index a7eda08..c163c18 100644
> --- a/include/net/ip_vs.h
> +++ b/include/net/ip_vs.h
> @@ -804,14 +804,16 @@ static inline void ip_vs_service_put(struct 
> ip_vs_service *svc)
>  }
>  
>  extern struct ip_vs_dest *
> -ip_vs_lookup_real_service(__u16 protocol, __be32 daddr, __be16 dport);
> +ip_vs_lookup_real_service(int af, __u16 protocol,
> +                       const union nf_inet_addr *daddr, __be16 dport);
> +
>  extern int ip_vs_use_count_inc(void);
>  extern void ip_vs_use_count_dec(void);
>  extern int ip_vs_control_init(void);
>  extern void ip_vs_control_cleanup(void);
>  extern struct ip_vs_dest *
> -ip_vs_find_dest(__be32 daddr, __be16 dport,
> -              __be32 vaddr, __be16 vport, __u16 protocol);
> +ip_vs_find_dest(int af, const union nf_inet_addr *daddr, __be16 dport,
> +             const union nf_inet_addr *vaddr, __be16 vport, __u16 protocol);
>  extern struct ip_vs_dest *ip_vs_try_bind_dest(struct ip_vs_conn *cp);
>  
>  
> diff --git a/net/ipv4/ipvs/ip_vs_conn.c b/net/ipv4/ipvs/ip_vs_conn.c
> index 814d416..2f5c4d8 100644
> --- a/net/ipv4/ipvs/ip_vs_conn.c
> +++ b/net/ipv4/ipvs/ip_vs_conn.c
> @@ -490,8 +490,9 @@ struct ip_vs_dest *ip_vs_try_bind_dest(struct ip_vs_conn 
> *cp)
>       struct ip_vs_dest *dest;
>  
>       if ((cp) && (!cp->dest)) {
> -             dest = ip_vs_find_dest(cp->daddr.ip, cp->dport,
> -                                    cp->vaddr.ip, cp->vport, cp->protocol);
> +             dest = ip_vs_find_dest(cp->af, &cp->daddr, cp->dport,
> +                                    &cp->vaddr, cp->vport,
> +                                    cp->protocol);
>               ip_vs_bind_dest(cp, dest);
>               return dest;
>       } else
> diff --git a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c
> index 0bf871c..2725b93 100644
> --- a/net/ipv4/ipvs/ip_vs_core.c
> +++ b/net/ipv4/ipvs/ip_vs_core.c
> @@ -956,8 +956,8 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb,
>                                                 sizeof(_ports), _ports);
>                       if (pptr == NULL)
>                               return NF_ACCEPT;       /* Not for me */
> -                     if (ip_vs_lookup_real_service(iph.protocol,
> -                                                   iph.saddr.ip,
> +                     if (ip_vs_lookup_real_service(af, iph.protocol,
> +                                                   &iph.saddr,
>                                                     pptr[0])) {
>                               /*
>                                * Notify the real server: there is no
> diff --git a/net/ipv4/ipvs/ip_vs_ctl.c b/net/ipv4/ipvs/ip_vs_ctl.c
> index 151d368..3dae1d9 100644
> --- a/net/ipv4/ipvs/ip_vs_ctl.c
> +++ b/net/ipv4/ipvs/ip_vs_ctl.c
> @@ -492,11 +492,20 @@ __ip_vs_unbind_svc(struct ip_vs_dest *dest)
>  /*
>   *   Returns hash value for real service
>   */
> -static __inline__ unsigned ip_vs_rs_hashkey(__be32 addr, __be16 port)
> +static __inline__ unsigned ip_vs_rs_hashkey(int af,
> +                                         const union nf_inet_addr *addr,
> +                                         __be16 port)
>  {
>       register unsigned porth = ntohs(port);
> +     __be32 addr_fold = addr->ip;
> +
> +#ifdef CONFIG_IP_VS_IPV6
> +     if (af == AF_INET6)
> +             addr_fold = addr->ip6[0]^addr->ip6[1]^
> +                         addr->ip6[2]^addr->ip6[3];
> +#endif
>  
> -     return (ntohl(addr)^(porth>>IP_VS_RTAB_BITS)^porth)
> +     return (ntohl(addr_fold)^(porth>>IP_VS_RTAB_BITS)^porth)
>               & IP_VS_RTAB_MASK;
>  }
>  
> @@ -516,7 +525,8 @@ static int ip_vs_rs_hash(struct ip_vs_dest *dest)
>        *      Hash by proto,addr,port,
>        *      which are the parameters of the real service.
>        */
> -     hash = ip_vs_rs_hashkey(dest->addr.ip, dest->port);
> +     hash = ip_vs_rs_hashkey(dest->af, &dest->addr, dest->port);
> +
>       list_add(&dest->d_list, &ip_vs_rtable[hash]);
>  
>       return 1;
> @@ -543,7 +553,9 @@ static int ip_vs_rs_unhash(struct ip_vs_dest *dest)
>   *   Lookup real service by <proto,addr,port> in the real service table.
>   */
>  struct ip_vs_dest *
> -ip_vs_lookup_real_service(__u16 protocol, __be32 daddr, __be16 dport)
> +ip_vs_lookup_real_service(int af, __u16 protocol,
> +                       const union nf_inet_addr *daddr,
> +                       __be16 dport)
>  {
>       unsigned hash;
>       struct ip_vs_dest *dest;
> @@ -552,11 +564,12 @@ ip_vs_lookup_real_service(__u16 protocol, __be32 daddr, 
> __be16 dport)
>        *      Check for "full" addressed entries
>        *      Return the first found entry
>        */
> -     hash = ip_vs_rs_hashkey(daddr, dport);
> +     hash = ip_vs_rs_hashkey(af, daddr, dport);
>  
>       read_lock(&__ip_vs_rs_lock);
>       list_for_each_entry(dest, &ip_vs_rtable[hash], d_list) {
> -             if ((dest->addr.ip == daddr)
> +             if ((dest->af == af)
> +                 && ip_vs_addr_equal(af, &dest->addr, daddr)
>                   && (dest->port == dport)
>                   && ((dest->protocol == protocol) ||
>                       dest->vfwmark)) {
> @@ -574,7 +587,8 @@ ip_vs_lookup_real_service(__u16 protocol, __be32 daddr, 
> __be16 dport)
>   *   Lookup destination by {addr,port} in the given service
>   */
>  static struct ip_vs_dest *
> -ip_vs_lookup_dest(struct ip_vs_service *svc, __be32 daddr, __be16 dport)
> +ip_vs_lookup_dest(struct ip_vs_service *svc, const union nf_inet_addr *daddr,
> +               __be16 dport)
>  {
>       struct ip_vs_dest *dest;
>  
> @@ -582,7 +596,9 @@ ip_vs_lookup_dest(struct ip_vs_service *svc, __be32 
> daddr, __be16 dport)
>        * Find the destination for the given service
>        */
>       list_for_each_entry(dest, &svc->destinations, n_list) {
> -             if ((dest->addr.ip == daddr) && (dest->port == dport)) {
> +             if ((dest->af == svc->af)
> +                 && ip_vs_addr_equal(svc->af, &dest->addr, daddr)
> +                 && (dest->port == dport)) {
>                       /* HIT */
>                       return dest;
>               }
> @@ -601,14 +617,14 @@ ip_vs_lookup_dest(struct ip_vs_service *svc, __be32 
> daddr, __be16 dport)
>   * ip_vs_lookup_real_service() looked promissing, but
>   * seems not working as expected.
>   */
> -struct ip_vs_dest *ip_vs_find_dest(__be32 daddr, __be16 dport,
> -                                 __be32 vaddr, __be16 vport, __u16 protocol)
> +struct ip_vs_dest *ip_vs_find_dest(int af, const union nf_inet_addr *daddr,
> +                                __be16 dport, const union nf_inet_addr 
> *vaddr,

Please split the line above.

> +                                __be16 vport, __u16 protocol)
>  {
>       struct ip_vs_dest *dest;
>       struct ip_vs_service *svc;
> -     union nf_inet_addr _vaddr = { .ip = vaddr };
>  
> -     svc = ip_vs_service_get(AF_INET, 0, protocol, &_vaddr, vport);
> +     svc = ip_vs_service_get(af, 0, protocol, vaddr, vport);
>       if (!svc)
>               return NULL;
>       dest = ip_vs_lookup_dest(svc, daddr, dport);
> @@ -629,7 +645,8 @@ struct ip_vs_dest *ip_vs_find_dest(__be32 daddr, __be16 
> dport,
>   *  scheduling.
>   */
>  static struct ip_vs_dest *
> -ip_vs_trash_get_dest(struct ip_vs_service *svc, __be32 daddr, __be16 dport)
> +ip_vs_trash_get_dest(struct ip_vs_service *svc, const union nf_inet_addr 
> *daddr,
> +                  __be16 dport)
>  {
>       struct ip_vs_dest *dest, *nxt;
>  
> @@ -637,17 +654,19 @@ ip_vs_trash_get_dest(struct ip_vs_service *svc, __be32 
> daddr, __be16 dport)
>        * Find the destination in trash
>        */
>       list_for_each_entry_safe(dest, nxt, &ip_vs_dest_trash, n_list) {
> -             IP_VS_DBG(3, "Destination %u/%u.%u.%u.%u:%u still in trash, "
> -                       "dest->refcnt=%d\n",
> -                       dest->vfwmark,
> -                       NIPQUAD(dest->addr.ip), ntohs(dest->port),
> -                       atomic_read(&dest->refcnt));
> -             if (dest->addr.ip == daddr &&
> +             IP_VS_DBG_BUF(3, "Destination %u/%s:%u still in trash, "
> +                           "dest->refcnt=%d\n",
> +                           dest->vfwmark,
> +                           IP_VS_DBG_ADDR(svc->af, &dest->addr),
> +                           ntohs(dest->port),
> +                           atomic_read(&dest->refcnt));
> +             if (dest->af == svc->af &&
> +                 ip_vs_addr_equal(svc->af, &dest->addr, daddr) &&
>                   dest->port == dport &&
>                   dest->vfwmark == svc->fwmark &&
>                   dest->protocol == svc->protocol &&
>                   (svc->fwmark ||
> -                  (dest->vaddr.ip == svc->addr.ip &&
> +                  (ip_vs_addr_equal(svc->af, &dest->vaddr, &svc->addr) &&
>                     dest->vport == svc->port))) {
>                       /* HIT */
>                       return dest;
> @@ -657,10 +676,11 @@ ip_vs_trash_get_dest(struct ip_vs_service *svc, __be32 
> daddr, __be16 dport)
>                * Try to purge the destination from trash if not referenced
>                */
>               if (atomic_read(&dest->refcnt) == 1) {
> -                     IP_VS_DBG(3, "Removing destination %u/%u.%u.%u.%u:%u "
> -                               "from trash\n",
> -                               dest->vfwmark,
> -                               NIPQUAD(dest->addr.ip), ntohs(dest->port));
> +                     IP_VS_DBG_BUF(3, "Removing destination %u/%s:%u "
> +                                   "from trash\n",
> +                                   dest->vfwmark,
> +                                   IP_VS_DBG_ADDR(svc->af, &dest->addr),
> +                                   ntohs(dest->port));
>                       list_del(&dest->n_list);
>                       ip_vs_dst_reset(dest);
>                       __ip_vs_unbind_svc(dest);
> @@ -847,7 +867,8 @@ ip_vs_add_dest(struct ip_vs_service *svc, struct 
> ip_vs_dest_user_kern *udest)
>       /*
>        * Check if the dest already exists in the list
>        */
> -     dest = ip_vs_lookup_dest(svc, daddr.ip, dport);
> +     dest = ip_vs_lookup_dest(svc, &daddr, dport);
> +
>       if (dest != NULL) {
>               IP_VS_DBG(1, "ip_vs_add_dest(): dest already exists\n");
>               return -EEXIST;
> @@ -857,7 +878,8 @@ ip_vs_add_dest(struct ip_vs_service *svc, struct 
> ip_vs_dest_user_kern *udest)
>        * Check if the dest already exists in the trash and
>        * is from the same service
>        */
> -     dest = ip_vs_trash_get_dest(svc, daddr.ip, dport);
> +     dest = ip_vs_trash_get_dest(svc, &daddr, dport);
> +
>       if (dest != NULL) {
>               IP_VS_DBG(3, "Get destination %u.%u.%u.%u:%u from trash, "
>                         "dest->refcnt=%d, service %u/%u.%u.%u.%u:%u\n",
> @@ -956,7 +978,8 @@ ip_vs_edit_dest(struct ip_vs_service *svc, struct 
> ip_vs_dest_user_kern *udest)
>       /*
>        *  Lookup the destination list
>        */
> -     dest = ip_vs_lookup_dest(svc, daddr.ip, dport);
> +     dest = ip_vs_lookup_dest(svc, &daddr, dport);
> +
>       if (dest == NULL) {
>               IP_VS_DBG(1, "ip_vs_edit_dest(): dest doesn't exist\n");
>               return -ENOENT;
> @@ -1054,7 +1077,7 @@ ip_vs_del_dest(struct ip_vs_service *svc, struct 
> ip_vs_dest_user_kern *udest)
>  
>       EnterFunction(2);
>  
> -     dest = ip_vs_lookup_dest(svc, udest->addr.ip, dport);
> +     dest = ip_vs_lookup_dest(svc, &udest->addr, dport);
>  
>       if (dest == NULL) {
>               IP_VS_DBG(1, "ip_vs_del_dest(): destination not found!\n");
> diff --git a/net/ipv4/ipvs/ip_vs_sync.c b/net/ipv4/ipvs/ip_vs_sync.c
> index 3ce1093..40647ed 100644
> --- a/net/ipv4/ipvs/ip_vs_sync.c
> +++ b/net/ipv4/ipvs/ip_vs_sync.c
> @@ -383,8 +383,11 @@ static void ip_vs_process_message(const char *buffer, 
> const size_t buflen)
>                        * If it is not found the connection will remain unbound
>                        * but still handled.
>                        */
> -                     dest = ip_vs_find_dest(s->daddr, s->dport,
> -                                            s->vaddr, s->vport,
> +                     dest = ip_vs_find_dest(AF_INET,
> +                                            (union nf_inet_addr *)&s->daddr,
> +                                            s->dport,
> +                                            (union nf_inet_addr *)&s->vaddr,
> +                                            s->vport,
>                                              s->protocol);
>                       /*  Set the approprite ativity flag */
>                       if (s->protocol == IPPROTO_TCP) {
> -- 
> 1.5.4.5
--
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>