aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter
diff options
context:
space:
mode:
authorJulius Volz <julius.volz@gmail.com>2008-11-01 09:13:19 -0400
committerDavid S. Miller <davem@davemloft.net>2008-11-03 02:52:01 -0500
commit20971a0afb8bc0eeb6865ceadd435e4a2dba0fd7 (patch)
tree2d53792b5f141608e7a7fcb018a252c1f3e70c88 /net/netfilter
parent2a6cf35543302e9a5c807eaf13298f510fbdf8f2 (diff)
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>
Diffstat (limited to 'net/netfilter')
-rw-r--r--net/netfilter/ipvs/ip_vs_dh.c30
-rw-r--r--net/netfilter/ipvs/ip_vs_sh.c30
2 files changed, 42 insertions, 18 deletions
diff --git a/net/netfilter/ipvs/ip_vs_dh.c b/net/netfilter/ipvs/ip_vs_dh.c
index 77179b913be0..d8258e0cb58c 100644
--- a/net/netfilter/ipvs/ip_vs_dh.c
+++ b/net/netfilter/ipvs/ip_vs_dh.c
@@ -64,9 +64,16 @@ struct ip_vs_dh_bucket {
64/* 64/*
65 * Returns hash value for IPVS DH entry 65 * Returns hash value for IPVS DH entry
66 */ 66 */
67static inline unsigned ip_vs_dh_hashkey(__be32 addr) 67static inline unsigned ip_vs_dh_hashkey(int af, const union nf_inet_addr *addr)
68{ 68{
69 return (ntohl(addr)*2654435761UL) & IP_VS_DH_TAB_MASK; 69 __be32 addr_fold = addr->ip;
70
71#ifdef CONFIG_IP_VS_IPV6
72 if (af == AF_INET6)
73 addr_fold = addr->ip6[0]^addr->ip6[1]^
74 addr->ip6[2]^addr->ip6[3];
75#endif
76 return (ntohl(addr_fold)*2654435761UL) & IP_VS_DH_TAB_MASK;
70} 77}
71 78
72 79
@@ -74,9 +81,10 @@ static inline unsigned ip_vs_dh_hashkey(__be32 addr)
74 * Get ip_vs_dest associated with supplied parameters. 81 * Get ip_vs_dest associated with supplied parameters.
75 */ 82 */
76static inline struct ip_vs_dest * 83static inline struct ip_vs_dest *
77ip_vs_dh_get(struct ip_vs_dh_bucket *tbl, __be32 addr) 84ip_vs_dh_get(int af, struct ip_vs_dh_bucket *tbl,
85 const union nf_inet_addr *addr)
78{ 86{
79 return (tbl[ip_vs_dh_hashkey(addr)]).dest; 87 return (tbl[ip_vs_dh_hashkey(af, addr)]).dest;
80} 88}
81 89
82 90
@@ -202,12 +210,14 @@ ip_vs_dh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
202{ 210{
203 struct ip_vs_dest *dest; 211 struct ip_vs_dest *dest;
204 struct ip_vs_dh_bucket *tbl; 212 struct ip_vs_dh_bucket *tbl;
205 struct iphdr *iph = ip_hdr(skb); 213 struct ip_vs_iphdr iph;
214
215 ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph);
206 216
207 IP_VS_DBG(6, "ip_vs_dh_schedule(): Scheduling...\n"); 217 IP_VS_DBG(6, "ip_vs_dh_schedule(): Scheduling...\n");
208 218
209 tbl = (struct ip_vs_dh_bucket *)svc->sched_data; 219 tbl = (struct ip_vs_dh_bucket *)svc->sched_data;
210 dest = ip_vs_dh_get(tbl, iph->daddr); 220 dest = ip_vs_dh_get(svc->af, tbl, &iph.daddr);
211 if (!dest 221 if (!dest
212 || !(dest->flags & IP_VS_DEST_F_AVAILABLE) 222 || !(dest->flags & IP_VS_DEST_F_AVAILABLE)
213 || atomic_read(&dest->weight) <= 0 223 || atomic_read(&dest->weight) <= 0
@@ -215,8 +225,10 @@ ip_vs_dh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
215 return NULL; 225 return NULL;
216 } 226 }
217 227
218 IP_VS_DBG(6, "DH: destination IP address %pI4 --> server %pI4:%d\n", 228 IP_VS_DBG_BUF(6, "DH: destination IP address %s --> server %s:%d\n",
219 &iph->daddr, &dest->addr.ip, ntohs(dest->port)); 229 IP_VS_DBG_ADDR(svc->af, &iph.daddr),
230 IP_VS_DBG_ADDR(svc->af, &dest->addr),
231 ntohs(dest->port));
220 232
221 return dest; 233 return dest;
222} 234}
@@ -232,7 +244,7 @@ static struct ip_vs_scheduler ip_vs_dh_scheduler =
232 .module = THIS_MODULE, 244 .module = THIS_MODULE,
233 .n_list = LIST_HEAD_INIT(ip_vs_dh_scheduler.n_list), 245 .n_list = LIST_HEAD_INIT(ip_vs_dh_scheduler.n_list),
234#ifdef CONFIG_IP_VS_IPV6 246#ifdef CONFIG_IP_VS_IPV6
235 .supports_ipv6 = 0, 247 .supports_ipv6 = 1,
236#endif 248#endif
237 .init_service = ip_vs_dh_init_svc, 249 .init_service = ip_vs_dh_init_svc,
238 .done_service = ip_vs_dh_done_svc, 250 .done_service = ip_vs_dh_done_svc,
diff --git a/net/netfilter/ipvs/ip_vs_sh.c b/net/netfilter/ipvs/ip_vs_sh.c
index be5863cb4723..4074ccf49208 100644
--- a/net/netfilter/ipvs/ip_vs_sh.c
+++ b/net/netfilter/ipvs/ip_vs_sh.c
@@ -61,9 +61,16 @@ struct ip_vs_sh_bucket {
61/* 61/*
62 * Returns hash value for IPVS SH entry 62 * Returns hash value for IPVS SH entry
63 */ 63 */
64static inline unsigned ip_vs_sh_hashkey(__be32 addr) 64static inline unsigned ip_vs_sh_hashkey(int af, const union nf_inet_addr *addr)
65{ 65{
66 return (ntohl(addr)*2654435761UL) & IP_VS_SH_TAB_MASK; 66 __be32 addr_fold = addr->ip;
67
68#ifdef CONFIG_IP_VS_IPV6
69 if (af == AF_INET6)
70 addr_fold = addr->ip6[0]^addr->ip6[1]^
71 addr->ip6[2]^addr->ip6[3];
72#endif
73 return (ntohl(addr_fold)*2654435761UL) & IP_VS_SH_TAB_MASK;
67} 74}
68 75
69 76
@@ -71,9 +78,10 @@ static inline unsigned ip_vs_sh_hashkey(__be32 addr)
71 * Get ip_vs_dest associated with supplied parameters. 78 * Get ip_vs_dest associated with supplied parameters.
72 */ 79 */
73static inline struct ip_vs_dest * 80static inline struct ip_vs_dest *
74ip_vs_sh_get(struct ip_vs_sh_bucket *tbl, __be32 addr) 81ip_vs_sh_get(int af, struct ip_vs_sh_bucket *tbl,
82 const union nf_inet_addr *addr)
75{ 83{
76 return (tbl[ip_vs_sh_hashkey(addr)]).dest; 84 return (tbl[ip_vs_sh_hashkey(af, addr)]).dest;
77} 85}
78 86
79 87
@@ -199,12 +207,14 @@ ip_vs_sh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
199{ 207{
200 struct ip_vs_dest *dest; 208 struct ip_vs_dest *dest;
201 struct ip_vs_sh_bucket *tbl; 209 struct ip_vs_sh_bucket *tbl;
202 struct iphdr *iph = ip_hdr(skb); 210 struct ip_vs_iphdr iph;
211
212 ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph);
203 213
204 IP_VS_DBG(6, "ip_vs_sh_schedule(): Scheduling...\n"); 214 IP_VS_DBG(6, "ip_vs_sh_schedule(): Scheduling...\n");
205 215
206 tbl = (struct ip_vs_sh_bucket *)svc->sched_data; 216 tbl = (struct ip_vs_sh_bucket *)svc->sched_data;
207 dest = ip_vs_sh_get(tbl, iph->saddr); 217 dest = ip_vs_sh_get(svc->af, tbl, &iph.saddr);
208 if (!dest 218 if (!dest
209 || !(dest->flags & IP_VS_DEST_F_AVAILABLE) 219 || !(dest->flags & IP_VS_DEST_F_AVAILABLE)
210 || atomic_read(&dest->weight) <= 0 220 || atomic_read(&dest->weight) <= 0
@@ -212,8 +222,10 @@ ip_vs_sh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
212 return NULL; 222 return NULL;
213 } 223 }
214 224
215 IP_VS_DBG(6, "SH: source IP address %pI4 --> server %pI4:%d\n", 225 IP_VS_DBG_BUF(6, "SH: source IP address %s --> server %s:%d\n",
216 &iph->saddr, &dest->addr.ip, ntohs(dest->port)); 226 IP_VS_DBG_ADDR(svc->af, &iph.saddr),
227 IP_VS_DBG_ADDR(svc->af, &dest->addr),
228 ntohs(dest->port));
217 229
218 return dest; 230 return dest;
219} 231}
@@ -229,7 +241,7 @@ static struct ip_vs_scheduler ip_vs_sh_scheduler =
229 .module = THIS_MODULE, 241 .module = THIS_MODULE,
230 .n_list = LIST_HEAD_INIT(ip_vs_sh_scheduler.n_list), 242 .n_list = LIST_HEAD_INIT(ip_vs_sh_scheduler.n_list),
231#ifdef CONFIG_IP_VS_IPV6 243#ifdef CONFIG_IP_VS_IPV6
232 .supports_ipv6 = 0, 244 .supports_ipv6 = 1,
233#endif 245#endif
234 .init_service = ip_vs_sh_init_svc, 246 .init_service = ip_vs_sh_init_svc,
235 .done_service = ip_vs_sh_done_svc, 247 .done_service = ip_vs_sh_done_svc,