Index: /branches/rel_apv_10_7/usr/click/bin/ha_domain/domain.c
===================================================================
--- /branches/rel_apv_10_7/usr/click/bin/ha_domain/domain.c	(revision 40078)
+++ /branches/rel_apv_10_7/usr/click/bin/ha_domain/domain.c	(working copy)
@@ -30,6 +30,7 @@
 #include <string.h>
 #include <sys/sysctl.h>
 #include <sys/syscall.h>
+#include <pthread.h>
 #include "ha_lib.h"
 #include "version.h"
 #include "domain.h"
@@ -3209,6 +3210,58 @@
 	return;
 }
 
+static void*
+ha_send_arp_thread(void *th_data)
+{
+	#define INTERVAL_1000MS		1000
+	#define INTERVAL_1000000US	(INTERVAL_1000MS*1000)
+	static uint64_t round_time = 0;
+
+	while(1) {
+		usleep(INTERVAL_1000000US);
+		if (ha_config_p->arp_interval == 0) {
+			continue;
+		}
+
+		round_time += INTERVAL_1000MS;
+		if (round_time < ha_config_p->arp_interval) {
+			continue;
+		}
+		round_time = 0;
+
+		/* all active fips to send arp */
+		if (unit_status_p->state == UNIT_UP) {
+			ha_send_continuous_arp_kern();
+		}
+	}
+
+	return NULL;
+}
+
+static int
+ha_thread_create(void *(func)(void*), void *th_data)
+{
+	int ret;
+	pthread_t thread_id;
+	pthread_attr_t attr;
+
+	if ((ret = pthread_attr_init(&attr)) != 0) {
+		return -1;
+	}
+
+	if ((ret = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED)) != 0) {
+		pthread_attr_destroy(&attr);
+		return -1;
+	}
+
+	if ((ret = pthread_create(&thread_id,&attr,func,th_data)) != 0) {
+		pthread_attr_destroy(&attr);
+		return -1;
+	}
+
+	pthread_attr_destroy(&attr);
+	return 0;
+}
 
 int main(int argc, char* argv[])
 {
@@ -3245,6 +3298,13 @@
         to.tv_nsec = 0;
         to.tv_sec = 1;
 
+	enable_multithread_kapi();
+
+	if (ha_thread_create(ha_send_arp_thread, NULL) < 0) {
+		ha_log(LOG_CRIT, "ha faild to create ha_send_arp_thread");
+		exit(0);
+	}
+
 	while (1)  {
 		if (ha_config_p->ha_enabled && check_netlink_config_changed()) {
 			remove_prev_netlink_sock();
@@ -3333,7 +3393,7 @@
 				if (unit_status_p->state == UNIT_UP) {
 					/* check and update peer unit status
 					 */
-					check_arp_interval_reached();
+					/*check_arp_interval_reached();*/
 					send_continuous_arp();
 					reduce_peer_unit_heartbeat_counter();
 				}
Index: /branches/rel_apv_10_7/usr/click/lib/libhalib/ha_lib.c
===================================================================
--- /branches/rel_apv_10_7/usr/click/lib/libhalib/ha_lib.c	(revision 40078)
+++ /branches/rel_apv_10_7/usr/click/lib/libhalib/ha_lib.c	(working copy)
@@ -615,16 +615,13 @@
 send_gratuitous_arp(char *ifname, struct in6_addr *ip_start, struct in6_addr *ip_end, int isipv6)
 {
 	struct in6_addr addr;
+	int addr_len;
 
 	bcopy(ip_start, &addr, sizeof(addr));
-	while(compaddr((uint8_t *)ip_end, (uint8_t *)&addr, isipv6 ? 16 : 4) != -1) {
-		if (isipv6 == 0) {
-			send_gratuitous_arp_kern(ifname, &addr, isipv6 ? 16 : 4);
-		} else {
-			/* XXX maybe resolve this issue in kernelapi */
-			send_unsolicited_na(ifname, &addr);
-		}
-		incaddr((uint8_t *)&addr, isipv6 ? 16 : 4);
+	addr_len = (isipv6)? sizeof(struct in6_addr) :sizeof(struct in_addr);
+	while(compaddr((uint8_t *)ip_end, (uint8_t *)&addr, addr_len) != -1) {
+		send_gratuitous_arp_kern(ifname, &addr, addr_len);
+		incaddr((uint8_t *)&addr, addr_len);
 	}
 }
 
@@ -2137,7 +2134,7 @@
 	/* for ipv6 */
 	if (strlen(ip6) != 0) {
 		inet_pton(AF_INET6, ip6, &addr6);
-		send_unsolicited_na(ifid_to_realIfName(if_id), &addr6);	
+		send_gratuitous_arp_kern(ifid_to_realIfName(if_id),  &addr6, sizeof(struct in6_addr));
 		ha_log(LOG_DEBUG, "send neighbor advertisement to: [%s] [%s]", ifid_to_ifname(if_id), 
 				inet_ntop(AF_INET6, &addr6, ip6, INET6_ADDRSTRLEN));
 	}
Index: /branches/rel_apv_10_7/usr/click/lib/libkernelapi/addCommands.pm
===================================================================
--- /branches/rel_apv_10_7/usr/click/lib/libkernelapi/addCommands.pm	(revision 40078)
+++ /branches/rel_apv_10_7/usr/click/lib/libkernelapi/addCommands.pm	(working copy)
@@ -5961,6 +5961,11 @@
 			{type => "INDATA"},
 			],
 	},
+    {
+        cmd_attribute => "CMD_KERN_API|CMD_KAPI_NOLOCK",
+        function_name => "ha_send_continuous_arp_kern",
+        function_args => [],
+    },
 	{
         cmd_attribute => "CMD_KERN_API|CMD_KAPI_NOLOCK",
         function_name => "ha_group_id_kern",
Index: /branches/rel_apv_10_7/usr/click/lib/libuinet-atcp/lib/libuinet/uinet_host_interface.c
===================================================================
--- /branches/rel_apv_10_7/usr/click/lib/libuinet-atcp/lib/libuinet/uinet_host_interface.c	(revision 40078)
+++ /branches/rel_apv_10_7/usr/click/lib/libuinet-atcp/lib/libuinet/uinet_host_interface.c	(working copy)
@@ -2034,6 +2034,36 @@
 }
 
 int
+uhi_fastlog_receive(int loops)
+{
+        size_t len;
+        log_entry_t new_entry;
+
+        if (fastlog_sock_init() != 0) {
+                return -1;
+        }
+
+        for (;loops--;) {
+                len = read(fastlog_fd, &new_entry, sizeof(new_entry));
+                if (len == -1 && errno == EWOULDBLOCK) {
+                        return -1;
+                } else if (len <= 0) {
+                        close(fastlog_fd);
+                        fastlog_fd = -1;
+                        if (fastlog_sock_init() != 0) {
+                                return -1;
+                        }
+                } else if (len == sizeof(new_entry)) {
+                        real_fastlog(&new_entry);
+                } else {
+                        printf("ERROR: fastlog entry is incomplete.\n");
+                }
+        }
+
+	return 0;
+}
+
+int
 fastlog_register_conn(int ns)
 {
 	struct epoll_event events;
Index: /branches/rel_apv_10_7/usr/src/sys/click/app/fastlog/fastlog.c
===================================================================
--- /branches/rel_apv_10_7/usr/src/sys/click/app/fastlog/fastlog.c	(revision 40078)
+++ /branches/rel_apv_10_7/usr/src/sys/click/app/fastlog/fastlog.c	(working copy)
@@ -2919,37 +2919,79 @@
 	close_all_log_conn(&log_config_data);
 	return 0;
 }
+
+static int fastlog_ticks_limit = 50;
+SYSCTL_INT(_net_inet_clicktcp, OID_AUTO, fastlog_ticks_limit, CTLFLAG_RW,
+	&fastlog_ticks_limit, 0, "The time limit for sending logs in one round");
+
 /* ATCP use kernelapi thread to write log */
 void fastlog_real(void)
 {
 	int i,j;
 	log_entry_t *logentry;
+	#define ATCP_QUEUE	0
+	#define FASTLOG_QUEUE   1
+	#define GLOBAL_QUEUE	2
+	static int que_next = ATCP_QUEUE;
+	static int th_next = 0;
+	static int j_next = 0;
+	int func_ticks = ticks;
+
+	if (que_next == ATCP_QUEUE) {
+		for (i = th_next; i < atcp_nthreads; i++) {
+			/* Write 100 logs at the most */
+			for (j = j_next; j < 100; j++) {
+				_ARQ_DEQUEUE(atcp_adapter_array[i]->atcp_fastlog_queue, logentry);
+				if (NULL == logentry) break;
+
+				real_fastlog(logentry);
+				FREE(logentry, M_TEMP);
+
+				/*check fastlog runing ticks*/
+				if (ticks - func_ticks > fastlog_ticks_limit) {
+					j_next = ++j;
+					th_next = i;
+					return;
+				}
+			}
+			j_next = 0;
+		}
+		th_next = 0;
+		que_next = FASTLOG_QUEUE;
+	}
+
+	if (que_next == FASTLOG_QUEUE) {
+		/* receive fastlog via Unix Socket */
+		for (j = j_next; j < 100; j++) {
+			if (uhi_fastlog_receive(1) < 0) break; // HERE
+			/*check fastlog runing ticks*/
+			if (ticks - func_ticks > fastlog_ticks_limit) {
+				j_next = ++j;
+				return;
+			}
+		}
+		j_next = 0;
+		que_next = GLOBAL_QUEUE;
+	}
 
-	/*snmp traps limit on all atcp threads*/
-	SNMP_TRAPS_LIMIT_ENABLE(atcp_nthreads);
-	for (i = 0; i < atcp_nthreads; i++) {
+	if (que_next == GLOBAL_QUEUE) {
 		/* Write 100 logs at the most */
-		for (j = 0; j < 100; j++) { 
-			_ARQ_DEQUEUE(atcp_adapter_array[i]->atcp_fastlog_queue, logentry);
+		for (j = j_next; j < 100; j++) {
+			_ARQ_DEQUEUE(global_fastlog_queue, logentry);
 			if (NULL == logentry) break;
 
 			real_fastlog(logentry);
 			FREE(logentry, M_TEMP);
-		}
-		SNMP_TRAPS_COUNT_RESET();
-	}
 
-	/* Write 100 logs at the most */
-	for (j = 0; j < 100; j++) { 
-		_ARQ_DEQUEUE(global_fastlog_queue, logentry);
-		if (NULL == logentry) break;
-
-		real_fastlog(logentry);
-		FREE(logentry, M_TEMP);
+			/*check fastlog runing ticks*/
+			if (ticks - func_ticks > fastlog_ticks_limit) {
+				j_next = ++j;
+				return;
+			}
+		}
+		j_next = 0;
+		que_next = ATCP_QUEUE;
 	}
-
-	/*snmp traps disable limit*/
-	SNMP_TRAPS_LIMIT_DISABLE();
 }
 
 /* return 1 if is the fastlog tcp packet, else return 0. */
Index: /branches/rel_apv_10_7/usr/src/sys/click/app/ha/ha_misc.c
===================================================================
--- /branches/rel_apv_10_7/usr/src/sys/click/app/ha/ha_misc.c	(revision 40078)
+++ /branches/rel_apv_10_7/usr/src/sys/click/app/ha/ha_misc.c	(working copy)
@@ -3215,3 +3215,41 @@
 
 	return 0;
 }
+
+extern unsigned int ip_incaddr(uint8_t *addr, int size);
+/* send gratuitous arp for all ACTIVE fip */
+int
+ha_send_continuous_arp_kern(void *pcb)
+{
+	int gid;
+	group_t *group;
+	ha_group_t *group_conf;
+	ha_fip_t *fip_p;
+	struct in6_addr addr;
+	int addr_len;
+
+	/* send gratuitous arp per fip */
+	for (gid = 0; gid < HA_GROUP_MAX; gid++) {
+		group = GET_GROUP_ADDR(LOCAL_UNIT, gid);
+		group_conf = &ha_config_p->group[gid];
+		if (group_conf->in_use == 0 ||
+			group->curr_status != GROUP_ACTIVE) {
+			continue;
+		}
+
+		SLB_TAILQ_FOREACH(fip_p, &group_conf->fips_list_head, fip_entry) {
+			if (!fip_p->in_use) {
+				continue;
+			}
+
+			bcopy(&fip_p->ip_start, &addr, sizeof(addr));
+			addr_len = (fip_p->isipv6)? sizeof(struct in6_addr): sizeof(struct in_addr);
+			while (compaddr((uint8_t *)&fip_p->ip_end, (uint8_t *)&addr, addr_len) != -1) {
+				send_gratuitous_arp_kern(NULL, fip_p->realIfName, &addr, addr_len);
+				ip_incaddr((uint8_t *)&addr, addr_len);
+			}
+		}
+	}
+
+	return 0;
+}
Index: /branches/rel_apv_10_7/usr/src/sys/click/app/snmp/snmp_trap.h
===================================================================
--- /branches/rel_apv_10_7/usr/src/sys/click/app/snmp/snmp_trap.h	(revision 40078)
+++ /branches/rel_apv_10_7/usr/src/sys/click/app/snmp/snmp_trap.h	(working copy)
@@ -11,12 +11,6 @@
 MALLOC_DECLARE(M_LOG_OID);
 #endif
 
-extern uint32_t traps_count;
-extern uint32_t traps_limit;
-#define SNMP_TRAPS_LIMIT_ENABLE(nthreads)      snmp_traps_limit_reset(nthreads) 
-#define SNMP_TRAPS_LIMIT_DISABLE()             (traps_limit = 0)
-#define SNMP_TRAPS_COUNT_RESET()               (traps_count = 0)
-
 int kern_snmp_init(void);
 int kern_snmp_send_link_trap(int type, int ifindex, int ifadminstatus,
 			     int ifoperstatus);
Index: /branches/rel_apv_10_7/usr/src/sys/click/app/snmp/snmp_trap.c
===================================================================
--- /branches/rel_apv_10_7/usr/src/sys/click/app/snmp/snmp_trap.c	(revision 40078)
+++ /branches/rel_apv_10_7/usr/src/sys/click/app/snmp/snmp_trap.c	(working copy)
@@ -1109,49 +1109,6 @@
         return 0;
 }
 
-static int snmp_traps_limit = 1000;
-SYSCTL_INT(_net_inet_clicktcp, OID_AUTO, snmp_traps_limit, CTLFLAG_RW,
-	&snmp_traps_limit, 0, "snmp traps limitation");
-
-static uint64_t snmp_traps_pass = 0;
-SYSCTL_ULONG(_net_inet_clicktcp, OID_AUTO, snmp_traps_pass, CTLFLAG_RW,
-	&snmp_traps_pass, 0, "snmp traps pass counter");
-static uint64_t snmp_traps_deny = 0;
-SYSCTL_ULONG(_net_inet_clicktcp, OID_AUTO, snmp_traps_deny, CTLFLAG_RW,
-	&snmp_traps_deny, 0, "snmp traps deny counter");
-
-uint32_t traps_count = 0;
-uint32_t traps_limit = 0;
-
-void snmp_traps_limit_reset(int nthreads) 
-{
-	int val = nthreads*kern_snmp_config.num_hosts;
-       
-	if (val) {
-		traps_limit = snmp_traps_limit/val;
-		if (traps_limit < 1) {
-			traps_limit = 1;
-		}
-	} else {
-		traps_limit = 0;
-	}
-	traps_count = 0;
-}
-
-int is_snmp_traps_deny(void)
-{
-	if (traps_limit == 0) {
-		return 0;
-	} else if (traps_count < traps_limit) {
-		traps_count++;
-		snmp_traps_pass++;
-		return 0;
-	}
-
-	snmp_traps_deny++;
-	return 1;
-}
-
 int
 kern_snmp_send_syslog_trap(log_entry_t *logentry)
 {	
@@ -1160,8 +1117,7 @@
 	uint32_t log_oid;
 
 	log_oid = is_snmp_trap_oid_configured(logentry->log_id);
-	if (TRAP_SEND_DISABLE || ((logentry->level > kern_snmp_config.traps_log_level) && log_oid == 0)
-			      || is_snmp_traps_deny()) {
+	if (TRAP_SEND_DISABLE || ((logentry->level > kern_snmp_config.traps_log_level) && log_oid == 0)) {	
 		return 0;
 	}
 	
Index: /branches/rel_apv_10_7/usr/src/sys/net/if.c
===================================================================
--- /branches/rel_apv_10_7/usr/src/sys/net/if.c	(revision 40078)
+++ /branches/rel_apv_10_7/usr/src/sys/net/if.c	(working copy)
@@ -4324,12 +4324,12 @@
 	return 0;
 }
 
-/* 
+/*
  * increase addr by 1
  * return 0 if not overflow
  * return 1 if overflow
  */
-static unsigned int 
+unsigned int
 ip_incaddr(uint8_t *addr, int size)
 {
 	int i;
