diff options
author | Julius Volz <juliusv@google.com> | 2008-09-02 09:55:38 -0400 |
---|---|---|
committer | Simon Horman <horms@verge.net.au> | 2008-09-04 21:17:05 -0400 |
commit | 3c2e0505d25cdc9425336f167fd4ff5f505aecff (patch) | |
tree | 819711ebce94061695fa8c0edb91a9372553cc73 | |
parent | b18610de9ec2728159f723a9b864ca78a5774193 (diff) |
IPVS: Add v6 support to ip_vs_service_get()
Add support for selecting services based on their address family to
ip_vs_service_get() and adjust the callers.
Signed-off-by: Julius Volz <juliusv@google.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
-rw-r--r-- | include/net/ip_vs.h | 3 | ||||
-rw-r--r-- | net/ipv4/ipvs/ip_vs_ctl.c | 24 | ||||
-rw-r--r-- | net/ipv4/ipvs/ip_vs_proto_tcp.c | 9 | ||||
-rw-r--r-- | net/ipv4/ipvs/ip_vs_proto_udp.c | 11 |
4 files changed, 28 insertions, 19 deletions
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index 1adf8a026e46..30baed0e696d 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h | |||
@@ -783,7 +783,8 @@ extern struct ip_vs_stats ip_vs_stats; | |||
783 | extern const struct ctl_path net_vs_ctl_path[]; | 783 | extern const struct ctl_path net_vs_ctl_path[]; |
784 | 784 | ||
785 | extern struct ip_vs_service * | 785 | extern struct ip_vs_service * |
786 | ip_vs_service_get(__u32 fwmark, __u16 protocol, __be32 vaddr, __be16 vport); | 786 | ip_vs_service_get(int af, __u32 fwmark, __u16 protocol, |
787 | const union nf_inet_addr *vaddr, __be16 vport); | ||
787 | 788 | ||
788 | static inline void ip_vs_service_put(struct ip_vs_service *svc) | 789 | static inline void ip_vs_service_put(struct ip_vs_service *svc) |
789 | { | 790 | { |
diff --git a/net/ipv4/ipvs/ip_vs_ctl.c b/net/ipv4/ipvs/ip_vs_ctl.c index a2d69b2ce6a1..1f3fc66e6943 100644 --- a/net/ipv4/ipvs/ip_vs_ctl.c +++ b/net/ipv4/ipvs/ip_vs_ctl.c | |||
@@ -421,23 +421,24 @@ __ip_vs_svc_fwm_get(int af, __u32 fwmark) | |||
421 | } | 421 | } |
422 | 422 | ||
423 | struct ip_vs_service * | 423 | struct ip_vs_service * |
424 | ip_vs_service_get(__u32 fwmark, __u16 protocol, __be32 vaddr, __be16 vport) | 424 | ip_vs_service_get(int af, __u32 fwmark, __u16 protocol, |
425 | const union nf_inet_addr *vaddr, __be16 vport) | ||
425 | { | 426 | { |
426 | struct ip_vs_service *svc; | 427 | struct ip_vs_service *svc; |
427 | union nf_inet_addr _vaddr = { .ip = vaddr }; | 428 | |
428 | read_lock(&__ip_vs_svc_lock); | 429 | read_lock(&__ip_vs_svc_lock); |
429 | 430 | ||
430 | /* | 431 | /* |
431 | * Check the table hashed by fwmark first | 432 | * Check the table hashed by fwmark first |
432 | */ | 433 | */ |
433 | if (fwmark && (svc = __ip_vs_svc_fwm_get(AF_INET, fwmark))) | 434 | if (fwmark && (svc = __ip_vs_svc_fwm_get(af, fwmark))) |
434 | goto out; | 435 | goto out; |
435 | 436 | ||
436 | /* | 437 | /* |
437 | * Check the table hashed by <protocol,addr,port> | 438 | * Check the table hashed by <protocol,addr,port> |
438 | * for "full" addressed entries | 439 | * for "full" addressed entries |
439 | */ | 440 | */ |
440 | svc = __ip_vs_service_get(AF_INET, protocol, &_vaddr, vport); | 441 | svc = __ip_vs_service_get(af, protocol, vaddr, vport); |
441 | 442 | ||
442 | if (svc == NULL | 443 | if (svc == NULL |
443 | && protocol == IPPROTO_TCP | 444 | && protocol == IPPROTO_TCP |
@@ -447,7 +448,7 @@ ip_vs_service_get(__u32 fwmark, __u16 protocol, __be32 vaddr, __be16 vport) | |||
447 | * Check if ftp service entry exists, the packet | 448 | * Check if ftp service entry exists, the packet |
448 | * might belong to FTP data connections. | 449 | * might belong to FTP data connections. |
449 | */ | 450 | */ |
450 | svc = __ip_vs_service_get(AF_INET, protocol, &_vaddr, FTPPORT); | 451 | svc = __ip_vs_service_get(af, protocol, vaddr, FTPPORT); |
451 | } | 452 | } |
452 | 453 | ||
453 | if (svc == NULL | 454 | if (svc == NULL |
@@ -455,16 +456,16 @@ ip_vs_service_get(__u32 fwmark, __u16 protocol, __be32 vaddr, __be16 vport) | |||
455 | /* | 456 | /* |
456 | * Check if the catch-all port (port zero) exists | 457 | * Check if the catch-all port (port zero) exists |
457 | */ | 458 | */ |
458 | svc = __ip_vs_service_get(AF_INET, protocol, &_vaddr, 0); | 459 | svc = __ip_vs_service_get(af, protocol, vaddr, 0); |
459 | } | 460 | } |
460 | 461 | ||
461 | out: | 462 | out: |
462 | read_unlock(&__ip_vs_svc_lock); | 463 | read_unlock(&__ip_vs_svc_lock); |
463 | 464 | ||
464 | IP_VS_DBG(9, "lookup service: fwm %u %s %u.%u.%u.%u:%u %s\n", | 465 | IP_VS_DBG_BUF(9, "lookup service: fwm %u %s %s:%u %s\n", |
465 | fwmark, ip_vs_proto_name(protocol), | 466 | fwmark, ip_vs_proto_name(protocol), |
466 | NIPQUAD(vaddr), ntohs(vport), | 467 | IP_VS_DBG_ADDR(af, vaddr), ntohs(vport), |
467 | svc?"hit":"not hit"); | 468 | svc ? "hit" : "not hit"); |
468 | 469 | ||
469 | return svc; | 470 | return svc; |
470 | } | 471 | } |
@@ -605,8 +606,9 @@ struct ip_vs_dest *ip_vs_find_dest(__be32 daddr, __be16 dport, | |||
605 | { | 606 | { |
606 | struct ip_vs_dest *dest; | 607 | struct ip_vs_dest *dest; |
607 | struct ip_vs_service *svc; | 608 | struct ip_vs_service *svc; |
609 | union nf_inet_addr _vaddr = { .ip = vaddr }; | ||
608 | 610 | ||
609 | svc = ip_vs_service_get(0, protocol, vaddr, vport); | 611 | svc = ip_vs_service_get(AF_INET, 0, protocol, &_vaddr, vport); |
610 | if (!svc) | 612 | if (!svc) |
611 | return NULL; | 613 | return NULL; |
612 | dest = ip_vs_lookup_dest(svc, daddr, dport); | 614 | dest = ip_vs_lookup_dest(svc, daddr, dport); |
diff --git a/net/ipv4/ipvs/ip_vs_proto_tcp.c b/net/ipv4/ipvs/ip_vs_proto_tcp.c index 15860e1441b0..fe93c9e6ff63 100644 --- a/net/ipv4/ipvs/ip_vs_proto_tcp.c +++ b/net/ipv4/ipvs/ip_vs_proto_tcp.c | |||
@@ -74,16 +74,19 @@ tcp_conn_schedule(struct sk_buff *skb, | |||
74 | { | 74 | { |
75 | struct ip_vs_service *svc; | 75 | struct ip_vs_service *svc; |
76 | struct tcphdr _tcph, *th; | 76 | struct tcphdr _tcph, *th; |
77 | struct ip_vs_iphdr iph; | ||
77 | 78 | ||
78 | th = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_tcph), &_tcph); | 79 | ip_vs_fill_iphdr(AF_INET, skb_network_header(skb), &iph); |
80 | |||
81 | th = skb_header_pointer(skb, iph.len, sizeof(_tcph), &_tcph); | ||
79 | if (th == NULL) { | 82 | if (th == NULL) { |
80 | *verdict = NF_DROP; | 83 | *verdict = NF_DROP; |
81 | return 0; | 84 | return 0; |
82 | } | 85 | } |
83 | 86 | ||
84 | if (th->syn && | 87 | if (th->syn && |
85 | (svc = ip_vs_service_get(skb->mark, ip_hdr(skb)->protocol, | 88 | (svc = ip_vs_service_get(AF_INET, skb->mark, iph.protocol, |
86 | ip_hdr(skb)->daddr, th->dest))) { | 89 | &iph.daddr, th->dest))) { |
87 | if (ip_vs_todrop()) { | 90 | if (ip_vs_todrop()) { |
88 | /* | 91 | /* |
89 | * It seems that we are very loaded. | 92 | * It seems that we are very loaded. |
diff --git a/net/ipv4/ipvs/ip_vs_proto_udp.c b/net/ipv4/ipvs/ip_vs_proto_udp.c index 8dfad5db8295..d208ed6eb9fc 100644 --- a/net/ipv4/ipvs/ip_vs_proto_udp.c +++ b/net/ipv4/ipvs/ip_vs_proto_udp.c | |||
@@ -80,16 +80,19 @@ udp_conn_schedule(struct sk_buff *skb, struct ip_vs_protocol *pp, | |||
80 | { | 80 | { |
81 | struct ip_vs_service *svc; | 81 | struct ip_vs_service *svc; |
82 | struct udphdr _udph, *uh; | 82 | struct udphdr _udph, *uh; |
83 | struct ip_vs_iphdr iph; | ||
83 | 84 | ||
84 | uh = skb_header_pointer(skb, ip_hdrlen(skb), | 85 | ip_vs_fill_iphdr(AF_INET, skb_network_header(skb), &iph); |
85 | sizeof(_udph), &_udph); | 86 | |
87 | uh = skb_header_pointer(skb, iph.len, sizeof(_udph), &_udph); | ||
86 | if (uh == NULL) { | 88 | if (uh == NULL) { |
87 | *verdict = NF_DROP; | 89 | *verdict = NF_DROP; |
88 | return 0; | 90 | return 0; |
89 | } | 91 | } |
90 | 92 | ||
91 | if ((svc = ip_vs_service_get(skb->mark, ip_hdr(skb)->protocol, | 93 | svc = ip_vs_service_get(AF_INET, skb->mark, iph.protocol, |
92 | ip_hdr(skb)->daddr, uh->dest))) { | 94 | &iph.daddr, uh->dest); |
95 | if (svc) { | ||
93 | if (ip_vs_todrop()) { | 96 | if (ip_vs_todrop()) { |
94 | /* | 97 | /* |
95 | * It seems that we are very loaded. | 98 | * It seems that we are very loaded. |