Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 12 Jul 2000 15:19:25 -0700
From:      jayanth <jayanth@yahoo-inc.com>
To:        net@FreeBSD.ORG
Subject:   diffs for deleting routing clones 
Message-ID:  <20000712151925.A22978@yahoo-inc.com>

next in thread | raw e-mail | index | archive | help

--YZ5djTAD1cGYuMQK
Content-Type: text/plain; charset=us-ascii

This is a hack for freeing up some memory from the routing table.
It happens only when a connection is dropped due to listen q overflow
and the associated route has no data cached in it.
Any feedback would be helpful.

jayanth

--YZ5djTAD1cGYuMQK
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="syn.patch"

Index: route.h
===================================================================
RCS file: /home/ncvs/src/sys/net/route.h,v
retrieving revision 1.36
diff -u -p -u -r1.36 route.h
--- route.h	2000/02/13 03:31:56	1.36
+++ route.h	2000/07/11 21:19:40
@@ -139,7 +139,7 @@ struct ortentry {
 #define	RTF_DYNAMIC	0x10		/* created dynamically (by redirect) */
 #define	RTF_MODIFIED	0x20		/* modified dynamically (by redirect) */
 #define RTF_DONE	0x40		/* message confirmed */
-/*			0x80		   unused */
+#define RTF_DELCLONE	0x80		/* delete cloned route */
 #define RTF_CLONING	0x100		/* generate new routes on use */
 #define RTF_XRESOLVE	0x200		/* external daemon resolves name */
 #define RTF_LLINFO	0x400		/* generated by link layer (e.g. ARP) */
Index: in_pcb.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/in_pcb.c,v
retrieving revision 1.66
diff -u -p -r1.66 in_pcb.c
--- in_pcb.c	2000/07/04 16:35:05	1.66
+++ in_pcb.c	2000/07/12 22:07:41
@@ -531,6 +531,7 @@ in_pcbdetach(inp)
 {
 	struct socket *so = inp->inp_socket;
 	struct inpcbinfo *ipi = inp->inp_pcbinfo;
+	struct rt_entry *rt = = inp->inp_route.ro_rt;
 
 #ifdef IPSEC
 	ipsec4_delete_pcbpolicy(inp);
@@ -541,8 +542,25 @@ in_pcbdetach(inp)
 	sofree(so);
 	if (inp->inp_options)
 		(void)m_free(inp->inp_options);
-	if (inp->inp_route.ro_rt)
-		rtfree(inp->inp_route.ro_rt);
+	if (rt){
+		/* route delete requires reference count to be <= zero */
+		if((rt->rt_flags & RTF_DELCLONE) &&
+		   (rt->rt_flags & RTF_WASCLONED)){
+			if(--rt->rt_refcnt <= 0){
+				rt->rt_flags &= ~RTF_UP;
+				rtrequest(RTM_DELETE, rt_key(rt),
+					  rt->rt_gateway, rt_mask(rt),
+					  rt->rt_flags, (struct rtentry **)0);
+			}
+			else
+				/* more than one reference, bump it up 
+				 * again.
+				 */
+				rt->rt_refcnt++;
+		}
+		else
+			rtfree(rt);
+	}
 	ip_freemoptions(inp->inp_moptions);
 	inp->inp_vflag = 0;
 	zfreei(ipi->ipi_zone, inp);
Index: tcp_input.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/tcp_input.c,v
retrieving revision 1.117
diff -u -p -r1.117 tcp_input.c
--- tcp_input.c	2000/07/09 13:01:59	1.117
+++ tcp_input.c	2000/07/12 22:07:41
@@ -121,6 +121,10 @@ SYSCTL_INT(_net_inet_tcp, OID_AUTO, dela
     &tcp_delack_enabled, 0, 
     "Delay ACK to try and piggyback it onto a data packet");
 
+int tcp_lq_overflow = 0;
+SYSCTL_INT(_net_inet_tcp, OID_AUTO, tcp_lq_overflow, CTLFLAG_RW,
+    &tcp_lq_overflow, 0,
+    "Listen Queue Overflow");
 #ifdef TCP_DROP_SYNFIN
 static int drop_synfin = 0;
 SYSCTL_INT(_net_inet_tcp, OID_AUTO, drop_synfin, CTLFLAG_RW,
@@ -710,6 +714,9 @@ findpcb:
 				tcpstat.tcps_listendrop++;
 				so2 = sodropablereq(so);
 				if (so2) {
+					if(tcp_lq_overflow)
+                                                sototcpcb(so2)->t_flags |= 
+							TF_LQ_OVERFLOW;
 					tcp_drop(sototcpcb(so2), ETIMEDOUT);
 					so2 = sonewconn(so, 0);
 				}
Index: tcp_subr.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/tcp_subr.c,v
retrieving revision 1.78
diff -u -p -r1.78 tcp_subr.c
--- tcp_subr.c	2000/07/04 16:35:05	1.78
+++ tcp_subr.c	2000/07/12 22:07:41
@@ -680,6 +680,17 @@ tcp_close(tp)
 			tcpstat.tcps_cachedssthresh++;
 		}
 	}
+	rt = inp->inp_route.ro_rt;
+        if(rt){
+		/* mark route for delete if no information is
+		 * cached
+		 */
+        	if ((tp->t_flags & TF_LQ_OVERFLOW) &&
+                    ((rt->rt_rmx.rmx_locks & RTV_RTT) == 0)){
+                	if(rt->rt_rmx.rmx_rtt == 0)
+                        rt->rt_flags |= RTF_DELCLONE;
+        	}
+        }
     no_valid_rt:
 	/* free the reassembly queue, if any */
 	while((q = LIST_FIRST(&tp->t_segq)) != NULL) {
Index: tcp_var.h
===================================================================
RCS file: /home/ncvs/src/sys/netinet/tcp_var.h,v
retrieving revision 1.59
diff -u -p -r1.59 tcp_var.h
--- tcp_var.h	2000/05/26 02:05:47	1.59
+++ tcp_var.h	2000/07/12 22:07:41
@@ -94,6 +94,7 @@ struct tcpcb {
 #define	TF_RCVD_CC	0x04000		/* a CC was received in SYN */
 #define	TF_SENDCCNEW	0x08000		/* send CCnew instead of CC in SYN */
 #define	TF_MORETOCOME	0x10000		/* More data to be appended to sock */
+#define TF_LQ_OVERFLOW	0x20000		/* listen queue overflow */
 	int	t_force;		/* 1 if forcing out a byte */
 
 	tcp_seq	snd_una;		/* send unacknowledged */

--YZ5djTAD1cGYuMQK--


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-net" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20000712151925.A22978>