Index: /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/net/click_ether.c
===================================================================
--- /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/net/click_ether.c	(revision 38770)
+++ /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/net/click_ether.c	(working copy)
@@ -2599,8 +2599,11 @@
 		if (isipv6 || (LOCAL_IP != iph->ip_dst.s_addr)) {
 			if (ip_p == IPPROTO_TCP){
 				tcph = (struct tcphdr *)l4_hdr;
-				if ((tcph->th_flags & (TH_SYN | TH_ACK)) != (TH_SYN | TH_ACK)){
-					rts_create(m, ip_v, EROUTE_RTS_BSD);
+                                /* only syn create rts, others do update only*/
+                                if (tcph->th_flags == TH_SYN) {
+                                    rts_create(m, ip_v, EROUTE_RTS_BSD);
+                                } else if ((tcph->th_flags & (TH_SYN | TH_ACK)) != (TH_SYN | TH_ACK)){
+                                    rts_create(m, ip_v, EROUTE_RTS_BSD | EROUTE_RTS_UPDATE);
 				}
 			}else if (ip_p == IPPROTO_UDP){
 				rts_create(m, ip_v, EROUTE_RTS_BSD);
Index: /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/netinet/click_eroute.h
===================================================================
--- /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/netinet/click_eroute.h	(revision 38770)
+++ /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/netinet/click_eroute.h	(working copy)
@@ -619,6 +619,7 @@
 #define EROUTELKUP_RTS_NOT_BSD   (1 << 2)
 #define EROUTELKUP_DEBUG         (1 << 3)
 #define EROUTELKUP_RTS_BSD       (1 << 4)
+#define EROUTELKUP_TIMO_NO_RESET (1 << 5)
 
 #define EROUTELKUP_HR_FILTER_DD         1	
 #define EROUTELKUP_NORMAL_DD     0	
@@ -647,8 +648,9 @@
 		(IS_HRULE((erti).rule) && (!rts_mode_all_enable))))))\
 		)
 
-#define EROUTE_RTS_NOT_BSD 0
-#define EROUTE_RTS_BSD 1 
+#define EROUTE_RTS_NOT_BSD     0x0
+#define EROUTE_RTS_BSD         0x1
+#define EROUTE_RTS_UPDATE      0x2
 
 extern int llb_bw_priority;
 
Index: /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/netinet/click_eroute.c
===================================================================
--- /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/netinet/click_eroute.c	(revision 38770)
+++ /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/netinet/click_eroute.c	(working copy)
@@ -384,6 +384,8 @@
 int *ustat_ipf_enable = &ipf_enable;
 uint32_t *ustat_ipf_overflow_num = ipf_overflow_num;
 uint32_t *ustat_rts_overflow_num = rts_overflow_num;
+pthread_mutex_t mutex;
+int counter = 0;
 
 #define RIRT_TABLE_LOCK(i) mtx_lock(&rirt_mtx[i])
 #define RIRT_TABLE_UNLOCK(i) mtx_unlock(&rirt_mtx[i])
@@ -10517,7 +10519,7 @@
 }
 
 void
-rts_create(struct mbuf * m, void *ip_v, int is_bsd)
+rts_create(struct mbuf * m, void *ip_v, int flag)
 {
 	struct in_addr local_ip;
 	struct in_addr remote_ip;
@@ -10531,6 +10533,7 @@
 	struct ip *ip;
 	struct ip6_hdr *ip6;
 	int isipv6;
+	int is_bsd = (flag & EROUTE_RTS_BSD);
 	hash_t *table;
 
 	clicktcp_enter_func(m, NULL);
@@ -10575,11 +10578,39 @@
 	}
 
 	RIRT_TABLE_LOCK(RIRT_LI(ori_key));
+
+        pthread_mutex_init (&mutex,NULL); 
+        pthread_mutex_lock(&mutex);
+        if ( counter < 50 ) {
+            struct in_addr myip1, myip2;
+            struct tcphdr *tcp;
+            struct udphdr *udp;
+            const char *myip_str1= "172.20.12.50", *myip_str2 ="172.20.12.54";
+
+            inet_pton(AF_INET, myip_str1, &myip1);
+            inet_pton(AF_INET, myip_str2, &myip2);
+            if(ntohl(local_ip.s_addr) >= ntohl(myip1.s_addr) && ntohl(local_ip.s_addr) <= ntohl(myip2.s_addr) ){
+                fastlog_syslog(LOG_DEBUG,"IP:count = %d: %d, %d,%d, %s, %s",counter, ip->ip_hl, ntohs(ip->ip_len), ip->ip_p, inet_ntoa(ip->ip_src), inet_ntoa(ip->ip_dst));
+                switch (ip->ip_p) {
+                    case IPPROTO_TCP:
+                        tcp = (struct tcphdr*)((char *)ip + ip->ip_hl *4);
+                        fastlog_syslog(LOG_DEBUG,"tcp: %d, %d, %u, %u, %d, 0x%x", tcp->th_sport, tcp->th_dport, tcp->th_seq, tcp->th_ack, tcp->th_off*4, tcp->th_flags);
+                    case IPPROTO_UDP:
+                        udp = (struct udphdr*)((char *)ip + ip->ip_hl *4);
+                        fastlog_syslog(LOG_DEBUG,"udp: %d, %d, %d, 0x%x", udp->uh_sport, udp->uh_dport, udp->uh_ulen, udp->uh_sum);
+                    default:
+                        fastlog_syslog(LOG_DEBUG,"protocol: %d", ip->ip_p);
+
+                }
+                counter++;
+            }
+        }
+        pthread_mutex_unlock(&mutex);
 	/*
 	 * Note the insertion is done with temporary entry.  We *need* to
 	 * set hp->rec to a permanent entry if hp->new is true.
 	 */
