aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulian Anastasov <ja@ssi.bg>2010-09-17 08:18:16 -0400
committerPatrick McHardy <kaber@trash.net>2010-09-17 08:18:16 -0400
commit3575792e005dc9994f15ae72c1c6f401d134177d (patch)
tree2383227df0b4ab3418ecb2167535063b7f829f4d
parentb23909695c33f53df5f1d16696b1aa5b874c1904 (diff)
ipvs: extend connection flags to 32 bits
- the sync protocol supports 16 bits only, so bits 0..15 should be used only for flags that should go to backup server, bits 16 and above should be allocated for flags not sent to backup. - use IP_VS_CONN_F_DEST_MASK as mask of connection flags in destination that can be changed by user space - allow IP_VS_CONN_F_ONE_PACKET to be set in destination Signed-off-by: Julian Anastasov <ja@ssi.bg> Signed-off-by: Patrick McHardy <kaber@trash.net>
-rw-r--r--include/linux/ip_vs.h8
-rw-r--r--include/net/ip_vs.h2
-rw-r--r--net/netfilter/ipvs/ip_vs_conn.c16
-rw-r--r--net/netfilter/ipvs/ip_vs_core.c11
-rw-r--r--net/netfilter/ipvs/ip_vs_ctl.c5
5 files changed, 28 insertions, 14 deletions
diff --git a/include/linux/ip_vs.h b/include/linux/ip_vs.h
index 9708de265bb1..003d75f6ffe1 100644
--- a/include/linux/ip_vs.h
+++ b/include/linux/ip_vs.h
@@ -70,6 +70,7 @@
70 70
71/* 71/*
72 * IPVS Connection Flags 72 * IPVS Connection Flags
73 * Only flags 0..15 are sent to backup server
73 */ 74 */
74#define IP_VS_CONN_F_FWD_MASK 0x0007 /* mask for the fwd methods */ 75#define IP_VS_CONN_F_FWD_MASK 0x0007 /* mask for the fwd methods */
75#define IP_VS_CONN_F_MASQ 0x0000 /* masquerading/NAT */ 76#define IP_VS_CONN_F_MASQ 0x0000 /* masquerading/NAT */
@@ -88,6 +89,13 @@
88#define IP_VS_CONN_F_TEMPLATE 0x1000 /* template, not connection */ 89#define IP_VS_CONN_F_TEMPLATE 0x1000 /* template, not connection */
89#define IP_VS_CONN_F_ONE_PACKET 0x2000 /* forward only one packet */ 90#define IP_VS_CONN_F_ONE_PACKET 0x2000 /* forward only one packet */
90 91
92/* Flags that are not sent to backup server start from bit 16 */
93
94/* Connection flags from destination that can be changed by user space */
95#define IP_VS_CONN_F_DEST_MASK (IP_VS_CONN_F_FWD_MASK | \
96 IP_VS_CONN_F_ONE_PACKET | \
97 0)
98
91#define IP_VS_SCHEDNAME_MAXLEN 16 99#define IP_VS_SCHEDNAME_MAXLEN 16
92#define IP_VS_IFNAME_MAXLEN 16 100#define IP_VS_IFNAME_MAXLEN 16
93 101
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index f976885f686f..62698a9c1631 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -366,6 +366,7 @@ struct ip_vs_conn {
366 union nf_inet_addr caddr; /* client address */ 366 union nf_inet_addr caddr; /* client address */
367 union nf_inet_addr vaddr; /* virtual address */ 367 union nf_inet_addr vaddr; /* virtual address */
368 union nf_inet_addr daddr; /* destination address */ 368 union nf_inet_addr daddr; /* destination address */
369 volatile __u32 flags; /* status flags */
369 __be16 cport; 370 __be16 cport;
370 __be16 vport; 371 __be16 vport;
371 __be16 dport; 372 __be16 dport;
@@ -378,7 +379,6 @@ struct ip_vs_conn {
378 379
379 /* Flags and state transition */ 380 /* Flags and state transition */
380 spinlock_t lock; /* lock for state transition */ 381 spinlock_t lock; /* lock for state transition */
381 volatile __u16 flags; /* status flags */
382 volatile __u16 state; /* state info */ 382 volatile __u16 state; /* state info */
383 volatile __u16 old_state; /* old state, to be used for 383 volatile __u16 old_state; /* old state, to be used for
384 * state transition triggerd 384 * state transition triggerd
diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c
index b71c69a2db13..9fe1da7bcf16 100644
--- a/net/netfilter/ipvs/ip_vs_conn.c
+++ b/net/netfilter/ipvs/ip_vs_conn.c
@@ -505,6 +505,8 @@ static inline int ip_vs_dest_totalconns(struct ip_vs_dest *dest)
505static inline void 505static inline void
506ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest) 506ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest)
507{ 507{
508 unsigned int conn_flags;
509
508 /* if dest is NULL, then return directly */ 510 /* if dest is NULL, then return directly */
509 if (!dest) 511 if (!dest)
510 return; 512 return;
@@ -512,16 +514,18 @@ ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest)
512 /* Increase the refcnt counter of the dest */ 514 /* Increase the refcnt counter of the dest */
513 atomic_inc(&dest->refcnt); 515 atomic_inc(&dest->refcnt);
514 516
517 conn_flags = atomic_read(&dest->conn_flags);
518 if (cp->protocol != IPPROTO_UDP)
519 conn_flags &= ~IP_VS_CONN_F_ONE_PACKET;
515 /* Bind with the destination and its corresponding transmitter */ 520 /* Bind with the destination and its corresponding transmitter */
516 if ((cp->flags & IP_VS_CONN_F_SYNC) && 521 if (cp->flags & IP_VS_CONN_F_SYNC) {
517 (!(cp->flags & IP_VS_CONN_F_TEMPLATE)))
518 /* if the connection is not template and is created 522 /* if the connection is not template and is created
519 * by sync, preserve the activity flag. 523 * by sync, preserve the activity flag.
520 */ 524 */
521 cp->flags |= atomic_read(&dest->conn_flags) & 525 if (!(cp->flags & IP_VS_CONN_F_TEMPLATE))
522 (~IP_VS_CONN_F_INACTIVE); 526 conn_flags &= ~IP_VS_CONN_F_INACTIVE;
523 else 527 }
524 cp->flags |= atomic_read(&dest->conn_flags); 528 cp->flags |= conn_flags;
525 cp->dest = dest; 529 cp->dest = dest;
526 530
527 IP_VS_DBG_BUF(7, "Bind-dest %s c:%s:%d v:%s:%d " 531 IP_VS_DBG_BUF(7, "Bind-dest %s c:%s:%d v:%s:%d "
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index 0c043b6ce65e..319991d4d251 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -194,7 +194,7 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
194 struct ip_vs_dest *dest; 194 struct ip_vs_dest *dest;
195 struct ip_vs_conn *ct; 195 struct ip_vs_conn *ct;
196 __be16 dport; /* destination port to forward */ 196 __be16 dport; /* destination port to forward */
197 __be16 flags; 197 unsigned int flags;
198 union nf_inet_addr snet; /* source network of the client, 198 union nf_inet_addr snet; /* source network of the client,
199 after masking */ 199 after masking */
200 200
@@ -382,7 +382,8 @@ ip_vs_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
382 struct ip_vs_conn *cp = NULL; 382 struct ip_vs_conn *cp = NULL;
383 struct ip_vs_iphdr iph; 383 struct ip_vs_iphdr iph;
384 struct ip_vs_dest *dest; 384 struct ip_vs_dest *dest;
385 __be16 _ports[2], *pptr, flags; 385 __be16 _ports[2], *pptr;
386 unsigned int flags;
386 387
387 ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph); 388 ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph);
388 pptr = skb_header_pointer(skb, iph.len, sizeof(_ports), _ports); 389 pptr = skb_header_pointer(skb, iph.len, sizeof(_ports), _ports);
@@ -473,9 +474,9 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb,
473 if (sysctl_ip_vs_cache_bypass && svc->fwmark && unicast) { 474 if (sysctl_ip_vs_cache_bypass && svc->fwmark && unicast) {
474 int ret, cs; 475 int ret, cs;
475 struct ip_vs_conn *cp; 476 struct ip_vs_conn *cp;
476 __u16 flags = (svc->flags & IP_VS_SVC_F_ONEPACKET && 477 unsigned int flags = (svc->flags & IP_VS_SVC_F_ONEPACKET &&
477 iph.protocol == IPPROTO_UDP)? 478 iph.protocol == IPPROTO_UDP)?
478 IP_VS_CONN_F_ONE_PACKET : 0; 479 IP_VS_CONN_F_ONE_PACKET : 0;
479 union nf_inet_addr daddr = { .all = { 0, 0, 0, 0 } }; 480 union nf_inet_addr daddr = { .all = { 0, 0, 0, 0 } };
480 481
481 ip_vs_service_put(svc); 482 ip_vs_service_put(svc);
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index ca8ec8c4f311..7bd41d28080c 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -765,7 +765,8 @@ __ip_vs_update_dest(struct ip_vs_service *svc,
765 765
766 /* set the weight and the flags */ 766 /* set the weight and the flags */
767 atomic_set(&dest->weight, udest->weight); 767 atomic_set(&dest->weight, udest->weight);
768 conn_flags = udest->conn_flags | IP_VS_CONN_F_INACTIVE; 768 conn_flags = udest->conn_flags & IP_VS_CONN_F_DEST_MASK;
769 conn_flags |= IP_VS_CONN_F_INACTIVE;
769 770
770 /* check if local node and update the flags */ 771 /* check if local node and update the flags */
771#ifdef CONFIG_IP_VS_IPV6 772#ifdef CONFIG_IP_VS_IPV6
@@ -782,7 +783,7 @@ __ip_vs_update_dest(struct ip_vs_service *svc,
782 } 783 }
783 784
784 /* set the IP_VS_CONN_F_NOOUTPUT flag if not masquerading/NAT */ 785 /* set the IP_VS_CONN_F_NOOUTPUT flag if not masquerading/NAT */
785 if ((conn_flags & IP_VS_CONN_F_FWD_MASK) != 0) { 786 if ((conn_flags & IP_VS_CONN_F_FWD_MASK) != IP_VS_CONN_F_MASQ) {
786 conn_flags |= IP_VS_CONN_F_NOOUTPUT; 787 conn_flags |= IP_VS_CONN_F_NOOUTPUT;
787 } else { 788 } else {
788 /* 789 /*