Index: /branches/rel_apv_10_7_2_14_qos/usr/click/bin/backend/sys_tool.c
===================================================================
--- /branches/rel_apv_10_7_2_14_qos/usr/click/bin/backend/sys_tool.c	(revision 38975)
+++ /branches/rel_apv_10_7_2_14_qos/usr/click/bin/backend/sys_tool.c	(working copy)
@@ -200,6 +200,7 @@
 static char *write_aaa_session(char *segment);
 static char *write_aaa_sso(char *segment);
 static char *write_qos(char *segment) ;
+static char *write_qos_session(char *segment) ;
 static char *write_dpi(char *segment);
 static char *write_segment(char *segment);
 /*vxlan_support*/
@@ -1096,6 +1097,12 @@
         "#Qos configuration"
     },
 
+    {
+        write_qos_session,
+        CMD_NORMAL|CMD_ARRAYOS|CMD_GLOBAL,
+        "#session QoS configuration"
+    },
+
     /* Bug 16763, chenyl, 20070925 */
     {
 	write_segment,
@@ -10734,6 +10741,17 @@
 	return buf;
 }
 
+static char *write_qos_session(char *segment)
+{
+    char *buf = NULL;
+    int  len;
+
+    if (write_qos_session_kern((void **) &buf, &len) < 0) {
+        return NULL;
+    }
+    return buf;
+}
+
 static int clear_qos(void)
 {
 	clear_qos_all_kern();
Index: /branches/rel_apv_10_7_2_14_qos/usr/click/lib/libkernelapi/addCommands.pm
===================================================================
--- /branches/rel_apv_10_7_2_14_qos/usr/click/lib/libkernelapi/addCommands.pm	(revision 38975)
+++ /branches/rel_apv_10_7_2_14_qos/usr/click/lib/libkernelapi/addCommands.pm	(working copy)
@@ -3977,6 +3977,27 @@
                 {type => "OUTDATA"},
             ],
     },
+
+   {
+        cmd_attribute => "CMD_KERN_API|CMD_KAPI_LOCK",
+        function_name => "write_qos_session_kern",
+        function_args => [
+                {type => "OUTDATA"},
+            ],
+    },
+    {
+        cmd_attribute => "CMD_KERN_API",
+        function_name => "qos_session_config_kern",
+        function_args => [
+            {type => "STRING"},
+            {type => "INDATA"},
+            {type => "INDATA"},
+            {type => "U32"},
+            {type => "U16"},
+            {type => "U32"},
+            {type => "U16"},
+        ],
+    },
     # Bug 14949(QoS), end
 #WRITE cache_filter_kern add by zhangjz
     {
Index: /branches/rel_apv_10_7_2_14_qos/usr/click/lib/libparser/commands.pm
===================================================================
--- /branches/rel_apv_10_7_2_14_qos/usr/click/lib/libparser/commands.pm	(revision 38975)
+++ /branches/rel_apv_10_7_2_14_qos/usr/click/lib/libparser/commands.pm	(working copy)
@@ -57918,6 +57918,284 @@
 							},
 						],
 	},
+
+	{
+		obj_type => "MENU",
+		name => "session",
+		parent_menu => "root_qos",
+		uniq_name => "root_qos_session",
+		cmd_attribute => "CMD_ARRAYOS|CMD_SPROXY|CMD_NORMAL",
+		user_level => "CLI_LEVEL_CONFIG",
+		help_string => "Configure QoS Session",
+	},
+        {
+                obj_type => "ITEM",
+                name => "add",
+                menu => "root_qos_session",
+                cmd_attribute => "CMD_ARRAYOS|CMD_SPROXY|CMD_NORMAL|CMD_GLOBAL",
+                user_level => "CLI_LEVEL_CONFIG",
+                help_string => "Add QoS Session Configuration",
+                function_name => "qos_session_config",
+                function_args => [
+                                                        {
+                                                                type => "STRING",
+                                                                help_string => "name",
+                                                                optional => "NO",
+                                                        },
+                                                        {
+                                                                type => "STRING",
+                                                                help_string => "Interface name (<system_ifname>|<vlan_ifname>|<bond_ifname>)",
+                                                                optional => "NO",
+                                                        },
+                                                        {
+                                                                type => "DOTTEDIP",
+                                                                help_string => "Source IP address (0.0.0.0 to match any)",
+                                                                optional => "NO",
+                                                        },
+                                                        {
+                                                                type => "U16",
+                                                                help_string => "Source port (0~65535) (0 to match any)",
+                                                                optional => "NO",
+                                                        },
+                                                        {
+                                                                type => "DOTTEDIP",
+                                                                help_string => "Destination IP address (0.0.0.0 to match any)",
+                                                                optional => "NO",
+                                                        },
+                                                        {
+                                                                type => "U16",
+                                                                help_string => "Destination port (0~65535) (0 to match any)",
+                                                                optional => "NO",
+                                                        },
+                                                        {
+                                                                type => "STRING",
+                                                                help_string => "Bandwidth per Session, suffixes may be b, Kb, Mb, and Gb",
+                                                                optional => "NO",
+                                                        },
+                                                        {
+                                                                type => "STRING",
+                                                                help_string => "Output/input direction (OUT/IN)",
+                                                                optional => "NO",
+                                                        },
+                                                ],
+        },
+	{
+		obj_type => "MENU",
+		name => "session",
+		parent_menu => "root_show_qos",
+		uniq_name => "root_show_qos_session",
+		cmd_attribute => "CMD_ARRAYOS|CMD_SPROXY|CMD_NORMAL",
+		user_level => "CLI_LEVEL_ENABLE",
+		help_string => "Show QoS Session",
+	},
+        {
+                obj_type => "ITEM",
+                name => "config",
+                menu => "root_show_qos_session",
+                cmd_attribute => "CMD_ARRAYOS|CMD_SPROXY|CMD_NORMAL|CMD_GLOBAL|CMD_KERN_API",
+                user_level => "CLI_LEVEL_ENABLE",
+                help_string => "Show configurations of QoS Session",
+                function_name => "show_qos_session_config",
+                function_args => [
+                                                        {
+                                                                type => "STRING",
+                                                                help_string => "Session QoS (optional, default is ALL)",
+                                                                optional => "YES",
+                                                                default_value => "\"ALL\"",
+                                                        },
+                                                ],
+        },
+        {
+                obj_type => "ITEM",
+                name => "count",
+                menu => "root_show_qos_session",
+                cmd_attribute => "CMD_ARRAYOS|CMD_SPROXY|CMD_NORMAL|CMD_GLOBAL|CMD_KERN_API",
+                user_level => "CLI_LEVEL_ENABLE",
+                help_string => "Show Session Count",
+                function_name => "show_current_queue_count_for_sessions",
+                function_args => [],
+        },
+        {
+                obj_type => "ITEM",
+                name => "session_queues",
+                menu => "root_show_qos_session",
+                cmd_attribute => "CMD_ARRAYOS|CMD_SPROXY|CMD_NORMAL|CMD_GLOBAL|CMD_KERN_API",
+                user_level => "CLI_LEVEL_ENGINEER",
+                help_string => "Show Session Queues",
+                function_name => "show_session_qos_queue_root_kern",
+                function_args => [],
+        },
+       {
+                obj_type => "ITEM",
+                name => "session_filters",
+                menu => "root_show_qos_session",
+                cmd_attribute => "CMD_ARRAYOS|CMD_SPROXY|CMD_NORMAL|CMD_GLOBAL|CMD_KERN_API",
+                user_level => "CLI_LEVEL_ENGINEER",
+                help_string => "Show Session filters",
+                function_name => "show_session_qos_filter_kern",
+                function_args => [],
+        },
+        {
+                obj_type => "ITEM",
+                name => "sespacketcnt",
+                menu => "root_show_qos_session",
+                help_string => "show minimum packet count in a stream to create a session",
+                cmd_attribute => "CMD_ARRAYOS|CMD_NORMAL|CMD_GLOBAL|CMD_KERN_API",
+                user_level => "CLI_LEVEL_ENGINEER",
+                function_name => "get_tuple_count",
+                function_args => [],
+        },
+        {
+                obj_type => "ITEM",
+                name => "sesdelstep",
+                menu => "root_show_qos_session",
+                help_string => "show session queue delete step count",
+                cmd_attribute => "CMD_ARRAYOS|CMD_NORMAL|CMD_GLOBAL|CMD_KERN_API",
+                user_level => "CLI_LEVEL_ENGINEER",
+                function_name => "get_q_del_step_size",
+                function_args => [],
+        },
+        {
+                obj_type => "ITEM",
+                name => "sesmaxcount",
+                menu => "root_show_qos_session",
+                help_string => "show max session count limit",
+                cmd_attribute => "CMD_ARRAYOS|CMD_NORMAL|CMD_GLOBAL|CMD_KERN_API",
+                user_level => "CLI_LEVEL_ENGINEER",
+                function_name => "get_qos_max_session_count",
+                function_args => [],
+        },
+        {
+                obj_type => "ITEM",
+                name => "qosclspos",
+                menu => "root_show_qos_session",
+                help_string => "show QoS class insert position",
+                cmd_attribute => "CMD_ARRAYOS|CMD_NORMAL|CMD_GLOBAL|CMD_KERN_API",
+                user_level => "CLI_LEVEL_ENGINEER",
+                function_name => "get_class_insert_pos",
+                function_args => [],
+        },
+        {
+                obj_type => "ITEM",
+                name => "qosclasscnt",
+                menu => "root_show_qos_session",
+                help_string => "show loop count to iterate over the QoS Session classes",
+                cmd_attribute => "CMD_ARRAYOS|CMD_NORMAL|CMD_GLOBAL|CMD_KERN_API",
+                user_level => "CLI_LEVEL_ENGINEER",
+                function_name => "get_loop_class_count",
+                function_args => [],
+        },
+        {
+                obj_type => "ITEM",
+                name => "qlenwait",
+                menu => "root_show_qos_session",
+                help_string => "show max outstanding mbuf allowed to be in queue",
+                cmd_attribute => "CMD_ARRAYOS|CMD_NORMAL|CMD_GLOBAL|CMD_KERN_API",
+                user_level => "CLI_LEVEL_ENGINEER",
+                function_name => "get_q_len_wait",
+                function_args => [],
+        },
+        {
+                obj_type => "ITEM",
+                name => "session",
+                menu => "root_no_qos",
+                cmd_attribute => "CMD_ARRAYOS|CMD_NORMAL|CMD_GLOBAL|CMD_KERN_API",
+                user_level => "CLI_LEVEL_CONFIG",
+                help_string => "Delete configuration of QoS Session",
+                function_name => "delete_qos_session_config",
+                function_args => [
+                                                        {
+                                                                type => "STRING",
+                                                                help_string => "type 'ALL' to delete all QoS Session configurations",
+                                                                optional => "NO",
+                                                        },
+                                                ],
+        },
+        {
+                obj_type => "ITEM",
+                name => "on",
+                menu => "root_qos_session",
+                help_string => "Activate QoS Session",
+                cmd_attribute => "CMD_ARRAYOS|CMD_NORMAL|CMD_GLOBAL|CMD_KERN_API",
+                user_level => "CLI_LEVEL_CONFIG",
+                function_name => "enable_session",
+                function_args => [],
+        },
+
+        {
+                obj_type => "ITEM",
+                name => "off",
+                menu => "root_qos_session",
+                help_string => "Deactivate QoS Session",
+                cmd_attribute => "CMD_ARRAYOS|CMD_NORMAL|CMD_GLOBAL|CMD_KERN_API",
+                user_level => "CLI_LEVEL_CONFIG",
+                function_name => "disable_session",
+                function_args => [],
+        },
+        {
+                obj_type => "ITEM",
+                name => "sespacketcnt",
+                menu => "root_qos_session",
+                help_string => "Minimum packet count in a stream to create a session",
+                cmd_attribute => "CMD_ARRAYOS|CMD_NORMAL|CMD_GLOBAL|CMD_KERN_API",
+                user_level => "CLI_LEVEL_ENGINEER",
+                function_name => "set_tuple_count",
+                function_args => [
+                        {
+                                        type => "U32",
+                                        help_string => "set count [1 to 1024]",
+                                        optional => "NO",
+                        },
+                ],
+        },
+        {
+                obj_type => "ITEM",
+                name => "sesdelstep",
+                menu => "root_qos_session",
+                help_string => "set session queue delete step count",
+                cmd_attribute => "CMD_ARRAYOS|CMD_NORMAL|CMD_GLOBAL|CMD_KERN_API",
+                user_level => "CLI_LEVEL_ENGINEER",
+                function_name => "set_q_del_step_size",
+                function_args => [
+                        {
+                                        type => "U32",
+                                        help_string => "set count [1 to 1024]",
+                                        optional => "NO",
+                        },
+                ],
+        },
+        {
+                obj_type => "ITEM",
+                name => "sesmaxcount",
+                menu => "root_qos_session",
+                help_string => "set max session count limit",
+                cmd_attribute => "CMD_ARRAYOS|CMD_NORMAL|CMD_GLOBAL|CMD_KERN_API|CMD_KAPI_LOCK",
+                user_level => "CLI_LEVEL_ENGINEER",
+                function_name => "set_qos_max_session_count",
+                function_args => [
+                        {
+                                        type => "U32",
+                                        help_string => "set count [max 700000]",
+                                        optional => "NO",
+                        },
+                ],
+        },
+        {
+                obj_type => "ITEM",
+                name => "qosclspos",
+                menu => "root_qos_session",
+                help_string => "set QoS class insert position",
+                cmd_attribute => "CMD_ARRAYOS|CMD_NORMAL|CMD_GLOBAL|CMD_KERN_API|CMD_KAPI_LOCK",
+                user_level => "CLI_LEVEL_ENGINEER",
+                function_name => "set_class_insert_pos",
+                function_args => [
+                        {
+                                        type => "U32",
+                                        help_string => "set count(1 to 50000)",
+                                        optional => "NO",
+                        },
+                ],
+        },
 	{
 		obj_type => "ITEM",
 		name => "sub",
Index: /branches/rel_apv_10_7_2_14_qos/usr/click/lib/libqos_cli/qos_cli.h
===================================================================
--- /branches/rel_apv_10_7_2_14_qos/usr/click/lib/libqos_cli/qos_cli.h	(revision 38975)
+++ /branches/rel_apv_10_7_2_14_qos/usr/click/lib/libqos_cli/qos_cli.h	(working copy)
@@ -20,6 +20,8 @@
 #define	RM_FILTER_GAIN	5	/* log2 of gain, e.g., 5 => 31/32 */
 #define	RM_NS_PER_SEC	(1000000000)
 
+#define SESSION_BASED_QOS_NLEN 15
+
 /*************************************************************************
  * STRUCTURE DEFINITIONS
  *************************************************************************/
@@ -35,4 +37,3 @@
 extern int challange_user(char *);
 
 #endif /* _QOS_H_DEFINED_ */
-
Index: /branches/rel_apv_10_7_2_14_qos/usr/click/lib/libqos_cli/qos_cli.c
===================================================================
--- /branches/rel_apv_10_7_2_14_qos/usr/click/lib/libqos_cli/qos_cli.c	(revision 38975)
+++ /branches/rel_apv_10_7_2_14_qos/usr/click/lib/libqos_cli/qos_cli.c	(working copy)
@@ -17,6 +17,7 @@
 #include <limits.h>
 #include <math.h>
 #include <stdint.h>
+#include <stdarg.h>
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -66,6 +67,7 @@
 
 #include <click/app/qos/qos_var.h>
 #include <click/app/qos/qos_scheduler.h>
+#include <click/app/qos/qos_classifier.h>
 #include <click/app/qos/altq_var.h>
 #include <click/app/qos/altq_cbq.h>
 #include "qos_cli.h"
@@ -84,6 +86,7 @@
 #define	SIOCGIFMTU		UINET_SIOCGIFMTU
 #endif
 
+
 /*
  * ------------------------ function prototypes ---------------------------
  */
@@ -748,6 +751,7 @@
 	return(0);
 }
 
+
 /* CLI: qos queue root ... */
 int qos_queue_root(char *sQueue, char *sIfName, char *sDir, char *sBand, uint32_t iPri, char *sBorrow, char *sDefault)
 {
@@ -855,8 +859,7 @@
 	}
 
 	return(0);
