[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20080902074635.GI13730@verge.net.au>
Date: Tue, 2 Sep 2008 17:46:37 +1000
From: Simon Horman <horms@...ge.net.au>
To: Julius Volz <juliusv@...gle.com>
Cc: netdev@...r.kernel.org, lvs-devel@...r.kernel.org, kaber@...sh.net,
vbusam@...gle.com
Subject: Re: [PATCHv2 RFC 17/25] IPVS: Convert real server lookup functions
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@...gle.com>
>
> 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 netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists