Hello Simon.

On 17 May 2010 00:11, Simon Horman <[email protected]> wrote:
> This looks good, though I have a few minor comments below.
> Could you address them and then repost with a Signed-off-by line?

No problem. The attached modified patch should address all of your comments.

Signed-off-by: Nick Chalk <[email protected]>

Nick.

-- 
Nick Chalk.

Loadbalancer.org Ltd.
Phone: +44 (0)870 443 8779
http://www.loadbalancer.org/
diff -ur linux-2.6.32.7/include/linux/ip_vs.h linux-2.6.32.7-ops/include/linux/ip_vs.h
--- linux-2.6.32.7/include/linux/ip_vs.h	2010-01-28 23:06:20.000000000 +0000
+++ linux-2.6.32.7-ops/include/linux/ip_vs.h	2010-05-17 09:17:57.000000000 +0100
@@ -19,6 +19,7 @@
  */
 #define IP_VS_SVC_F_PERSISTENT	0x0001		/* persistent port */
 #define IP_VS_SVC_F_HASHED	0x0002		/* hashed entry */
+#define IP_VS_SVC_F_ONEPACKET	0x0004		/* one-packet scheduling */
 
 /*
  *      Destination Server Flags
@@ -85,6 +86,7 @@
 #define IP_VS_CONN_F_SEQ_MASK	0x0600		/* in/out sequence mask */
 #define IP_VS_CONN_F_NO_CPORT	0x0800		/* no client port set yet */
 #define IP_VS_CONN_F_TEMPLATE	0x1000		/* template, not connection */
+#define IP_VS_CONN_F_ONE_PACKET	0x2000		/* forward only one packet */
 
 #define IP_VS_SCHEDNAME_MAXLEN	16
 #define IP_VS_IFNAME_MAXLEN	16
diff -ur linux-2.6.32.7/net/netfilter/ipvs/ip_vs_conn.c linux-2.6.32.7-ops/net/netfilter/ipvs/ip_vs_conn.c
--- linux-2.6.32.7/net/netfilter/ipvs/ip_vs_conn.c	2010-01-28 23:06:20.000000000 +0000
+++ linux-2.6.32.7-ops/net/netfilter/ipvs/ip_vs_conn.c	2010-05-14 10:09:48.000000000 +0100
@@ -142,6 +142,9 @@
 	unsigned hash;
 	int ret;
 
+	if (cp->flags & IP_VS_CONN_F_ONE_PACKET)
+		return 0;
+
 	/* Hash by protocol, client address and port */
 	hash = ip_vs_conn_hashkey(cp->af, cp->protocol, &cp->caddr, cp->cport);
 
@@ -339,8 +342,9 @@
  */
 void ip_vs_conn_put(struct ip_vs_conn *cp)
 {
-	/* reset it expire in its timeout */
-	mod_timer(&cp->timer, jiffies+cp->timeout);
+	unsigned long t = (cp->flags & IP_VS_CONN_F_ONE_PACKET) ?
+		0 : cp->timeout;
+	mod_timer(&cp->timer, jiffies+t);
 
 	__ip_vs_conn_put(cp);
 }
@@ -633,7 +637,7 @@
 	/*
 	 *	unhash it if it is hashed in the conn table
 	 */
-	if (!ip_vs_conn_unhash(cp))
+	if (!ip_vs_conn_unhash(cp) && !(cp->flags & IP_VS_CONN_F_ONE_PACKET))
 		goto expire_later;
 
 	/*
diff -ur linux-2.6.32.7/net/netfilter/ipvs/ip_vs_core.c linux-2.6.32.7-ops/net/netfilter/ipvs/ip_vs_core.c
--- linux-2.6.32.7/net/netfilter/ipvs/ip_vs_core.c	2010-01-28 23:06:20.000000000 +0000
+++ linux-2.6.32.7-ops/net/netfilter/ipvs/ip_vs_core.c	2010-05-17 09:19:41.000000000 +0100
@@ -190,6 +190,7 @@
 	struct ip_vs_dest *dest;
 	struct ip_vs_conn *ct;
 	__be16  dport;			/* destination port to forward */
+	__be16  flags;	
 	union nf_inet_addr snet;	/* source network of the client,
 					   after masking */
 
@@ -336,6 +337,10 @@
 		dport = ports[1];
 	}
 