-}
-
+} 
 /* CLI: no qos queue root ... */
 int no_qos_queue_root(char *sQueue)
 {
@@ -1077,3 +1080,95 @@
  * ------------------------ QoS Classifier functions ---------------------------
  */
 
+int qos_session_config (char *name, char *sIfName, uint32_t sip, uint16_t sport, uint32_t dip, uint16_t dport, char *sBand, char *sDir) {
+	qos_queue_root_t qQoSRoot;
+	struct altq_conf confALTQ;
+	int nIfMtu = 0;
+	int iErrCode = 0;
+	char *sDefault = NULL;
+	char *sBorrow = NULL;
+
+	QOS_CHECK_LICENSE;
+
+	bzero(&qQoSRoot, sizeof(qQoSRoot));
+	bzero(&confALTQ, sizeof(confALTQ));
+
+	bzero(qQoSRoot.sQName, QOS_QNAME_SIZE);
+
+	strncpy(qQoSRoot.sIfName, sIfName, QOS_CANAME_MAXLEN - 1);
+	if (sDir) {
+		strncpy(qQoSRoot.sDir, sDir, QOSD_STR_MAXLEN - 1);
+	} else {
+		strncpy(qQoSRoot.sDir, QOSD_IO_DEFAULT, QOSD_STR_MAXLEN - 1);
+	}
+	if (sBand) {
+		strncpy(qQoSRoot.sBand, sBand, QOS_BANDWIDTH_MAXLEN - 1);
+	} else {
+		strncpy(qQoSRoot.sBand, QOSD_BANDWIDTH_DEFAULT, QOS_BANDWIDTH_MAXLEN - 1);
+	}
+	qQoSRoot.iPri = 1;
+	if (sDefault) {
+		strncpy(qQoSRoot.sDefault, sDefault, QOS_DEFAULT_MAXLEN - 1);
+	} else {
+		strncpy(qQoSRoot.sDefault, QOS_DEFAULT_QUEUE_DEFAULT, QOS_DEFAULT_MAXLEN - 1);
+	}
+	if (sBorrow) {
+		strncpy(qQoSRoot.sBorrow, sBorrow, QOS_BORROW_MAXLEN - 1);
+	} else {
+		strncpy(qQoSRoot.sBorrow, QOS_BORROW_DEFAULT, QOS_BORROW_MAXLEN - 1);
+	}
+
+	strncpy(confALTQ.qname, qQoSRoot.sQName, QOS_QNAME_SIZE - 1);
+	strncpy(confALTQ.parent, "ROOT", QOS_QNAME_SIZE - 1);
+
+	if (getrealif(qQoSRoot.sIfName, confALTQ.ifname) != 0) {
+		printf("ERROR: can't find the QoS interface %s\n", qQoSRoot.sIfName);
+		return(-1);
+	}
+
+	if (qos_direction_str2num(qQoSRoot.sDir, &confALTQ.direction) == -1) {
+		return(-1);
+	}
+
+	if (qos_bandwidth_str2num(qQoSRoot.sBand, &confALTQ.bandwidth) == -1) {
+		return(-1);
+	}
+
+	if (qQoSRoot.iPri >= QOS_MAXPRIO || qQoSRoot.iPri < 0) {
+		printf("ERROR: priority out of range (0 ~ 7)\n");
+		return(-1);
+	} else {
+		confALTQ.priority = qQoSRoot.iPri;
+	}
+
+	if (qos_default_set(qQoSRoot.sDefault, &confALTQ) == -1) {
+		return(-1);
+	}
+
+	if (qos_borrow_set(qQoSRoot.sBorrow, &confALTQ) == -1) {
+		return(-1);
+	}
+
+	/* Fill altq_conf */
+	if (qos_get_ifmtu(confALTQ.ifname, &nIfMtu) == -1) {
+		return(-1);
+	}
+	confALTQ.scheduler = ALTQT_CBQ;
+
+	confALTQ.ifbandwidth = qos_get_ifbandwidth_kern(&confALTQ, sizeof(confALTQ));
+	if (confALTQ.ifbandwidth == 0) {
+		return(-1);
+	}
+
+	qos_evaluate(nIfMtu, &confALTQ);
+
+	/* Kernel config */
+	if ((iErrCode = qos_session_config_kern (name, &qQoSRoot, sizeof(qQoSRoot), &confALTQ, sizeof(confALTQ), sip, sport, dip, dport)) != QOS_SUCCESS)     {
+		if (iErrCode != QOS_USERLAND_FAILURE) {
+			printf("ERROR: %s\n", strerror(iErrCode));
+		}
+		return(-1);
+	}
+
+	return(0);
+}
Index: /branches/rel_apv_10_7_2_14_qos/usr/click/lib/libuinet-atcp/lib/libuinet/Makefile
===================================================================
--- /branches/rel_apv_10_7_2_14_qos/usr/click/lib/libuinet-atcp/lib/libuinet/Makefile	(revision 38975)
+++ /branches/rel_apv_10_7_2_14_qos/usr/click/lib/libuinet-atcp/lib/libuinet/Makefile	(working copy)
@@ -680,8 +680,9 @@
 	qos_classifier.c	\
 	qos_http.c	\
 	qos_scheduler.c	\
+	qos_dynamic.c   \
 	qos_subr.c
-	
+
 CLICK_APP_RADIUS_SRCS+=	\
 	radius_proxy.c
 	
Index: /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/altq_cbq.h
===================================================================
--- /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/altq_cbq.h	(revision 38975)
+++ /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/altq_cbq.h	(working copy)
@@ -90,7 +90,11 @@
 
 #ifdef _KERNEL
 
-#define	CBQ_MAX_CLASSES	256
+#ifndef MAX_DYN_QUEUE
+#define MAX_DYN_QUEUE 1000000
+#endif
+
+#define	CBQ_MAX_CLASSES	(MAX_DYN_QUEUE + 1024)
 
 /*
  * Define State structures.
Index: /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/altq_cbq.c
===================================================================
--- /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/altq_cbq.c	(revision 38975)
+++ /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/altq_cbq.c	(working copy)
@@ -65,6 +65,11 @@
 #ifdef __QOS_COMPILED__
 #include <click/app/qos/altq_cbq.h>
 
+#include <click/app/fastlog/fastlog.h>
+#include <click/app/qos/qos_dynamic.h>
+
+
+
 /*
  * Forward Declarations.
  */
@@ -556,6 +561,7 @@
 
 	len = m_pktlen(m);
 	if (rmc_queue_packet(cl, m) != 0) {
+                fastlog_syslog(LOG_DEBUG, "error queueing the packets. Current queue length %d\n", cl->q_->qlen_);
 		/* drop occurred.  some mbuf was freed in rmc_queue_packet. */
 		PKTCNTR_ADD(&cl->stats_.drop_cnt, len);
 		return (ENOBUFS);
@@ -575,6 +581,11 @@
 
 	IFQ_LOCK_ASSERT(ifq);
 
+        if ((op == ALTDQ_REMOVE) && (cbqp->cbq_qlen <= 0)) {
+            return NULL;
+        }
+
+
 	m = rmc_dequeue_next(&cbqp->ifnp, op);
 
 	if (m && op == ALTDQ_REMOVE) {
@@ -584,6 +595,13 @@
 		/* Update the class. */
 		rmc_update_class_util(&cbqp->ifnp);
 	}
+
+#ifdef MORELOG
+        if (!m) {
+            fastlog_syslog(LOG_DEBUG, "cbq_dequeue : %x - no packet to dequue, no of outstanding packets to be dequeued : %d\n", cbqp, cbqp->cbq_qlen);
+        }
+#endif
+	total_outstanding_mbuf = cbqp->cbq_qlen;
 	return (m);
 }
 
Index: /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/altq_classq.h
===================================================================
--- /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/altq_classq.h	(revision 38975)
+++ /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/altq_classq.h	(working copy)
@@ -33,6 +33,9 @@
 /*
  * class queue definitions extracted from rm_class.h.
  */
+#include <click/app/fastlog/fastlog.h>
+
+
 #ifndef _ALTQ_ALTQ_CLASSQ_H_
 #define	_ALTQ_ALTQ_CLASSQ_H_
 
@@ -58,6 +61,7 @@
 	int	qlen_;		/* Queue length (in number of packets) */
 	int	qlim_;		/* Queue limit (in number of packets*) */
 	int	qtype_;		/* Queue type */
+	struct  mtx qos_qtail_lock; /* Queue thread lock */
 };
 
 typedef struct _class_queue_	class_queue_t;
@@ -83,13 +87,17 @@
 extern void		_flushq(class_queue_t *);
 
 #else /* __GNUC__ && !ALTQ_DEBUG */
+
+
 /*
  * inlined versions
  */
 static __inline void
 _addq(class_queue_t *q, struct mbuf *m)
 {
-        struct mbuf *m0;
+	struct mbuf *m0;
+
+	mtx_lock (&q->qos_qtail_lock);
 
 	if ((m0 = qtail(q)) != NULL)
 		m->m_nextpkt = m0->m_nextpkt;
@@ -98,6 +106,7 @@
 	m0->m_nextpkt = m;
 	qtail(q) = m;
 	qlen(q)++;
+	mtx_unlock (&q->qos_qtail_lock);
 }
 
 static __inline struct mbuf *
@@ -105,14 +114,18 @@
 {
 	struct mbuf  *m, *m0;
 
-	if ((m = qtail(q)) == NULL)
+	mtx_lock (&q->qos_qtail_lock);
+	if ((m = qtail(q)) == NULL) {
+                mtx_unlock (&q->qos_qtail_lock);
 		return (NULL);
+	}
 	if ((m0 = m->m_nextpkt) != m)
 		m->m_nextpkt = m0->m_nextpkt;
 	else
 		qtail(q) = NULL;
 	qlen(q)--;
 	m0->m_nextpkt = NULL;
+	mtx_unlock (&q->qos_qtail_lock);
 	return (m0);
 }
 
Index: /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/altq_rmclass.h
===================================================================
--- /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/altq_rmclass.h	(revision 38975)
+++ /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/altq_rmclass.h	(working copy)
@@ -192,6 +192,7 @@
 	rm_class_t	*next_;		/* Next pointer, used if child */
 
 	rm_class_t	*peer_;		/* Peer class */
+	rm_class_t	*prev_peer_;	/* Previous Peer class */
 	rm_class_t	*borrow_;	/* Borrow class */
 	rm_class_t	*parent_;	/* Parent class */
 
@@ -227,6 +228,7 @@
 	int		qi_;		/* In/out pointers for downstream */
 	int		qo_;		/* packets */
 
+        struct  mtx lock;
 	/*
 	 * Active class state and WRR state.
 	 */
Index: /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/altq_rmclass.c
===================================================================
--- /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/altq_rmclass.c	(revision 38975)
+++ /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/altq_rmclass.c	(working copy)
@@ -45,6 +45,7 @@
 #define ALTQ_DEBUG 1
 */
 
+
 #if (__FreeBSD__ != 2)
 #include "opt_inet.h"
 #ifdef __FreeBSD__
@@ -74,16 +75,28 @@
 #include <click/app/qos/altq_rmclass.h>
 #include <click/app/qos/altq_red.h>
 
+#include <sys/syslog.h>
+#include <click/app/qos/qos_dynamic.h>
+#include <click/netinet/click_var.h>
+#include <click/app/qos/qos_classifier.h>
 /*
  * Local Macros
  */
 
 #define	reset_cutoff(ifd)	{ ifd->cutoff_ = RM_MAXDEPTH; }
 
+
 /*
  * Local routines.
  */
 
+
+extern int class_insert_pos;
+extern int loop_class_count;
+extern int q_len_wait;
+
+extern qos_filter_share_t qos_filter_share;
+
 static int	rmc_satisfied(struct rm_class *, struct timeval *);
 static void	rmc_wrr_set_weights(struct rm_ifdat *);
 static void	rmc_depth_compute(struct rm_class *);
@@ -309,6 +322,14 @@
 	return;
 }
 
+void qlockinit (class_queue_t *q) {
+     mtx_init(&q->qos_qtail_lock, "qos queue tail lock", NULL, MTX_DEF | MTX_NOWITNESS);
+}
+
+void qlockdestroy (class_queue_t *q) {
+     mtx_destroy(&q->qos_qtail_lock);
+}
+
 struct rm_class *
 rmc_newclass(int pri, struct rm_ifdat *ifd, u_int nsecPerByte,
     void (*action)(rm_class_t *, rm_class_t *), int maxq,
@@ -318,6 +339,7 @@
 	struct rm_class	*cl;
 	struct rm_class	*peer;
 	int		 s;
+	int ncount = 0;
 
 	if (pri >= RM_MAXPRIO)
 		return (NULL);
@@ -369,6 +391,7 @@
 	qlimit(cl->q_) = maxq;
 	qtype(cl->q_) = Q_DROPHEAD;
 	qlen(cl->q_) = 0;
+	qlockinit(cl->q_);
 	cl->flags_ = flags;
 
 #if 1 /* minidle is also scaled in ALTQ */
@@ -444,15 +467,23 @@
 	s = splimp();
 #endif
 	IFQ_LOCK(ifd->ifq_);
+	mtx_lock(&ifd->lock);
 	if ((peer = ifd->active_[pri]) != NULL) {
-		/* find the last class at this pri */
-		cl->peer_ = peer;
-		while (peer->peer_ != ifd->active_[pri])
+		while (peer->peer_ != NULL && ++ncount < class_insert_pos)
 			peer = peer->peer_;
-		peer->peer_ = cl;
+                if (peer->peer_ == NULL) {
+	            peer->peer_ = cl;
+                    cl->prev_peer_ = peer;
+		    cl->peer_ = NULL;
+                } else {
+                        cl->peer_ = peer->peer_;
+                        peer->peer_ = cl;
+                        cl->prev_peer_ = peer;
+                }
 	} else {
+		cl->peer_ = NULL;
+                cl->prev_peer_ = NULL;
 		ifd->active_[pri] = cl;
-		cl->peer_ = cl;
 	}
 
 	if (cl->parent_) {
@@ -473,8 +504,9 @@
 	if (ifd->wrr_) {
 		ifd->num_[pri]++;
 		ifd->alloc_[pri] += cl->allotment_;
-		rmc_wrr_set_weights(ifd);
+		cl->w_allotment_ = cl->allotment_;
 	}
+        mtx_unlock(&ifd->lock);
 	IFQ_UNLOCK(ifd->ifq_);
 	splx(s);
 	return (cl);
@@ -738,22 +770,22 @@
 	/*
 	 * Delete class from class priority peer list.
 	 */
-	if ((p = ifd->active_[cl->pri_]) != NULL) {
+	if ((ifd->active_[cl->pri_]) != NULL) {
 		/*
 		 * If there is more than one member of this priority
 		 * level, then look for class(cl) in the priority level.
 		 */
-		if (p != p->peer_) {
-			while (p->peer_ != cl)
-				p = p->peer_;
-			p->peer_ = cl->peer_;
-
-			if (ifd->active_[cl->pri_] == cl)
-				ifd->active_[cl->pri_] = cl->peer_;
-		} else {
-			ALTQ_ASSERT(p == cl);
-			ifd->active_[cl->pri_] = NULL;
-		}
+                if (cl == ifd->active_[cl->pri_]) {
+                    ifd->active_[cl->pri_] = cl->peer_;
+                    if (cl->peer_) {
+                        cl->peer_->prev_peer_ = NULL;
+                    }
+                } else {
+                     if (cl->prev_peer_)
+                        cl->prev_peer_->peer_ = cl->peer_;
+                     if (cl->peer_)
+                        cl->peer_->prev_peer_ = cl->prev_peer_;
+                }
 	}
 
 	/*
@@ -762,7 +794,7 @@
 	if (ifd->wrr_) {
 		ifd->alloc_[cl->pri_] -= cl->allotment_;
 		ifd->num_[cl->pri_]--;
-		rmc_wrr_set_weights(ifd);
+		cl->w_allotment_ = cl->allotment_;
 	}
 
 	/*
@@ -790,6 +822,7 @@
 			red_destroy(cl->red_);
 #endif
 	}
+	qlockdestroy(cl->q_);
 	FREE(cl->q_, M_DEVBUF);
 	FREE(cl, M_DEVBUF);
 }
@@ -832,6 +865,7 @@
 	ifd->ns_per_byte_ = nsecPerByte;
 	ifd->maxpkt_ = mtu;
 	ifd->wrr_ = (flags & RMCF_WRR) ? 1 : 0;
+        mtx_init(&ifd->lock, "qos cbq interface lock", NULL, MTX_DEF | MTX_NOWITNESS);
 	ifd->efficient_ = (flags & RMCF_EFFICIENT) ? 1 : 0;
 #if 1
 	ifd->maxiftime_ = mtu * nsecPerByte / 1000 * 16;
@@ -889,6 +923,7 @@
  *	Returns:	0 on successful queueing
  *			-1 when packet drop occurs
  */
+
 int
 rmc_queue_packet(struct rm_class *cl, mbuf_t *m)
 {
@@ -934,9 +969,12 @@
 #endif /* !ALTQ */
 	}
 
-	if (_rmc_addq(cl, m) < 0)
+	if (_rmc_addq(cl, m) < 0) {
 		/* failed */
+		qos_filter_share.fltr_g_stats.q_enqueue_fail[cpri]++;
+		fastlog_syslog(LOG_DEBUG, "rmc_queue_packet : FAILED to enqueue mbuf for the class : %x\n", cl);
 		return (-1);
+        }
 
 	if (is_empty) {
 		CBQTRACE(rmc_queue_packet, 'ytpe', cl->stats_.handle);
@@ -945,9 +983,30 @@
 
 	if (qlen(cl->q_) > qlimit(cl->q_)) {
 		/* note: qlimit can be set to 0 or 1 */
+                fastlog_syslog(LOG_DEBUG, "mbuf DROP action for class : %x. Pending mbuf's : %d. Max allowed mbuf's : %d\n", cl, qlen(cl->q_), qlimit(cl->q_));
+		qos_filter_share.fltr_g_stats.q_full_count[cpri]++;
 		rmc_drop_action(cl);
 		return (-1);
 	}
+#ifdef MORELOG
+	fastlog_syslog(LOG_DEBUG, "rmc_queue_packet : mbuf enqueued for the class : %x\n", cl);
+#endif
+	mtx_lock(&ifd->lock);
+	if (cl == ifd->active_[cl->pri_])
+	    ;
+	else {
+	    if (cl->prev_peer_ != NULL )
+		cl->prev_peer_->peer_ = cl->peer_;
+	    if (cl->peer_ != NULL)
+		cl->peer_->prev_peer_ = cl->prev_peer_;
+	    cl->peer_ = ifd->active_[cl->pri_]->peer_;
+	    ifd->active_[cl->pri_]->peer_ = cl;
+	    cl->prev_peer_ = ifd->active_[cl->pri_];
+	    if (cl->peer_) {
+		cl->peer_->prev_peer_ = cl;
+	    }
+	}
+	mtx_unlock(&ifd->lock);
 	return (0);
 }
 
@@ -972,7 +1031,7 @@
 					return;
 				}
 				p = p->peer_;
-			} while (p != bp);
+			} while (p != NULL);
 		}
 	}
 
@@ -1028,19 +1087,20 @@
 	 * If cl is the root class, then always return that it is
 	 * underlimit.  Otherwise, check to see if the class is underlimit.
 	 */
-	if (cl->parent_ == NULL)
+	if (cl->parent_ == NULL) {
 		return (1);
-
+        }
 	top = NULL;
 	while (cl->undertime_.tv_sec && TV_LT(now, &cl->undertime_)) {
 		if (((cl = cl->borrow_) == NULL) ||
 		    (cl->depth_ > ifd->cutoff_)) {
 #ifdef ADJUST_CUTOFF
-			if (cl != NULL)
+			if (cl != NULL) {
 				/* cutoff is taking effect, just
 				   return false without calling
 				   the delay action. */
 				return (0);
+                        }
 #endif
 #ifdef BORROW_OFFTIME
 			/*
@@ -1056,6 +1116,9 @@
 			if (top != NULL && top->avgidle_ == top->minidle_)
 				top = NULL;
 			p->overtime_ = *now;
+#ifdef MORELOG
+                        fastlog_syslog(LOG_DEBUG, "overlimit action top : %p, class : %x\n", top, cl);
+#endif
 			(p->overlimit)(p, top);
 #else
 			p->overtime_ = *now;
@@ -1103,6 +1166,8 @@
 	mbuf_t		*m;
 	struct timeval	 now;
 
+	u_int		 loop_ct;
+
 	RM_GETTIME(now);
 
 	/*
@@ -1133,6 +1198,7 @@
 		if (ifd->na_[cpri] == 0)
 			continue;
 		deficit = 0;
+                loop_ct = 0;
 		/*
 		 * Loop through twice for a priority level, if some class
 		 * was unable to send a packet the first round because
@@ -1144,29 +1210,47 @@
 		 */
  _wrr_loop:
 		cl = ifd->active_[cpri];
+                if (cl == NULL) {
+                    fastlog_syslog(LOG_DEBUG, "_rmc_wrr_dequeue_next : no active mbuf to process\n");
+                    return NULL;
+                }
 		ALTQ_ASSERT(cl != NULL);
 		do {
-			if ((deficit < 2) && (cl->bytes_alloc_ <= 0))
+                        ++loop_ct;
+			if ((deficit < 2) && (cl->bytes_alloc_ <= 0)) {
 				cl->bytes_alloc_ += cl->w_allotment_;
+			}
 			if (!qempty(cl->q_)) {
+				qos_filter_share.fltr_g_stats.cur_pend_mbuf[cpri] = qlen(cl->q_);
+				qos_filter_share.fltr_g_stats.total_outstanding_mbuf = total_outstanding_mbuf;
 				if ((cl->undertime_.tv_sec == 0) ||
 				    rmc_under_limit(cl, &now)) {
-					if (cl->bytes_alloc_ > 0 || deficit > 1)
+					if (cl->bytes_alloc_ > 0 || deficit > 1) {
 						goto _wrr_out;
-
-					/* underlimit but no alloc */
-					deficit = 1;
-#if 1
+                                        }
+                                    deficit = 1;
+                                    ifd->borrowed_[ifd->qi_] = NULL;
+
+                                } else if ( qlen(cl->q_) >= q_len_wait) {
+#ifdef MORELOG
+                                        fastlog_syslog(LOG_DEBUG, "current pending mbufs for class : %x is %d.....sending out\n", cl, qlen(cl->q_));
+#endif
+					qos_filter_share.fltr_g_stats.q_overload_count[cpri]++;
 					ifd->borrowed_[ifd->qi_] = NULL;
+                                        goto _wrr_out;
+                                } else if (first == NULL && cl->borrow_ != NULL) {
+				    first = cl; /* borrowing candidate */
+                                }
+#ifdef MORELOG
+                                else {
+                                        fastlog_syslog(LOG_DEBUG, "queue not empty but will not process, as it is overlimit class : %x, qlen is %d\n", cl, qlen(cl->q_));
+                                }
 #endif
-				}
-				else if (first == NULL && cl->borrow_ != NULL)
-					first = cl; /* borrowing candidate */
+				first = cl; /* if no underlimit class found, we will attempt this class */
 			}
-
 			cl->bytes_alloc_ = 0;
 			cl = cl->peer_;
-		} while (cl != ifd->active_[cpri]);
+		} while (cl != NULL && loop_ct <= loop_class_count); // while (cl != ifd->active_[cpri]);
 
 		if (deficit == 1) {
 			/* first loop found an underlimit class with deficit */
@@ -1195,9 +1279,12 @@
 	reset_cutoff(ifd);
 	CBQTRACE(_rmc_wrr_dequeue_next, 'otsr', ifd->cutoff_);
 
-	if (!ifd->efficient_ || first == NULL)
+	if (!ifd->efficient_ || first == NULL) {
+#ifdef MORELOG
+		fastlog_syslog(LOG_DEBUG, "dequeue failed. return NULL\n");
+#endif
 		return (NULL);
-
+        }
 	cl = first;
 	cpri = cl->pri_;
 #if 0	/* too time-consuming for nothing */
@@ -1213,23 +1300,42 @@
 	 * Deque the packet and do the book keeping...
 	 */
  _wrr_out:
+
+
 	if (op == ALTDQ_REMOVE) {
 		m = _rmc_getq(cl);
-		if (m == NULL)
+		if (m == NULL) {
+                        fastlog_syslog(LOG_DEBUG, "panic in _rmc_getq\n");
 			panic("_rmc_wrr_dequeue_next");
-		if (qempty(cl->q_))
+                }
+#ifdef MORELOG
+                fastlog_syslog(LOG_DEBUG, "DEQUEUE done for the class : %x but still : %d mbuf remaining....\n", cl, qlen(cl->q_));
+#endif
+                mtx_lock(&ifd->lock);
+		if (qempty(cl->q_)) {
 			ifd->na_[cpri]--;
+#ifdef MORELOG
+                        fastlog_syslog(LOG_DEBUG, "all packets empty for one of the class : %x. total class's in priority %d is %d\n", cl, cpri, ifd->na_[cpri]);
+#endif
+                        qos_filter_share.fltr_g_stats.total_active_class[cpri] = ifd->na_[cpri];
+                }
+                else if (cl == ifd->active_[cl->pri_]) ;
+                else {
+                        if (cl->prev_peer_ != NULL )
+                            cl->prev_peer_->peer_ = cl->peer_;
+                        if (cl->peer_ != NULL) {
+                            cl->peer_->prev_peer_ = cl->prev_peer_;
+                        }
+                        cl->prev_peer_ = NULL;
+                        cl->peer_ = ifd->active_[cl->pri_];
+	                ifd->active_[cl->pri_]->prev_peer_ = cl;
+			ifd->active_[cl->pri_] = cl;
+                }
+                mtx_unlock(&ifd->lock);
 
 		/*
 		 * Update class statistics and link data.
 		 */
-		if (cl->bytes_alloc_ > 0)
-			cl->bytes_alloc_ -= m_pktlen(m);
-
-		if ((cl->bytes_alloc_ <= 0) || first == cl)
-			ifd->active_[cl->pri_] = cl->peer_;
-		else
-			ifd->active_[cl->pri_] = cl;
 
 		ifd->class_[ifd->qi_] = cl;
 		ifd->curlen_[ifd->qi_] = m_pktlen(m);
@@ -1291,7 +1397,7 @@
 					first = cl;
 			}
 			cl = cl->peer_;
-		} while (cl != ifd->active_[cpri]);
+		} while ((cl != NULL) && (cl != ifd->active_[cpri]));
 	}
 
 #ifdef ADJUST_CUTOFF