-	hp = hashInSearch(table, ori_key, &tmp_rirtentry, HASH_INSERT);
+	hp = hashInSearch(table, ori_key, &tmp_rirtentry, (flag & EROUTE_RTS_UPDATE)? HASH_NOINSERT: HASH_INSERT);
 	if (NULL == hp) {
 		/* out of memory, throw away oldest */
 		rirt = TIMER_FIRST(rts_lru[isipv6][RIRT_LI(ori_key)]);
@@ -10714,7 +10745,11 @@
 		RIRT_TABLE_UNLOCK(RIRT_LI(ori_key));
 		return;
 	}
-	
+
+        if (flag & EROUTE_RTS_UPDATE) {
+            RIRT_TABLE_UNLOCK(RIRT_LI(ori_key));
+            return;
+        }
 creat_entry:
 
 	erule = rts_get_erule(m, is_bsd);
@@ -10907,10 +10942,12 @@
 			
 			rtsstat(isipv6).rts_lokp++;
 			rirt->rir_rts.rts_hits++;
-			if (!IS_HRULE_RIRT(rirt)) {
-				TIMER_RESET(rirt, &(rts_lru[isipv6][RIRT_LI(ori_key)]), rir_rtimo);
-			} else {
-				TIMER_RESET(rirt, &(rts_h_lru[isipv6][RIRT_LI(ori_key)]), rir_rtimo);
+                        if (!(flag & EROUTELKUP_TIMO_NO_RESET)) {
+                            if (!IS_HRULE_RIRT(rirt)) {
+                                TIMER_RESET(rirt, &(rts_lru[isipv6][RIRT_LI(ori_key)]), rir_rtimo);
+                            } else {
+                                TIMER_RESET(rirt, &(rts_h_lru[isipv6][RIRT_LI(ori_key)]), rir_rtimo);
+                            }
 			}
 			if(unlock_flag)	RIRT_TABLE_UNLOCK(RIRT_LI(ori_key));
 			if(flag & EROUTELKUP_HROUTE_IGN) { 
Index: /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/netinet/click_input.c
===================================================================
--- /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/netinet/click_input.c	(revision 38770)
+++ /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/netinet/click_input.c	(working copy)
@@ -3817,6 +3817,7 @@
 	int proto;
 	caddr_t l4_hdr = NULL;
 	void *sip, *dip;
+        int rts_flag;
 	
 	_IFA_DEQUEUE(ErouteBSD_queue, m);
 	if (!m) {
@@ -3894,7 +3895,20 @@
 		}
 
 		if (rtsbsd_enable && rts_enable) {
-			erule = rts_lookup(isipv6, NULL, 0, 0, sip, dip, NULL);
+                    rts_flag = 0;
+                    if(proto == IPPROTO_TCP) {
+                        if (isipv6) {
+                            tcph = (struct tcphdr *)l4_hdr;
+                        }else {
+                            tcph = (struct tcphdr *)((char *)iph + iph_len);
+                        }
+
+
+                        if (tcph->th_flags == TH_SYN) {
+                            rts_flag |= EROUTELKUP_TIMO_NO_RESET;
+                        }
+                    }
+                    erule = rts_lookup(isipv6, NULL, 0, rts_flag, sip, dip, NULL);
 			if (erule) {
                 		ERT_GWHITS(erule)++;
 				rtsbsd_snd++;
@@ -3981,6 +3995,7 @@
 	int isipv6;	
 	int iphlen;
 	int proto;
+        int rts_flag;
 
 	eh = mtod((*mp), struct ether_header *);
 	ether_type = ntohs(eh->ether_type);
@@ -4030,7 +4045,24 @@
 	}
 
 	if (rtsbsd_enable && rts_enable) {
-		erule = rts_lookup(isipv6, NULL, 0, 0, sip, dip, NULL);
+            rts_flag = 0;
+            if(proto == IPPROTO_TCP) {
+                if (isipv6) {
+                    tcph = (struct tcphdr *)l4_hdr;
+                }else {
+                    if((m = m_pull(m, l2_hdrlen + iphlen + sizeof(struct tcphdr))) == NULL) {
+                        return 0;
+                    }
+                    ip4 = (struct ip *)mtodo(m, l2_hdrlen);
+                    tcph = (struct tcphdr *)((caddr_t)ip4 + iphlen);
+                }
+
+
+                if (tcph->th_flags == TH_SYN) {
+                    rts_flag |= EROUTELKUP_TIMO_NO_RESET;
+                }
+            }
+            erule = rts_lookup(isipv6, NULL, 0, rts_flag, sip, dip, NULL);
 		if (erule) {
             		ERT_GWHITS(erule)++;
 			m_adj(m, l2_hdrlen);
@@ -15182,8 +15214,11 @@
 		}		
 		
 		if (proto == IPPROTO_TCP){
-			if ((tcp->th_flags & (TH_SYN | TH_ACK)) != (TH_SYN | TH_ACK)){
-				rts_create(m, ip_p, EROUTE_RTS_BSD);
+                    if (tcp->th_flags == TH_SYN) {
+                        rts_create(m, ip_p, EROUTE_RTS_BSD);
+                    } else if ((tcp->th_flags & (TH_SYN | TH_ACK)) != (TH_SYN | TH_ACK)) {
+                        rts_create(m, ip_p, EROUTE_RTS_BSD | EROUTE_RTS_UPDATE);
+
 			}
 		}else if (proto == IPPROTO_UDP){
 			rts_create(m, ip_p, EROUTE_RTS_BSD);
