IPVS: Add IPv6 support to SH and DH schedulers
Add IPv6 support to SH and DH schedulers. I hope this simple IPv6 address hashing is good enough. The 128 bit are just XORed into 32 before hashing them like an IPv4 address. Signed-off-by: Julius Volz <julius.volz@gmail.com> Acked-by: Simon Horman <horms@verge.net.au> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
2a6cf35543
commit
20971a0afb
@ -64,9 +64,16 @@ struct ip_vs_dh_bucket {
|
|||||||
/*
|
/*
|
||||||
* Returns hash value for IPVS DH entry
|
* Returns hash value for IPVS DH entry
|
||||||
*/
|
*/
|
||||||
static inline unsigned ip_vs_dh_hashkey(__be32 addr)
|
static inline unsigned ip_vs_dh_hashkey(int af, const union nf_inet_addr *addr)
|
||||||
{
|
{
|
||||||
return (ntohl(addr)*2654435761UL) & IP_VS_DH_TAB_MASK;
|
__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_fold)*2654435761UL) & IP_VS_DH_TAB_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -74,9 +81,10 @@ static inline unsigned ip_vs_dh_hashkey(__be32 addr)
|
|||||||
* Get ip_vs_dest associated with supplied parameters.
|
* Get ip_vs_dest associated with supplied parameters.
|
||||||
*/
|
*/
|
||||||
static inline struct ip_vs_dest *
|
static inline struct ip_vs_dest *
|
||||||
ip_vs_dh_get(struct ip_vs_dh_bucket *tbl, __be32 addr)
|
ip_vs_dh_get(int af, struct ip_vs_dh_bucket *tbl,
|
||||||
|
const union nf_inet_addr *addr)
|
||||||
{
|
{
|
||||||
return (tbl[ip_vs_dh_hashkey(addr)]).dest;
|
return (tbl[ip_vs_dh_hashkey(af, addr)]).dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -202,12 +210,14 @@ ip_vs_dh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
|
|||||||
{
|
{
|
||||||
struct ip_vs_dest *dest;
|
struct ip_vs_dest *dest;
|
||||||
struct ip_vs_dh_bucket *tbl;
|
struct ip_vs_dh_bucket *tbl;
|
||||||
struct iphdr *iph = ip_hdr(skb);
|
struct ip_vs_iphdr iph;
|
||||||
|
|
||||||
|
ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph);
|
||||||
|
|
||||||
IP_VS_DBG(6, "ip_vs_dh_schedule(): Scheduling...\n");
|
IP_VS_DBG(6, "ip_vs_dh_schedule(): Scheduling...\n");
|
||||||
|
|
||||||
tbl = (struct ip_vs_dh_bucket *)svc->sched_data;
|
tbl = (struct ip_vs_dh_bucket *)svc->sched_data;
|
||||||
dest = ip_vs_dh_get(tbl, iph->daddr);
|
dest = ip_vs_dh_get(svc->af, tbl, &iph.daddr);
|
||||||
if (!dest
|
if (!dest
|
||||||
|| !(dest->flags & IP_VS_DEST_F_AVAILABLE)
|
|| !(dest->flags & IP_VS_DEST_F_AVAILABLE)
|
||||||
|| atomic_read(&dest->weight) <= 0
|
|| atomic_read(&dest->weight) <= 0
|
||||||
@ -215,8 +225,10 @@ ip_vs_dh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
IP_VS_DBG(6, "DH: destination IP address %pI4 --> server %pI4:%d\n",
|
IP_VS_DBG_BUF(6, "DH: destination IP address %s --> server %s:%d\n",
|
||||||
&iph->daddr, &dest->addr.ip, ntohs(dest->port));
|
IP_VS_DBG_ADDR(svc->af, &iph.daddr),
|
||||||
|
IP_VS_DBG_ADDR(svc->af, &dest->addr),
|
||||||
|
ntohs(dest->port));
|
||||||
|
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
@ -232,7 +244,7 @@ static struct ip_vs_scheduler ip_vs_dh_scheduler =
|
|||||||
.module = THIS_MODULE,
|
.module = THIS_MODULE,
|
||||||
.n_list = LIST_HEAD_INIT(ip_vs_dh_scheduler.n_list),
|
.n_list = LIST_HEAD_INIT(ip_vs_dh_scheduler.n_list),
|
||||||
#ifdef CONFIG_IP_VS_IPV6
|
#ifdef CONFIG_IP_VS_IPV6
|
||||||
.supports_ipv6 = 0,
|
.supports_ipv6 = 1,
|
||||||
#endif
|
#endif
|
||||||
.init_service = ip_vs_dh_init_svc,
|
.init_service = ip_vs_dh_init_svc,
|
||||||
.done_service = ip_vs_dh_done_svc,
|
.done_service = ip_vs_dh_done_svc,
|
||||||
|
@ -61,9 +61,16 @@ struct ip_vs_sh_bucket {
|
|||||||
/*
|
/*
|
||||||
* Returns hash value for IPVS SH entry
|
* Returns hash value for IPVS SH entry
|
||||||
*/
|
*/
|
||||||
static inline unsigned ip_vs_sh_hashkey(__be32 addr)
|
static inline unsigned ip_vs_sh_hashkey(int af, const union nf_inet_addr *addr)
|
||||||
{
|
{
|
||||||
return (ntohl(addr)*2654435761UL) & IP_VS_SH_TAB_MASK;
|
__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_fold)*2654435761UL) & IP_VS_SH_TAB_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -71,9 +78,10 @@ static inline unsigned ip_vs_sh_hashkey(__be32 addr)
|
|||||||
* Get ip_vs_dest associated with supplied parameters.
|
* Get ip_vs_dest associated with supplied parameters.
|
||||||
*/
|
*/
|
||||||
static inline struct ip_vs_dest *
|
static inline struct ip_vs_dest *
|
||||||
ip_vs_sh_get(struct ip_vs_sh_bucket *tbl, __be32 addr)
|
ip_vs_sh_get(int af, struct ip_vs_sh_bucket *tbl,
|
||||||
|
const union nf_inet_addr *addr)
|
||||||
{
|
{
|
||||||
return (tbl[ip_vs_sh_hashkey(addr)]).dest;
|
return (tbl[ip_vs_sh_hashkey(af, addr)]).dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -199,12 +207,14 @@ ip_vs_sh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
|
|||||||
{
|
{
|
||||||
struct ip_vs_dest *dest;
|
struct ip_vs_dest *dest;
|
||||||
struct ip_vs_sh_bucket *tbl;
|
struct ip_vs_sh_bucket *tbl;
|
||||||
struct iphdr *iph = ip_hdr(skb);
|
struct ip_vs_iphdr iph;
|
||||||
|
|
||||||
|
ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph);
|
||||||
|
|
||||||
IP_VS_DBG(6, "ip_vs_sh_schedule(): Scheduling...\n");
|
IP_VS_DBG(6, "ip_vs_sh_schedule(): Scheduling...\n");
|
||||||
|
|
||||||
tbl = (struct ip_vs_sh_bucket *)svc->sched_data;
|
tbl = (struct ip_vs_sh_bucket *)svc->sched_data;
|
||||||
dest = ip_vs_sh_get(tbl, iph->saddr);
|
dest = ip_vs_sh_get(svc->af, tbl, &iph.saddr);
|
||||||
if (!dest
|
if (!dest
|
||||||
|| !(dest->flags & IP_VS_DEST_F_AVAILABLE)
|
|| !(dest->flags & IP_VS_DEST_F_AVAILABLE)
|
||||||
|| atomic_read(&dest->weight) <= 0
|
|| atomic_read(&dest->weight) <= 0
|
||||||
@ -212,8 +222,10 @@ ip_vs_sh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
IP_VS_DBG(6, "SH: source IP address %pI4 --> server %pI4:%d\n",
|
IP_VS_DBG_BUF(6, "SH: source IP address %s --> server %s:%d\n",
|
||||||
&iph->saddr, &dest->addr.ip, ntohs(dest->port));
|
IP_VS_DBG_ADDR(svc->af, &iph.saddr),
|
||||||
|
IP_VS_DBG_ADDR(svc->af, &dest->addr),
|
||||||
|
ntohs(dest->port));
|
||||||
|
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
@ -229,7 +241,7 @@ static struct ip_vs_scheduler ip_vs_sh_scheduler =
|
|||||||
.module = THIS_MODULE,
|
.module = THIS_MODULE,
|
||||||
.n_list = LIST_HEAD_INIT(ip_vs_sh_scheduler.n_list),
|
.n_list = LIST_HEAD_INIT(ip_vs_sh_scheduler.n_list),
|
||||||
#ifdef CONFIG_IP_VS_IPV6
|
#ifdef CONFIG_IP_VS_IPV6
|
||||||
.supports_ipv6 = 0,
|
.supports_ipv6 = 1,
|
||||||
#endif
|
#endif
|
||||||
.init_service = ip_vs_sh_init_svc,
|
.init_service = ip_vs_sh_init_svc,
|
||||||
.done_service = ip_vs_sh_done_svc,
|
.done_service = ip_vs_sh_done_svc,
|
||||||
|
Loading…
Reference in New Issue
Block a user