@@ -1367,12 +1473,16 @@
 mbuf_t *
 rmc_dequeue_next(struct rm_ifdat *ifd, int mode)
 {
-	if (ifd->queued_ >= ifd->maxqueued_)
+	if (ifd->queued_ >= ifd->maxqueued_) {
+                fastlog_syslog(LOG_DEBUG, "classes are ovelimit not dequeuing. current size : %d.  max : %d\n", ifd->queued_, ifd->maxqueued_);
 		return (NULL);
-	else if (ifd->wrr_)
+        }
+	else if (ifd->wrr_) {
 		return (_rmc_wrr_dequeue_next(ifd, mode));
-	else
+        }
+	else {
 		return (_rmc_prr_dequeue_next(ifd, mode));
+        }
 }
 
 /*
@@ -1631,6 +1741,9 @@
 	int	delay, t, extradelay;
 
 	do {
+#ifdef MORELOG
+                fastlog_syslog(LOG_DEBUG, "rmc_delay_action for class : %x\n", cl);
+#endif
 		cl->stats_.overactions++;
 
 		if (!cl->sleeping_) {
@@ -1685,6 +1798,10 @@
 	#endif
 			} else
 				t = 2;
+#ifdef MORELOG
+		        fastlog_syslog(LOG_DEBUG, "rmc_restart : fixing to 2 ticks appeared to have better performace at higher QoS sessions\n");
+#endif
+			t = 2;
 			CALLOUT_RESET(&cl->callout_, t,
 				      (timeout_t *)rmc_restart, (caddr_t)cl);
 		}
@@ -1716,6 +1833,7 @@
 	struct rm_ifdat	*ifd = cl->ifdat_;
 	int		 s;
 
+	fastlog_syslog(LOG_DEBUG, "rmc_restart for the class : %x\n", cl);
 #ifdef __NetBSD__
 	s = splnet();
 #else
@@ -1730,6 +1848,22 @@
 			CBQTRACE(rmc_restart, 'trts', cl->stats_.handle);
 			(ifd->restart)(ifd->ifq_);
 		}
+	        mtx_lock(&ifd->lock);
+	        if (cl == ifd->active_[cl->pri_])
+	            ;
+	        else {
+	            if (cl->prev_peer_ != NULL )
+		        cl->prev_peer_->peer_ = cl->peer_;
+	                if (cl->peer_ != NULL)
+		            cl->peer_->prev_peer_ = cl->prev_peer_;
+	                    cl->peer_ = ifd->active_[cl->pri_]->peer_;
+	                    ifd->active_[cl->pri_]->peer_ = cl;
+	                    cl->prev_peer_ = ifd->active_[cl->pri_];
+	                    if (cl->peer_) {
+		                cl->peer_->prev_peer_ = cl;
+	                    }
+	        }
+	        mtx_unlock(&ifd->lock);
 	}
 	IFQ_UNLOCK(ifd->ifq_);
 	splx(s);
@@ -1746,6 +1880,7 @@
 static void
 rmc_root_overlimit(struct rm_class *cl, struct rm_class *borrow)
 {
+    fastlog_syslog(LOG_DEBUG, "rmc_root_overlimit:PANIC\n");
     panic("rmc_root_overlimit");
 }
 
Index: /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/altq_subr.c
===================================================================
--- /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/altq_subr.c	(revision 38975)
+++ /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/altq_subr.c	(working copy)
@@ -54,6 +54,7 @@
 #include <sys/sysctl.h>
 #include <sys/queue.h>
 #include <sys/pcpu.h>
+#include <click/app/fastlog/fastlog.h>
 
 #include <net/if.h>
 #include <net/if_dl.h>
@@ -280,8 +281,10 @@
 			tbr->tbr_last = now;
 		}
 		/* if token is still negative, don't allow dequeue */
-		if (tbr->tbr_token <= 0)
+		if (tbr->tbr_token <= 0) {
+			fastlog_syslog(LOG_DEBUG, "token is still negative, don't allow dequeue\n");
 			return (NULL);
+                }
 	}
 
 	if (ALTQ_IS_ENABLED(ifq))
Index: /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/qos_classifier.h
===================================================================
--- /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/qos_classifier.h	(revision 38975)
+++ /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/qos_classifier.h	(working copy)
@@ -31,9 +31,16 @@
 #define QOS_FLTR_NLEN 32
 
 /*
- * maximum filter number
+ * maximum filter number. It is recommended not to create QoS filters when 'QoS Session' feature is enabled.
  */
-#define QOS_MAX_FLTR_NUM 1024
+
+
+#ifndef MAX_DYN_QUEUE
+#define MAX_DYN_QUEUE 1000000
+#endif
+
+#define QOS_MAX_FLTR_NUM (MAX_DYN_QUEUE + 1024)
+
 
 /*
  * static filter and dynamic filter
@@ -176,6 +183,12 @@
 	uint32_t count_add_dyn_table_fail;
 	uint32_t count_del_table_fail;
 	uint32_t count_del_dyn_table_fail;
+	uint32_t q_overload_count[8];
+	uint32_t q_enqueue_fail[8];
+	uint32_t q_full_count[8];
+	uint32_t cur_pend_mbuf[8];
+	uint32_t total_active_class[8];
+	uint32_t total_outstanding_mbuf;
 }qos_filter_tatol_stats_t;
 
 typedef struct __qos_filter_share {
@@ -201,7 +214,7 @@
  * VARIABLE DEFINITIONS
  *************************************************************************/
 extern qos_filter_share_t qos_filter_share;
-
+extern unsigned int current_dyn_q_count;
 /*************************************************************************
  * FUNCTION PROTOTYPES
  *************************************************************************/
@@ -215,6 +228,7 @@
 int qos_dyn_del(clickrule_5tuple_t *tp, struct qos_queue_info *qqi);
 int qos_filter_dyn_clear_interface(struct qos_queue_info *qqi);
 int qos_filter_clear_all(void *pcb);
+int qos_filter_clear_all_dyn(void *pcb);
 int qos_filter_clear_interface(void *pcb, struct ifnet *ifp, uint8_t dir);
 
 #define qos_printf(fmt, arg...)
Index: /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/qos_classifier.c
===================================================================
--- /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/qos_classifier.c	(revision 38975)
+++ /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/qos_classifier.c	(working copy)
@@ -54,8 +54,17 @@
 #include <click/app/qos/qos_classifier.h>
 
 #include <click/app/fastlog/fastlog.h>
+#include <click/app/qos/qos_dynamic.h>
 
+#ifndef MAX_DYN_QUEUE
+#define MAX_DYN_QUEUE 1000000
+#endif
+
+extern uint32_t max_dyn_queue;
+
+uint16_t ports_record[65536];
 
+static void delete_dyn_queues (void);
 static int qos_filter_add_table(qos_filter_share_t *qs, qos_filter_t *pfltr);
 static int qos_filter_del_table(qos_filter_share_t *qs, qos_filter_t *pfltr);
 static int qos_filter_rebuild(struct ifnet *ifp, int dir);
@@ -64,6 +73,13 @@
 static int qos_filter_iftable_init(qos_filter_ifnode_t *ifn_p);
 static void qos_get_class(clickrule_gnode_t *gnode_p, struct qos_pktattr *pktattr, int flag);
 
+unsigned int current_dyn_q_count = 0;
+unsigned int enq_idx = 0;
+unsigned int deq_idx = 0;
+
+int qos_session_cleanup = 0;
+int n_filters = 0;
+
 
 #define QOS_CLASSFIER_DEBUG_FOR_STATIC_POLICY 0
 
@@ -115,12 +131,18 @@
 static uint8_t  dyni_order[] = {0,5,6,7,8,1,2,3,4,11,12,9,10};
 static uint8_t  dyno_order[] = {0,5,6,7,8,1,2,3,4,9,10,11,12};
 
+static uint8_t  i_net_order[] = {1,12,13,14,15,4,5,6,7,8,9,10,11};
+static uint8_t  o_net_order[] = {1,14,15,12,13,4,5,6,7,8,9,10,11};
 /*
  * Storing up all qos filter information.
  */
 qos_filter_share_t qos_filter_share;
 extern uint32_t **clickrule_notfound;
-
+extern int qos_session_status;
+extern uint32_t repeat_segment_num;
+extern uint32_t q_del_step_size;
+extern struct mtx qos_session_lock;
+extern struct mtx qos_filter_lock;
 /******************************************************************************
  * Return the current valid class poniter.
  *
@@ -187,6 +209,89 @@
 }
 
 
+void create_queue_filter(uint32_t sip, uint16_t sport, uint32_t dip, uint16_t dport,char *sDir, qos_queue_root_t *pQoSQRoot, struct altq_conf *pALTConf)
+{
+    char q_name[32] = "";
+    char f_name[32] = "";
+    char ip_str[20];
+    uint32_t smask = -1;
+    uint32_t dmask = -1;
+    int count = 0;
+    int q_create_fail, f_create_fail;
+
+    mtx_lock (&qos_session_lock);
+    if (qos_session_cleanup) {
+        mtx_unlock (&qos_session_lock);
+        return;
+    }
+
+/* On reaching MAX session queues, we flush the filters and start to delete the queues. Till we delete all queues, we will not be creating any new filter and queue for the sessions and all packets will use 'default' queue */
+    if (current_dyn_q_count >= max_dyn_queue) {
+	fastlog_syslog(LOG_DEBUG, "QoS sessions reached maximum limit : %u. Recycling old sessions\n", max_dyn_queue);
+        if (qos_session_cleanup == 0) {
+            mtx_lock (&qos_filter_lock);
+            qos_session_cleanup = 1;
+#ifdef QOS_FLUSH
+            qos_filter_clear_all_dyn (NULL);
+#endif
+            n_filters = 0;
+            mtx_unlock (&qos_filter_lock);
+        }
+        mtx_unlock (&qos_session_lock);
+        return;
+    }
+    mtx_unlock (&qos_session_lock);
+
+    if (sip) {
+        sprintf (ip_str, "%u", sip);
+    } else {
+        sprintf (ip_str, "%u", dip);
+    }
+
+    sprintf (q_name, "%s%s%u%u%c", DYNAMIC_QUEUE_PREFIX, ip_str, sport, dport, sDir[0]);
+    sprintf (f_name, "%s%s%u%u%c", DYNAMIC_FILTER_PREFIX, ip_str, sport, dport, sDir[0]);
+
+    strncpy(pQoSQRoot->sQName, q_name, 32);
+    strncpy(pALTConf->qname, q_name, 32);
+
+    q_create_fail = qos_queue_root_kern (NULL, pQoSQRoot, sizeof(qos_queue_root_t), pALTConf, sizeof(struct altq_conf));
+
+    if (q_create_fail) {
+	fastlog_syslog(LOG_DEBUG, "Queue creation failed : %s\n", q_name);
+        return;
+    }
+
+    if (!sip) {
+        smask = 0;
+    }
+    if (!dip) {
+        dmask = 0;
+    }
+    f_create_fail = qos_filter_kern(NULL, f_name, q_name, sip, smask, sport, dip, dmask, dport, "any", 1);
+    if (f_create_fail) {
+        no_qos_queue_root_sess_kern (q_name);
+	fastlog_syslog(LOG_DEBUG, "filter creation failed : %s\n", f_name);
+        return;
+    }
+    ++current_dyn_q_count;
+
+}
+
+
+static void delete_dyn_queues () {
+    int count;
+    unsigned int actual_q_count;
+
+    count = q_del_step_size;
+
+    while(count) {
+        if (no_qos_queue_root_sess_kern (NULL) == QOS_DYN_Q_DELETE_COMPLETE)
+            break;
+        --count;
+    }
+}
+
+
 /******************************************************************************
  *  Get a proper class for the outbound or inbound packets
  *
@@ -211,6 +316,21 @@
 	struct ip *ip;
 	struct mbuf *m;
 
+	uint32_t src_ip_qos = 0;
+	uint16_t src_port_qos = 0;
+	uint32_t dst_ip_qos = 0;
+	uint16_t dst_port_qos = 0;
+
+	dyn_qos_session_lookup_t *temp = NULL;
+	int i, j;
+	char *sDir;
+	int src_ip_index;
+	int dst_ip_index;
+
+	qos_queue_root_t local_qos_q_conf;
+	struct altq_conf local_altq_conf;
+
+
 	m = *mp;
 	if(NULL == ifp || NULL == m || NULL == pktattr) {
 		englog(ENGLOG_QOS, QOS_ENGLOG_ERR, "qos_etherclassify: ifp, m or pktattr is NULL.\n");
@@ -296,20 +416,41 @@
 		pktattr->pattr_class = NULL;
 		return;
 	}
-   
+
+	rtuple = (uint8_t *)a5tuple_p;
+
 	ifn_p = (qos_filter_ifnode_t *)
 		clickrule4_lookup(&qos_filter_share.iftable, (uint32_t)(uintptr_t)ifp);
 	/*
 	 * (NULL == ifn_p) means that the interface is not init(no filters).
 	 */
+
 	if (NULL == ifn_p) {
-		pktattr->pattr_class = NULL;
-		qos_filter_share.fltr_g_stats.hits_interface_fail++;
-		/*englog(ENGLOG_QOS, QOS_ENGLOG_DEBUG, "qos_etherclassify: No filters in the interface.\n");*/
-		return;
+            if (qos_session_status == SESSION_ENABLE)
+		goto label;
+            pktattr->pattr_class = NULL;
+            qos_filter_share.fltr_g_stats.hits_interface_fail++;
+            return;
 	}
+#if 0
+	if(QOSD_INPUT == direction) {
+		table = &(ifn_p->if_i_table);
+		rorder = (uint8_t *) table->rule_order;
+	    fastlog_syslog(LOG_DEBUG, "QOS input dirn.. protocol : %d...src port : %d %d\n", rtuple[rorder[0]], rtuple[rorder[1]],rtuple[rorder[2]]);
+	    fastlog_syslog(LOG_DEBUG, "QOS input dirn.. dst port : %d %d\n", rtuple[rorder[3]],rtuple[rorder[4]]);
+	    fastlog_syslog(LOG_DEBUG, "QOS inut src ip : %d %d %d %d\n", rtuple[rorder[5]], rtuple[rorder[6]],rtuple[rorder[7]],rtuple[rorder[8]]);
+	    fastlog_syslog(LOG_DEBUG, "QOS inut dst ip :  %d %d %d %d\n", rtuple[rorder[9]], rtuple[rorder[10]], rtuple[rorder[11]],rtuple[rorder[12]]);
+    }
+	if(QOSD_OUTPUT == direction) {
+		table = &(ifn_p->if_o_table);
+		rorder = (uint8_t *) table->rule_order;
+	    fastlog_syslog(LOG_DEBUG, "QOS out dirn.. protocol : %d...src port : %d %d\n", rtuple[rorder[0]], rtuple[rorder[1]],rtuple[rorder[2]]);
+	    fastlog_syslog(LOG_DEBUG, "QOS out dirn.. dst port : %d %d\n", rtuple[rorder[3]],rtuple[rorder[4]]);
+	    fastlog_syslog(LOG_DEBUG, "QOS out src ip : %d %d %d %d\n", rtuple[rorder[5]], rtuple[rorder[6]],rtuple[rorder[7]],rtuple[rorder[8]]);
+	    fastlog_syslog(LOG_DEBUG, "QOS out dst ip :  %d %d %d %d\n", rtuple[rorder[9]], rtuple[rorder[10]], rtuple[rorder[11]],rtuple[rorder[12]]);
+    }
+#endif
 
-	rtuple = (uint8_t *)a5tuple_p;
 	if(QOSD_OUTPUT == direction) {
 		table = &(ifn_p->if_dyno_table);
 		rorder = (uint8_t *) table->rule_order;
@@ -415,6 +556,85 @@
 		}
 	}
 
