Index: /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/app/qos/altq_classq.h
===================================================================
--- /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/app/qos/altq_classq.h	(revision 38153)
+++ /branches/rel_apv_10_4_0_112_gail/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,6 +87,8 @@
 extern void		_flushq(class_queue_t *);
 
 #else /* __GNUC__ && !ALTQ_DEBUG */
+
+
 /*
  * inlined versions
  */
@@ -91,6 +97,8 @@
 {
         struct mbuf *m0;
 
+        mtx_lock (&q->qos_qtail_lock);
+ 
 	if ((m0 = qtail(q)) != NULL)
 		m->m_nextpkt = m0->m_nextpkt;
 	else
@@ -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_4_0_112_gail/usr/src/sys/click/app/qos/altq_rmclass.c
===================================================================
--- /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/app/qos/altq_rmclass.c	(revision 38153)
+++ /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/app/qos/altq_rmclass.c	(working copy)
@@ -309,6 +309,10 @@
 	return;
 }
 
+void qlockinit (class_queue_t *q) {
+     mtx_init(&q->qos_qtail_lock, "qos queue tail lock", NULL, MTX_DEF | MTX_NOWITNESS);
+}
+
 struct rm_class *
 rmc_newclass(int pri, struct rm_ifdat *ifd, u_int nsecPerByte,
     void (*action)(rm_class_t *, rm_class_t *), int maxq,
@@ -369,6 +373,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 */
Index: /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/app/qos/qos_classifier.c
===================================================================
--- /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/app/qos/qos_classifier.c	(revision 38153)
+++ /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/app/qos/qos_classifier.c	(working copy)
@@ -61,6 +61,7 @@
 #define MAX_DYN_QUEUE 50000
 #endif
 
+
 uint16_t ports_record[65536];
 
 static void delete_dyn_queues (void);
@@ -75,7 +76,7 @@
 unsigned int current_dyn_q_count = 0;
 unsigned int enq_idx = 0;
 unsigned int deq_idx = 0;
-char q_dynamic_list[MAX_DYN_QUEUE][32];
+
 int qos_session_cleanup = 0;
 
 
@@ -139,6 +140,7 @@
 extern int qos_session_status;
 extern uint32_t repeat_segment_num;
 extern uint32_t q_del_step_size;
+extern struct mtx qos_session_lock;
 /******************************************************************************
  * Return the current valid class poniter.
  *
@@ -214,13 +216,24 @@
     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 start to 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_ERR, "QoS sessions reached maximum limit : %u. Recycling old sessions\n", MAX_DYN_QUEUE);
-        qos_session_cleanup = 1;
-        qos_filter_clear_all_dyn (NULL);
+	fastlog_syslog(LOG_DEBUG, "QoS sessions reached maximum limit : %u. Recycling old sessions\n", MAX_DYN_QUEUE);
+        if (qos_session_cleanup == 0) {
+            qos_session_cleanup = 1;
+            qos_filter_clear_all_dyn (NULL);
+        }
+        mtx_unlock (&qos_session_lock);
         return;
     }
+    mtx_unlock (&qos_session_lock);
 
     if (sip) {
         sprintf (ip_str, "%u", sip);
@@ -237,7 +250,7 @@
     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_ERR, "Q create fail : %s\n", q_name);
+	fastlog_syslog(LOG_DEBUG, "Queue creation failed : %s\n", q_name);
         return;
     }
 
@@ -251,17 +264,9 @@
     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;
     }
-
-    bzero(q_dynamic_list[enq_idx], 32);
-    sprintf (q_dynamic_list[enq_idx], "%s", q_name);
-    ++enq_idx;
-    ++current_dyn_q_count;
-
-    if (enq_idx == MAX_DYN_QUEUE) {
-        enq_idx = 0;
-    }
 }
 
 
@@ -269,23 +274,13 @@
     int count;
     unsigned int actual_q_count;
 
-    count = (current_dyn_q_count >= q_del_step_size) ? q_del_step_size : current_dyn_q_count;
+    count = q_del_step_size;
 
     while(count) {
-        if (deq_idx == MAX_DYN_QUEUE) {
-            deq_idx = 0;
-        }
-        no_qos_queue_root_sess_kern (q_dynamic_list[deq_idx]);
-        ++deq_idx;
-        --current_dyn_q_count;
+        if (no_qos_queue_root_sess_kern (NULL) == QOS_DYN_Q_DELETE_COMPLETE)
+            break;
         --count;
     }
-
-    if (current_dyn_q_count <= 0) {
-        actual_q_count = qos_queue_count();
-      	fastlog_syslog(LOG_ERR, "actual queue count now : %u\n", actual_q_count);
-        qos_session_cleanup = 0;
-    }
 }
 
 
@@ -1047,7 +1042,7 @@
 
 	if('\0' == qos_filter->qqi_name[0]) {
 		app_printf(pcb, "ERROR: queue name is NULL\n");
-		fastlog_syslog (LOG_ERR, "ERROR: queue name is NULL\n");
+		fastlog_syslog (LOG_DEBUG, "ERROR: queue name is NULL\n");
 		return QOS_FAILURE;
 	}
 
@@ -1057,19 +1052,19 @@
 	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_ERR, "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_ERR, "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_ERR, "ERROR: interace id is wrong\n");
+		fastlog_syslog (LOG_DEBUG, "ERROR: interace id is wrong\n");
 		goto ADD_FLTR_ERROR;
 	}
 
@@ -1087,7 +1082,7 @@
 
 		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_ERR,  "ERROR: the QoS L4 filter name - %s has aready existed\n", pfltr->fltr_name);
+			fastlog_syslog (LOG_DEBUG,  "ERROR: the QoS L4 filter name - %s has aready existed\n", pfltr->fltr_name);
 			goto ADD_FLTR_ERROR;
 		}
 
@@ -1095,7 +1090,7 @@
 					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_ERR, "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);
 			goto ADD_FLTR_ERROR;
 		}
 	}
@@ -1112,7 +1107,7 @@
 	}
 	if (i == QOS_MAX_FLTR_NUM) {
 		app_printf(pcb, "ERROR: maximum number of QoS L4 filters reached. maximum %u\n", QOS_MAX_FLTR_NUM);
-		fastlog_syslog (LOG_ERR, "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);
 		goto ADD_FLTR_ERROR;
 	}
 
@@ -1125,6 +1120,7 @@
 	if(QOS_FAILURE == ret) {
 		bzero(pfltr, sizeof(qos_filter_t));
 		qos_filter_share.fltr_g_stats.count_add_table_fail++;
+		fastlog_syslog(LOG_DEBUG, "ERROR: failed to add the filter to the table\n");
 		goto ADD_FLTR_ERROR;
 	}
 
@@ -1222,10 +1218,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;
 		}
 
@@ -1237,6 +1235,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;
 		}
 
@@ -1264,6 +1263,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;
 	}
 
@@ -1395,13 +1395,13 @@
 
 	if(strlen(fltr_name) == 0) {
 		app_printf(pcb, "ERROR: The input name is illegal, it can not be an empty string\n");
-		fastlog_syslog(LOG_ERR, "ERROR: The input name is illegal, it can not be an empty string : %s\n", fltr_name);
+		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);
-		fastlog_syslog(LOG_ERR, "ERROR: The input name - %s is too long, maximum is %d\n", fltr_name, QOS_FLTR_NLEN-1);
+		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;
 	}
 
@@ -1410,7 +1410,7 @@
 			(fltr_name[2] == 'l' || fltr_name[2] == 'L') &&
 			strlen(fltr_name) == 3) {
 		app_printf(pcb, "ERROR: \"%s\" is reserved for system\n", fltr_name);
-		fastlog_syslog (LOG_ERR, "ERROR: \"%s\" is reserved for system\n", fltr_name);
+		fastlog_syslog (LOG_DEBUG, "ERROR: \"%s\" is reserved for system\n", fltr_name);
 		return QOS_FAILURE;
 	}
 
@@ -1419,21 +1419,21 @@
 
 	if (!clickrule_mask(smask) ) {
 		app_printf(pcb, "ERROR: invalid source mask\n");
-		fastlog_syslog(LOG_ERR, "ERROR: invalid source mask\n");
+		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");
-		fastlog_syslog(LOG_ERR, "ERROR: invalid destination mask\n");
+		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");
-		fastlog_syslog(LOG_ERR, "ERROR: invalid source ip and mask pair\n");
+		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");
-		fastlog_syslog(LOG_ERR, "ERROR: invalid destination ip and mask pair\n");
+		fastlog_syslog(LOG_DEBUG, "ERROR: invalid destination ip and mask pair\n");
 		return QOS_FAILURE;
 	}
 
@@ -1446,7 +1446,7 @@
 	} else {
 		app_printf(pcb, "ERROR: invalid protocol string, please use %s, %s or %s\n",
 				PROTO_TCP_STR, PROTO_UDP_STR, PROTO_ANY_STR);
-		fastlog_syslog(LOG_ERR, "ERROR: invalid protocol string, please use %s, %s or %s\n", PROTO_TCP_STR, PROTO_UDP_STR, PROTO_ANY_STR);
+		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;
 	}
 
@@ -1468,7 +1468,7 @@
 
 	if(QOS_FAILURE == qos_filter_add(pcb, &fltr)) {
 		app_printf(pcb, "Failed to add the filter.\n");
-		fastlog_syslog(LOG_ERR, "Failed to add the filter : %s\n", fltr_name);
+		fastlog_syslog(LOG_DEBUG, "Failed to add the filter : %s\n", fltr_name);
 		return QOS_FAILURE;
 	}
 
Index: /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/app/qos/qos_dynamic.h
===================================================================
--- /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/app/qos/qos_dynamic.h	(revision 38153)
+++ /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/app/qos/qos_dynamic.h	(working copy)
@@ -1,7 +1,7 @@
 #include <click/app/qos/qos_scheduler.h>
 
-#define QOS_SNAME_MAX  15
-#define PORT_NAME_MAX  8
+#define QOS_SNAME_MAX  32
+#define PORT_NAME_MAX  32
 #define MAX_QOS_SESSION_CONFIG 1024
 #define N_CHILDREN 256
 #define SESSION_ENABLE  1
@@ -27,7 +27,7 @@
 extern int qos_session_status;
 extern uint32_t repeat_segment_num;
 extern uint32_t q_del_step_size;
-
+extern struct mtx qos_session_lock;
 
 typedef struct dyn_qos_session_lookup {
     struct dyn_qos_session_lookup *dyn_qos_session_lookup_node[N_CHILDREN];
@@ -60,3 +60,4 @@
 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);
Index: /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/app/qos/qos_dynamic.c
===================================================================
--- /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/app/qos/qos_dynamic.c	(revision 38153)
+++ /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/app/qos/qos_dynamic.c	(working copy)
@@ -28,6 +28,8 @@
 
 #define TUPLE_LEN 12 /* src ip + src port + dest ip + dst port */
 
+struct mtx qos_session_lock;
+
 int qos_session_status = SESSION_DISABLE;
 
 uint32_t repeat_segment_num = 50;
@@ -195,7 +197,7 @@
     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) && strncmp(name, QOS_NAME_FOR_ALL, sizeof(QOS_NAME_FOR_ALL))) {
+        if(strcmp(name, dyn_qos_conf_run->name) && strcmp(name, "ALL") && strcmp(name, "all")) {
             continue;
         }
 
@@ -344,12 +346,14 @@
 
 void free_qos_session_lookup(dyn_qos_session_lookup_t *root) {
     int i;
-    fastlog_syslog(LOG_DEBUG, "Cleanup session lookup table.\n");
-    
     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);
     }
 }
