diff options
author | Julius Volz <juliusv@google.com> | 2008-09-02 09:55:37 -0400 |
---|---|---|
committer | Simon Horman <horms@verge.net.au> | 2008-09-04 21:17:05 -0400 |
commit | b18610de9ec2728159f723a9b864ca78a5774193 (patch) | |
tree | 0e433de080cd5bbfc0d2c24c5d80c5904d2b238c /net/ipv4/ipvs | |
parent | c860c6b1479992440e4962e9c95d258bfdce4fca (diff) |
IPVS: Convert __ip_vs_svc_get() and __ip_vs_fwm_get()
Add support for getting services based on their address family to
__ip_vs_service_get(), __ip_vs_fwm_get() and the helper hash function
ip_vs_svc_hashkey(). Adjust the callers.
Signed-off-by: Julius Volz <juliusv@google.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
Diffstat (limited to 'net/ipv4/ipvs')
-rw-r--r-- | net/ipv4/ipvs/ip_vs_ctl.c | 79 |
1 files changed, 47 insertions, 32 deletions
diff --git a/net/ipv4/ipvs/ip_vs_ctl.c b/net/ipv4/ipvs/ip_vs_ctl.c index a0c8b7bb5530..a2d69b2ce6a1 100644 --- a/net/ipv4/ipvs/ip_vs_ctl.c +++ b/net/ipv4/ipvs/ip_vs_ctl.c | |||
@@ -282,11 +282,19 @@ static atomic_t ip_vs_nullsvc_counter = ATOMIC_INIT(0); | |||
282 | * Returns hash value for virtual service | 282 | * Returns hash value for virtual service |
283 | */ | 283 | */ |
284 | static __inline__ unsigned | 284 | static __inline__ unsigned |
285 | ip_vs_svc_hashkey(unsigned proto, __be32 addr, __be16 port) | 285 | ip_vs_svc_hashkey(int af, unsigned proto, const union nf_inet_addr *addr, |
286 | __be16 port) | ||
286 | { | 287 | { |
287 | register unsigned porth = ntohs(port); | 288 | register unsigned porth = ntohs(port); |
289 | __be32 addr_fold = addr->ip; | ||
288 | 290 | ||
289 | return (proto^ntohl(addr)^(porth>>IP_VS_SVC_TAB_BITS)^porth) | 291 | #ifdef CONFIG_IP_VS_IPV6 |
292 | if (af == AF_INET6) | ||
293 | addr_fold = addr->ip6[0]^addr->ip6[1]^ | ||
294 | addr->ip6[2]^addr->ip6[3]; | ||
295 | #endif | ||
296 | |||
297 | return (proto^ntohl(addr_fold)^(porth>>IP_VS_SVC_TAB_BITS)^porth) | ||
290 | & IP_VS_SVC_TAB_MASK; | 298 | & IP_VS_SVC_TAB_MASK; |
291 | } | 299 | } |
292 | 300 | ||
@@ -317,7 +325,7 @@ static int ip_vs_svc_hash(struct ip_vs_service *svc) | |||
317 | /* | 325 | /* |
318 | * Hash it by <protocol,addr,port> in ip_vs_svc_table | 326 | * Hash it by <protocol,addr,port> in ip_vs_svc_table |
319 | */ | 327 | */ |
320 | hash = ip_vs_svc_hashkey(svc->protocol, svc->addr.ip, | 328 | hash = ip_vs_svc_hashkey(svc->af, svc->protocol, &svc->addr, |
321 | svc->port); | 329 | svc->port); |
322 | list_add(&svc->s_list, &ip_vs_svc_table[hash]); | 330 | list_add(&svc->s_list, &ip_vs_svc_table[hash]); |
323 | } else { | 331 | } else { |
@@ -364,17 +372,19 @@ static int ip_vs_svc_unhash(struct ip_vs_service *svc) | |||
364 | /* | 372 | /* |
365 | * Get service by {proto,addr,port} in the service table. | 373 | * Get service by {proto,addr,port} in the service table. |
366 | */ | 374 | */ |
367 | static __inline__ struct ip_vs_service * | 375 | static inline struct ip_vs_service * |
368 | __ip_vs_service_get(__u16 protocol, __be32 vaddr, __be16 vport) | 376 | __ip_vs_service_get(int af, __u16 protocol, const union nf_inet_addr *vaddr, |
377 | __be16 vport) | ||
369 | { | 378 | { |
370 | unsigned hash; | 379 | unsigned hash; |
371 | struct ip_vs_service *svc; | 380 | struct ip_vs_service *svc; |
372 | 381 | ||
373 | /* Check for "full" addressed entries */ | 382 | /* Check for "full" addressed entries */ |
374 | hash = ip_vs_svc_hashkey(protocol, vaddr, vport); | 383 | hash = ip_vs_svc_hashkey(af, protocol, vaddr, vport); |
375 | 384 | ||
376 | list_for_each_entry(svc, &ip_vs_svc_table[hash], s_list){ | 385 | list_for_each_entry(svc, &ip_vs_svc_table[hash], s_list){ |
377 | if ((svc->addr.ip == vaddr) | 386 | if ((svc->af == af) |
387 | && ip_vs_addr_equal(af, &svc->addr, vaddr) | ||
378 | && (svc->port == vport) | 388 | && (svc->port == vport) |
379 | && (svc->protocol == protocol)) { | 389 | && (svc->protocol == protocol)) { |
380 | /* HIT */ | 390 | /* HIT */ |
@@ -390,7 +400,8 @@ __ip_vs_service_get(__u16 protocol, __be32 vaddr, __be16 vport) | |||
390 | /* | 400 | /* |
391 | * Get service by {fwmark} in the service table. | 401 | * Get service by {fwmark} in the service table. |
392 | */ | 402 | */ |
393 | static __inline__ struct ip_vs_service *__ip_vs_svc_fwm_get(__u32 fwmark) | 403 | static inline struct ip_vs_service * |
404 | __ip_vs_svc_fwm_get(int af, __u32 fwmark) | ||
394 | { | 405 | { |
395 | unsigned hash; | 406 | unsigned hash; |
396 | struct ip_vs_service *svc; | 407 | struct ip_vs_service *svc; |
@@ -399,7 +410,7 @@ static __inline__ struct ip_vs_service *__ip_vs_svc_fwm_get(__u32 fwmark) | |||
399 | hash = ip_vs_svc_fwm_hashkey(fwmark); | 410 | hash = ip_vs_svc_fwm_hashkey(fwmark); |
400 | 411 | ||
401 | list_for_each_entry(svc, &ip_vs_svc_fwm_table[hash], f_list) { | 412 | list_for_each_entry(svc, &ip_vs_svc_fwm_table[hash], f_list) { |
402 | if (svc->fwmark == fwmark) { | 413 | if (svc->fwmark == fwmark && svc->af == af) { |
403 | /* HIT */ | 414 | /* HIT */ |
404 | atomic_inc(&svc->usecnt); | 415 | atomic_inc(&svc->usecnt); |
405 | return svc; | 416 | return svc; |
@@ -413,20 +424,20 @@ struct ip_vs_service * | |||
413 | ip_vs_service_get(__u32 fwmark, __u16 protocol, __be32 vaddr, __be16 vport) | 424 | ip_vs_service_get(__u32 fwmark, __u16 protocol, __be32 vaddr, __be16 vport) |
414 | { | 425 | { |
415 | struct ip_vs_service *svc; | 426 | struct ip_vs_service *svc; |
416 | 427 | union nf_inet_addr _vaddr = { .ip = vaddr }; | |
417 | read_lock(&__ip_vs_svc_lock); | 428 | read_lock(&__ip_vs_svc_lock); |
418 | 429 | ||
419 | /* | 430 | /* |
420 | * Check the table hashed by fwmark first | 431 | * Check the table hashed by fwmark first |
421 | */ | 432 | */ |
422 | if (fwmark && (svc = __ip_vs_svc_fwm_get(fwmark))) | 433 | if (fwmark && (svc = __ip_vs_svc_fwm_get(AF_INET, fwmark))) |
423 | goto out; | 434 | goto out; |
424 | 435 | ||
425 | /* | 436 | /* |
426 | * Check the table hashed by <protocol,addr,port> | 437 | * Check the table hashed by <protocol,addr,port> |
427 | * for "full" addressed entries | 438 | * for "full" addressed entries |
428 | */ | 439 | */ |
429 | svc = __ip_vs_service_get(protocol, vaddr, vport); | 440 | svc = __ip_vs_service_get(AF_INET, protocol, &_vaddr, vport); |
430 | 441 | ||
431 | if (svc == NULL | 442 | if (svc == NULL |
432 | && protocol == IPPROTO_TCP | 443 | && protocol == IPPROTO_TCP |
@@ -436,7 +447,7 @@ ip_vs_service_get(__u32 fwmark, __u16 protocol, __be32 vaddr, __be16 vport) | |||
436 | * Check if ftp service entry exists, the packet | 447 | * Check if ftp service entry exists, the packet |
437 | * might belong to FTP data connections. | 448 | * might belong to FTP data connections. |
438 | */ | 449 | */ |
439 | svc = __ip_vs_service_get(protocol, vaddr, FTPPORT); | 450 | svc = __ip_vs_service_get(AF_INET, protocol, &_vaddr, FTPPORT); |
440 | } | 451 | } |
441 | 452 | ||
442 | if (svc == NULL | 453 | if (svc == NULL |
@@ -444,7 +455,7 @@ ip_vs_service_get(__u32 fwmark, __u16 protocol, __be32 vaddr, __be16 vport) | |||
444 | /* | 455 | /* |
445 | * Check if the catch-all port (port zero) exists | 456 | * Check if the catch-all port (port zero) exists |
446 | */ | 457 | */ |
447 | svc = __ip_vs_service_get(protocol, vaddr, 0); | 458 | svc = __ip_vs_service_get(AF_INET, protocol, &_vaddr, 0); |
448 | } | 459 | } |
449 | 460 | ||
450 | out: | 461 | out: |
@@ -2016,10 +2027,10 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len) | |||
2016 | 2027 | ||
2017 | /* Lookup the exact service by <protocol, addr, port> or fwmark */ | 2028 | /* Lookup the exact service by <protocol, addr, port> or fwmark */ |
2018 | if (usvc.fwmark == 0) | 2029 | if (usvc.fwmark == 0) |
2019 | svc = __ip_vs_service_get(usvc.protocol, | 2030 | svc = __ip_vs_service_get(usvc.af, usvc.protocol, |
2020 | usvc.addr.ip, usvc.port); | 2031 | &usvc.addr, usvc.port); |
2021 | else | 2032 | else |
2022 | svc = __ip_vs_svc_fwm_get(usvc.fwmark); | 2033 | svc = __ip_vs_svc_fwm_get(usvc.af, usvc.fwmark); |
2023 | 2034 | ||
2024 | if (cmd != IP_VS_SO_SET_ADD | 2035 | if (cmd != IP_VS_SO_SET_ADD |
2025 | && (svc == NULL || svc->protocol != usvc.protocol)) { | 2036 | && (svc == NULL || svc->protocol != usvc.protocol)) { |
@@ -2141,13 +2152,15 @@ __ip_vs_get_dest_entries(const struct ip_vs_get_dests *get, | |||
2141 | struct ip_vs_get_dests __user *uptr) | 2152 | struct ip_vs_get_dests __user *uptr) |
2142 | { | 2153 | { |
2143 | struct ip_vs_service *svc; | 2154 | struct ip_vs_service *svc; |
2155 | union nf_inet_addr addr = { .ip = get->addr }; | ||
2144 | int ret = 0; | 2156 | int ret = 0; |
2145 | 2157 | ||
2146 | if (get->fwmark) | 2158 | if (get->fwmark) |
2147 | svc = __ip_vs_svc_fwm_get(get->fwmark); | 2159 | svc = __ip_vs_svc_fwm_get(AF_INET, get->fwmark); |
2148 | else | 2160 | else |
2149 | svc = __ip_vs_service_get(get->protocol, | 2161 | svc = __ip_vs_service_get(AF_INET, get->protocol, &addr, |
2150 | get->addr, get->port); | 2162 | get->port); |
2163 | |||
2151 | if (svc) { | 2164 | if (svc) { |
2152 | int count = 0; | 2165 | int count = 0; |
2153 | struct ip_vs_dest *dest; | 2166 | struct ip_vs_dest *dest; |
@@ -2282,13 +2295,15 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) | |||
2282 | { | 2295 | { |
2283 | struct ip_vs_service_entry *entry; | 2296 | struct ip_vs_service_entry *entry; |
2284 | struct ip_vs_service *svc; | 2297 | struct ip_vs_service *svc; |
2298 | union nf_inet_addr addr; | ||
2285 | 2299 | ||
2286 | entry = (struct ip_vs_service_entry *)arg; | 2300 | entry = (struct ip_vs_service_entry *)arg; |
2301 | addr.ip = entry->addr; | ||
2287 | if (entry->fwmark) | 2302 | if (entry->fwmark) |
2288 | svc = __ip_vs_svc_fwm_get(entry->fwmark); | 2303 | svc = __ip_vs_svc_fwm_get(AF_INET, entry->fwmark); |
2289 | else | 2304 | else |
2290 | svc = __ip_vs_service_get(entry->protocol, | 2305 | svc = __ip_vs_service_get(AF_INET, entry->protocol, |
2291 | entry->addr, entry->port); | 2306 | &addr, entry->port); |
2292 | if (svc) { | 2307 | if (svc) { |
2293 | ip_vs_copy_service(entry, svc); | 2308 | ip_vs_copy_service(entry, svc); |
2294 | if (copy_to_user(user, entry, sizeof(*entry)) != 0) | 2309 | if (copy_to_user(user, entry, sizeof(*entry)) != 0) |
@@ -2613,10 +2628,10 @@ static int ip_vs_genl_parse_service(struct ip_vs_service_user_kern *usvc, | |||
2613 | 2628 | ||
2614 | /* prefill flags from service if it already exists */ | 2629 | /* prefill flags from service if it already exists */ |
2615 | if (usvc->fwmark) | 2630 | if (usvc->fwmark) |
2616 | svc = __ip_vs_svc_fwm_get(usvc->fwmark); | 2631 | svc = __ip_vs_svc_fwm_get(usvc->af, usvc->fwmark); |
2617 | else | 2632 | else |
2618 | svc = __ip_vs_service_get(usvc->protocol, usvc->addr.ip, | 2633 | svc = __ip_vs_service_get(usvc->af, usvc->protocol, |
2619 | usvc->port); | 2634 | &usvc->addr, usvc->port); |
2620 | if (svc) { | 2635 | if (svc) { |
2621 | usvc->flags = svc->flags; | 2636 | usvc->flags = svc->flags; |
2622 | ip_vs_service_put(svc); | 2637 | ip_vs_service_put(svc); |
@@ -2644,10 +2659,10 @@ static struct ip_vs_service *ip_vs_genl_find_service(struct nlattr *nla) | |||
2644 | return ERR_PTR(ret); | 2659 | return ERR_PTR(ret); |
2645 | 2660 | ||
2646 | if (usvc.fwmark) | 2661 | if (usvc.fwmark) |
2647 | return __ip_vs_svc_fwm_get(usvc.fwmark); | 2662 | return __ip_vs_svc_fwm_get(usvc.af, usvc.fwmark); |
2648 | else | 2663 | else |
2649 | return __ip_vs_service_get(usvc.protocol, usvc.addr.ip, | 2664 | return __ip_vs_service_get(usvc.af, usvc.protocol, |
2650 | usvc.port); | 2665 | &usvc.addr, usvc.port); |
2651 | } | 2666 | } |
2652 | 2667 | ||
2653 | static int ip_vs_genl_fill_dest(struct sk_buff *skb, struct ip_vs_dest *dest) | 2668 | static int ip_vs_genl_fill_dest(struct sk_buff *skb, struct ip_vs_dest *dest) |
@@ -2955,10 +2970,10 @@ static int ip_vs_genl_set_cmd(struct sk_buff *skb, struct genl_info *info) | |||
2955 | 2970 | ||
2956 | /* Lookup the exact service by <protocol, addr, port> or fwmark */ | 2971 | /* Lookup the exact service by <protocol, addr, port> or fwmark */ |
2957 | if (usvc.fwmark == 0) | 2972 | if (usvc.fwmark == 0) |
2958 | svc = __ip_vs_service_get(usvc.protocol, usvc.addr.ip, | 2973 | svc = __ip_vs_service_get(usvc.af, usvc.protocol, |
2959 | usvc.port); | 2974 | &usvc.addr, usvc.port); |
2960 | else | 2975 | else |
2961 | svc = __ip_vs_svc_fwm_get(usvc.fwmark); | 2976 | svc = __ip_vs_svc_fwm_get(usvc.af, usvc.fwmark); |
2962 | 2977 | ||
2963 | /* Unless we're adding a new service, the service must already exist */ | 2978 | /* Unless we're adding a new service, the service must already exist */ |
2964 | if ((cmd != IPVS_CMD_NEW_SERVICE) && (svc == NULL)) { | 2979 | if ((cmd != IPVS_CMD_NEW_SERVICE) && (svc == NULL)) { |