diff options
author | Julius Volz <julius.volz@gmail.com> | 2008-11-01 09:13:19 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-11-03 02:52:01 -0500 |
commit | 20971a0afb8bc0eeb6865ceadd435e4a2dba0fd7 (patch) | |
tree | 2d53792b5f141608e7a7fcb018a252c1f3e70c88 /net/netfilter | |
parent | 2a6cf35543302e9a5c807eaf13298f510fbdf8f2 (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.c | 30 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_sh.c | 30 |
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 | */ |
67 | static inline unsigned ip_vs_dh_hashkey(__be32 addr) | 67 | static 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 | */ |
76 | static inline struct ip_vs_dest * | 83 | static inline struct ip_vs_dest * |
77 | ip_vs_dh_get(struct ip_vs_dh_bucket *tbl, __be32 addr) | 84 | ip_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 | */ |
64 | static inline unsigned ip_vs_sh_hashkey(__be32 addr) | 64 | static 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 | */ |
73 | static inline struct ip_vs_dest * | 80 | static inline struct ip_vs_dest * |
74 | ip_vs_sh_get(struct ip_vs_sh_bucket *tbl, __be32 addr) | 81 | ip_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, |