Index: /branches/rel_apv_10_4_0_112_gail/usr/click/lib/libparser/commands.pm
===================================================================
--- /branches/rel_apv_10_4_0_112_gail/usr/click/lib/libparser/commands.pm	(revision 39063)
+++ /branches/rel_apv_10_4_0_112_gail/usr/click/lib/libparser/commands.pm	(working copy)
@@ -19393,6 +19393,21 @@
 					optional => "YES",
 					default_value => "60",},
 		    ],
+	},
+	{
+		obj_type => "ITEM",
+		name => "blacklist",
+		menu => "root_ip_rts",
+		help_string => "Blacklist ip's for rts",
+		cmd_attribute => "CMD_ARRAYOS|CMD_SPROXY|CMD_KERN_API|CMD_NORMAL|CMD_MONITOR|CMD_GLOBAL",
+		user_level => "CLI_LEVEL_ENABLE",
+		function_name => "blacklist_ip_rts",
+		function_args => [{
+			type => "STRING",
+			help_string => "Please input the ip addresses you want to blacklist in the route entry seperated by forward slash or enter \\\"disable\\\" to disable the blacklisting feature.",
+			optional => "NO",
+		},
+		],
 	},		
 	{
 		obj_type => "ITEM",
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 39063)
+++ /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/netinet/click_eroute.c	(working copy)
@@ -25,6 +25,8 @@
 #include <netinet/in_systm.h>
 #include <netinet/ip.h>
 #include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/icmp6.h>
 #include <netinet/tcp.h>
 #include <netinet/tcpip.h>
 #include <netinet/tcp_fsm.h>
@@ -10518,6 +10520,49 @@
 	return ret;
 }
 
+int blacklisted = 0;
+char blk_ips[100][100];
+int blk_count;
+
+
+int blacklist_ip_rts(void *pcb, char *ip_str)
+{
+	int ip_count = 0;
+	int len = strlen(ip_str);
+	int start = 0;
+	int end = 0;
+
+	if (ip_str[0] == '\0'){
+		app_printf(pcb, "please enter blacklisting ip address or disable");
+		return EROUTE_CLI_OK;
+	}
+	if (strncmp(ip_str, "disable", 7) == 0) {
+		blacklisted = 0;
+		return 0;
+	}
+
+	while (end <= len) {
+		if (ip_str[end] == '/' || ip_str[end] == '\0') {
+			strncpy(blk_ips[ip_count], ip_str + start, end - start);
+			blk_ips[ip_count][end - start] = '\0';
+
+			start = end + 1;
+			ip_count++;
+		}
+
+		end++;
+	}
+	blk_count = ip_count;
+	int i;
+	for ( i = 0; i < ip_count; i++) {
+		printf("blacklisted ips %d: %s\n", i + 1, blk_ips[i]);
+	}
+
+	blacklisted = 1;
+	return 0;
+
+}
+
 void
 rts_create(struct mbuf * m, void *ip_v, int flag)
 {
@@ -10534,6 +10579,7 @@
 	struct ip6_hdr *ip6;
 	int isipv6;
 	int is_bsd = (flag & EROUTE_RTS_BSD);
+	int proto;
 	hash_t *table;
 
 	clicktcp_enter_func(m, NULL);
@@ -10564,6 +10610,7 @@
 
 		ori_key = RIRT_LK_V6(&local_ip6, &remote_ip6);
 		table = rirt_table_v6;
+		proto = ip6->ip6_nxt;
 	}else{
 		ip = (struct ip*)ip_v;
 		/* get ip header and flip ips because they need to match on the way back */
@@ -10575,6 +10622,58 @@
 
 		ori_key = RIRT_LK(&local_ip, &remote_ip);
 		table = rirt_table;
+		proto = ip->ip_p;
+	}
+
+	/* In case of TCP allow only SYN packets and for icmp allow only
+	 * echorequet to create an entry in rts table
+	 */
+	if (proto == IPPROTO_TCP) {
+		struct tcphdr *tcp;
+		tcp = (struct tcphdr*)((char *)ip + ip->ip_hl *4);
+		if ((tcp->th_flags != (TH_SYN | TH_ACK)) && (tcp->th_flags != TH_SYN)) {
+			flag = (flag | EROUTE_RTS_UPDATE);
+		} else if (tcp->th_flags  == (TH_SYN | TH_ACK)) {
+			return;
+		}
+	} else if (proto == IPPROTO_ICMP){
+		struct icmp *ih;
+		if (isipv6) {
+			ih =  (struct icmp *)(ip6 + 1);
+		} else {
+			ih = GETHDR(ip, icmp);
+		}
+		if (ih->icmp_type == ICMP_ECHOREPLY){
+			return;
+		}
+	}else if (proto == IPPROTO_ICMPV6){
+		struct icmp6_hdr *ih6;
+		ih6 =  (struct icmp6_hdr *)(ip6 + 1);
+		if (ih6->icmp6_type == ICMP6_ECHO_REPLY){
+			return;
+		}
+	}
+
+	/* Enable blacklisting ips from cli using "ip rts blacklist ip1/ip2/..".
+	 * If these ip's are seen under destination ips just return without creating any entry
+	 */
+	if (blacklisted){
+		int i;
+		for( i = 0; i< blk_count; i++){
+			if (strstr(words[i], ".") == NULL) {
+				struct in6_addr blk_ip;
+				inet_pton(AF_INET6, words[i], &blk_ip);
+				if(in6_addr_cmp(&local_ip6, &blk_ip) == 0){
+					return;
+				}
+			}else{
+				struct in_addr blk_ip;
+				inet_aton(words[i], &blk_ip);
+				if(local_ip.s_addr == blk_ip.s_addr){
+					return;
+				}
+			}
+		}
 	}
 
 	RIRT_TABLE_LOCK(RIRT_LI(ori_key));