+
+label:
+        if (qos_session_status == SESSION_ENABLE) {
+            if (qos_session_cleanup) {
+#ifdef QOS_FLUSH
+                delete_dyn_queues();
+#else
+    ;
+#endif
+
+            }
+            else {
+	        if (QOSD_OUTPUT == direction) {
+		    rorder = (uint8_t *) o_net_order;
+                    sDir = "OUT";
+                    *((uint8_t *)&src_port_qos + 0) = rtuple[rorder[4]];
+                    *((uint8_t *)&src_port_qos + 1) = rtuple[rorder[3]];
+
+                    *((uint8_t *)&dst_port_qos + 0) = rtuple[rorder[2]];
+                    *((uint8_t *)&dst_port_qos + 1) = rtuple[rorder[1]];
+                } else {
+		    rorder = (uint8_t *) i_net_order;
+                    sDir = "IN";
+                    *((uint8_t *)&src_port_qos + 0) = rtuple[rorder[2]];
+                    *((uint8_t *)&src_port_qos + 1) = rtuple[rorder[1]];
+
+                    *((uint8_t *)&dst_port_qos + 0) = rtuple[rorder[4]];
+                    *((uint8_t *)&dst_port_qos + 1) = rtuple[rorder[3]];
+                }
+
+                src_ip_index = 5;
+                dst_ip_index = 9;
+
+
+                for (i = 0; i < 4; i++) {
+                    *((uint8_t *)&src_ip_qos + i) = rtuple[rorder[i+src_ip_index]];
+                }
+                for (i = 0; i < 4; i++) {
+                    *((uint8_t *)&dst_ip_qos + i) = rtuple[rorder[i+dst_ip_index]];
+                }
+
+#if 0
+	fastlog_syslog(LOG_DEBUG, "TO CHECK ..src ip : %u, src_port : %u, dst_ip : %u, dst_port : %u, dir : %d\n",src_ip_qos, src_port_qos, dst_ip_qos, dst_port_qos, direction);
+#endif
+
+                temp = qos_session_lookup(src_ip_qos, src_port_qos, dst_ip_qos, dst_port_qos, direction);
+
+                if (temp && !strcmp(temp->qos_session_altq_conf_save->ifname, ifp->if_xname) 
+                    && !strcmp(temp->qos_session_q_save->sDir, sDir))    {
+
+                    ++ports_record[src_port_qos];
+
+                    if (ports_record[src_port_qos] >= repeat_segment_num){
+                        ports_record[src_port_qos] = 0;
+
+                        if (!temp->is_sip_match) {
+                            src_ip_qos = 0;
+                        }
+                        if (!src_ip_qos && !temp->is_sport_match) {
+                            src_port_qos = 0;
+                        }
+                        if (!temp->is_dip_match) {
+                            dst_ip_qos = 0;
+                        }
+                        if (!dst_ip_qos && !temp->is_dport_match) {
+                            dst_port_qos = 0;
+                        }
+
+                        bzero (&local_qos_q_conf, sizeof (qos_queue_root_t));
+                        bzero (&local_altq_conf, sizeof (struct altq_conf));
+
+                        memmove (&local_qos_q_conf, temp->qos_session_q_save, sizeof (qos_queue_root_t));
+                        memmove (&local_altq_conf, temp->qos_session_altq_conf_save, sizeof (struct altq_conf));
+                        create_queue_filter(src_ip_qos, src_port_qos, dst_ip_qos, dst_port_qos, sDir, &local_qos_q_conf, &local_altq_conf);
+                    }
+                }
+            }
+        }
+
 	pktattr->pattr_class = NULL;
 	qos_filter_share.fltr_g_stats.hits_filter_fail++;
 	qos_printf("qos_etherclassify: Not found the class.\n");
@@ -699,6 +919,40 @@
 	return QOS_SUCCESS;
 }
 
+/******************************************************************************
+ *  Clear all qos filters. This function is optimized for QoS session cleanup
+ *
+ *  return: QOS_SUCCESS, success; QOS_FAILURE,failure.
+ ******************************************************************************/
+int qos_filter_clear_all_dyn(void *pcb)
+{
+	qos_filter_share_t *qs;
+	qos_filter_ifnode_t *ifn_p;
+	qos_filter_t *pfltr;
+	int i;
+	int s = 0;
+
+	qs = &qos_filter_share;
+
+	for(i=0; i < QOS_MAX_INTERFACE; i++) {
+		ifn_p = &(qs->ifnodes[i]);
+
+		if(!ifn_p->initiation) {
+			continue;
+		}
+
+		/* Security */
+		s = splimp();
+		clickrule_clear(&ifn_p->if_o_table);
+		clickrule_clear(&ifn_p->if_i_table);
+		splx(s);
+	}
+
+        qos_filter_init();
+
+	return QOS_SUCCESS;
+}
+
 
 /******************************************************************************
  *  Init classifier.
@@ -801,6 +1055,7 @@
 
 	if('\0' == qos_filter->qqi_name[0]) {
 		app_printf(pcb, "ERROR: queue name is NULL\n");
+		fastlog_syslog (LOG_DEBUG, "ERROR: queue name is NULL\n");
 		return QOS_FAILURE;
 	}
 
@@ -810,25 +1065,35 @@
 	ret = qos_queue_get(&qos_filter->qosq_info);
 	if(QOS_FAILURE == ret) {
 		app_printf(pcb, "ERROR: Can not get the information of queue \"%s\".\n", qos_filter->qqi_name);
+		fastlog_syslog(LOG_DEBUG, "ERROR: Can not get the information of queue \"%s\".\n", qos_filter->qqi_name);
 		return QOS_FAILURE;
 	}
 
 	if(qos_filter->priority <= QOS_FLTR_PRI_MIN || qos_filter->priority >= QOS_FLTR_PRI_MAX) {
 		app_printf(pcb, "ERROR: priority out of range (%d ~ %d)\n", QOS_FLTR_PRI_MIN+1, QOS_FLTR_PRI_MAX-1);
+		fastlog_syslog (LOG_DEBUG, "ERROR: priority out of range (%d ~ %d)\n", QOS_FLTR_PRI_MIN+1, QOS_FLTR_PRI_MAX-1);
 		goto ADD_FLTR_ERROR;
 	}
 
 	if(qos_filter->qqi_nic >= QOS_MAX_INTERFACE) {
 		app_printf(pcb, "ERROR: interace id is wrong\n");
+		fastlog_syslog (LOG_DEBUG, "ERROR: interace id is wrong\n");
 		goto ADD_FLTR_ERROR;
 	}
 
+	mtx_lock (&qos_filter_lock);
+	if (qos_session_cleanup) {
+	    mtx_unlock (&qos_filter_lock);
+	    goto ADD_FLTR_ERROR;
+	}
+
 	qs = &qos_filter_share;
 
 	/*
 	 * Check existing filters.
 	 */
-	for(i=0; i < QOS_MAX_FLTR_NUM; i++) {
+        if (qos_session_status != SESSION_ENABLE) {
+	    for(i=0; i < QOS_MAX_FLTR_NUM; i++) {
 		pfltr = &qs->a_fltrs[i];
 
 		if(!pfltr->used) {
@@ -837,6 +1102,8 @@
 
 		if(!strcmp(qos_filter->fltr_name, pfltr->fltr_name)) {
 			app_printf(pcb, "ERROR: the QoS L4 filter name has aready existed\n");
+			fastlog_syslog (LOG_DEBUG,  "ERROR: the QoS L4 filter name - %s has aready existed\n", pfltr->fltr_name);
+			mtx_unlock (&qos_filter_lock);
 			goto ADD_FLTR_ERROR;
 		}
 
@@ -844,14 +1111,17 @@
 					sizeof(struct qos_queue_info)) &&
 				!bcmp(&qos_filter->tp, &pfltr->tp, sizeof(clickrule_5tuple_t))){
 			app_printf(pcb, "ERROR: found a duplicate QoS L4 filter name: \"%s\"\n", pfltr->fltr_name);
+			fastlog_syslog (LOG_DEBUG, "ERROR: found a duplicate QoS L4 filter name: \"%s\"\n", pfltr->fltr_name);
+			mtx_unlock (&qos_filter_lock);
 			goto ADD_FLTR_ERROR;
 		}
-	}
+	    }
+        }
 
-	/*
-	 * Find an empty one.
-	 */
-	for(i=0; i < QOS_MAX_FLTR_NUM; i++) {
+        /*
+        * Find an empty one.
+	*/
+	for(i = n_filters; i < QOS_MAX_FLTR_NUM; i++) {
 		pfltr = &qs->a_fltrs[i];
 
 		if(!pfltr->used) {
@@ -859,28 +1129,36 @@
 		}
 	}
 	if (i == QOS_MAX_FLTR_NUM) {
-		app_printf(pcb, "ERROR: maximum number of QoS L4 filters reached (maximum 1024)\n");
+		app_printf(pcb, "ERROR: maximum number of QoS L4 filters reached. maximum %u\n", QOS_MAX_FLTR_NUM);
+		fastlog_syslog (LOG_DEBUG, "ERROR: maximum number of QoS L4 filters reached maximum %u\n", QOS_MAX_FLTR_NUM);
+		mtx_unlock (&qos_filter_lock);
 		goto ADD_FLTR_ERROR;
 	}
 
 	/*
-	 * Add the qos filter to qos filter array.
-	 */
+	* Add the qos filter to qos filter array.
+	*/
 	bcopy(qos_filter, pfltr, sizeof(qos_filter_t));
 
+
 	ret = qos_filter_add_table(qs, pfltr);
 	if(QOS_FAILURE == ret) {
-		bzero(pfltr, sizeof(qos_filter_t));
-		qos_filter_share.fltr_g_stats.count_add_table_fail++;
-		goto ADD_FLTR_ERROR;
+	    bzero(pfltr, sizeof(qos_filter_t));
+	    qos_filter_share.fltr_g_stats.count_add_table_fail++;
+	    mtx_unlock (&qos_filter_lock);
+	    fastlog_syslog(LOG_DEBUG, "ERROR: failed to add the filter to the table\n");
+	    goto ADD_FLTR_ERROR;
 	}
-
 	pfltr->used = 1;
+	++n_filters;
+	mtx_unlock (&qos_filter_lock);
 
 	return QOS_SUCCESS;
 
 ADD_FLTR_ERROR:
-	qos_queue_free(&qos_filter->qosq_info);
+	if (qos_session_status != SESSION_ENABLE) {
+	    qos_queue_free(&qos_filter->qosq_info);
+	}
 	return QOS_FAILURE;
 }
 
@@ -969,10 +1247,12 @@
 
 		if(ifn_p->initiation) {
 			englog(ENGLOG_QOS, QOS_ENGLOG_ERR, "qos_filter_add_table: Clickule talbes have been initial.\n");
+		        fastlog_syslog(LOG_DEBUG, "filter add table : have init\n");
 			return QOS_FAILURE;
 		}
 
 		if(QOS_FAILURE == qos_filter_iftable_init(ifn_p)) {
+		        fastlog_syslog(LOG_DEBUG, "filter add table : cound not not init\n");
 			return QOS_FAILURE;
 		}
 
@@ -984,6 +1264,7 @@
 
 		if(CRULE_OK != ret) {
 			englog(ENGLOG_QOS, QOS_ENGLOG_ERR, "qos_filter_add_table: Fail to add ifnode to clickrule4.\n");
+		        fastlog_syslog(LOG_DEBUG, "filter add table : fail to add ifnode\n");
 			return QOS_FAILURE;
 		}
 
@@ -1011,6 +1292,7 @@
 
 	if(CRULE_OK != ret) {
 		englog(ENGLOG_QOS, QOS_ENGLOG_ERR, "qos_filter_add_table: Fail to add data to clickrule static talbe.\n");
+		fastlog_syslog(LOG_DEBUG, "filter add fail: Fail to add data to clickrule static ta\n");
 		return QOS_FAILURE;
 	}
 
@@ -1142,12 +1424,14 @@
 
 	if(strlen(fltr_name) == 0) {
 		app_printf(pcb, "ERROR: The input name is illegal, it can not be an empty string\n");
-		return QOS_SUCCESS;
+		fastlog_syslog(LOG_DEBUG, "ERROR: The input name is illegal, it can not be an empty string : %s\n", fltr_name);
+		return QOS_FAILURE;
 	}
 
 	if(strlen(fltr_name) >= QOS_FLTR_NLEN) {
 		app_printf(pcb, "ERROR: The input name is too long, maximum is %d\n", QOS_FLTR_NLEN-1);
-		return QOS_SUCCESS;
+		fastlog_syslog(LOG_DEBUG, "ERROR: The input name - %s is too long, maximum is %d\n", fltr_name, QOS_FLTR_NLEN-1);
+		return QOS_FAILURE;
 	}
 
 	if((fltr_name[0] == 'a' || fltr_name[0] == 'A') &&
@@ -1155,7 +1439,8 @@
 			(fltr_name[2] == 'l' || fltr_name[2] == 'L') &&
 			strlen(fltr_name) == 3) {
 		app_printf(pcb, "ERROR: \"%s\" is reserved for system\n", fltr_name);
-		return QOS_SUCCESS;
+		fastlog_syslog (LOG_DEBUG, "ERROR: \"%s\" is reserved for system\n", fltr_name);
+		return QOS_FAILURE;
 	}
 
 	snprintf(fltr.fltr_name, QOS_FLTR_NLEN, "%s", fltr_name);
@@ -1163,18 +1448,22 @@
 
 	if (!clickrule_mask(smask) ) {
 		app_printf(pcb, "ERROR: invalid source mask\n");
-		return QOS_SUCCESS;
+		fastlog_syslog(LOG_DEBUG, "ERROR: invalid source mask\n");
+		return QOS_FAILURE;
 	} else if(!clickrule_mask(dmask)) {
 		app_printf(pcb, "ERROR: invalid destination mask\n");
-		return QOS_SUCCESS;
+		fastlog_syslog(LOG_DEBUG, "ERROR: invalid destination mask\n");
+		return QOS_FAILURE;
 	}
 
 	if ((sip & smask) != sip) {
 		app_printf(pcb, "ERROR: invalid source ip and mask pair\n");
-		return QOS_SUCCESS;
+		fastlog_syslog(LOG_DEBUG, "ERROR: invalid source ip and mask pair\n");
+		return QOS_FAILURE;
 	} else if ((dip & dmask) != dip) {
 		app_printf(pcb, "ERROR: invalid destination ip and mask pair\n");
-		return QOS_SUCCESS;
+		fastlog_syslog(LOG_DEBUG, "ERROR: invalid destination ip and mask pair\n");
+		return QOS_FAILURE;
 	}
 
 	if ((strcmp(proto_str, PROTO_TCP_STR) == 0)) {
@@ -1186,7 +1475,8 @@
 	} else {
 		app_printf(pcb, "ERROR: invalid protocol string, please use %s, %s or %s\n",
 				PROTO_TCP_STR, PROTO_UDP_STR, PROTO_ANY_STR);
-		return QOS_SUCCESS;
+		fastlog_syslog(LOG_DEBUG, "ERROR: invalid protocol string, please use %s, %s or %s\n", PROTO_TCP_STR, PROTO_UDP_STR, PROTO_ANY_STR);
+		return QOS_FAILURE;
 	}
 
 	fltr.tp.proto = proto;
@@ -1206,7 +1496,9 @@
 	fltr.priority = pri;
 
 	if(QOS_FAILURE == qos_filter_add(pcb, &fltr)) {
-		/*app_printf(pcb, "Fail to add filter\n");*/
+		app_printf(pcb, "Failed to add the filter.\n");
+		fastlog_syslog(LOG_DEBUG, "Failed to add the filter : %s\n", fltr_name);
+		return QOS_FAILURE;
 	}
 
 	return QOS_SUCCESS;
@@ -1288,6 +1580,9 @@
 			}
 		}
 
+		if (!strncmp(pfltr->fltr_name, DYNAMIC_FILTER_PREFIX, strlen(DYNAMIC_FILTER_PREFIX))) {
+			continue;
+		}
 		isfound = 1;
 
 		smask.s_addr = pfltr->tp.smask;
@@ -1322,6 +1617,71 @@
 	}
 
 	return QOS_SUCCESS;
+}
+
+int show_current_queue_count_for_sessions(void *pcb)
+{
+	app_printf(pcb, "Session Queues count : %u\n\n", current_dyn_q_count);
+	return QOS_SUCCESS;
+}
+
+int show_session_qos_filter_kern(void *pcb)
+{
+	qos_filter_share_t *qs;
+	qos_filter_t *pfltr;
+	int i;
+	int isfound;
+	struct in_addr smask, dmask;
+	char sip_str[16], smsk_str[16],dip_str[16], dmsk_str[16], pro_str[16];
+
+	QOS_CHECK_LICENSE;
+
+	qs = &qos_filter_share;
+
+	isfound = 0;
+	for(i=0; i < QOS_MAX_FLTR_NUM; i++) {
+		pfltr = &qs->a_fltrs[i];
+
+		/*
+		 * Find a valid item.
+		 */
+		if(!pfltr->used) {
+			continue;
+		}
+
+		if (strncmp(pfltr->fltr_name, DYNAMIC_FILTER_PREFIX, strlen(DYNAMIC_FILTER_PREFIX))) {
+			continue;
+		}
+		isfound = 1;
+
+		smask.s_addr = pfltr->tp.smask;
+		dmask.s_addr = pfltr->tp.dmask;
+		snprintf(sip_str, 16, "%s", inet_ntoa(pfltr->tp.sip));
+		snprintf(smsk_str, 16, "%s", inet_ntoa(smask));
+		snprintf(dip_str, 16, "%s", inet_ntoa(pfltr->tp.dip));
+		snprintf(dmsk_str, 16, "%s", inet_ntoa(dmask));
+
+		if(IPPROTO_TCP == pfltr->tp.proto) {
+			snprintf(pro_str, 16, "%s", PROTO_TCP_STR);
+		}
+		else if(IPPROTO_UDP == pfltr->tp.proto) {
+			snprintf(pro_str, 16, "%s", PROTO_UDP_STR);
+		}
+		else if(IPPROTO_IP == pfltr->tp.proto) {
+			snprintf(pro_str, 16, "%s", PROTO_ANY_STR);
+		}
+		else {
+			snprintf(pro_str, 16, "%s", "ERROR");
+		}
+
+		app_printf(pcb, "qos filter \"%s\" \"%s\" %s %s %d %s %s %d %s %d\n",
+				pfltr->fltr_name, pfltr->qqi_name,
+				sip_str, smsk_str, ntohs(pfltr->tp.sport),
+				dip_str, dmsk_str, ntohs(pfltr->tp.dport),
+				pro_str, pfltr->priority);
+	}
+
+	return QOS_SUCCESS;
 }
 
 
