IPVS: Add v6 support to ip_vs_service_get()
authorJulius Volz <juliusv@google.com>
Tue, 2 Sep 2008 13:55:38 +0000 (15:55 +0200)
committerSimon Horman <horms@verge.net.au>
Fri, 5 Sep 2008 01:17:05 +0000 (11:17 +1000)
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>
include/net/ip_vs.h
net/ipv4/ipvs/ip_vs_ctl.c
net/ipv4/ipvs/ip_vs_proto_tcp.c
net/ipv4/ipvs/ip_vs_proto_udp.c

index 1adf8a026e46626f1bc093eedd7485ea0c4a422c..30baed0e696d98e5849ebaa4eb9ce8a729e36ae3 100644 (file)
@@ -783,7 +783,8 @@ extern struct ip_vs_stats ip_vs_stats;
 extern const struct ctl_path net_vs_ctl_path[];
 
 extern struct ip_vs_service *
-ip_vs_service_get(__u32 fwmark, __u16 protocol, __be32 vaddr, __be16 vport);
+ip_vs_service_get(int af, __u32 fwmark, __u16 protocol,
+                 const union nf_inet_addr *vaddr, __be16 vport);
 
 static inline void ip_vs_service_put(struct ip_vs_service *svc)
 {
index a2d69b2ce6a1dae6951dd8deca6f53ab2cd53d66..1f3fc66e694376af41f0a9694e5ed2e003d99b2d 100644 (file)
@@ -421,23 +421,24 @@ __ip_vs_svc_fwm_get(int af, __u32 fwmark)
 }
 
 struct ip_vs_service *
-ip_vs_service_get(__u32 fwmark, __u16 protocol, __be32 vaddr, __be16 vport)
+ip_vs_service_get(int af, __u32 fwmark, __u16 protocol,
+                 const union nf_inet_addr *vaddr, __be16 vport)
 {
        struct ip_vs_service *svc;
-       union nf_inet_addr _vaddr = { .ip = vaddr };
+
        read_lock(&__ip_vs_svc_lock);
 
        /*
         *      Check the table hashed by fwmark first
         */
-       if (fwmark && (svc = __ip_vs_svc_fwm_get(AF_INET, fwmark)))
+       if (fwmark && (svc = __ip_vs_svc_fwm_get(af, fwmark)))
                goto out;
 
        /*
         *      Check the table hashed by <protocol,addr,port>
         *      for "full" addressed entries
         */
-       svc = __ip_vs_service_get(AF_INET, protocol, &_vaddr, vport);
+       svc = __ip_vs_service_get(af, protocol, vaddr, vport);
 
        if (svc == NULL
            && protocol == IPPROTO_TCP
@@ -447,7 +448,7 @@ ip_vs_service_get(__u32 fwmark, __u16 protocol, __be32 vaddr, __be16 vport)
                 * Check if ftp service entry exists, the packet
                 * might belong to FTP data connections.
                 */
-               svc = __ip_vs_service_get(AF_INET, protocol, &_vaddr, FTPPORT);
+               svc = __ip_vs_service_get(af, protocol, vaddr, FTPPORT);
        }
 
        if (svc == NULL
@@ -455,16 +456,16 @@ ip_vs_service_get(__u32 fwmark, __u16 protocol, __be32 vaddr, __be16 vport)
                /*
                 * Check if the catch-all port (port zero) exists
                 */
-               svc = __ip_vs_service_get(AF_INET, protocol, &_vaddr, 0);
+               svc = __ip_vs_service_get(af, protocol, vaddr, 0);
        }
 
   out:
        read_unlock(&__ip_vs_svc_lock);
 
-       IP_VS_DBG(9, "lookup service: fwm %u %s %u.%u.%u.%u:%u %s\n",
-                 fwmark, ip_vs_proto_name(protocol),
-                 NIPQUAD(vaddr), ntohs(vport),
-                 svc?"hit":"not hit");
+       IP_VS_DBG_BUF(9, "lookup service: fwm %u %s %s:%u %s\n",
+                     fwmark, ip_vs_proto_name(protocol),
+                     IP_VS_DBG_ADDR(af, vaddr), ntohs(vport),
+                     svc ? "hit" : "not hit");
 
        return svc;
 }
@@ -605,8 +606,9 @@ struct ip_vs_dest *ip_vs_find_dest(__be32 daddr, __be16 dport,
 {
        struct ip_vs_dest *dest;
        struct ip_vs_service *svc;
+       union nf_inet_addr _vaddr = { .ip = vaddr };
 
-       svc = ip_vs_service_get(0, protocol, vaddr, vport);
+       svc = ip_vs_service_get(AF_INET, 0, protocol, &_vaddr, vport);
        if (!svc)
                return NULL;
        dest = ip_vs_lookup_dest(svc, daddr, dport);
index 15860e1441b08fd41d96a413015aa59633f29ae7..fe93c9e6ff63c3ffb55b121729bc2ffddcc0181c 100644 (file)
@@ -74,16 +74,19 @@ tcp_conn_schedule(struct sk_buff *skb,
 {
        struct ip_vs_service *svc;
        struct tcphdr _tcph, *th;
+       struct ip_vs_iphdr iph;
 
-       th = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_tcph), &_tcph);
+       ip_vs_fill_iphdr(AF_INET, skb_network_header(skb), &iph);
+
+       th = skb_header_pointer(skb, iph.len, sizeof(_tcph), &_tcph);
        if (th == NULL) {
                *verdict = NF_DROP;
                return 0;
        }
 
        if (th->syn &&
-           (svc = ip_vs_service_get(skb->mark, ip_hdr(skb)->protocol,
-                                    ip_hdr(skb)->daddr, th->dest))) {
+           (svc = ip_vs_service_get(AF_INET, skb->mark, iph.protocol,
+                                    &iph.daddr, th->dest))) {
                if (ip_vs_todrop()) {
                        /*
                         * It seems that we are very loaded.
index 8dfad5db8295291a1a92073f9dadc9d58658692f..d208ed6eb9fca36c0ef7c4056153d5eed6a55bd3 100644 (file)
@@ -80,16 +80,19 @@ udp_conn_schedule(struct sk_buff *skb, struct ip_vs_protocol *pp,
 {
        struct ip_vs_service *svc;
        struct udphdr _udph, *uh;
+       struct ip_vs_iphdr iph;
 
-       uh = skb_header_pointer(skb, ip_hdrlen(skb),
-                               sizeof(_udph), &_udph);
+       ip_vs_fill_iphdr(AF_INET, skb_network_header(skb), &iph);
+
+       uh = skb_header_pointer(skb, iph.len, sizeof(_udph), &_udph);
        if (uh == NULL) {
                *verdict = NF_DROP;
                return 0;
        }
 
-       if ((svc = ip_vs_service_get(skb->mark, ip_hdr(skb)->protocol,
-                                    ip_hdr(skb)->daddr, uh->dest))) {
+       svc = ip_vs_service_get(AF_INET, skb->mark, iph.protocol,
+                               &iph.daddr, uh->dest);
+       if (svc) {
                if (ip_vs_todrop()) {
                        /*
                         * It seems that we are very loaded.