+	flags = (svc->flags & IP_VS_SVC_F_ONEPACKET
+		 && iph.protocol == IPPROTO_UDP)?
+		IP_VS_CONN_F_ONE_PACKET : 0;
+
 	/*
 	 *    Create a new connection according to the template
 	 */
@@ -343,7 +348,7 @@
 			    &iph.saddr, ports[0],
 			    &iph.daddr, ports[1],
 			    &dest->addr, dport,
-			    0,
+			    flags,
 			    dest);
 	if (cp == NULL) {
 		ip_vs_conn_put(ct);
@@ -373,7 +378,7 @@
 	struct ip_vs_conn *cp = NULL;
 	struct ip_vs_iphdr iph;
 	struct ip_vs_dest *dest;
-	__be16 _ports[2], *pptr;
+	__be16 _ports[2], *pptr, flags;
 
 	ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph);
 	pptr = skb_header_pointer(skb, iph.len, sizeof(_ports), _ports);
@@ -403,6 +408,10 @@
 		return NULL;
 	}
 
+	flags = (svc->flags & IP_VS_SVC_F_ONEPACKET
+		 && iph.protocol == IPPROTO_UDP)?
+		IP_VS_CONN_F_ONE_PACKET : 0;
+
 	/*
 	 *    Create a connection entry.
 	 */
@@ -410,7 +419,7 @@
 			    &iph.saddr, pptr[0],
 			    &iph.daddr, pptr[1],
 			    &dest->addr, dest->port ? dest->port : pptr[1],
-			    0,
+			    flags,
 			    dest);
 	if (cp == NULL)
 		return NULL;
@@ -460,6 +469,9 @@
 	if (sysctl_ip_vs_cache_bypass && svc->fwmark && unicast) {
 		int ret, cs;
 		struct ip_vs_conn *cp;
+		__u16 flags = (svc->flags & IP_VS_SVC_F_ONEPACKET &&
+				iph.protocol == IPPROTO_UDP)?
+				IP_VS_CONN_F_ONE_PACKET : 0;
 		union nf_inet_addr daddr =  { .all = { 0, 0, 0, 0 } };
 
 		ip_vs_service_put(svc);
@@ -470,7 +482,7 @@
 				    &iph.saddr, pptr[0],
 				    &iph.daddr, pptr[1],
 				    &daddr, 0,
-				    IP_VS_CONN_F_BYPASS,
+				    IP_VS_CONN_F_BYPASS | flags,
 				    NULL);
 		if (cp == NULL)
 			return NF_DROP;
diff -ur linux-2.6.32.7/net/netfilter/ipvs/ip_vs_ctl.c linux-2.6.32.7-ops/net/netfilter/ipvs/ip_vs_ctl.c
--- linux-2.6.32.7/net/netfilter/ipvs/ip_vs_ctl.c	2010-01-28 23:06:20.000000000 +0000
+++ linux-2.6.32.7-ops/net/netfilter/ipvs/ip_vs_ctl.c	2010-05-17 09:33:14.000000000 +0100
@@ -1863,14 +1863,16 @@
 					   svc->scheduler->name);
 			else
 #endif
-				seq_printf(seq, "%s  %08X:%04X %s ",
+				seq_printf(seq, "%s  %08X:%04X %s %s ",
 					   ip_vs_proto_name(svc->protocol),
 					   ntohl(svc->addr.ip),
 					   ntohs(svc->port),
-					   svc->scheduler->name);
+					   svc->scheduler->name,
+					   (svc->flags & IP_VS_SVC_F_ONEPACKET)?"ops ":"");
 		} else {
-			seq_printf(seq, "FWM  %08X %s ",
-				   svc->fwmark, svc->scheduler->name);
+			seq_printf(seq, "FWM  %08X %s %s",
+				   svc->fwmark, svc->scheduler->name,
+				   (svc->flags & IP_VS_SVC_F_ONEPACKET)?"ops ":"");
 		}
 
 		if (svc->flags & IP_VS_SVC_F_PERSISTENT)
_______________________________________________
Please read the documentation before posting - it's available at:
http://www.linuxvirtualserver.org/

LinuxVirtualServer.org mailing list - [email protected]
Send requests to [email protected]
or go to http://lists.graemef.net/mailman/listinfo/lvs-users

Reply via email to