aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulius Volz <juliusv@google.com>2008-09-02 09:55:38 -0400
committerSimon Horman <horms@verge.net.au>2008-09-04 21:17:05 -0400
commit3c2e0505d25cdc9425336f167fd4ff5f505aecff (patch)
tree819711ebce94061695fa8c0edb91a9372553cc73
parentb18610de9ec2728159f723a9b864ca78a5774193 (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.h3
-rw-r--r--net/ipv4/ipvs/ip_vs_ctl.c24
-rw-r--r--net/ipv4/ipvs/ip_vs_proto_tcp.c9
-rw-r--r--net/ipv4/ipvs/ip_vs_proto_udp.c11
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;
783extern const struct ctl_path net_vs_ctl_path[]; 783extern const struct ctl_path net_vs_ctl_path[];
784 784
785extern struct ip_vs_service * 785extern struct ip_vs_service *
786ip_vs_service_get(__u32 fwmark, __u16 protocol, __be32 vaddr, __be16 vport); 786ip_vs_service_get(int af, __u32 fwmark, __u16 protocol,
787 const union nf_inet_addr *vaddr, __be16 vport);
787 788
788static inline void ip_vs_service_put(struct ip_vs_service *svc) 789static 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
423struct ip_vs_service * 423struct ip_vs_service *
424ip_vs_service_get(__u32 fwmark, __u16 protocol, __be32 vaddr, __be16 vport) 424ip_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.