@@ -358,39 +362,17 @@
 int del_dyn_qos_session_config (void *pcb, char *name) {
     int i, j;
     int found = 0;
-    unsigned char tuple[TUPLE_LEN];
 
     dyn_session_qos_conf_t *dyn_ses_conf_node = NULL;
 
-    fastlog_syslog(LOG_DEBUG, "Attempt to delete QoS session : %s\n", name);
 
     STAILQ_FOREACH(dyn_ses_conf_node, &dyn_session_qos_conf_head, list_entry) {
-        if (strcmp(name, "ALL") ) {
-            if (strcmp(name, dyn_ses_conf_node->name)) {
-                continue;
-            }
-        }
         found = 1;
-        j = 0;
-        for (i = 3; i >= 0; --i) {
-            tuple[j++] = (unsigned char ) (dyn_ses_conf_node->sip >> (i * 8)) & 0xFF;
-        }
-        for (i = 1; i >= 0; --i) {
-            tuple[j++] = (unsigned char ) (dyn_ses_conf_node->sport >> (i * 8)) & 0xFF;
-        }
-        for (i = 3; i >= 0; --i) {
-            tuple[j++] = (unsigned char ) (dyn_ses_conf_node->dip >> (i * 8)) & 0xFF;
-        }
-        for (i = 1; i >= 0; --i) {
-            tuple[j++] = (unsigned char ) (dyn_ses_conf_node->dport >> (i * 8)) & 0xFF;
-        }
-       
         STAILQ_REMOVE(&dyn_session_qos_conf_head, dyn_ses_conf_node, dyn_session_qos_conf, list_entry);
         free(dyn_ses_conf_node, M_QOS);
-        remove_tuple_from_lookup(tuple);
     }
 
-    if (found && !qos_session_config_count()) {
+    if (found) {
         free_qos_session_lookup (dyn_qos_session_lookup_root);
         dyn_qos_session_lookup_root = NULL;
     }
@@ -400,19 +382,25 @@
 
 
 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, "enable syslog %d\n", qos_session_status);
+    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, "disable syslog %d\n", qos_session_status);
+    fastlog_syslog(LOG_DEBUG, "Disabled QoS Session.\n");
     return QOS_SUCCESS;
 }
 