Index: /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/qos_dynamic.h
===================================================================
--- /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/qos_dynamic.h	(revision 0)
+++ /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/qos_dynamic.h	(working copy)
@@ -0,0 +1,80 @@
+#include <click/app/qos/qos_scheduler.h>
+
+#define QOS_SNAME_MAX  32
+#define PORT_NAME_MAX  32
+#define MAX_QOS_SESSION_CONFIG 1024
+#define N_CHILDREN 256
+#define SESSION_ENABLE  1
+#define SESSION_DISABLE 0
+#define DYNAMIC_QUEUE_PREFIX  "qd_"
+#define DYNAMIC_FILTER_PREFIX "fd_"
+
+typedef struct dyn_session_qos_conf {
+    char name[QOS_SNAME_MAX];
+    char port[PORT_NAME_MAX];
+    uint32_t sip;
+    uint16_t sport;
+    uint32_t dip;
+    uint16_t dport; 
+    char band[QOS_BANDWIDTH_MAXLEN];
+    char dir[QOSD_STR_MAXLEN];
+    STAILQ_ENTRY(dyn_session_qos_conf) list_entry;
+} dyn_session_qos_conf_t;
+
+STAILQ_HEAD(dyn_session_qos_conf_head, dyn_session_qos_conf);
+
+extern struct dyn_session_qos_conf_head dyn_session_qos_conf_head;
+extern int qos_session_status;
+extern uint32_t repeat_segment_num;
+extern uint32_t q_del_step_size;
+extern struct mtx qos_session_lock;
+extern struct mtx qos_filter_lock;
+
+extern uint32_t max_dyn_queue;
+extern uint32_t total_outstanding_mbuf;
+
+//CBQ
+extern int class_insert_pos;
+extern int loop_class_count;
+extern int q_len_wait;
+
+typedef struct dyn_qos_session_lookup {
+    struct dyn_qos_session_lookup *dyn_qos_session_lookup_node[N_CHILDREN];
+    qos_queue_root_t *qos_session_q_save;
+    struct altq_conf *qos_session_altq_conf_save;
+    int direction;
+    int is_sip_match;
+    int is_dip_match;
+    int is_sport_match;
+    int is_dport_match;
+    int is_leaf;
+} dyn_qos_session_lookup_t;
+
+
+dyn_qos_session_lookup_t *createNode(void);
+int qos_session_config_kern(void *pcb, char *name, void *pRoot, int32_t nRoot, void *pALTQ, int32_t nALTQ, uint32_t sip, uint16_t sport, uint32_t dip, uint16_t dport);
+static int save_dyn_qos_session_config (void *pcb, char *name, char *port, uint32_t sip, uint16_t sport, uint32_t dip, uint16_t dport, char *band, char *dir);
+static int is_duplicate_session_name (char *name);
+void *qos_session_lookup(uint32_t sip, uint16_t sport, uint32_t dip, uint16_t dport, uint8_t direction);
+void display_qos_session_config(void *pcb, dyn_session_qos_conf_t *node, uint64_t prefix);
+int show_qos_session_config(void *pcb, char *name);
+int delete_qos_session_config(void *pcb, char *name);
+int del_dyn_qos_session_config (void *pcb, char *name);
+void remove_tuple_from_lookup (unsigned char tuple[]);
+void free_qos_session_lookup(dyn_qos_session_lookup_t *root);
+static int qos_session_config_count(void);
+int enable_session (void *pcb);
+int disable_session (void *pcb);
+int set_tuple_count (void *pcb, uint32_t count);
+int get_tuple_count (void *pcb);
+int set_q_del_step_size (void *pcb, uint32_t count);
+int get_q_del_step_size (void *pcb);
+int qos_session_init (void);
+int set_qos_max_session_count (void *pcb, uint32_t count);
+int get_qos_max_session_count (void *pcb);
+int set_loop_class_count (void *pcb, uint32_t count);
+int get_loop_class_count (void *pcb);
+int set_class_insert_pos (void *pcb, uint32_t count);
+int get_class_insert_pos (void *pcb);
+int set_q_len_wait (void *pcb, uint32_t count);
+int get_q_len_wait (void *pcb);
Index: /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/qos_dynamic.c
===================================================================
--- /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/qos_dynamic.c	(revision 0)
+++ /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/qos_dynamic.c	(working copy)
@@ -0,0 +1,494 @@
+#include <sys/types.h>
+#include <sys/ctype.h>
+#include <sys/param.h>
+#include <sys/lock.h>
+#include <sys/systm.h>
+#include <sys/sysctl.h>
+#include <sys/socket.h>
+#include <sys/mbuf.h>
+#include <sys/syslog.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/pcpu.h>
+#include <net/if.h>
+#include <net/if_var.h>
+#include <net/netisr.h>
+#include <net/ethernet.h>
+#include <net/route.h>
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/in_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcpip.h>
+#include <machine/in_cksum.h>
+#include <click/app/qos/qos_dynamic.h>
+
+#define TUPLE_LEN 12 /* src ip + src port + dest ip + dst port */
+
+#ifndef MAX_DYN_QUEUE
+#define MAX_DYN_QUEUE 1000000
+#endif
+
+struct mtx qos_session_lock;
+struct mtx qos_filter_lock;
+
+int qos_session_status = SESSION_DISABLE;
+
+
+uint32_t repeat_segment_num = 50;
+uint32_t q_del_step_size = 1;
+uint32_t max_dyn_queue = 800000;
+uint32_t total_outstanding_mbuf = 0;
+
+int class_insert_pos = 8;
+int loop_class_count = 48;
+int q_len_wait = 1027; /* default value is set above 1024 which is the max queue length. We can tune this to smaller value for better performance */
+
+struct dyn_session_qos_conf_head dyn_session_qos_conf_head = STAILQ_HEAD_INITIALIZER(dyn_session_qos_conf_head);
+
+dyn_qos_session_lookup_t *dyn_qos_session_lookup_root = NULL;
+
+
+dyn_qos_session_lookup_t *createNode(void) {
+    int i;
+    dyn_qos_session_lookup_t *node = (dyn_qos_session_lookup_t *) malloc(sizeof(dyn_qos_session_lookup_t), M_QOS, M_NOWAIT | M_ZERO);
+    if (node) {
+        node->is_leaf = 0;
+        for (i = 0; i < N_CHILDREN; ++i) {
+            node->dyn_qos_session_lookup_node[i] = NULL;
+        }
+    }
+    node->qos_session_q_save = NULL;
+    node->qos_session_altq_conf_save = NULL;
+
+    return node;
+}
+
+
+int qos_session_config_kern(void *pcb, char *name, void *pRoot, int32_t nRoot, void *pALTQ, int32_t nALTQ, uint32_t sip, uint16_t sport, uint32_t dip, uint16_t dport) {
+
+    qos_queue_root_t *pQoSQRoot = NULL;
+    struct altq_conf *pALTQConf = NULL;
+
+    int s = 0;
+    int i, j, save_fail;
+    uint8_t direction = 0;
+    int octet;
+    unsigned char tuple[TUPLE_LEN];
+
+    QOS_CHECK_LICENSE;
+
+    if ((pRoot == NULL) || (sizeof(qos_queue_root_t) != nRoot) ||
+            (pALTQ == NULL) || (sizeof(struct altq_conf) != nALTQ)) {
+        return(QOS_USERLAND_FAILURE);
+    }
+    if (!sip && !dip) {
+        app_printf(pcb, "ERROR : wildcard entries for both source IP and destination IP are not allowed.\n");
+        return(QOS_USERLAND_FAILURE);
+    }
+    pQoSQRoot = (qos_queue_root_t *)pRoot;
+    pALTQConf = (struct altq_conf *)pALTQ;
+
+    save_fail = save_dyn_qos_session_config (pcb, name, pQoSQRoot->sIfName, sip, sport, dip, dport, pQoSQRoot->sBand, pQoSQRoot->sDir);
+    if (save_fail) {
+        return (QOS_USERLAND_FAILURE);
+    }
+    direction = pALTQConf -> direction;
+
+    if (dyn_qos_session_lookup_root == NULL)
+        dyn_qos_session_lookup_root = createNode();
+
+    dyn_qos_session_lookup_t *current = dyn_qos_session_lookup_root;
+
+    for (i = 3; i >= 0; --i) {
+        int octet = (sip >> (i * 8)) & 0xFF;
+
+        if (!current->dyn_qos_session_lookup_node[octet]) {
+            current->dyn_qos_session_lookup_node[octet] = createNode();
+        }
+        current = current->dyn_qos_session_lookup_node[octet];
+    }
+    for (i = 1; i >= 0; --i) {
+        int octet = (sport >> (i * 8)) & 0xFF;
+
+        if (!current->dyn_qos_session_lookup_node[octet]) {
+            current->dyn_qos_session_lookup_node[octet] = createNode();
+        }
+        current = current->dyn_qos_session_lookup_node[octet];
+    }
+    for (i = 3; i >= 0; --i) {
+        int octet = (dip >> (i * 8)) & 0xFF;
+
+        if (!current->dyn_qos_session_lookup_node[octet]) {
+            current->dyn_qos_session_lookup_node[octet] = createNode();
+        }
+        current = current->dyn_qos_session_lookup_node[octet];
+    }
+    for (i = 1; i >= 0; --i) {
+        int octet = (dport >> (i * 8)) & 0xFF;
+
+        if (!current->dyn_qos_session_lookup_node[octet]) {
+            current->dyn_qos_session_lookup_node[octet] = createNode();
+        }
+        current = current->dyn_qos_session_lookup_node[octet];
+    }
+
+    current->direction = direction;
+    current->is_leaf = 1;
+
+    current->qos_session_q_save = (qos_queue_root_t *) malloc(sizeof(qos_queue_root_t), M_QOS, M_NOWAIT | M_ZERO);
+    memmove(current->qos_session_q_save, pQoSQRoot, sizeof(qos_queue_root_t));
+
+    current->qos_session_altq_conf_save = (struct altq_conf *) malloc(sizeof(struct altq_conf), M_QOS, M_NOWAIT | M_ZERO);
+    memmove(current->qos_session_altq_conf_save, pALTQConf, sizeof(struct altq_conf));
+
+    return (QOS_SUCCESS);
+}
+
+
+static int is_duplicate_session_name (char *name) {
+    dyn_session_qos_conf_t *dyn_session_conf_run = NULL;
+
+    STAILQ_FOREACH(dyn_session_conf_run, &dyn_session_qos_conf_head, list_entry) {
+        /* check session qos name */
+        if(!strcmp(name, dyn_session_conf_run->name)) {
+            return 1;
+        }
+    }
+    return 0;
+}
+
+
+static int save_dyn_qos_session_config (void *pcb, char *name, char *port, uint32_t sip, uint16_t sport, uint32_t dip, uint16_t dport, char *band, char *dir) {
+
+    int session_confg_count = 0;
+    dyn_session_qos_conf_t *dyn_session_qos_data = NULL;
+
+    if (is_duplicate_session_name (name)) {
+        app_printf(pcb, "QoS Session configuration with this name already exists.\n");
+        return 1;
+    }
+
+    session_confg_count = qos_session_config_count();
+    if (session_confg_count >= MAX_QOS_SESSION_CONFIG) {
+        app_printf(pcb, "Too many QoS session groups configured (maximum %d)\n", MAX_QOS_SESSION_CONFIG);
+        return 1;
+    }
+    dyn_session_qos_data = (dyn_session_qos_conf_t *)malloc(sizeof(dyn_session_qos_conf_t), M_QOS, M_NOWAIT | M_ZERO);
+    if (!dyn_session_qos_data) {
+        app_printf(pcb, "Failed to allocate memory for QoS Session configuration\n");
+        return 1;
+    }
+
+    strcpy (dyn_session_qos_data->name, name);
+    strcpy (dyn_session_qos_data->port, port);
+    strcpy (dyn_session_qos_data->band, band);
+    strcpy (dyn_session_qos_data->dir, dir);
+
+    dyn_session_qos_data->sip = sip;
+    dyn_session_qos_data->sport = sport;
+    dyn_session_qos_data->dip = dip;
+    dyn_session_qos_data->dport = dport;
+
+
+    STAILQ_INSERT_TAIL(&dyn_session_qos_conf_head, dyn_session_qos_data, list_entry);
+    return 0;
+}
+
+
+int show_qos_session_config(void *pcb, char *name) {
+
+    if (qos_session_status == SESSION_ENABLE)
+        app_printf(pcb, "qos session on\n");
+    else
+        app_printf(pcb, "qos session off\n");
+
+    dyn_session_qos_conf_t *dyn_qos_conf_run = NULL;
+
+    STAILQ_FOREACH(dyn_qos_conf_run, &dyn_session_qos_conf_head, list_entry) {
+        if(strcmp(name, dyn_qos_conf_run->name) && strcmp(name, "ALL") && strcmp(name, "all")) {
+            continue;
+        }
+
+        app_printf(pcb,  "qos session \"%s\" %s %u.%u.%u.%u %u %u.%u.%u.%u %u %s %s\n",
+            dyn_qos_conf_run->name, dyn_qos_conf_run->port,
+            (dyn_qos_conf_run->sip) & 0xFF,
+            (dyn_qos_conf_run->sip >> 8) & 0xFF,
+            (dyn_qos_conf_run->sip >> 16) & 0xFF,
+            (dyn_qos_conf_run->sip >> 24) & 0xFF,
+            dyn_qos_conf_run->sport,
+            (dyn_qos_conf_run->dip) & 0xFF,
+            (dyn_qos_conf_run->dip >> 8) & 0xFF,
+            (dyn_qos_conf_run->dip >> 16) & 0xFF,
+            (dyn_qos_conf_run->dip >> 24) & 0xFF,
+            dyn_qos_conf_run->dport,
+            dyn_qos_conf_run->band, dyn_qos_conf_run->dir);
+    }
+    return QOS_SUCCESS;
+}
+
+
+void *qos_session_lookup(uint32_t sip, uint16_t sport, uint32_t dip, uint16_t dport, uint8_t direction) {
+    int i;
+    int octet;
+    int wild_card;
+    int is_sip_match = 0;
+    int is_dip_match = 0;
+    int is_sport_match = 0;
+    int is_dport_match = 0;
+
+    dyn_qos_session_lookup_t* current = dyn_qos_session_lookup_root;
+    if (current == NULL)
+        return current;
+
+    wild_card = 0;
+    for (i = 3; i >= 0; --i) {
+        int octet = (sip >> (i * 8)) & 0xFF;
+
+        if (!wild_card && (current->dyn_qos_session_lookup_node[octet])) {
+            current = current->dyn_qos_session_lookup_node[octet];
+        }
+        else if (current->dyn_qos_session_lookup_node[0]) {
+            wild_card = 1;
+            current = current->dyn_qos_session_lookup_node[0];
+        }
+        else {
+            return NULL;
+        }
+    }
+    if (!wild_card)
+        is_sip_match = 1;
+
+    wild_card = 0;
+    for (i = 1; i >= 0; --i) {
+        int octet = (sport >> (i * 8)) & 0xFF;
+
+        if (!wild_card && (current->dyn_qos_session_lookup_node[octet])) {
+            current = current->dyn_qos_session_lookup_node[octet];
+        }
+        else if (current->dyn_qos_session_lookup_node[0]) {
+            wild_card = 1;
+            current = current->dyn_qos_session_lookup_node[0];
+        }
+        else {
+            return NULL;
+        }
+    }
+    if (!wild_card)
+        is_sport_match = 1;
+
+    wild_card = 0;
+    for (i = 3; i >= 0; --i) {
+        int octet = (dip >> (i * 8)) & 0xFF;
+
+        if (!wild_card && (current->dyn_qos_session_lookup_node[octet])) {
+            current = current->dyn_qos_session_lookup_node[octet];
+        }
+        else if (current->dyn_qos_session_lookup_node[0]) {
+            wild_card = 1;
+            current = current->dyn_qos_session_lookup_node[0];
+        }
+        else {
+            return NULL;
+        }
+    }
+    if (!wild_card)
+        is_dip_match = 1;
+
+    wild_card = 0;
+    for (i = 1; i >= 0; --i) {
+        int octet = (dport >> (i * 8)) & 0xFF;
+
+        if (!wild_card && (current->dyn_qos_session_lookup_node[octet])) {
+            current = current->dyn_qos_session_lookup_node[octet];
+        }
+        else if (current->dyn_qos_session_lookup_node[0]) {
+            wild_card = 1;
+            current = current->dyn_qos_session_lookup_node[0];
+        }
+        else {
+            return NULL;
+        }
+    }
+    if (!wild_card)
+        is_dport_match = 1;
+
+    if ((current->direction == direction) && current->is_leaf) {
+        current->is_sip_match = is_sip_match;
+        current->is_dip_match = is_dip_match;
+        current->is_sport_match = is_sport_match;
+        current->is_dport_match = is_dport_match;
+        return current;
+    }
+    return NULL;
+}
+
+
+void remove_tuple_from_lookup( unsigned char tuple[]) {
+    int i;
+
+    dyn_qos_session_lookup_t *current = dyn_qos_session_lookup_root;
+    if (current == NULL) {
+        return;
+    }
+    for (i = 0; i < TUPLE_LEN; i++) {
+        if (current && !current->dyn_qos_session_lookup_node[tuple[i]]) {
+            return;
+        }
+        current = current->dyn_qos_session_lookup_node[tuple[i]];
+    }
+    current->is_leaf = 0;
+}
+
+
+static int qos_session_config_count(void)
+{
+    dyn_session_qos_conf_t *current = NULL;
+    int count = 0;
+
+    STAILQ_FOREACH(current, &dyn_session_qos_conf_head, list_entry) {
+        count++;
+    }
+    return(count);
+}
+
+
+void free_qos_session_lookup(dyn_qos_session_lookup_t *root) {
+    int i;
+    if (root) {
+        for (i = 0; i < N_CHILDREN; ++i) {
+            free_qos_session_lookup (root->dyn_qos_session_lookup_node[i]);
+        }
+        if (root->is_leaf) {
+            free(root->qos_session_q_save, M_QOS);
+            free(root->qos_session_altq_conf_save, M_QOS);
+        }
+        free(root, M_QOS);
+    }
+}
+
+
+int del_dyn_qos_session_config (void *pcb, char *name) {
+    int i, j;
+    int found = 0;
+
+    dyn_session_qos_conf_t *dyn_ses_conf_node = NULL;
+
+
+    STAILQ_FOREACH(dyn_ses_conf_node, &dyn_session_qos_conf_head, list_entry) {
+        found = 1;
+        STAILQ_REMOVE(&dyn_session_qos_conf_head, dyn_ses_conf_node, dyn_session_qos_conf, list_entry);
+        free(dyn_ses_conf_node, M_QOS);
+    }
+
+    if (found) {
+        free_qos_session_lookup (dyn_qos_session_lookup_root);
+        dyn_qos_session_lookup_root = NULL;
+    }
+
+    return QOS_SUCCESS;
+}
+
+
+int delete_qos_session_config(void *pcb, char *name) {
+    fastlog_syslog(LOG_DEBUG, "Attempt to delete QoS Session configurations.\n");
+
+    if (strcmp(name, "all") && strcmp(name, "ALL")) {
+        app_printf(pcb, "ERROR : type 'ALL' to delete all QoS Session configurations\n");
+        return (QOS_USERLAND_FAILURE);
+    }
+    del_dyn_qos_session_config (pcb, name);
+    return QOS_SUCCESS;
+}
+
+int enable_session (void *pcb) {
+    qos_session_status = SESSION_ENABLE;
+    fastlog_syslog(LOG_DEBUG, "Enabled QoS Session.\n");
+    return QOS_SUCCESS;
+}
+
+int disable_session (void *pcb) {
+    qos_session_status = SESSION_DISABLE;
+    fastlog_syslog(LOG_DEBUG, "Disabled QoS Session.\n");
+    return QOS_SUCCESS;
+}
+
+int set_tuple_count (void *pcb, uint32_t count) {
+    if (count < 1 || count > 1024) {
+        app_printf(pcb, "ERROR : count should be between 1 to 1024.\n");
+        return (QOS_USERLAND_FAILURE);
+    }
+    repeat_segment_num = count;
+    return QOS_SUCCESS;
+}
+int get_tuple_count (void *pcb) {
+    app_printf(pcb, "count : %u\n", repeat_segment_num);
+    return QOS_SUCCESS;
+}
+
+int set_q_del_step_size (void *pcb, uint32_t count) {
+    if (count < 1 || count > 1024) {
+        app_printf(pcb, "ERROR : count should be between 1 to 1024.\n");
+        return (QOS_USERLAND_FAILURE);
+    }
+    q_del_step_size = count;
+    return QOS_SUCCESS;
+}
+
+int get_q_del_step_size (void *pcb) {
+    app_printf(pcb, "count : %u\n", q_del_step_size);
+    return QOS_SUCCESS;
+}
+
+int qos_session_init (void) {
+    mtx_init(&qos_session_lock, "qos session lock", NULL, MTX_DEF | MTX_NOWITNESS);
+    mtx_init(&qos_filter_lock, "qos filter lock", NULL, MTX_DEF | MTX_NOWITNESS);
+    return QOS_SUCCESS;
+}
+
+int set_qos_max_session_count (void *pcb, uint32_t count) {
+    if (count > MAX_DYN_QUEUE) {
+        app_printf(pcb, "ERROR : count can not be set more then %d\n", MAX_DYN_QUEUE);
+        return (QOS_USERLAND_FAILURE);
+    }
+    max_dyn_queue = count;
+    return QOS_SUCCESS;
+}
+
+int get_qos_max_session_count (void *pcb) {
+    app_printf(pcb, "count : %u\n", max_dyn_queue);
+    return QOS_SUCCESS;
+}
+
+int set_loop_class_count (void *pcb, uint32_t count) {
+    loop_class_count = count;
+    return QOS_SUCCESS;
+}
+
+int get_loop_class_count (void *pcb) {
+    app_printf(pcb, "loop_class_count : %u\n", loop_class_count);
+    return QOS_SUCCESS;
+}
+
+int set_class_insert_pos (void *pcb, uint32_t count) {
+    class_insert_pos = count;
+    return QOS_SUCCESS;
+}
+
+int get_class_insert_pos (void *pcb) {
+    app_printf(pcb, "class_insert_pos : %u\n", class_insert_pos);
+    return QOS_SUCCESS;
+}
+
+int set_q_len_wait (void *pcb, uint32_t count) {
+    q_len_wait = count;
+    return QOS_SUCCESS;
+}
+
+int get_q_len_wait (void *pcb) {
+    app_printf(pcb, "q_len_wait : %u\n", q_len_wait);
+    return QOS_SUCCESS;
+}
Index: /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/qos_getstat.c
===================================================================
--- /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/qos_getstat.c	(revision 38975)
+++ /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/qos_getstat.c	(working copy)
@@ -72,43 +72,44 @@
 	int ret;
 	struct rm_class *cl;
 
