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>
This commit is contained in:
committed by
Simon Horman
parent
b18610de9e
commit
3c2e0505d2
@@ -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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|||||||
* 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)
|
|||||||
/*
|
/*
|
||||||
* 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,
|
|||||||
{
|
{
|
||||||
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,
|
|||||||
{
|
{
|
||||||
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,
|
|||||||
{
|
{
|
||||||
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.
|
||||||
|
Reference in New Issue
Block a user