@@ -441,3 +429,8 @@
     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);
+    return QOS_SUCCESS;
+}
Index: /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/app/qos/qos_scheduler.c
===================================================================
--- /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/app/qos/qos_scheduler.c	(revision 38153)
+++ /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/app/qos/qos_scheduler.c	(working copy)
@@ -63,6 +63,9 @@
 #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;
@@ -250,6 +253,7 @@
 void qos_start(struct ifnet *ifp)
 {
 	struct mbuf *m_head;
+        char temp;
 
 	while (!IFQ_IS_EMPTY(&ifp->if_rcv)) {
 		if (ifp->if_rcv.ifq_head != NULL) {
@@ -688,7 +692,7 @@
 	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_ERR, "ERROR: kernel input parameters invalid\n");
+		fastlog_syslog(LOG_DEBUG, "ERROR: kernel input parameters invalid\n");
 		return(QOS_USERLAND_FAILURE);
 	}
 
@@ -696,7 +700,7 @@
         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_ERR, "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);
 	    }
         }
@@ -719,14 +723,14 @@
 	ifp = ifunit(pALTQConf->ifname);
 	if (ifp == NULL) {
 		app_printf(pcb, "ERROR: can not find the QoS interface\n");
-		fastlog_syslog(LOG_ERR, "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_ERR, "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 {
@@ -737,7 +741,7 @@
 	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_ERR, "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;
@@ -745,21 +749,26 @@
 	}
 
 	/* Check duplicated queue name */
+        mtx_lock (&qos_session_lock);
 	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_ERR, "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) {
+        if (!qos_session_status) {
+	    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_ERR, "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) {
@@ -768,9 +777,11 @@
 			break;
 		}
 	}
+
 	if (pQoSIfConf == NULL) {
 		app_printf(pcb, "ERROR: %s QoS has not configured on the interface\n", pQoSQRoot->sDir);
-		fastlog_syslog(LOG_ERR, "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;
@@ -778,6 +789,8 @@
 
 	pALTQConf->qid = ++qos_index;
 
+        mtx_unlock (&qos_session_lock);
+
         if (!qos_session_status) {
 	/* Check bandwidth */
 	    nBandCheck = pALTQConf->bandwidth;
@@ -798,7 +811,7 @@
 	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_ERR, "ERROR: allocate memory failed\n");
+		fastlog_syslog(LOG_DEBUG, "ERROR: allocate memory failed\n");
 		--qos_index;
 		return(QOS_USERLAND_FAILURE);
 	}
@@ -809,10 +822,11 @@
 
 	/* Add the class */
 	iErrCode = altq_add_queue(pALTQConf);
+
 	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);
-			fastlog_syslog(LOG_ERR, "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;
@@ -823,8 +837,11 @@
 	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);
+        ++current_dyn_q_count;
+        mtx_unlock (&qos_session_lock);
 	splx(s);
 	return(QOS_SUCCESS);
 
@@ -836,8 +853,7 @@
 }
 
 