+	if (!current_dyn_q_count) {
+	    if (*status == NULL) {
+		    MALLOC(*status, void* , sizeof(ustat_network_qos_QosRootQueue_t), ustat_status_type, M_NOWAIT);
+		    ((ustat_network_qos_QosRootQueue_t*)(*status))->pQosIfConf = STAILQ_FIRST(&qos_interface_conf_head);
+		    ((ustat_network_qos_QosRootQueue_t*)(*status))->pQosQRoot = STAILQ_FIRST(&qos_queue_root_head);
+	    } else {
+		    ((ustat_network_qos_QosRootQueue_t*)(*status))->pQosQRoot = STAILQ_NEXT(((ustat_network_qos_QosRootQueue_t*)(*status))->pQosQRoot, list_entry);
+	    }
 
-	if (*status == NULL) {
-		MALLOC(*status, void* , sizeof(ustat_network_qos_QosRootQueue_t), ustat_status_type, M_NOWAIT);	
-		((ustat_network_qos_QosRootQueue_t*)(*status))->pQosIfConf = STAILQ_FIRST(&qos_interface_conf_head);
-		((ustat_network_qos_QosRootQueue_t*)(*status))->pQosQRoot = STAILQ_FIRST(&qos_queue_root_head);
-	} else {
-		((ustat_network_qos_QosRootQueue_t*)(*status))->pQosQRoot = STAILQ_NEXT(((ustat_network_qos_QosRootQueue_t*)(*status))->pQosQRoot, list_entry);
-	}
-
-	for(; ((ustat_network_qos_QosRootQueue_t*)(*status))->pQosIfConf; ((ustat_network_qos_QosRootQueue_t*)(*status))->pQosIfConf = STAILQ_NEXT(((ustat_network_qos_QosRootQueue_t*)(*status))->pQosIfConf, list_entry)) {
-
-		for(; ((ustat_network_qos_QosRootQueue_t*)(*status))->pQosQRoot; ((ustat_network_qos_QosRootQueue_t*)(*status))->pQosQRoot = STAILQ_NEXT(((ustat_network_qos_QosRootQueue_t*)(*status))->pQosQRoot, list_entry)) {
-
-			if(((ustat_network_qos_QosRootQueue_t*)(*status))->pQosIfConf->iDir != ((ustat_network_qos_QosRootQueue_t*)(*status))->pQosQRoot->iDir) {
-				continue;
-			}
+	    for(; ((ustat_network_qos_QosRootQueue_t*)(*status))->pQosIfConf; ((ustat_network_qos_QosRootQueue_t*)(*status))->pQosIfConf = STAILQ_NEXT(((ustat_network_qos_QosRootQueue_t*)(*status))->pQosIfConf, list_entry)) {
 
-			if(strcmp(((ustat_network_qos_QosRootQueue_t*)(*status))->pQosIfConf->sHwIf, ((ustat_network_qos_QosRootQueue_t*)(*status))->pQosQRoot->sHwIf)) {
-				continue;
-			}
+		    for(; ((ustat_network_qos_QosRootQueue_t*)(*status))->pQosQRoot; ((ustat_network_qos_QosRootQueue_t*)(*status))->pQosQRoot = STAILQ_NEXT(((ustat_network_qos_QosRootQueue_t*)(*status))->pQosQRoot, list_entry)) {
 
-			snprintf(qosq_info.name, QOS_QNAME_SIZE, "%s", ((ustat_network_qos_QosRootQueue_t*)(*status))->pQosQRoot->sQName);
-			ret = qos_queue_get(&qosq_info);
-			if(QOS_FAILURE == ret) {
-				continue;
-			}
+			    if(((ustat_network_qos_QosRootQueue_t*)(*status))->pQosIfConf->iDir != ((ustat_network_qos_QosRootQueue_t*)(*status))->pQosQRoot->iDir) {
+					continue;
+			    }
 
-			qos_queue_free(&qosq_info);
+			    if(strcmp(((ustat_network_qos_QosRootQueue_t*)(*status))->pQosIfConf->sHwIf, ((ustat_network_qos_QosRootQueue_t*)(*status))->pQosQRoot->sHwIf)) {
+				    continue;
+			    }
+
+			    snprintf(qosq_info.name, QOS_QNAME_SIZE, "%s", ((ustat_network_qos_QosRootQueue_t*)(*status))->pQosQRoot->sQName);
+			    ret = qos_queue_get(&qosq_info);
+			    if(QOS_FAILURE == ret) {
+				    continue;
+			    }
+
+			    qos_queue_free(&qosq_info);
+
+			    cl = (struct rm_class *)qosq_info.qp;
+			    ((ustat_network_qos_QosRootQueue_t*)(*status))->cl = cl;
+			    return;
+		    }
+	    }
 
-			cl = (struct rm_class *)qosq_info.qp;
-			((ustat_network_qos_QosRootQueue_t*)(*status))->cl = cl;
-			return;
-		}
+	    free(*status, ustat_status_type);
+	    *status = NULL;
 	}
-
-	free(*status, ustat_status_type);
-	*status = NULL;
 }
 
 void ustat_data_assign_network_qos_QosRootQueue(void **status, void *data)
@@ -154,49 +155,51 @@
 	int ret;
 	struct rm_class *cl;
 
-	if (*status == NULL) {
-		MALLOC(*status, void* , sizeof(ustat_network_qos_QosSubQueue_t), ustat_status_type, M_NOWAIT);	
-		((ustat_network_qos_QosSubQueue_t*)(*status))->pQosIfConf = STAILQ_FIRST(&qos_interface_conf_head);
-		((ustat_network_qos_QosSubQueue_t*)(*status))->pQosQRoot = STAILQ_FIRST(&qos_queue_root_head);
-	} else {
-		((ustat_network_qos_QosSubQueue_t*)(*status))->pQosQRoot = STAILQ_NEXT(((ustat_network_qos_QosSubQueue_t*)(*status))->pQosQRoot, list_entry);
-	}
+	if (!current_dyn_q_count) {
+	    if (*status == NULL) {
+		    MALLOC(*status, void* , sizeof(ustat_network_qos_QosSubQueue_t), ustat_status_type, M_NOWAIT);
+		    ((ustat_network_qos_QosSubQueue_t*)(*status))->pQosIfConf = STAILQ_FIRST(&qos_interface_conf_head);
+		    ((ustat_network_qos_QosSubQueue_t*)(*status))->pQosQRoot = STAILQ_FIRST(&qos_queue_root_head);
+	    } else {
+		    ((ustat_network_qos_QosSubQueue_t*)(*status))->pQosQRoot = STAILQ_NEXT(((ustat_network_qos_QosSubQueue_t*)(*status))->pQosQRoot, list_entry);
+	    }
 
-	for(; ((ustat_network_qos_QosSubQueue_t*)(*status))->pQosIfConf; ((ustat_network_qos_QosSubQueue_t*)(*status))->pQosIfConf = STAILQ_NEXT(((ustat_network_qos_QosSubQueue_t*)(*status))->pQosIfConf, list_entry)) {
+	    for(; ((ustat_network_qos_QosSubQueue_t*)(*status))->pQosIfConf; ((ustat_network_qos_QosSubQueue_t*)(*status))->pQosIfConf = STAILQ_NEXT(((ustat_network_qos_QosSubQueue_t*)(*status))->pQosIfConf, list_entry)) {
 
-		for(; ((ustat_network_qos_QosSubQueue_t*)(*status))->pQosQRoot; ((ustat_network_qos_QosSubQueue_t*)(*status))->pQosQRoot = STAILQ_NEXT(((ustat_network_qos_QosSubQueue_t*)(*status))->pQosQRoot, list_entry)) {
+		    for(; ((ustat_network_qos_QosSubQueue_t*)(*status))->pQosQRoot; ((ustat_network_qos_QosSubQueue_t*)(*status))->pQosQRoot = STAILQ_NEXT(((ustat_network_qos_QosSubQueue_t*)(*status))->pQosQRoot, list_entry)) {
 
 			if(((ustat_network_qos_QosSubQueue_t*)(*status))->pQosIfConf->iDir != ((ustat_network_qos_QosSubQueue_t*)(*status))->pQosQRoot->iDir) {
-				continue;
-			}	
+				    continue;
+			    }
 
-			if(strcmp(((ustat_network_qos_QosSubQueue_t*)(*status))->pQosIfConf->sHwIf, ((ustat_network_qos_QosSubQueue_t*)(*status))->pQosQRoot->sHwIf)) {
-				continue;
-			}
-
-			STAILQ_FOREACH(((ustat_network_qos_QosSubQueue_t*)(*status))->pQosQSub, &qos_queue_sub_head, list_entry) {
-				if(strcmp(((ustat_network_qos_QosSubQueue_t*)(*status))->pQosQRoot->sQName, ((ustat_network_qos_QosSubQueue_t*)(*status))->pQosQSub->sQRoot)) {
-					continue;
-				}
-
-			snprintf(qosq_info.name, QOS_QNAME_SIZE, "%s", ((ustat_network_qos_QosSubQueue_t*)(*status))->pQosQSub->sQName);
-			ret = qos_queue_get(&qosq_info);
-			if(QOS_FAILURE == ret) {
-				continue;
-			}
-
-			qos_queue_free(&qosq_info);
-
-			cl = (struct rm_class *)qosq_info.qp;
-			((ustat_network_qos_QosSubQueue_t*)(*status))->cl = cl;
-			return;
-			}	
-
-		}
-	}
-
-	free(*status, ustat_status_type);
-	*status = NULL;
+			    if(strcmp(((ustat_network_qos_QosSubQueue_t*)(*status))->pQosIfConf->sHwIf, ((ustat_network_qos_QosSubQueue_t*)(*status))->pQosQRoot->sHwIf)) {
+				    continue;
+			    }
+
+			    STAILQ_FOREACH(((ustat_network_qos_QosSubQueue_t*)(*status))->pQosQSub, &qos_queue_sub_head, list_entry) {
+				    if(strcmp(((ustat_network_qos_QosSubQueue_t*)(*status))->pQosQRoot->sQName, ((ustat_network_qos_QosSubQueue_t*)(*status))->pQosQSub->sQRoot)) {
+					    continue;
+				    }
+
+				    snprintf(qosq_info.name, QOS_QNAME_SIZE, "%s", ((ustat_network_qos_QosSubQueue_t*)(*status))->pQosQSub->sQName);
+				    ret = qos_queue_get(&qosq_info);
+				    if(QOS_FAILURE == ret) {
+					    continue;
+				    }
+
+				    qos_queue_free(&qosq_info);
+
+				    cl = (struct rm_class *)qosq_info.qp;
+				    ((ustat_network_qos_QosSubQueue_t*)(*status))->cl = cl;
+				    return;
+			    }
+
+		    }
+	    }
+
+	    free(*status, ustat_status_type);
+	    *status = NULL;
+        }
 }
 
 void ustat_data_assign_network_qos_QosSubQueue(void **status, void *data)
@@ -241,25 +244,26 @@
 {
 	qos_filter_share_t *qs;
 
-	if (*status == NULL) {
-		MALLOC(*status, void* , sizeof(ustat_network_qos_QosFilter_t), ustat_status_type, M_NOWAIT);
-		((ustat_network_qos_QosFilter_t*)(*status))->pQosIfConf = STAILQ_FIRST(&qos_interface_conf_head);
-		((ustat_network_qos_QosFilter_t*)(*status))->pQosQRoot = STAILQ_FIRST(&qos_queue_root_head);
-		((ustat_network_qos_QosFilter_t*)(*status))->pQosQSub = STAILQ_FIRST(&qos_queue_sub_head); 
-		((ustat_network_qos_QosFilter_t*)(*status))->i = 0;
-		((ustat_network_qos_QosFilter_t*)(*status))->j = 0;
-	} else {
+	if (!current_dyn_q_count) {
+	    if (*status == NULL) {
+		    MALLOC(*status, void* , sizeof(ustat_network_qos_QosFilter_t), ustat_status_type, M_NOWAIT);
+		    ((ustat_network_qos_QosFilter_t*)(*status))->pQosIfConf = STAILQ_FIRST(&qos_interface_conf_head);
+		    ((ustat_network_qos_QosFilter_t*)(*status))->pQosQRoot = STAILQ_FIRST(&qos_queue_root_head);
+		    ((ustat_network_qos_QosFilter_t*)(*status))->pQosQSub = STAILQ_FIRST(&qos_queue_sub_head);
+		    ((ustat_network_qos_QosFilter_t*)(*status))->i = 0;
+		    ((ustat_network_qos_QosFilter_t*)(*status))->j = 0;
+	    } else {
 
-		if (((ustat_network_qos_QosFilter_t*)(*status))->i < QOS_MAX_FLTR_NUM) {
+		    if (((ustat_network_qos_QosFilter_t*)(*status))->i < QOS_MAX_FLTR_NUM) {
 			((ustat_network_qos_QosFilter_t*)(*status))->i++;
-		} else {
+		    } else {
 			((ustat_network_qos_QosFilter_t*)(*status))->j++;
-		}
-	}
+		    }
+	    }
 
-	qs = &qos_filter_share;
+	    qs = &qos_filter_share;
 
-	for( ; ((ustat_network_qos_QosFilter_t*)(*status))->pQosIfConf; ((ustat_network_qos_QosFilter_t*)(*status))->pQosIfConf = STAILQ_NEXT(((ustat_network_qos_QosFilter_t*)(*status))->pQosIfConf, list_entry)) {
+	    for( ; ((ustat_network_qos_QosFilter_t*)(*status))->pQosIfConf; ((ustat_network_qos_QosFilter_t*)(*status))->pQosIfConf = STAILQ_NEXT(((ustat_network_qos_QosFilter_t*)(*status))->pQosIfConf, list_entry)) {
 
 		for(; ((ustat_network_qos_QosFilter_t*)(*status))->pQosQRoot ;((ustat_network_qos_QosFilter_t*)(*status))->pQosQRoot = STAILQ_NEXT(((ustat_network_qos_QosFilter_t*)(*status))->pQosQRoot, list_entry)) {
 
@@ -295,10 +299,11 @@
 			}
 			((ustat_network_qos_QosFilter_t*)(*status))->i = 0;
 		}
-	}
+	    }
 
-	free(*status, ustat_status_type);
-	*status = NULL;
+	    free(*status, ustat_status_type);
+	    *status = NULL;
+        }
 }
 
 void ustat_data_assign_network_qos_QosFilter(void **status, void *data)
Index: /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/qos_scheduler.h
===================================================================
--- /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/qos_scheduler.h	(revision 38975)
+++ /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/qos_scheduler.h	(working copy)
@@ -19,6 +19,7 @@
 #define QOSD_OUTPUT_STR	"OUT"
 #define QOSD_INPUT_STR	"IN"
 #define QOSD_ANY_STR	"ANY"
+#define QOSD_BIDIRECTION_STR	"Both"
 #define QOSD_STR_MAXLEN	4
 
 #define QOSD_IO_DEFAULT	QOSD_OUTPUT_STR
@@ -41,8 +42,8 @@
 
 #define QOS_BORROW_DEFAULT	QOS_UNBORROW
 
-/* QoS queue size limit */
-#define QOS_DEFAULT_QLIMIT	1024
+
+#define QOS_DEFAULT_QLIMIT 1024
 
 /*************************************************************************
  * STRUCTURE DEFINITIONS
Index: /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/qos_scheduler.c
===================================================================
--- /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/qos_scheduler.c	(revision 38975)
+++ /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/qos_scheduler.c	(working copy)
@@ -54,12 +54,17 @@
 #include <click/app/qos/qos_var.h>
 #include <click/app/qos/qos_scheduler.h>
 #include <click/app/qos/qos_classifier.h>
+#include <click/app/qos/qos_dynamic.h>
 
 #include <click/app/qos/altq_var.h>
 #include <click/app/qos/altq_cbq.h>
 
 #include <click/app/qos/qos_http.h>
 
+extern int qos_session_status;
+extern int qos_session_cleanup;
+extern struct mtx qos_session_lock;
+extern unsigned int current_dyn_q_count;
 
 /* QoS qid generator */
 static uint32_t qos_index = 0;
@@ -78,7 +83,7 @@
 struct qos_queue_sub_head qos_queue_sub_head = STAILQ_HEAD_INITIALIZER(qos_queue_sub_head);
 
 /* Calculate queue number */
