Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 20971a0a authored by Julius Volz's avatar Julius Volz Committed by David S. Miller
Browse files

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: default avatarJulius Volz <julius.volz@gmail.com>
Acked-by: default avatarSimon Horman <horms@verge.net.au>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 2a6cf355
Loading
Loading
Loading
Loading
+21 −9
Original line number Original line Diff line number Diff line
@@ -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,
+21 −9
Original line number Original line Diff line number Diff line
@@ -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,