-/* delete dynamically created queues */
-int no_qos_queue_root_sess_kern(char *sQueue)
+int no_qos_queue_root_sess_kern (char *sQueue)
 {
 	qos_queue_sub_t *pQoSQSub = NULL;
 	qos_queue_root_t *pQoSQRoot = NULL;
@@ -852,8 +868,16 @@
 
 	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 (strcmp(sQueue, pQoSQRoot->sQName) == 0) {
+                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);
@@ -863,21 +887,28 @@
 	}
 
 	if (pQoSQRoot == NULL) {
-		fastlog_syslog(LOG_ERR, "ERROR: can not find the root queue : %s\n", sQueue);
-		return(QOS_USERLAND_FAILURE);
+		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_ERR, "ERROR: can not find the QoS interface\n");
+		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_ERR, "ERROR: can not find the QoS interface\n");
+		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;
@@ -885,6 +916,8 @@
 	/* Free memory */
 	STAILQ_REMOVE(&qos_queue_root_head, pQoSQRoot, qos_queue_root, list_entry);
 	free(pQoSQRoot, M_QOS);
+        --current_dyn_q_count;
+        mtx_unlock (&qos_session_lock);
 
 	/* Security */
 	s = splimp();
Index: /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/app/qos/qos_subr.c
===================================================================
--- /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/app/qos/qos_subr.c	(revision 38153)
+++ /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/app/qos/qos_subr.c	(working copy)
@@ -91,6 +91,10 @@
 		return(QOS_FAILURE);
 	}
 
+	if (qos_session_init() != QOS_SUCCESS) {
+		return(QOS_FAILURE);
+	}
+
 	return(0);
 }
 
Index: /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/app/qos/qos_var.h
===================================================================
--- /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/app/qos/qos_var.h	(revision 38153)
+++ /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/app/qos/qos_var.h	(working copy)
@@ -75,7 +75,8 @@
 enum {
 	QOS_USERLAND_FAILURE = -1,
 	QOS_SUCCESS = 0,
-	QOS_FAILURE
+	QOS_FAILURE,
+	QOS_DYN_Q_DELETE_COMPLETE
 };
 
 /*************************************************************************
