Commit dacc62db authored by David S. Miller's avatar David S. Miller
parents 47abf28d c051a0a2
This diff is collapsed.
...@@ -24,6 +24,14 @@ menuconfig IP_VS ...@@ -24,6 +24,14 @@ menuconfig IP_VS
if IP_VS if IP_VS
config IP_VS_IPV6
bool "IPv6 support for IPVS (DANGEROUS)"
depends on EXPERIMENTAL && (IPV6 = y || IP_VS = IPV6)
---help---
Add IPv6 support to IPVS. This is incomplete and might be dangerous.
Say N if unsure.
config IP_VS_DEBUG config IP_VS_DEBUG
bool "IP virtual server debugging" bool "IP virtual server debugging"
---help--- ---help---
...@@ -33,7 +41,8 @@ config IP_VS_DEBUG ...@@ -33,7 +41,8 @@ config IP_VS_DEBUG
config IP_VS_TAB_BITS config IP_VS_TAB_BITS
int "IPVS connection table size (the Nth power of 2)" int "IPVS connection table size (the Nth power of 2)"
default "12" range 8 20
default 12
---help--- ---help---
The IPVS connection hash table uses the chaining scheme to handle The IPVS connection hash table uses the chaining scheme to handle
hash collisions. Using a big IPVS connection hash table will greatly hash collisions. Using a big IPVS connection hash table will greatly
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -218,7 +218,7 @@ ip_vs_dh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) ...@@ -218,7 +218,7 @@ ip_vs_dh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
IP_VS_DBG(6, "DH: destination IP address %u.%u.%u.%u " IP_VS_DBG(6, "DH: destination IP address %u.%u.%u.%u "
"--> server %u.%u.%u.%u:%d\n", "--> server %u.%u.%u.%u:%d\n",
NIPQUAD(iph->daddr), NIPQUAD(iph->daddr),
NIPQUAD(dest->addr), NIPQUAD(dest->addr.ip),
ntohs(dest->port)); ntohs(dest->port));
return dest; return dest;
...@@ -234,6 +234,9 @@ static struct ip_vs_scheduler ip_vs_dh_scheduler = ...@@ -234,6 +234,9 @@ static struct ip_vs_scheduler ip_vs_dh_scheduler =
.refcnt = ATOMIC_INIT(0), .refcnt = ATOMIC_INIT(0),
.module = THIS_MODULE, .module = THIS_MODULE,
.n_list = LIST_HEAD_INIT(ip_vs_dh_scheduler.n_list), .n_list = LIST_HEAD_INIT(ip_vs_dh_scheduler.n_list),
#ifdef CONFIG_IP_VS_IPV6
.supports_ipv6 = 0,
#endif
.init_service = ip_vs_dh_init_svc, .init_service = ip_vs_dh_init_svc,
.done_service = ip_vs_dh_done_svc, .done_service = ip_vs_dh_done_svc,
.update_service = ip_vs_dh_update_svc, .update_service = ip_vs_dh_update_svc,
......
...@@ -65,37 +65,37 @@ static void estimation_timer(unsigned long arg) ...@@ -65,37 +65,37 @@ static void estimation_timer(unsigned long arg)
s = container_of(e, struct ip_vs_stats, est); s = container_of(e, struct ip_vs_stats, est);
spin_lock(&s->lock); spin_lock(&s->lock);
n_conns = s->conns; n_conns = s->ustats.conns;
n_inpkts = s->inpkts; n_inpkts = s->ustats.inpkts;
n_outpkts = s->outpkts; n_outpkts = s->ustats.outpkts;
n_inbytes = s->inbytes; n_inbytes = s->ustats.inbytes;
n_outbytes = s->outbytes; n_outbytes = s->ustats.outbytes;
/* scaled by 2^10, but divided 2 seconds */ /* scaled by 2^10, but divided 2 seconds */
rate = (n_conns - e->last_conns)<<9; rate = (n_conns - e->last_conns)<<9;
e->last_conns = n_conns; e->last_conns = n_conns;
e->cps += ((long)rate - (long)e->cps)>>2; e->cps += ((long)rate - (long)e->cps)>>2;
s->cps = (e->cps+0x1FF)>>10; s->ustats.cps = (e->cps+0x1FF)>>10;
rate = (n_inpkts - e->last_inpkts)<<9; rate = (n_inpkts - e->last_inpkts)<<9;
e->last_inpkts = n_inpkts; e->last_inpkts = n_inpkts;
e->inpps += ((long)rate - (long)e->inpps)>>2; e->inpps += ((long)rate - (long)e->inpps)>>2;
s->inpps = (e->inpps+0x1FF)>>10; s->ustats.inpps = (e->inpps+0x1FF)>>10;
rate = (n_outpkts - e->last_outpkts)<<9; rate = (n_outpkts - e->last_outpkts)<<9;
e->last_outpkts = n_outpkts; e->last_outpkts = n_outpkts;
e->outpps += ((long)rate - (long)e->outpps)>>2; e->outpps += ((long)rate - (long)e->outpps)>>2;
s->outpps = (e->outpps+0x1FF)>>10; s->ustats.outpps = (e->outpps+0x1FF)>>10;
rate = (n_inbytes - e->last_inbytes)<<4; rate = (n_inbytes - e->last_inbytes)<<4;
e->last_inbytes = n_inbytes; e->last_inbytes = n_inbytes;
e->inbps += ((long)rate - (long)e->inbps)>>2; e->inbps += ((long)rate - (long)e->inbps)>>2;
s->inbps = (e->inbps+0xF)>>5; s->ustats.inbps = (e->inbps+0xF)>>5;
rate = (n_outbytes - e->last_outbytes)<<4; rate = (n_outbytes - e->last_outbytes)<<4;
e->last_outbytes = n_outbytes; e->last_outbytes = n_outbytes;
e->outbps += ((long)rate - (long)e->outbps)>>2; e->outbps += ((long)rate - (long)e->outbps)>>2;
s->outbps = (e->outbps+0xF)>>5; s->ustats.outbps = (e->outbps+0xF)>>5;
spin_unlock(&s->lock); spin_unlock(&s->lock);
} }
spin_unlock(&est_lock); spin_unlock(&est_lock);
...@@ -108,20 +108,20 @@ void ip_vs_new_estimator(struct ip_vs_stats *stats) ...@@ -108,20 +108,20 @@ void ip_vs_new_estimator(struct ip_vs_stats *stats)
INIT_LIST_HEAD(&est->list); INIT_LIST_HEAD(&est->list);
est->last_conns = stats->conns; est->last_conns = stats->ustats.conns;
est->cps = stats->cps<<10; est->cps = stats->ustats.cps<<10;
est->last_inpkts = stats->inpkts; est->last_inpkts = stats->ustats.inpkts;
est->inpps = stats->inpps<<10; est->inpps = stats->ustats.inpps<<10;
est->last_outpkts = stats->outpkts; est->last_outpkts = stats->ustats.outpkts;
est->outpps = stats->outpps<<10; est->outpps = stats->ustats.outpps<<10;
est->last_inbytes = stats->inbytes; est->last_inbytes = stats->ustats.inbytes;
est->inbps = stats->inbps<<5; est->inbps = stats->ustats.inbps<<5;
est->last_outbytes = stats->outbytes; est->last_outbytes = stats->ustats.outbytes;
est->outbps = stats->outbps<<5; est->outbps = stats->ustats.outbps<<5;
spin_lock_bh(&est_lock); spin_lock_bh(&est_lock);
list_add(&est->list, &est_list); list_add(&est->list, &est_list);
......
...@@ -140,13 +140,21 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp, ...@@ -140,13 +140,21 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp,
struct tcphdr *th; struct tcphdr *th;
char *data, *data_limit; char *data, *data_limit;
char *start, *end; char *start, *end;
__be32 from; union nf_inet_addr from;
__be16 port; __be16 port;
struct ip_vs_conn *n_cp; struct ip_vs_conn *n_cp;
char buf[24]; /* xxx.xxx.xxx.xxx,ppp,ppp\000 */ char buf[24]; /* xxx.xxx.xxx.xxx,ppp,ppp\000 */
unsigned buf_len; unsigned buf_len;
int ret; int ret;
#ifdef CONFIG_IP_VS_IPV6
/* This application helper doesn't work with IPv6 yet,
* so turn this into a no-op for IPv6 packets
*/
if (cp->af == AF_INET6)
return 1;
#endif
*diff = 0; *diff = 0;
/* Only useful for established sessions */ /* Only useful for established sessions */
...@@ -166,24 +174,25 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp, ...@@ -166,24 +174,25 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp,
if (ip_vs_ftp_get_addrport(data, data_limit, if (ip_vs_ftp_get_addrport(data, data_limit,
SERVER_STRING, SERVER_STRING,
sizeof(SERVER_STRING)-1, ')', sizeof(SERVER_STRING)-1, ')',
&from, &port, &from.ip, &port,
&start, &end) != 1) &start, &end) != 1)
return 1; return 1;
IP_VS_DBG(7, "PASV response (%u.%u.%u.%u:%d) -> " IP_VS_DBG(7, "PASV response (%u.%u.%u.%u:%d) -> "
"%u.%u.%u.%u:%d detected\n", "%u.%u.%u.%u:%d detected\n",
NIPQUAD(from), ntohs(port), NIPQUAD(cp->caddr), 0); NIPQUAD(from.ip), ntohs(port),
NIPQUAD(cp->caddr.ip), 0);
/* /*
* Now update or create an connection entry for it * Now update or create an connection entry for it
*/ */
n_cp = ip_vs_conn_out_get(iph->protocol, from, port, n_cp = ip_vs_conn_out_get(AF_INET, iph->protocol, &from, port,
cp->caddr, 0); &cp->caddr, 0);
if (!n_cp) { if (!n_cp) {
n_cp = ip_vs_conn_new(IPPROTO_TCP, n_cp = ip_vs_conn_new(AF_INET, IPPROTO_TCP,
cp->caddr, 0, &cp->caddr, 0,
cp->vaddr, port, &cp->vaddr, port,
from, port, &from, port,
IP_VS_CONN_F_NO_CPORT, IP_VS_CONN_F_NO_CPORT,
cp->dest); cp->dest);
if (!n_cp) if (!n_cp)
...@@ -196,9 +205,9 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp, ...@@ -196,9 +205,9 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp,
/* /*
* Replace the old passive address with the new one * Replace the old passive address with the new one
*/ */
from = n_cp->vaddr; from.ip = n_cp->vaddr.ip;
port = n_cp->vport; port = n_cp->vport;
sprintf(buf,"%d,%d,%d,%d,%d,%d", NIPQUAD(from), sprintf(buf, "%d,%d,%d,%d,%d,%d", NIPQUAD(from.ip),
(ntohs(port)>>8)&255, ntohs(port)&255); (ntohs(port)>>8)&255, ntohs(port)&255);
buf_len = strlen(buf); buf_len = strlen(buf);
...@@ -243,10 +252,18 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp, ...@@ -243,10 +252,18 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp,
struct tcphdr *th; struct tcphdr *th;
char *data, *data_start, *data_limit; char *data, *data_start, *data_limit;
char *start, *end; char *start, *end;
__be32 to; union nf_inet_addr to;
__be16 port; __be16 port;
struct ip_vs_conn *n_cp; struct ip_vs_conn *n_cp;
#ifdef CONFIG_IP_VS_IPV6
/* This application helper doesn't work with IPv6 yet,
* so turn this into a no-op for IPv6 packets
*/
if (cp->af == AF_INET6)
return 1;
#endif
/* no diff required for incoming packets */ /* no diff required for incoming packets */
*diff = 0; *diff = 0;
...@@ -291,12 +308,12 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp, ...@@ -291,12 +308,12 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp,
*/ */
if (ip_vs_ftp_get_addrport(data_start, data_limit, if (ip_vs_ftp_get_addrport(data_start, data_limit,
CLIENT_STRING, sizeof(CLIENT_STRING)-1, CLIENT_STRING, sizeof(CLIENT_STRING)-1,
'\r', &to, &port, '\r', &to.ip, &port,
&start, &end) != 1) &start, &end) != 1)
return 1; return 1;
IP_VS_DBG(7, "PORT %u.%u.%u.%u:%d detected\n", IP_VS_DBG(7, "PORT %u.%u.%u.%u:%d detected\n",
NIPQUAD(to), ntohs(port)); NIPQUAD(to.ip), ntohs(port));
/* Passive mode off */ /* Passive mode off */
cp->app_data = NULL; cp->app_data = NULL;
...@@ -306,16 +323,16 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp, ...@@ -306,16 +323,16 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp,
*/ */
IP_VS_DBG(7, "protocol %s %u.%u.%u.%u:%d %u.%u.%u.%u:%d\n", IP_VS_DBG(7, "protocol %s %u.%u.%u.%u:%d %u.%u.%u.%u:%d\n",
ip_vs_proto_name(iph->protocol), ip_vs_proto_name(iph->protocol),
NIPQUAD(to), ntohs(port), NIPQUAD(cp->vaddr), 0); NIPQUAD(to.ip), ntohs(port), NIPQUAD(cp->vaddr.ip), 0);
n_cp = ip_vs_conn_in_get(iph->protocol, n_cp = ip_vs_conn_in_get(AF_INET, iph->protocol,
to, port, &to, port,
cp->vaddr, htons(ntohs(cp->vport)-1)); &cp->vaddr, htons(ntohs(cp->vport)-1));
if (!n_cp) { if (!n_cp) {
n_cp = ip_vs_conn_new(IPPROTO_TCP, n_cp = ip_vs_conn_new(AF_INET, IPPROTO_TCP,
to, port, &to, port,
cp->vaddr, htons(ntohs(cp->vport)-1), &cp->vaddr, htons(ntohs(cp->vport)-1),
cp->daddr, htons(ntohs(cp->dport)-1), &cp->daddr, htons(ntohs(cp->dport)-1),
0, 0,
cp->dest); cp->dest);
if (!n_cp) if (!n_cp)
......
...@@ -422,7 +422,7 @@ __ip_vs_lblc_schedule(struct ip_vs_service *svc, struct iphdr *iph) ...@@ -422,7 +422,7 @@ __ip_vs_lblc_schedule(struct ip_vs_service *svc, struct iphdr *iph)
IP_VS_DBG(6, "LBLC: server %d.%d.%d.%d:%d " IP_VS_DBG(6, "LBLC: server %d.%d.%d.%d:%d "
"activeconns %d refcnt %d weight %d overhead %d\n", "activeconns %d refcnt %d weight %d overhead %d\n",
NIPQUAD(least->addr), ntohs(least->port), NIPQUAD(least->addr.ip), ntohs(least->port),
atomic_read(&least->activeconns), atomic_read(&least->activeconns),
atomic_read(&least->refcnt), atomic_read(&least->refcnt),
atomic_read(&least->weight), loh); atomic_read(&least->weight), loh);
...@@ -506,7 +506,7 @@ ip_vs_lblc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) ...@@ -506,7 +506,7 @@ ip_vs_lblc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
IP_VS_DBG(6, "LBLC: destination IP address %u.%u.%u.%u " IP_VS_DBG(6, "LBLC: destination IP address %u.%u.%u.%u "
"--> server %u.%u.%u.%u:%d\n", "--> server %u.%u.%u.%u:%d\n",
NIPQUAD(iph->daddr), NIPQUAD(iph->daddr),
NIPQUAD(dest->addr), NIPQUAD(dest->addr.ip),
ntohs(dest->port)); ntohs(dest->port));
return dest; return dest;
...@@ -522,6 +522,9 @@ static struct ip_vs_scheduler ip_vs_lblc_scheduler = ...@@ -522,6 +522,9 @@ static struct ip_vs_scheduler ip_vs_lblc_scheduler =
.refcnt = ATOMIC_INIT(0), .refcnt = ATOMIC_INIT(0),
.module = THIS_MODULE, .module = THIS_MODULE,
.n_list = LIST_HEAD_INIT(ip_vs_lblc_scheduler.n_list), .n_list = LIST_HEAD_INIT(ip_vs_lblc_scheduler.n_list),
#ifdef CONFIG_IP_VS_IPV6
.supports_ipv6 = 0,
#endif
.init_service = ip_vs_lblc_init_svc, .init_service = ip_vs_lblc_init_svc,
.done_service = ip_vs_lblc_done_svc, .done_service = ip_vs_lblc_done_svc,
.schedule = ip_vs_lblc_schedule, .schedule = ip_vs_lblc_schedule,
......
...@@ -204,7 +204,7 @@ static inline struct ip_vs_dest *ip_vs_dest_set_min(struct ip_vs_dest_set *set) ...@@ -204,7 +204,7 @@ static inline struct ip_vs_dest *ip_vs_dest_set_min(struct ip_vs_dest_set *set)
IP_VS_DBG(6, "ip_vs_dest_set_min: server %d.%d.%d.%d:%d " IP_VS_DBG(6, "ip_vs_dest_set_min: server %d.%d.%d.%d:%d "
"activeconns %d refcnt %d weight %d overhead %d\n", "activeconns %d refcnt %d weight %d overhead %d\n",
NIPQUAD(least->addr), ntohs(least->port), NIPQUAD(least->addr.ip), ntohs(least->port),
atomic_read(&least->activeconns), atomic_read(&least->activeconns),
atomic_read(&least->refcnt), atomic_read(&least->refcnt),
atomic_read(&least->weight), loh); atomic_read(&least->weight), loh);
...@@ -250,7 +250,7 @@ static inline struct ip_vs_dest *ip_vs_dest_set_max(struct ip_vs_dest_set *set) ...@@ -250,7 +250,7 @@ static inline struct ip_vs_dest *ip_vs_dest_set_max(struct ip_vs_dest_set *set)
IP_VS_DBG(6, "ip_vs_dest_set_max: server %d.%d.%d.%d:%d " IP_VS_DBG(6, "ip_vs_dest_set_max: server %d.%d.%d.%d:%d "
"activeconns %d refcnt %d weight %d overhead %d\n", "activeconns %d refcnt %d weight %d overhead %d\n",
NIPQUAD(most->addr), ntohs(most->port), NIPQUAD(most->addr.ip), ntohs(most->port),
atomic_read(&most->activeconns), atomic_read(&most->activeconns),
atomic_read(&most->refcnt), atomic_read(&most->refcnt),
atomic_read(&most->weight), moh); atomic_read(&most->weight), moh);
...@@ -598,7 +598,7 @@ __ip_vs_lblcr_schedule(struct ip_vs_service *svc, struct iphdr *iph) ...@@ -598,7 +598,7 @@ __ip_vs_lblcr_schedule(struct ip_vs_service *svc, struct iphdr *iph)
IP_VS_DBG(6, "LBLCR: server %d.%d.%d.%d:%d " IP_VS_DBG(6, "LBLCR: server %d.%d.%d.%d:%d "
"activeconns %d refcnt %d weight %d overhead %d\n", "activeconns %d refcnt %d weight %d overhead %d\n",
NIPQUAD(least->addr), ntohs(least->port), NIPQUAD(least->addr.ip), ntohs(least->port),
atomic_read(&least->activeconns), atomic_read(&least->activeconns),
atomic_read(&least->refcnt), atomic_read(&least->refcnt),
atomic_read(&least->weight), loh); atomic_read(&least->weight), loh);
...@@ -706,7 +706,7 @@ ip_vs_lblcr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) ...@@ -706,7 +706,7 @@ ip_vs_lblcr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
IP_VS_DBG(6, "LBLCR: destination IP address %u.%u.%u.%u " IP_VS_DBG(6, "LBLCR: destination IP address %u.%u.%u.%u "
"--> server %u.%u.%u.%u:%d\n", "--> server %u.%u.%u.%u:%d\n",
NIPQUAD(iph->daddr), NIPQUAD(iph->daddr),
NIPQUAD(dest->addr), NIPQUAD(dest->addr.ip),
ntohs(dest->port)); ntohs(dest->port));
return dest; return dest;
...@@ -722,6 +722,9 @@ static struct ip_vs_scheduler ip_vs_lblcr_scheduler = ...@@ -722,6 +722,9 @@ static struct ip_vs_scheduler ip_vs_lblcr_scheduler =
.refcnt = ATOMIC_INIT(0), .refcnt = ATOMIC_INIT(0),
.module = THIS_MODULE, .module = THIS_MODULE,
.n_list = LIST_HEAD_INIT(ip_vs_lblcr_scheduler.n_list), .n_list = LIST_HEAD_INIT(ip_vs_lblcr_scheduler.n_list),
#ifdef CONFIG_IP_VS_IPV6
.supports_ipv6 = 0,
#endif
.init_service = ip_vs_lblcr_init_svc, .init_service = ip_vs_lblcr_init_svc,
.done_service = ip_vs_lblcr_done_svc, .done_service = ip_vs_lblcr_done_svc,
.schedule = ip_vs_lblcr_schedule, .schedule = ip_vs_lblcr_schedule,
......
...@@ -67,10 +67,10 @@ ip_vs_lc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) ...@@ -67,10 +67,10 @@ ip_vs_lc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
} }
if (least) if (least)
IP_VS_DBG(6, "LC: server %u.%u.%u.%u:%u activeconns %d inactconns %d\n", IP_VS_DBG_BUF(6, "LC: server %s:%u activeconns %d inactconns %d\n",
NIPQUAD(least->addr), ntohs(least->port), IP_VS_DBG_ADDR(svc->af, &least->addr), ntohs(least->port),
atomic_read(&least->activeconns), atomic_read(&least->activeconns),
atomic_read(&least->inactconns)); atomic_read(&least->inactconns));
return least; return least;
} }
...@@ -81,6 +81,9 @@ static struct ip_vs_scheduler ip_vs_lc_scheduler = { ...@@ -81,6 +81,9 @@ static struct ip_vs_scheduler ip_vs_lc_scheduler = {
.refcnt = ATOMIC_INIT(0), .refcnt = ATOMIC_INIT(0),
.module = THIS_MODULE, .module = THIS_MODULE,
.n_list = LIST_HEAD_INIT(ip_vs_lc_scheduler.n_list), .n_list = LIST_HEAD_INIT(ip_vs_lc_scheduler.n_list),
#ifdef CONFIG_IP_VS_IPV6
.supports_ipv6 = 1,
#endif
.schedule = ip_vs_lc_schedule, .schedule = ip_vs_lc_schedule,
}; };
......
...@@ -99,12 +99,12 @@ ip_vs_nq_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) ...@@ -99,12 +99,12 @@ ip_vs_nq_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
return NULL; return NULL;
out: out:
IP_VS_DBG(6, "NQ: server %u.%u.%u.%u:%u " IP_VS_DBG_BUF(6, "NQ: server %s:%u "
"activeconns %d refcnt %d weight %d overhead %d\n", "activeconns %d refcnt %d weight %d overhead %d\n",
NIPQUAD(least->addr), ntohs(least->port), IP_VS_DBG_ADDR(svc->af, &least->addr), ntohs(least->port),
atomic_read(&least->activeconns), atomic_read(&least->activeconns),
atomic_read(&least->refcnt), atomic_read(&least->refcnt),
atomic_read(&least->weight), loh); atomic_read(&least->weight), loh);
return least; return least;
} }
...@@ -116,6 +116,9 @@ static struct ip_vs_scheduler ip_vs_nq_scheduler = ...@@ -116,6 +116,9 @@ static struct ip_vs_scheduler ip_vs_nq_scheduler =
.refcnt = ATOMIC_INIT(0), .refcnt = ATOMIC_INIT(0),
.module = THIS_MODULE, .module = THIS_MODULE,
.n_list = LIST_HEAD_INIT(ip_vs_nq_scheduler.n_list), .n_list = LIST_HEAD_INIT(ip_vs_nq_scheduler.n_list),
#ifdef CONFIG_IP_VS_IPV6
.supports_ipv6 = 1,
#endif
.schedule = ip_vs_nq_schedule, .schedule = ip_vs_nq_schedule,
}; };
......
...@@ -151,11 +151,11 @@ const char * ip_vs_state_name(__u16 proto, int state) ...@@ -151,11 +151,11 @@ const char * ip_vs_state_name(__u16 proto, int state)
} }
void static void
ip_vs_tcpudp_debug_packet(struct ip_vs_protocol *pp, ip_vs_tcpudp_debug_packet_v4(struct ip_vs_protocol *pp,
const struct sk_buff *skb, const struct sk_buff *skb,
int offset, int offset,
const char *msg) const char *msg)
{ {
char buf[128]; char buf[128];
struct iphdr _iph, *ih; struct iphdr _iph, *ih;
...@@ -189,6 +189,61 @@ ip_vs_tcpudp_debug_packet(struct ip_vs_protocol *pp, ...@@ -189,6 +189,61 @@ ip_vs_tcpudp_debug_packet(struct ip_vs_protocol *pp,
printk(KERN_DEBUG "IPVS: %s: %s\n", msg, buf); printk(KERN_DEBUG "IPVS: %s: %s\n", msg, buf);
} }
#ifdef CONFIG_IP_VS_IPV6
static void
ip_vs_tcpudp_debug_packet_v6(struct ip_vs_protocol *pp,
const struct sk_buff *skb,
int offset,
const char *msg)
{
char buf[192];
struct ipv6hdr _iph, *ih;
ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph);
if (ih == NULL)
sprintf(buf, "%s TRUNCATED", pp->name);
else if (ih->nexthdr == IPPROTO_FRAGMENT)
sprintf(buf, "%s " NIP6_FMT "->" NIP6_FMT " frag",
pp->name, NIP6(ih->saddr),
NIP6(ih->daddr));
else {
__be16 _ports[2], *pptr;
pptr = skb_header_pointer(skb, offset + sizeof(struct ipv6hdr),
sizeof(_ports), _ports);
if (pptr == NULL)
sprintf(buf, "%s TRUNCATED " NIP6_FMT "->" NIP6_FMT,
pp->name,
NIP6(ih->saddr),
NIP6(ih->daddr));
else
sprintf(buf, "%s " NIP6_FMT ":%u->" NIP6_FMT ":%u",
pp->name,
NIP6(ih->saddr),
ntohs(pptr[0]),
NIP6(ih->daddr),
ntohs(pptr[1]));
}
printk(KERN_DEBUG "IPVS: %s: %s\n", msg, buf);
}
#endif
void
ip_vs_tcpudp_debug_packet(struct ip_vs_protocol *pp,
const struct sk_buff *skb,
int offset,
const char *msg)
{
#ifdef CONFIG_IP_VS_IPV6
if (skb->protocol == __constant_htons(ETH_P_IPV6))
ip_vs_tcpudp_debug_packet_v6(pp, skb, offset, msg);
else
#endif
ip_vs_tcpudp_debug_packet_v4(pp, skb, offset, msg);
}
int __init ip_vs_protocol_init(void) int __init ip_vs_protocol_init(void)
{ {
......
...@@ -39,25 +39,23 @@ struct isakmp_hdr { ...@@ -39,25 +39,23 @@ struct isakmp_hdr {
static struct ip_vs_conn * static struct ip_vs_conn *
ah_esp_conn_in_get(const struct sk_buff *skb, ah_esp_conn_in_get(int af, const struct sk_buff *skb, struct ip_vs_protocol *pp,
struct ip_vs_protocol *pp, const struct ip_vs_iphdr *iph, unsigned int proto_off,
const struct iphdr *iph,
unsigned int proto_off,
int inverse) int inverse)
{ {
struct ip_vs_conn *cp; struct ip_vs_conn *cp;
if (likely(!inverse)) { if (likely(!inverse)) {
cp = ip_vs_conn_in_get(IPPROTO_UDP, cp = ip_vs_conn_in_get(af, IPPROTO_UDP,
iph->saddr, &iph->saddr,
htons(PORT_ISAKMP), htons(PORT_ISAKMP),
iph->daddr, &iph->daddr,
htons(PORT_ISAKMP)); htons(PORT_ISAKMP));
} else { } else {
cp = ip_vs_conn_in_get(IPPROTO_UDP, cp = ip_vs_conn_in_get(af, IPPROTO_UDP,
iph->daddr, &iph->daddr,
htons(PORT_ISAKMP), htons(PORT_ISAKMP),
iph->saddr, &iph->saddr,
htons(PORT_ISAKMP)); htons(PORT_ISAKMP));
} }
...@@ -66,12 +64,12 @@ ah_esp_conn_in_get(const struct sk_buff *skb, ...@@ -66,12 +64,12 @@ ah_esp_conn_in_get(const struct sk_buff *skb,
* We are not sure if the packet is from our * We are not sure if the packet is from our
* service, so our conn_schedule hook should return NF_ACCEPT * service, so our conn_schedule hook should return NF_ACCEPT
*/ */
IP_VS_DBG(12, "Unknown ISAKMP entry for outin packet " IP_VS_DBG_BUF(12, "Unknown ISAKMP entry for outin packet "
"%s%s %u.%u.%u.%u->%u.%u.%u.%u\n", "%s%s %s->%s\n",
inverse ? "ICMP+" : "", inverse ? "ICMP+" : "",
pp->name, pp->name,
NIPQUAD(iph->saddr), IP_VS_DBG_ADDR(af, &iph->saddr),
NIPQUAD(iph->daddr)); IP_VS_DBG_ADDR(af, &iph->daddr));
} }
return cp; return cp;
...@@ -79,32 +77,35 @@ ah_esp_conn_in_get(const struct sk_buff *skb, ...@@ -79,32 +77,35 @@ ah_esp_conn_in_get(const struct sk_buff *skb,
static struct ip_vs_conn * static struct ip_vs_conn *
ah_esp_conn_out_get(const struct sk_buff *skb, struct ip_vs_protocol *pp, ah_esp_conn_out_get(int af, const struct sk_buff *skb,
const struct iphdr *iph, unsigned int proto_off, int inverse) struct ip_vs_protocol *pp,
const struct ip_vs_iphdr *iph,
unsigned int proto_off,
int inverse)
{ {
struct ip_vs_conn *cp; struct ip_vs_conn *cp;
if (likely(!inverse)) { if (likely(!inverse)) {
cp = ip_vs_conn_out_get(IPPROTO_UDP, cp = ip_vs_conn_out_get(af, IPPROTO_UDP,
iph->saddr, &iph->saddr,
htons(PORT_ISAKMP), htons(PORT_ISAKMP),
iph->daddr, &iph->daddr,
htons(PORT_ISAKMP)); htons(PORT_ISAKMP));
} else { } else {
cp = ip_vs_conn_out_get(IPPROTO_UDP, cp = ip_vs_conn_out_get(af, IPPROTO_UDP,
iph->daddr, &iph->daddr,
htons(PORT_ISAKMP), htons(PORT_ISAKMP),
iph->saddr, &iph->saddr,
htons(PORT_ISAKMP)); htons(PORT_ISAKMP));
} }
if (!cp) { if (!cp) {
IP_VS_DBG(12, "Unknown ISAKMP entry for inout packet " IP_VS_DBG_BUF(12, "Unknown ISAKMP entry for inout packet "
"%s%s %u.%u.%u.%u->%u.%u.%u.%u\n", "%s%s %s->%s\n",
inverse ? "ICMP+" : "", inverse ? "ICMP+" : "",
pp->name, pp->name,
NIPQUAD(iph->saddr), IP_VS_DBG_ADDR(af, &iph->saddr),
NIPQUAD(iph->daddr)); IP_VS_DBG_ADDR(af, &iph->daddr));
} }
return cp; return cp;
...@@ -112,8 +113,7 @@ ah_esp_conn_out_get(const struct sk_buff *skb, struct ip_vs_protocol *pp, ...@@ -112,8 +113,7 @@ ah_esp_conn_out_get(const struct sk_buff *skb, struct ip_vs_protocol *pp,
static int static int
ah_esp_conn_schedule(struct sk_buff *skb, ah_esp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
struct ip_vs_protocol *pp,
int *verdict, struct ip_vs_conn **cpp) int *verdict, struct ip_vs_conn **cpp)
{ {
/* /*
...@@ -125,8 +125,8 @@ ah_esp_conn_schedule(struct sk_buff *skb, ...@@ -125,8 +125,8 @@ ah_esp_conn_schedule(struct sk_buff *skb,
static void static void
ah_esp_debug_packet(struct ip_vs_protocol *pp, const struct sk_buff *skb, ah_esp_debug_packet_v4(struct ip_vs_protocol *pp, const struct sk_buff *skb,
int offset, const char *msg) int offset, const char *msg)
{ {
char buf[256]; char buf[256];
struct iphdr _iph, *ih; struct iphdr _iph, *ih;
...@@ -142,6 +142,38 @@ ah_esp_debug_packet(struct ip_vs_protocol *pp, const struct sk_buff *skb, ...@@ -142,6 +142,38 @@ ah_esp_debug_packet(struct ip_vs_protocol *pp, const struct sk_buff *skb,
printk(KERN_DEBUG "IPVS: %s: %s\n", msg, buf); printk(KERN_DEBUG "IPVS: %s: %s\n", msg, buf);
} }
#ifdef CONFIG_IP_VS_IPV6
static void
ah_esp_debug_packet_v6(struct ip_vs_protocol *pp, const struct sk_buff *skb,
int offset, const char *msg)
{
char buf[256];
struct ipv6hdr _iph, *ih;
ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph);
if (ih == NULL)
sprintf(buf, "%s TRUNCATED", pp->name);
else
sprintf(buf, "%s " NIP6_FMT "->" NIP6_FMT,
pp->name, NIP6(ih->saddr),
NIP6(ih->daddr));
printk(KERN_DEBUG "IPVS: %s: %s\n", msg, buf);
}
#endif
static void
ah_esp_debug_packet(struct ip_vs_protocol *pp, const struct sk_buff *skb,
int offset, const char *msg)
{
#ifdef CONFIG_IP_VS_IPV6
if (skb->protocol == __constant_htons(ETH_P_IPV6))
ah_esp_debug_packet_v6(pp, skb, offset, msg);
else
#endif
ah_esp_debug_packet_v4(pp, skb, offset, msg);
}
static void ah_esp_init(struct ip_vs_protocol *pp) static void ah_esp_init(struct ip_vs_protocol *pp)
{ {
......
This diff is collapsed.
This diff is collapsed.
...@@ -74,11 +74,11 @@ ip_vs_rr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) ...@@ -74,11 +74,11 @@ ip_vs_rr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
out: out:
svc->sched_data = q; svc->sched_data = q;
write_unlock(&svc->sched_lock); write_unlock(&svc->sched_lock);
IP_VS_DBG(6, "RR: server %u.%u.%u.%u:%u " IP_VS_DBG_BUF(6, "RR: server %s:%u "
"activeconns %d refcnt %d weight %d\n", "activeconns %d refcnt %d weight %d\n",
NIPQUAD(dest->addr), ntohs(dest->port), IP_VS_DBG_ADDR(svc->af, &dest->addr), ntohs(dest->port),
atomic_read(&dest->activeconns), atomic_read(&dest->activeconns),
atomic_read(&dest->refcnt), atomic_read(&dest->weight)); atomic_read(&dest->refcnt), atomic_read(&dest->weight));
return dest; return dest;
} }
...@@ -89,6 +89,9 @@ static struct ip_vs_scheduler ip_vs_rr_scheduler = { ...@@ -89,6 +89,9 @@ static struct ip_vs_scheduler ip_vs_rr_scheduler = {
.refcnt = ATOMIC_INIT(0), .refcnt = ATOMIC_INIT(0),
.module = THIS_MODULE, .module = THIS_MODULE,
.n_list = LIST_HEAD_INIT(ip_vs_rr_scheduler.n_list), .n_list = LIST_HEAD_INIT(ip_vs_rr_scheduler.n_list),
#ifdef CONFIG_IP_VS_IPV6
.supports_ipv6 = 1,
#endif
.init_service = ip_vs_rr_init_svc, .init_service = ip_vs_rr_init_svc,
.update_service = ip_vs_rr_update_svc, .update_service = ip_vs_rr_update_svc,
.schedule = ip_vs_rr_schedule, .schedule = ip_vs_rr_schedule,
......
...@@ -101,12 +101,12 @@ ip_vs_sed_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) ...@@ -101,12 +101,12 @@ ip_vs_sed_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
} }
} }
IP_VS_DBG(6, "SED: server %u.%u.%u.%u:%u " IP_VS_DBG_BUF(6, "SED: server %s:%u "
"activeconns %d refcnt %d weight %d overhead %d\n", "activeconns %d refcnt %d weight %d overhead %d\n",
NIPQUAD(least->addr), ntohs(least->port), IP_VS_DBG_ADDR(svc->af, &least->addr), ntohs(least->port),
atomic_read(&least->activeconns), atomic_read(&least->activeconns),
atomic_read(&least->refcnt), atomic_read(&least->refcnt),
atomic_read(&least->weight), loh); atomic_read(&least->weight), loh);
return least; return least;
} }
...@@ -118,6 +118,9 @@ static struct ip_vs_scheduler ip_vs_sed_scheduler = ...@@ -118,6 +118,9 @@ static struct ip_vs_scheduler ip_vs_sed_scheduler =
.refcnt = ATOMIC_INIT(0), .refcnt = ATOMIC_INIT(0),
.module = THIS_MODULE, .module = THIS_MODULE,
.n_list = LIST_HEAD_INIT(ip_vs_sed_scheduler.n_list), .n_list = LIST_HEAD_INIT(ip_vs_sed_scheduler.n_list),
#ifdef CONFIG_IP_VS_IPV6
.supports_ipv6 = 1,
#endif
.schedule = ip_vs_sed_schedule, .schedule = ip_vs_sed_schedule,
}; };
......
...@@ -215,7 +215,7 @@ ip_vs_sh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) ...@@ -215,7 +215,7 @@ ip_vs_sh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
IP_VS_DBG(6, "SH: source IP address %u.%u.%u.%u " IP_VS_DBG(6, "SH: source IP address %u.%u.%u.%u "
"--> server %u.%u.%u.%u:%d\n", "--> server %u.%u.%u.%u:%d\n",
NIPQUAD(iph->saddr), NIPQUAD(iph->saddr),
NIPQUAD(dest->addr), NIPQUAD(dest->addr.ip),
ntohs(dest->port)); ntohs(dest->port));
return dest; return dest;
...@@ -231,6 +231,9 @@ static struct ip_vs_scheduler ip_vs_sh_scheduler = ...@@ -231,6 +231,9 @@ static struct ip_vs_scheduler ip_vs_sh_scheduler =
.refcnt = ATOMIC_INIT(0), .refcnt = ATOMIC_INIT(0),
.module = THIS_MODULE, .module = THIS_MODULE,
.n_list = LIST_HEAD_INIT(ip_vs_sh_scheduler.n_list), .n_list = LIST_HEAD_INIT(ip_vs_sh_scheduler.n_list),
#ifdef CONFIG_IP_VS_IPV6
.supports_ipv6 = 0,
#endif
.init_service = ip_vs_sh_init_svc, .init_service = ip_vs_sh_init_svc,
.done_service = ip_vs_sh_done_svc, .done_service = ip_vs_sh_done_svc,
.update_service = ip_vs_sh_update_svc, .update_service = ip_vs_sh_update_svc,
......
...@@ -256,9 +256,9 @@ void ip_vs_sync_conn(struct ip_vs_conn *cp) ...@@ -256,9 +256,9 @@ void ip_vs_sync_conn(struct ip_vs_conn *cp)
s->cport = cp->cport; s->cport = cp->cport;
s->vport = cp->vport; s->vport = cp->vport;
s->dport = cp->dport; s->dport = cp->dport;
s->caddr = cp->caddr; s->caddr = cp->caddr.ip;
s->vaddr = cp->vaddr; s->vaddr = cp->vaddr.ip;
s->daddr = cp->daddr; s->daddr = cp->daddr.ip;
s->flags = htons(cp->flags & ~IP_VS_CONN_F_HASHED); s->flags = htons(cp->flags & ~IP_VS_CONN_F_HASHED);
s->state = htons(cp->state); s->state = htons(cp->state);
if (cp->flags & IP_VS_CONN_F_SEQ_MASK) { if (cp->flags & IP_VS_CONN_F_SEQ_MASK) {
...@@ -366,21 +366,28 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen) ...@@ -366,21 +366,28 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
} }
if (!(flags & IP_VS_CONN_F_TEMPLATE)) if (!(flags & IP_VS_CONN_F_TEMPLATE))
cp = ip_vs_conn_in_get(s->protocol, cp = ip_vs_conn_in_get(AF_INET, s->protocol,
s->caddr, s->cport, (union nf_inet_addr *)&s->caddr,
s->vaddr, s->vport); s->cport,
(union nf_inet_addr *)&s->vaddr,
s->vport);
else else
cp = ip_vs_ct_in_get(s->protocol, cp = ip_vs_ct_in_get(AF_INET, s->protocol,
s->caddr, s->cport, (union nf_inet_addr *)&s->caddr,
s->vaddr, s->vport); s->cport,
(union nf_inet_addr *)&s->vaddr,
s->vport);
if (!cp) { if (!cp) {
/* /*
* Find the appropriate destination for the connection. * Find the appropriate destination for the connection.
* If it is not found the connection will remain unbound * If it is not found the connection will remain unbound
* but still handled. * but still handled.
*/ */
dest = ip_vs_find_dest(s->daddr, s->dport, dest = ip_vs_find_dest(AF_INET,
s->vaddr, s->vport, (union nf_inet_addr *)&s->daddr,
s->dport,
(union nf_inet_addr *)&s->vaddr,
s->vport,
s->protocol); s->protocol);
/* Set the approprite ativity flag */ /* Set the approprite ativity flag */
if (s->protocol == IPPROTO_TCP) { if (s->protocol == IPPROTO_TCP) {
...@@ -389,10 +396,13 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen) ...@@ -389,10 +396,13 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
else else
flags &= ~IP_VS_CONN_F_INACTIVE; flags &= ~IP_VS_CONN_F_INACTIVE;
} }
cp = ip_vs_conn_new(s->protocol, cp = ip_vs_conn_new(AF_INET, s->protocol,
s->caddr, s->cport, (union nf_inet_addr *)&s->caddr,
s->vaddr, s->vport, s->cport,
s->daddr, s->dport, (union nf_inet_addr *)&s->vaddr,
s->vport,
(union nf_inet_addr *)&s->daddr,
s->dport,
flags, dest); flags, dest);
if (dest) if (dest)
atomic_dec(&dest->refcnt); atomic_dec(&dest->refcnt);
......
...@@ -89,12 +89,12 @@ ip_vs_wlc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) ...@@ -89,12 +89,12 @@ ip_vs_wlc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
} }
} }
IP_VS_DBG(6, "WLC: server %u.%u.%u.%u:%u " IP_VS_DBG_BUF(6, "WLC: server %s:%u "
"activeconns %d refcnt %d weight %d overhead %d\n", "activeconns %d refcnt %d weight %d overhead %d\n",
NIPQUAD(least->addr), ntohs(least->port), IP_VS_DBG_ADDR(svc->af, &least->addr), ntohs(least->port),
atomic_read(&least->activeconns), atomic_read(&least->activeconns),
atomic_read(&least->refcnt), atomic_read(&least->refcnt),
atomic_read(&least->weight), loh); atomic_read(&least->weight), loh);
return least; return least;
} }
...@@ -106,6 +106,9 @@ static struct ip_vs_scheduler ip_vs_wlc_scheduler = ...@@ -106,6 +106,9 @@ static struct ip_vs_scheduler ip_vs_wlc_scheduler =
.refcnt = ATOMIC_INIT(0), .refcnt = ATOMIC_INIT(0),
.module = THIS_MODULE, .module = THIS_MODULE,
.n_list = LIST_HEAD_INIT(ip_vs_wlc_scheduler.n_list), .n_list = LIST_HEAD_INIT(ip_vs_wlc_scheduler.n_list),
#ifdef CONFIG_IP_VS_IPV6
.supports_ipv6 = 1,
#endif
.schedule = ip_vs_wlc_schedule, .schedule = ip_vs_wlc_schedule,
}; };
......
...@@ -195,12 +195,12 @@ ip_vs_wrr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) ...@@ -195,12 +195,12 @@ ip_vs_wrr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
} }
} }
IP_VS_DBG(6, "WRR: server %u.%u.%u.%u:%u " IP_VS_DBG_BUF(6, "WRR: server %s:%u "
"activeconns %d refcnt %d weight %d\n", "activeconns %d refcnt %d weight %d\n",
NIPQUAD(dest->addr), ntohs(dest->port), IP_VS_DBG_ADDR(svc->af, &dest->addr), ntohs(dest->port),
atomic_read(&dest->activeconns), atomic_read(&dest->activeconns),
atomic_read(&dest->refcnt), atomic_read(&dest->refcnt),
atomic_read(&dest->weight)); atomic_read(&dest->weight));
out: out:
write_unlock(&svc->sched_lock); write_unlock(&svc->sched_lock);
...@@ -213,6 +213,9 @@ static struct ip_vs_scheduler ip_vs_wrr_scheduler = { ...@@ -213,6 +213,9 @@ static struct ip_vs_scheduler ip_vs_wrr_scheduler = {
.refcnt = ATOMIC_INIT(0), .refcnt = ATOMIC_INIT(0),
.module = THIS_MODULE, .module = THIS_MODULE,
.n_list = LIST_HEAD_INIT(ip_vs_wrr_scheduler.n_list), .n_list = LIST_HEAD_INIT(ip_vs_wrr_scheduler.n_list),
#ifdef CONFIG_IP_VS_IPV6
.supports_ipv6 = 1,
#endif
.init_service = ip_vs_wrr_init_svc, .init_service = ip_vs_wrr_init_svc,
.done_service = ip_vs_wrr_done_svc, .done_service = ip_vs_wrr_done_svc,
.update_service = ip_vs_wrr_update_svc, .update_service = ip_vs_wrr_update_svc,
......
This diff is collapsed.
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