-static int qos_queue_count(void);
+int qos_queue_count(void);
 
 /*************************************************************************
  * QoS scheduler initialize routine.
@@ -118,6 +123,7 @@
 	/* Find in sub queue list */
 	for(;;){
 		STAILQ_FOREACH(pQoSQSub, &qos_queue_sub_head, list_entry) {
+	                fastlog_syslog(LOG_DEBUG, "qos_queue_get: qos sub\n");
 			if (strcmp(pParent, pQoSQSub->sQName) == 0) {
 				if (NULL == pQoSQSubFirst) {
 					pQoSQSubFirst = pQoSQSub;
@@ -167,11 +173,13 @@
 		return(QOS_FAILURE);
 	}
 
+	if (!qos_session_status) {
 	/* Referrence count */
-	if (NULL == pQoSQSubFirst) {
+	    if (NULL == pQoSQSubFirst) {
 		pQoSQRoot->ref_cnt++;
-	} else {
+	    } else {
 		pQoSQSubFirst->ref_cnt++;
+	    }
 	}
 
 	return(QOS_SUCCESS);
@@ -225,11 +233,13 @@
 	}
 
 	/* Referrence count */
-	if (NULL == pQoSQSubFirst) {
+	if (!qos_session_status) {
+	    if (NULL == pQoSQSubFirst) {
 		pQoSQRoot->ref_cnt--;
-	} else {
+	    } else {
 		pQoSQSubFirst->ref_cnt--;
-	}
+	    }
+        }
 
 	return(QOS_SUCCESS);
 }
@@ -241,26 +251,28 @@
  *
  * return: VOID.
  *************************************************************************/
+
 void qos_start(struct ifnet *ifp)
 {
-	struct mbuf *m_head;
+        struct mbuf *m_head;
 
-	while (!IFQ_IS_EMPTY(&ifp->if_rcv)) {
-		if (ifp->if_rcv.ifq_head != NULL) {
-			IF_DEQUEUE(&ifp->if_rcv, m_head);
-		} else {
-			IF_LOCK(&ifp->if_rcv);
-			m_head = tbr_dequeue_ptr(&ifp->if_rcv, ALTDQ_REMOVE);
-			IF_UNLOCK(&ifp->if_rcv);
-		}
-		if (m_head == NULL) { break; }
+        while (!IFQ_IS_EMPTY(&ifp->if_rcv)) {
+                if (ifp->if_rcv.ifq_head != NULL) {
+                        IF_DEQUEUE(&ifp->if_rcv, m_head);
+                } else {
+                        IF_LOCK(&ifp->if_rcv);
+                        m_head = tbr_dequeue_ptr(&ifp->if_rcv, ALTDQ_REMOVE);
+                        IF_UNLOCK(&ifp->if_rcv);
+                }
+                if (m_head == NULL) { break; }
 
-		(*ifp->if_input)(ifp, m_head);
-	}
+                (*ifp->if_input)(ifp, m_head);
+        }
 
-	return;
+        return;
 }
 
+
 /*************************************************************************
  * QoS CLI kernelapi implementation
  *************************************************************************/
@@ -645,7 +657,7 @@
 }
 
 /* Calculate queue number */
-static int qos_queue_count(void)
+int qos_queue_count(void)
 {
 	qos_queue_sub_t *pQoSQSub = NULL;
 	qos_queue_root_t *pQoSQRoot = NULL;
@@ -682,14 +694,18 @@
 	if ((pRoot == NULL) || (sizeof(qos_queue_root_t) != nRoot) ||
 			(pALTQ == NULL) || (sizeof(struct altq_conf) != nALTQ)) {
 		app_printf(pcb, "ERROR: kernel input parameters invalid\n");
+		fastlog_syslog(LOG_DEBUG, "ERROR: kernel input parameters invalid\n");
 		return(QOS_USERLAND_FAILURE);
 	}
 
 	/* Set the global maximun number */
-	if (qos_queue_count() >= QOS_MAXQ) {
-		app_printf(pcb, "ERROR: too many queues configured (maximum %d)\n", QOS_MAXQ);
-		return(QOS_USERLAND_FAILURE);
-	}
+        if (!qos_session_status) {
+            if (qos_queue_count() >= QOS_MAXQ) {
+	        app_printf(pcb, "ERROR: too many queues configured (maximum %d)\n", QOS_MAXQ);
+		fastlog_syslog(LOG_DEBUG, "ERROR: too many queues configured (maximum %d)\n", QOS_MAXQ);
+	        return(QOS_USERLAND_FAILURE);
+	    }
+        }
 
 	pQoSQRoot = (qos_queue_root_t *)pRoot;
 	pALTQConf = (struct altq_conf *)pALTQ;
@@ -709,12 +725,15 @@
 	ifp = ifunit(pALTQConf->ifname);
 	if (ifp == NULL) {
 		app_printf(pcb, "ERROR: can not find the QoS interface\n");
+		fastlog_syslog(LOG_DEBUG, "ERROR: can not find the QoS interface\n");
 		return(QOS_USERLAND_FAILURE);
 	}
 
 	if (pALTQConf->direction == QOSD_OUTPUT) {
 		if (!ALTQ_IS_ATTACHED(&ifp->if_snd)) {
 			app_printf(pcb, "ERROR: output QoS has not been configured on the interface\n");
+			fastlog_syslog(LOG_DEBUG, "ERROR: output QoS has not been configured on the interface\n");
+ 
 			return(QOS_USERLAND_FAILURE);
 		} else {
 			pALTQConf->altq_disc = ifp->if_snd.altq_disc;
@@ -724,26 +743,39 @@
 	if (pALTQConf->direction == QOSD_INPUT) {
 		if (!ALTQ_IS_ATTACHED(&ifp->if_rcv)) {
 			app_printf(pcb, "ERROR: input QoS has not been configured on the interface\n");
+			fastlog_syslog(LOG_DEBUG, "ERROR: input QoS has not been configured on the interface\n");
 			return(QOS_USERLAND_FAILURE);
 		} else {
 			pALTQConf->altq_disc = ifp->if_rcv.altq_disc;
 		}
 	}
 
+        mtx_lock (&qos_session_lock);
+	if (qos_session_cleanup) {
+	    mtx_unlock (&qos_session_lock);
+	    return(QOS_USERLAND_FAILURE);
+	}
+
 	/* Check duplicated queue name */
-	STAILQ_FOREACH(pQoSQRootSave, &qos_queue_root_head, list_entry) {
+        if (!qos_session_status) {
+	    STAILQ_FOREACH(pQoSQRootSave, &qos_queue_root_head, list_entry) {
 		if (strcmp(pQoSQRootSave->sQName, pQoSQRoot->sQName) == 0) {
 			app_printf(pcb, "ERROR: root queue %s has been configured\n",pQoSQRoot->sQName);
+			fastlog_syslog(LOG_DEBUG, "ERROR: root queue %s has been configured\n",pQoSQRoot->sQName);
+                        mtx_unlock (&qos_session_lock);
 			return(QOS_USERLAND_FAILURE);
 		}
-	}
+	    }
 
-	STAILQ_FOREACH(pQoSQSub, &qos_queue_sub_head, list_entry) {
+	    STAILQ_FOREACH(pQoSQSub, &qos_queue_sub_head, list_entry) {
 		if (strcmp(pQoSQSub->sQName, pQoSQRoot->sQName) == 0) {
 			app_printf(pcb, "ERROR: sub queue %s has been configured\n",pQoSQRoot->sQName);
+			fastlog_syslog(LOG_DEBUG, "ERROR: sub queue %s has been configured\n",pQoSQRoot->sQName);
+                        mtx_unlock (&qos_session_lock);
 			return(QOS_USERLAND_FAILURE);
 		}
-	}
+	    }
+        }
 
 	/* QoS queue ID */
 	STAILQ_FOREACH(pQoSIfConf, &qos_interface_conf_head, list_entry) {
@@ -752,8 +784,11 @@
 			break;
 		}
 	}
+
 	if (pQoSIfConf == NULL) {
 		app_printf(pcb, "ERROR: %s QoS has not configured on the interface\n", pQoSQRoot->sDir);
+		fastlog_syslog(LOG_DEBUG, "ERROR: %s QoS has not configured on the interface\n", pQoSQRoot->sDir);
+                mtx_unlock (&qos_session_lock);
 		return(QOS_USERLAND_FAILURE);
 	} else {
 		pALTQConf->parent_qid = pQoSIfConf->iQID;
@@ -761,24 +796,29 @@
 
 	pALTQConf->qid = ++qos_index;
 
+        mtx_unlock (&qos_session_lock);
+
+        if (!qos_session_status) {
 	/* Check bandwidth */
-	nBandCheck = pALTQConf->bandwidth;
-	STAILQ_FOREACH(pQoSQRootSave, &qos_queue_root_head, list_entry) {
+	    nBandCheck = pALTQConf->bandwidth;
+	    STAILQ_FOREACH(pQoSQRootSave, &qos_queue_root_head, list_entry) {
 		if ((strcmp(pQoSQRootSave->sHwIf, pQoSIfConf->sHwIf) == 0) &&
 				(pQoSQRootSave->iDir == pQoSIfConf->iDir)) {
 			nBandCheck += pQoSQRootSave->nBand;
 		}
-	}
-	if (nBandCheck > pQoSIfConf->nBand || nBandCheck < pALTQConf->bandwidth) {
+	    }
+	    if (nBandCheck > pQoSIfConf->nBand || nBandCheck < pALTQConf->bandwidth) {
 		app_printf(pcb, "ERROR: total bandwidth of %s root queues is greater than interface bandwidth\n", pQoSQRoot->sDir);
 		--qos_index;
 		return(QOS_USERLAND_FAILURE);
-	}
+	    }
+        }
 
 	/* Save user configuration */
 	pQoSQRootSave = malloc(sizeof(qos_queue_root_t), M_QOS, M_NOWAIT | M_ZERO);
 	if (pQoSQRootSave == NULL) {
 		app_printf(pcb, "ERROR: allocate memory failed\n");
+		fastlog_syslog(LOG_DEBUG, "ERROR: allocate memory failed\n");
 		--qos_index;
 		return(QOS_USERLAND_FAILURE);
 	}
@@ -788,11 +828,14 @@
 	s = splimp();
 
 	/* Add the class */
-	iErrCode = altq_add_queue(pALTQConf);
+        mtx_lock (&qos_session_lock);
+        iErrCode = altq_add_queue(pALTQConf);
+        mtx_unlock (&qos_session_lock);
+
 	if (iErrCode != 0) {
 		if (EMFILE == iErrCode) {
-			app_printf(pcb, "ERROR: too many queues configured on the direction of interface (maximum %d)\n",
-				CBQ_MAX_CLASSES - 1);
+			app_printf(pcb, "ERROR: too many queues configured on the direction of interface (maximum %d)\n", CBQ_MAX_CLASSES - 1);
+			fastlog_syslog(LOG_DEBUG, "ERROR: too many queues configured on the direction of interface (maximum %d)\n", CBQ_MAX_CLASSES - 1);
 			iErrCode = QOS_USERLAND_FAILURE;
 		}
 		goto ERROR0;
@@ -803,8 +846,10 @@
 	pQoSQRootSave->iDir = pALTQConf->direction;
 	pQoSQRootSave->nBand = pALTQConf->bandwidth;
 	pQoSQRootSave->iQID = pALTQConf->qid;
-	STAILQ_INSERT_TAIL(&qos_queue_root_head, pQoSQRootSave, list_entry);
 
+        mtx_lock (&qos_session_lock);
+        STAILQ_INSERT_HEAD(&qos_queue_root_head, pQoSQRootSave, list_entry);
+        mtx_unlock (&qos_session_lock);
 	splx(s);
 	return(QOS_SUCCESS);
 
@@ -815,6 +860,84 @@
 	return(iErrCode);
 }
 
+
+int no_qos_queue_root_sess_kern (char *sQueue)
+{
+	qos_queue_sub_t *pQoSQSub = NULL;
+	qos_queue_root_t *pQoSQRoot = NULL;
+	struct altq_conf confALTQ;
+	qos_queue_info_t infoQoSQueue;
+	int iErrCode = 0, iErrCode1 = 0;
+	int s = 0;
+
+
+	bzero(&confALTQ, sizeof(confALTQ));
+	bzero(&infoQoSQueue, sizeof(infoQoSQueue));
+
+	confALTQ.scheduler = ALTQT_CBQ;
+
+        mtx_lock (&qos_session_lock);
+
+        if (!qos_session_cleanup) {
+            mtx_unlock (&qos_session_lock);
+	    return(QOS_DYN_Q_DELETE_COMPLETE);
+        }
+	STAILQ_FOREACH(pQoSQRoot, &qos_queue_root_head, list_entry) {
+                if ((sQueue && strcmp(sQueue, pQoSQRoot->sQName) == 0) ||
+                        strncmp(DYNAMIC_QUEUE_PREFIX, pQoSQRoot->sQName, strlen(DYNAMIC_QUEUE_PREFIX)) == 0) {
+
+			confALTQ.qid = pQoSQRoot->iQID;
+			strcpy(confALTQ.ifname, pQoSQRoot->sHwIf);
+			confALTQ.direction = pQoSQRoot->iDir;
+			break;
+		}
+	}
+
+	if (pQoSQRoot == NULL) {
+		fastlog_syslog(LOG_DEBUG, "All QoS Sessions queues are flushed\n");
+                if (qos_session_cleanup) {
+                    qos_session_cleanup = 0;
+                    current_dyn_q_count = 0;
+                }
+                mtx_unlock (&qos_session_lock);
+		return(QOS_DYN_Q_DELETE_COMPLETE);
+	}
+
+	/* Get discipline */
+	confALTQ.altq_disc = altq_lookup(confALTQ.ifname, confALTQ.direction, ALTQT_CBQ);
+	if (confALTQ.altq_disc == NULL) {
+		fastlog_syslog(LOG_DEBUG, "ERROR: can not find the QoS interface\n");
+                mtx_unlock (&qos_session_lock);
+		return(QOS_USERLAND_FAILURE);
+	}
+
+	/* Prepare clearing dynamic filters */
+	infoQoSQueue.ifp = ifunit(confALTQ.ifname);
+	if (infoQoSQueue.ifp == NULL) {
+		fastlog_syslog(LOG_DEBUG, "ERROR: can not find the QoS interface\n");
+                mtx_unlock (&qos_session_lock);
+		return(QOS_USERLAND_FAILURE);
+	}
+	infoQoSQueue.direction = confALTQ.direction;
+
+	/* Free memory */
+	STAILQ_REMOVE(&qos_queue_root_head, pQoSQRoot, qos_queue_root, list_entry);
+	free(pQoSQRoot, M_QOS);
+        --current_dyn_q_count;
+
+	/* Security */
+	s = splimp();
+
+	/* Remove queue */
+	iErrCode1 = altq_remove_queue(&confALTQ);
+	if (!iErrCode) {iErrCode = iErrCode1;}
+
+	splx(s);
+	mtx_unlock (&qos_session_lock);
+	return(iErrCode);
+}
+
+
 /* CLI: no qos queue root ... */
 int no_qos_queue_root_kern(void *pcb, char *sQueue)
 {
@@ -849,10 +972,12 @@
 	/* Check reference count and Get necessary fields */
 	STAILQ_FOREACH(pQoSQRoot, &qos_queue_root_head, list_entry) {
 		if (strcmp(sQueue, pQoSQRoot->sQName) == 0) {
-			if (pQoSQRoot->ref_cnt > 0) {
+	                if (!qos_session_status) {
+			    if (pQoSQRoot->ref_cnt > 0) {
 				app_printf(pcb, "ERROR: please delete QoS filters on the queue firstly\n");
 				return(QOS_USERLAND_FAILURE);
-			}
+			    }
+                        }
 
 			confALTQ.qid = pQoSQRoot->iQID;
 			strcpy(confALTQ.ifname, pQoSQRoot->sHwIf);
@@ -1074,17 +1199,19 @@
 	/* QoS queue ID */
 	pALTQConf->qid = ++qos_index;
 
+	if (!qos_session_status) {
 	/* Check bandwidth */
-	nBandCheck = pALTQConf->bandwidth;
-	STAILQ_FOREACH(pQoSQSubSave, &qos_queue_sub_head, list_entry) {
+	    nBandCheck = pALTQConf->bandwidth;
+	    STAILQ_FOREACH(pQoSQSubSave, &qos_queue_sub_head, list_entry) {
 		if ((strcmp(pQoSQSubSave->sParent, pQoSQSub->sParent) == 0)) {
 			nBandCheck += pQoSQSubSave->nBand;
 		}
-	}
-	if (nBandCheck > nParentBand  || nBandCheck < pALTQConf->bandwidth) {
+	    }
+	    if (nBandCheck > nParentBand  || nBandCheck < pALTQConf->bandwidth) {
 		app_printf(pcb, "ERROR: total bandwidth of sub queues is greater than parent bandwidth\n");
 		--qos_index;
 		return(QOS_USERLAND_FAILURE);
+	    }
 	}
 
 	/* Save user configuration */
@@ -1169,13 +1296,14 @@
 			if (strcmp(pParent, pQoSQSub->sQName) == 0) {
 				if (NULL == pQoSQSubFirst) {
 					pQoSQSubFirst = pQoSQSub;
-
-					if (pQoSQSub->ref_cnt > 0) {
+	                                if (!qos_session_status) {
+					    if (pQoSQSub->ref_cnt > 0) {
 						app_printf(pcb, "ERROR: please delete QoS filters on the queue firstly\n");
 						return(QOS_USERLAND_FAILURE);
-					} else {
+					    } else {
 						confALTQ.qid = pQoSQSub->iQID;
-					}
+					    }
+                                        }
 				}
 
 				pParent = pQoSQSub->sParent;
@@ -1563,6 +1691,10 @@
 			}
 		}
 
+		if (!strncmp(pQoSQRoot->sQName, DYNAMIC_QUEUE_PREFIX, strlen(DYNAMIC_QUEUE_PREFIX))) {
+			continue;
+		}
+
 		isfound = 1;
 
 		app_printf(pcb, "qos queue root \"%s\" \"%s\" %s %s %d %s %s\n",
@@ -1579,6 +1711,30 @@
 }
 
 
+int show_session_qos_queue_root_kern(void *pcb)
+{
+	int i;
+	qos_queue_root_t *pQoSQRoot = NULL;
+
+	QOS_CHECK_LICENSE;
+
+	STAILQ_FOREACH(pQoSQRoot, &qos_queue_root_head, list_entry) {
+		/* check qos queue name */
+
+		if (strncmp(pQoSQRoot->sQName, DYNAMIC_QUEUE_PREFIX, strlen(DYNAMIC_QUEUE_PREFIX))) {
+			continue;
+		}
+
+		app_printf(pcb, "qos queue root \"%s\" \"%s\" %s %s %d %s %s\n",
+				pQoSQRoot->sQName, pQoSQRoot->sIfName, pQoSQRoot->sDir,
+				pQoSQRoot->sBand, pQoSQRoot->iPri, pQoSQRoot->sBorrow,
+				pQoSQRoot->sDefault);
+	}
+
+	return QOS_SUCCESS;
+}
+
+
 /******************************************************************************
  *  CLI interfaces of qos queue sub
  *  Show.
@@ -1653,6 +1809,10 @@
 	/* show_qos_queue_sub_kern(pcb, QOS_NAME_FOR_ALL); */
 
 	STAILQ_FOREACH(pQoSQRoot, &qos_queue_root_head, list_entry) {
+		if (!strncmp(pQoSQRoot->sQName, DYNAMIC_QUEUE_PREFIX, strlen(DYNAMIC_QUEUE_PREFIX))) {
+			continue;
+		}
+
 		app_printf(pcb, "qos queue root \"%s\" \"%s\" %s %s %d %s %s\n",
 				pQoSQRoot->sQName, pQoSQRoot->sIfName, pQoSQRoot->sDir,
 				pQoSQRoot->sBand, pQoSQRoot->iPri, pQoSQRoot->sBorrow,
@@ -1663,7 +1823,6 @@
 			if(strcmp(pQoSQRoot->sQName, pQoSQSub->sQRoot)) {
 				continue;
 			}
-
 			app_printf(pcb, "    %s \"%s\" \"%s\" %s %d %s %s\n", "qos queue sub",
 					pQoSQSub->sQName, pQoSQSub->sParent,pQoSQSub->sBand,
 					pQoSQSub->iPri, pQoSQSub->sBorrow, pQoSQSub->sDefault);
Index: /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/qos_subr.c
===================================================================
--- /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/qos_subr.c	(revision 38975)
+++ /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/qos_subr.c	(working copy)
@@ -52,6 +52,7 @@
 #include <click/app/qos/qos_var.h>
 #include <click/app/qos/qos_scheduler.h>
 #include <click/app/qos/qos_classifier.h>
+#include <click/app/qos/qos_dynamic.h>
 #include <click/app/qos/altq_classq.h>
 #include <click/app/qos/altq_rmclass.h>
 #include <click/app/qos/altq_cbq.h>
@@ -67,6 +68,8 @@
 #define QOS_INDENT_2 "        "
 #define QOS_INDENT_3 "            "
 
+#define NET_BYTES 16
+
 /* QoS license */
 int qos_license = 0;
 
@@ -87,6 +90,10 @@
 		return(QOS_FAILURE);
 	}
 
+	if (qos_session_init() != QOS_SUCCESS) {
+		return(QOS_FAILURE);
+	}
+
 	return(0);
 }
 
@@ -137,6 +144,10 @@
 static void qos_print_class_stat(void *pcb, struct rm_class *cl)
 {
 	int cursor;
+
+	if (cl == NULL) {
+	    return;
+	}
 	if(cl->band_stat.sec_cursor == 0) {
 		cursor = SEC_PER_MIN - 1;
 	} else {
@@ -189,6 +200,10 @@
 	struct rm_class *cl, *sub_cl;
 	struct qos_queue_info qosq_info;
 
+	struct ifnet    *ifp;
+	struct ifaltq *ifq;
+	cbq_state_t *cbqp;
+
 	QOS_CHECK_LICENSE;
 
 	if(!strcmp(QOS_NAME_FOR_ALL, sHwIf)) {
@@ -230,7 +245,18 @@
 
 		app_printf(pcb, "QoS statistics for interface \"%s\" %s %s\n", pQoSIfConf->sIfName, pQoSIfConf->sDir,pQoSIfConf->sBand);
 
-		STAILQ_FOREACH(pQoSQRoot, &qos_queue_root_head, list_entry) {
+                ifp = ifunit(pQoSIfConf->sHwIf);
+                if (!strcmp (pQoSIfConf->sDir, "OUT")) {
+                    ifq = &ifp->if_snd;
+                } else {
+                    ifq = &ifp->if_rcv;
+                }
+                cbqp = (cbq_state_t *)ifq->altq_disc;
+                cl = cbqp->ifnp.default_;
+                qos_print_class_stat(pcb, cl);
+
+		if (!current_dyn_q_count) {
+		    STAILQ_FOREACH(pQoSQRoot, &qos_queue_root_head, list_entry) {
 			if(pQoSIfConf->iDir != pQoSQRoot->iDir) {
 				continue;
 			}
@@ -296,6 +322,7 @@
 				}
 
 			}
+		    }
 		}
 	}
 
@@ -317,11 +344,21 @@
 	app_printf(pcb, "%15u failed operations of adding static filters\n", qs->fltr_g_stats.count_add_table_fail);
 	app_printf(pcb, "%15u failed operations of adding dynamic filters\n", qs->fltr_g_stats.count_add_dyn_table_fail);
 	app_printf(pcb, "%15u failed operations of deleting static filters\n", qs->fltr_g_stats.count_del_table_fail);
-	app_printf(pcb, "%15u failed operations of deleting dynamic filters\n", qs->fltr_g_stats.count_del_dyn_table_fail);
+	app_printf(pcb, "%15u failed operations of deleting dynamic filters\n\n", qs->fltr_g_stats.count_del_dyn_table_fail);
+	app_printf(pcb, "QoS statistics for Class Based Queues\n");
+	for (i = 0; i < 8; i++) {
+	    app_printf(pcb, "Statistic for the Priority : %d\n", i);
+	    app_printf(pcb, "%15u queue full\n", qs->fltr_g_stats.q_full_count[i]);
+	    app_printf(pcb, "%15u overload queues\n", qs->fltr_g_stats.q_overload_count[i]);
+	    app_printf(pcb, "%15u enqueue failure\n", qs->fltr_g_stats.q_enqueue_fail[i]);
+	    app_printf(pcb, "%15u current pending mbuf\n", qs->fltr_g_stats.cur_pend_mbuf[i]);
+	    app_printf(pcb, "%15u Total active classes\n\n", qs->fltr_g_stats.total_active_class[i]);
+	}
+	app_printf(pcb, "%15u Total outstanding mbuf\n", qs->fltr_g_stats.total_outstanding_mbuf);
 
     /* bug 14949, qiuzj, http qos */
-    app_printf(pcb,"\n");
-    show_qos_http_url_statistics(pcb);
+	app_printf(pcb,"\n");
+	show_qos_http_url_statistics(pcb);
 
 	return QOS_SUCCESS;
 }
@@ -366,9 +403,18 @@
  ******************************************************************************/
 int clear_qos_all_kern(void *pcb)
 {
-    /* bug 14949, qiuzj, http qos */
-    clear_qos_http_url(pcb);
-    
+
+	delete_qos_session_config (pcb, QOS_NAME_FOR_ALL);
+	disable_session (pcb);
+	if (current_dyn_q_count > 0) {
+		app_printf(pcb,"Reboot required to clear the default and"
+			" internally created QoS session queues\n");
+		return QOS_SUCCESS;
+	}
+
+	/* bug 14949, qiuzj, http qos */
+	clear_qos_http_url(pcb);
+
 	qos_filter_clear_all(pcb);
 	qos_interface_clear_all(pcb);
 
@@ -394,9 +440,9 @@
 	qos_queue_root_t *pQoSQRoot = NULL;
 	qos_queue_sub_t *pQoSQSub = NULL;
 	struct in_addr smask, dmask;
-	char sip_str[16], smsk_str[16],dip_str[16], dmsk_str[16], pro_str[16];
-    
-     http_qos_rule_t *rule_p;
+	char sip_str[NET_BYTES], smsk_str[NET_BYTES],dip_str[NET_BYTES], dmsk_str[NET_BYTES], pro_str[NET_BYTES];
+
+	http_qos_rule_t *rule_p;
 
 	QOS_CHECK_LICENSE;
 
@@ -464,6 +510,9 @@
 				continue;
 			}
 
+			if (!strncmp(pQoSQRoot->sQName, DYNAMIC_QUEUE_PREFIX, strlen(DYNAMIC_QUEUE_PREFIX))) {
+				continue;
+			}
 			app_printf(pcb, "%sqos queue root \"%s\" \"%s\" %s %s %d %s %s\n",
 					QOS_INDENT_1, pQoSQRoot->sQName, pQoSQRoot->sIfName, pQoSQRoot->sDir,
 					pQoSQRoot->sBand, pQoSQRoot->iPri, pQoSQRoot->sBorrow,
@@ -479,22 +528,22 @@
 
 				smask.s_addr = pfltr->tp.smask;
 				dmask.s_addr = pfltr->tp.dmask;
-				snprintf(sip_str, 16, "%s", inet_ntoa(pfltr->tp.sip));
-				snprintf(smsk_str, 16, "%s", inet_ntoa(smask));
-				snprintf(dip_str, 16, "%s", inet_ntoa(pfltr->tp.dip));
-				snprintf(dmsk_str, 16, "%s", inet_ntoa(dmask));
+				snprintf(sip_str, NET_BYTES, "%s", inet_ntoa(pfltr->tp.sip));
+				snprintf(smsk_str, NET_BYTES, "%s", inet_ntoa(smask));
+				snprintf(dip_str, NET_BYTES, "%s", inet_ntoa(pfltr->tp.dip));
+				snprintf(dmsk_str, NET_BYTES, "%s", inet_ntoa(dmask));
 
 				if(IPPROTO_TCP == pfltr->tp.proto) {
-					snprintf(pro_str, 16, "%s", PROTO_TCP_STR);
+					snprintf(pro_str, NET_BYTES, "%s", PROTO_TCP_STR);
 				}
 				else if(IPPROTO_UDP == pfltr->tp.proto) {
-					snprintf(pro_str, 16, "%s", PROTO_UDP_STR);
+					snprintf(pro_str, NET_BYTES, "%s", PROTO_UDP_STR);
 				}
 				else if(IPPROTO_IP == pfltr->tp.proto) {
-					snprintf(pro_str, 16, "%s", PROTO_ANY_STR);
+					snprintf(pro_str, NET_BYTES, "%s", PROTO_ANY_STR);
 				}
 				else {
-					snprintf(pro_str, 16, "%s", "ERROR");
+					snprintf(pro_str, NET_BYTES, "%s", "ERROR");
 				}
 
 				app_printf(pcb, "%sqos filter \"%s\" \"%s\" %s %s %d %s %s %d %s %d\n",
@@ -535,22 +584,22 @@
 					}
 					smask.s_addr = pfltr->tp.smask;
 					dmask.s_addr = pfltr->tp.dmask;
-					snprintf(sip_str, 16, "%s", inet_ntoa(pfltr->tp.sip));
-					snprintf(smsk_str, 16, "%s", inet_ntoa(smask));
-					snprintf(dip_str, 16, "%s", inet_ntoa(pfltr->tp.dip));
-					snprintf(dmsk_str, 16, "%s", inet_ntoa(dmask));
+					snprintf(sip_str, NET_BYTES, "%s", inet_ntoa(pfltr->tp.sip));
+					snprintf(smsk_str, NET_BYTES, "%s", inet_ntoa(smask));
+					snprintf(dip_str, NET_BYTES, "%s", inet_ntoa(pfltr->tp.dip));
+					snprintf(dmsk_str, NET_BYTES, "%s", inet_ntoa(dmask));
 
 					if(IPPROTO_TCP == pfltr->tp.proto) {
-						snprintf(pro_str, 16, "%s", PROTO_TCP_STR);
+						snprintf(pro_str, NET_BYTES, "%s", PROTO_TCP_STR);
 					}
 					else if(IPPROTO_UDP == pfltr->tp.proto) {
-						snprintf(pro_str, 16, "%s", PROTO_UDP_STR);
+						snprintf(pro_str, NET_BYTES, "%s", PROTO_UDP_STR);
 					}
 					else if(IPPROTO_IP == pfltr->tp.proto) {
-						snprintf(pro_str, 16, "%s", PROTO_ANY_STR);
+						snprintf(pro_str, NET_BYTES, "%s", PROTO_ANY_STR);
 					}
 					else {
-						snprintf(pro_str, 16, "%s", "ERROR");
+						snprintf(pro_str, NET_BYTES, "%s", "ERROR");
 					}
 
 					app_printf(pcb, "%sqos filter \"%s\" \"%s\" %s %s %d %s %s %d %s %d\n",
@@ -576,11 +625,13 @@
 			}
 		}
 	}
-    
+
 	if(!isfound) {
 		return QOS_USERLAND_FAILURE;
 	}
 
+        show_qos_session_config (pcb, QOS_NAME_FOR_ALL);
+
 	return QOS_SUCCESS;
 }
 
@@ -622,7 +673,8 @@
 	qs = &qos_filter_share;
 
 	isfound = 0;
-	STAILQ_FOREACH(pQoSIfConf, &qos_interface_conf_head, list_entry) {
+	if (!current_dyn_q_count) {
+	    STAILQ_FOREACH(pQoSIfConf, &qos_interface_conf_head, list_entry) {
 		/*
 		 * QoS interface
 		 */
@@ -708,10 +760,7 @@
 				}
 			}
 		}
-	}
-        
-	if(!isfound) {
-		return QOS_USERLAND_FAILURE;
+	    }
 	}
 
 	/*
@@ -726,7 +775,16 @@
 	qs->fltr_g_stats.count_add_dyn_table_fail = 0;
 	qs->fltr_g_stats.count_del_table_fail = 0;
 	qs->fltr_g_stats.count_del_dyn_table_fail = 0;
-	
+        for (i = 0; i < 8; i++) {
+            qs->fltr_g_stats.q_full_count[i] = 0;
+            qs->fltr_g_stats.q_overload_count[i] = 0;
+            qs->fltr_g_stats.q_enqueue_fail[i] = 0;
+            qs->fltr_g_stats.cur_pend_mbuf[i] = 0;
+            qs->fltr_g_stats.total_active_class[i] = 0;
+
+        }
+        qs->fltr_g_stats.total_outstanding_mbuf = 0;
+
 	/* bug 14949, qiuzj, http qos */
     if (name_for_all == 1) {
         clear_qos_http_url_statistics(pcb);
@@ -753,7 +811,7 @@
 	qos_filter_t *pfltr;
 	int i;
 	struct in_addr smask, dmask;
-	char sip_str[16], smsk_str[16],dip_str[16], dmsk_str[16], pro_str[16];
+	char sip_str[NET_BYTES], smsk_str[NET_BYTES],dip_str[NET_BYTES], dmsk_str[NET_BYTES], pro_str[NET_BYTES];
 
 	/*
 	 * qos filter len
@@ -817,6 +875,10 @@
 	 * write qos queue root
 	 */
 	STAILQ_FOREACH(pQoSQRoot, &qos_queue_root_head, list_entry) {
+		if (!strncmp(pQoSQRoot->sQName, DYNAMIC_QUEUE_PREFIX, strlen(DYNAMIC_QUEUE_PREFIX))) {
+			continue;
+		}
+
 		cur += sprintf(cur, "qos queue root \"%s\" \"%s\" %s %s %d %s %s\n",
 				pQoSQRoot->sQName, pQoSQRoot->sIfName, pQoSQRoot->sDir,
 				pQoSQRoot->sBand, pQoSQRoot->iPri, pQoSQRoot->sBorrow,
@@ -843,24 +905,28 @@
 			continue;
 		}
 
+		if (!strncmp(pfltr->fltr_name, DYNAMIC_FILTER_PREFIX, strlen(DYNAMIC_FILTER_PREFIX))) {
+		    continue;
+		}
+
 		smask.s_addr = pfltr->tp.smask;
 		dmask.s_addr = pfltr->tp.dmask;
-		snprintf(sip_str, 16, "%s", inet_ntoa(pfltr->tp.sip));
-		snprintf(smsk_str, 16, "%s", inet_ntoa(smask));
-		snprintf(dip_str, 16, "%s", inet_ntoa(pfltr->tp.dip));
-		snprintf(dmsk_str, 16, "%s", inet_ntoa(dmask));
+		snprintf(sip_str, NET_BYTES, "%s", inet_ntoa(pfltr->tp.sip));
+		snprintf(smsk_str, NET_BYTES, "%s", inet_ntoa(smask));
+		snprintf(dip_str, NET_BYTES, "%s", inet_ntoa(pfltr->tp.dip));
+		snprintf(dmsk_str, NET_BYTES, "%s", inet_ntoa(dmask));
 
 		if(IPPROTO_TCP == pfltr->tp.proto) {
-			snprintf(pro_str, 16, "%s", PROTO_TCP_STR);
+			snprintf(pro_str, NET_BYTES, "%s", PROTO_TCP_STR);
 		}
 		else if(IPPROTO_UDP == pfltr->tp.proto) {
-			snprintf(pro_str, 16, "%s", PROTO_UDP_STR);
+			snprintf(pro_str, NET_BYTES, "%s", PROTO_UDP_STR);
 		}
 		else if(IPPROTO_IP == pfltr->tp.proto) {
-			snprintf(pro_str, 16, "%s", PROTO_ANY_STR);
+			snprintf(pro_str, NET_BYTES, "%s", PROTO_ANY_STR);
 		}
 		else {
-			snprintf(pro_str, 16, "%s", "ERROR");
+			snprintf(pro_str, NET_BYTES, "%s", "ERROR");
 		}
 
 		cur += sprintf(cur, "qos filter \"%s\" \"%s\" %s %s %d %s %s %d %s %d\n",
@@ -878,3 +944,70 @@
 	return QOS_SUCCESS;
 }
 
+
+int write_qos_session_kern(void *pcb, void **config_data, int *length) {
+    unsigned int len;
+    char *cur, *buffer;
+    struct in_addr smask, dmask;
+    char sip_str[NET_BYTES], smsk_str[NET_BYTES], dip_str[NET_BYTES], dmsk_str[NET_BYTES], pro_str[NET_BYTES];
+
+    dyn_session_qos_conf_t *dyn_qos_conf_run = NULL;
+
+    /* QoS session command format */
+    char qos_session_conf_cmd[] = "qos session add xxxxxx xxx.xxx.xxx.xxx xxxxx xxx.xxx.xxx.xxx xxxxx xxxxxxx xxx";
+    char qos_session_status_cmd[] = "qos session xxx";
+    char qos_session_tuple_count_cmd[] = "qos session sespacketcnt xxxx";
+    char qos_session_q_del_step_count_cmd[] = "qos session sessionqdelstepcount xxxx";
+    char qos_session_q_len_wait_cmd[] = "qos session qlenwait xxxx";
+    char qos_session_q_class_count_cmd[] = "qos session qosclasscnt xxxx";
+    char qos_session_q_class_insert_pos_cmd[] = "qos session qosclspos xxxx";
+
+    len = (sizeof (qos_session_conf_cmd) + QOS_SNAME_MAX + 1) * MAX_QOS_SESSION_CONFIG;
+    len += sizeof (qos_session_status_cmd) + 1;
+    len += sizeof (qos_session_tuple_count_cmd) + 1;
+    len += sizeof (qos_session_q_del_step_count_cmd) + 1;
+    len += sizeof (qos_session_q_len_wait_cmd) + 1;
+    len += sizeof (qos_session_q_class_count_cmd) + 1;
+    len += sizeof (qos_session_q_class_insert_pos_cmd) + 1;
+
+    MALLOC(buffer, char *, len, M_TEMP, M_NOWAIT);
+
+    if (NULL == buffer) {
+        app_printf(pcb, "ERROR: out of memory for QoS Session config buffer size %d(%lld)\n", len, (long long int)(uintptr_t) buffer);
+        return QOS_FAILURE;
+    }
+
+    bzero(buffer, len);
+    cur = buffer;
+
+    if (qos_session_status == SESSION_ENABLE)
+        cur += sprintf (cur, "qos session on\n");
+    else
+        cur += sprintf (cur, "qos session off\n");
+
+    cur += sprintf (cur, "qos session sespacketcnt %u\n", repeat_segment_num);
+    cur += sprintf (cur, "qos session sessionqdelstepcount %u\n", q_del_step_size);
+    cur += sprintf (cur, "qos session qlenwait %d\n", q_len_wait);
+    cur += sprintf (cur, "qos session qosclasscnt %d\n", loop_class_count);
+    cur += sprintf (cur, "qos session qosclspos %d\n", class_insert_pos);
+
+    STAILQ_FOREACH(dyn_qos_conf_run, &dyn_session_qos_conf_head, list_entry) {
+        cur += sprintf (cur, "qos session add \"%s\" %s %u.%u.%u.%u %u %u.%u.%u.%u %u %s %s\n",
+        dyn_qos_conf_run->name, dyn_qos_conf_run->port,
+        (dyn_qos_conf_run->sip) & 0xFF,
+        (dyn_qos_conf_run->sip >> 8) & 0xFF,
+        (dyn_qos_conf_run->sip >> 16) & 0xFF,
+        (dyn_qos_conf_run->sip >> 24) & 0xFF,
+        dyn_qos_conf_run->sport,
+        (dyn_qos_conf_run->dip) & 0xFF,
+        (dyn_qos_conf_run->dip >> 8) & 0xFF,
+        (dyn_qos_conf_run->dip >> 16) & 0xFF,
+        (dyn_qos_conf_run->dip >> 24) & 0xFF,
+        dyn_qos_conf_run->dport,
+        dyn_qos_conf_run->band, dyn_qos_conf_run->dir);
+    }
+    *length = cur - buffer + 1; /* Add 1 for the NULL character */
+    *config_data = buffer;
+
+    return QOS_SUCCESS;
+}
Index: /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/qos_var.h
===================================================================
--- /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/qos_var.h	(revision 38975)
+++ /branches/rel_apv_10_7_2_14_qos/usr/src/sys/click/app/qos/qos_var.h	(working copy)
@@ -45,7 +45,11 @@
 #define QOS_MAXPRIO		8
 
 /* QoS maximum queue */
-#define QOS_MAXQ		1024
+#ifndef MAX_DYN_QUEUE
+#define MAX_DYN_QUEUE 1000000
+#endif
+
+#define QOS_MAXQ (MAX_DYN_QUEUE + 1024)
 
 /* QoS interface maximum number */
 #define MAX_VLAN 4094
@@ -71,7 +75,8 @@
 enum {
 	QOS_USERLAND_FAILURE = -1,
 	QOS_SUCCESS = 0,
-	QOS_FAILURE
+	QOS_FAILURE,
+	QOS_DYN_Q_DELETE_COMPLETE
 };
 
 /*************************************************************************
