Commit 3c2e0505 authored by Julius Volz's avatar Julius Volz Committed by Simon Horman

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: default avatarJulius Volz <juliusv@google.com>
Signed-off-by: default avatarSimon Horman <horms@verge.net.au>
parent b18610de
...@@ -783,7 +783,8 @@ extern struct ip_vs_stats ip_vs_stats; ...@@ -783,7 +783,8 @@ extern struct ip_vs_stats ip_vs_stats;
extern const struct ctl_path net_vs_ctl_path[]; extern const struct ctl_path net_vs_ctl_path[];
extern struct ip_vs_service * 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) static inline void ip_vs_service_put(struct ip_vs_service *svc)
{ {
......
...@@ -421,23 +421,24 @@ __ip_vs_svc_fwm_get(int af, __u32 fwmark) ...@@ -421,23 +421,24 @@ __ip_vs_svc_fwm_get(int af, __u32 fwmark)
} }
struct ip_vs_service * 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; struct ip_vs_service *svc;
union nf_inet_addr _vaddr = { .ip = vaddr };
read_lock(&__ip_vs_svc_lock); read_lock(&__ip_vs_svc_lock);
/* /*
* Check the table hashed by fwmark first * 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; goto out;
/* /*
* Check the table hashed by <protocol,addr,port> * Check the table hashed by <protocol,addr,port>
* for "full" addressed entries * 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 if (svc == NULL
&& protocol == IPPROTO_TCP && protocol == IPPROTO_TCP
...@@ -447,7 +448,7 @@ ip_vs_service_get(__u32 fwmark, __u16 protocol, __be32 vaddr, __be16 vport) ...@@ -447,7 +448,7 @@ ip_vs_service_get(__u32 fwmark, __u16 protocol, __be32 vaddr, __be16 vport)
* Check if ftp service entry exists, the packet * Check if ftp service entry exists, the packet
* might belong to FTP data connections. * 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 if (svc == NULL
...@@ -455,16 +456,16 @@ ip_vs_service_get(__u32 fwmark, __u16 protocol, __be32 vaddr, __be16 vport) ...@@ -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 * 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: out:
read_unlock(&__ip_vs_svc_lock); read_unlock(&__ip_vs_svc_lock);
IP_VS_DBG(9, "lookup service: fwm %u %s %u.%u.%u.%u:%u %s\n", IP_VS_DBG_BUF(9, "lookup service: fwm %u %s %s:%u %s\n",
fwmark, ip_vs_proto_name(protocol), fwmark, ip_vs_proto_name(protocol),
NIPQUAD(vaddr), ntohs(vport), IP_VS_DBG_ADDR(af, vaddr), ntohs(vport),
svc?"hit":"not hit"); svc ? "hit" : "not hit");
return svc; return svc;
} }
...@@ -605,8 +606,9 @@ struct ip_vs_dest *ip_vs_find_dest(__be32 daddr, __be16 dport, ...@@ -605,8 +606,9 @@ struct ip_vs_dest *ip_vs_find_dest(__be32 daddr, __be16 dport,
{ {
struct ip_vs_dest *dest; struct ip_vs_dest *dest;
struct ip_vs_service *svc; 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) if (!svc)
return NULL; return NULL;
dest = ip_vs_lookup_dest(svc, daddr, dport); dest = ip_vs_lookup_dest(svc, daddr, dport);
......
...@@ -74,16 +74,19 @@ tcp_conn_schedule(struct sk_buff *skb, ...@@ -74,16 +74,19 @@ tcp_conn_schedule(struct sk_buff *skb,
{ {
struct ip_vs_service *svc; struct ip_vs_service *svc;
struct tcphdr _tcph, *th; 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) { if (th == NULL) {
*verdict = NF_DROP; *verdict = NF_DROP;
return 0; return 0;
} }
if (th->syn && if (th->syn &&
(svc = ip_vs_service_get(skb->mark, ip_hdr(skb)->protocol, (svc = ip_vs_service_get(AF_INET, skb->mark, iph.protocol,
ip_hdr(skb)->daddr, th->dest))) { &iph.daddr, th->dest))) {
if (ip_vs_todrop()) { if (ip_vs_todrop()) {
/* /*
* It seems that we are very loaded. * It seems that we are very loaded.
......
...@@ -80,16 +80,19 @@ udp_conn_schedule(struct sk_buff *skb, struct ip_vs_protocol *pp, ...@@ -80,16 +80,19 @@ udp_conn_schedule(struct sk_buff *skb, struct ip_vs_protocol *pp,
{ {
struct ip_vs_service *svc; struct ip_vs_service *svc;
struct udphdr _udph, *uh; struct udphdr _udph, *uh;
struct ip_vs_iphdr iph;
uh = skb_header_pointer(skb, ip_hdrlen(skb), ip_vs_fill_iphdr(AF_INET, skb_network_header(skb), &iph);
sizeof(_udph), &_udph);
uh = skb_header_pointer(skb, iph.len, sizeof(_udph), &_udph);
if (uh == NULL) { if (uh == NULL) {
*verdict = NF_DROP; *verdict = NF_DROP;
return 0; return 0;
} }
if ((svc = ip_vs_service_get(skb->mark, ip_hdr(skb)->protocol, svc = ip_vs_service_get(AF_INET, skb->mark, iph.protocol,
ip_hdr(skb)->daddr, uh->dest))) { &iph.daddr, uh->dest);
if (svc) {
if (ip_vs_todrop()) { if (ip_vs_todrop()) {
/* /*
* It seems that we are very loaded. * It seems that we are very loaded.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment