Index: /branches/rel_apv_10_4_0_112_gail/usr/click/lib/libparser/commands.pm
===================================================================
--- /branches/rel_apv_10_4_0_112_gail/usr/click/lib/libparser/commands.pm	(revision 38066)
+++ /branches/rel_apv_10_4_0_112_gail/usr/click/lib/libparser/commands.pm	(working copy)
@@ -53426,7 +53426,7 @@
                 function_args => [
                                                         {
                                                                 type => "STRING",
-                                                                help_string => "name",
+                                                                help_string => "name, (ALL to delete all QoS Session configurations)",
                                                                 optional => "NO",
                                                         },
                                                 ],
Index: /branches/rel_apv_10_4_0_112_gail/usr/click/webui/htdocs/new/src/apv/tree.py
===================================================================
--- /branches/rel_apv_10_4_0_112_gail/usr/click/webui/htdocs/new/src/apv/tree.py	(revision 38066)
+++ /branches/rel_apv_10_4_0_112_gail/usr/click/webui/htdocs/new/src/apv/tree.py	(working copy)
@@ -148,7 +148,7 @@
             ('qos_queue', {'cls':ModelNode, 'model':'network.qos.QosQueue'}),
             ('qos_filter', {'cls':ModelNode, 'model':'network.qos.QosFilter'}),
             ('qos_status', {'cls':ModelNode, 'model':'network.qos.QosStatistics'}),
-            ('qos_session', {'cls':ModelNode, 'model':'network.qos.QosSession'}),
+            #('qos_session', {'cls':ModelNode, 'model':'network.qos.QosSession'}),
         ])}),
         ('ipv6', {'cls':MenuNode, 'license':'IPv6', 'verbose_name':_('IPv6 Advanced Settings'), 'sub_nodes':D([
             ('nat64', {'cls':ModelNode, 'model':'nat.nat.NAT64Settings'}),
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 38066)
+++ /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/app/qos/qos_dynamic.h	(working copy)
@@ -2,6 +2,7 @@
 
 #define QOS_SNAME_MAX  15
 #define PORT_NAME_MAX  8
+#define MAX_QOS_SESSION_CONFIG 1024
 #define N_CHILDREN 256
 #define SESSION_ENABLE  1
 #define SESSION_DISABLE 0
@@ -22,6 +23,9 @@
 
 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;
+
 
 typedef struct dyn_qos_session_lookup {
     struct dyn_qos_session_lookup *dyn_qos_session_lookup_node[N_CHILDREN];
@@ -38,7 +42,8 @@
 
 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);
-void save_dyn_qos_session_config (char *name, char *port, uint32_t sip, uint16_t sport, uint32_t dip, uint16_t dport, char *band, char *dir);
+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);
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 38066)
+++ /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/app/qos/qos_dynamic.c	(working copy)
@@ -57,9 +57,10 @@
     struct altq_conf *pALTQConf = NULL;
 
     int s = 0;
-    int i;
+    int i, j, save_fail;
     uint8_t direction = 0;
     int octet;
+    unsigned char tuple[TUPLE_LEN];
 
     QOS_CHECK_LICENSE;
 
@@ -71,6 +72,10 @@
     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) 
@@ -120,16 +125,43 @@
     current->qos_session_altq_conf_save = (struct altq_conf *) malloc(sizeof(struct altq_conf), M_QOS, M_NOWAIT | M_ZERO);
     memcpy(current->qos_session_altq_conf_save, pALTQConf, sizeof(struct altq_conf));
 
-    save_dyn_qos_session_config (name, pQoSQRoot->sIfName, sip, sport, dip, dport, pQoSQRoot->sBand, pQoSQRoot->sDir);
+    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;
 }
 
 
-void save_dyn_qos_session_config (char *name, char *port, uint32_t sip, uint16_t sport, uint32_t dip, uint16_t dport, char *band, char *dir) {
+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);
@@ -143,11 +175,17 @@
 
 
     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) {
@@ -155,7 +193,7 @@
             continue;
         }
 
-        app_printf(pcb,  "qos dynamic \"%s\" %s %u.%u.%u.%u %u %u.%u.%u.%u %u %s %s\n", 
+        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,
@@ -313,6 +351,7 @@
 
 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;
@@ -320,35 +359,32 @@
     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, dyn_ses_conf_node->name) == 0) {
-            break;
+        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;
         }
-    }
-
-    if (dyn_ses_conf_node == NULL) {
-        app_printf(pcb, "QoS Session not found!\n");
-        return QOS_SUCCESS;
-    }
-
-    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);
+        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 (!qos_session_config_count()) {
+    if (found && !qos_session_config_count()) {
         free_qos_session_lookup (dyn_qos_session_lookup_root);
         dyn_qos_session_lookup_root = NULL;
     }
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 38066)
+++ /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/app/qos/qos_subr.c	(working copy)
@@ -371,7 +371,7 @@
 int clear_qos_all_kern(void *pcb)
 {
 
-    qos_session_clear_all(pcb);
+    delete_qos_session_config (pcb, QOS_NAME_FOR_ALL);
     /* bug 14949, qiuzj, http qos */
     clear_qos_http_url(pcb);
     
@@ -595,9 +595,7 @@
 		return QOS_USERLAND_FAILURE;
 	}
 
-	if (name_for_all && dir_for_any) {
-		show_session_qos_kern (pcb, QOS_NAME_FOR_ALL);
-	}
+	show_qos_session_config (pcb, QOS_NAME_FOR_ALL);
 
 	return QOS_SUCCESS;
 }
@@ -915,48 +913,44 @@
     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];
 
-    session_qos_conf_t *qos_conf_run = NULL;
+    dyn_session_qos_conf_t *dyn_qos_conf_run = NULL;
 
     /* QoS session command format */
-    char qos_session_cmd[] = "qos session xxxxxx xxx xxxxxxxx xxx.xxx.xxx.xxx xxx.xxx.xxx.xxx xxxxx xxx.xxx.xxx.xxx xxx.xxx.xxx.xxx xxxxx xxxxx";
+    char qos_session_conf_cmd[] = "qos session xxxxxx xxx.xxx.xxx.xxx xxxxx xxx.xxx.xxx.xxx xxxxx xxxxxxx xxx";
+    char qos_session_status_cmd[] = "qos session_xxx";
 
-    len = (sizeof(qos_session_cmd) + SESSION_BASED_QOS_NLEN + 1) * QOS_MAX_SESSION_NUM;
+    len = (sizeof (qos_session_conf_cmd) + QOS_SNAME_MAX + 1) * MAX_QOS_SESSION_CONFIG;
+    len += sizeof (qos_session_status_cmd) + 1;
 
     MALLOC(buffer, char *, len, M_TEMP, M_NOWAIT);
 
     if (NULL == buffer) {
-        app_printf(pcb, "ERROR: out of memory for session buffer size %d(%lld)\n", len, (long long int)(uintptr_t) 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;
-    STAILQ_FOREACH(qos_conf_run, &session_qos_conf_head, list_entry) {
-        smask.s_addr = qos_conf_run->tp.smask;
-        dmask.s_addr = qos_conf_run->tp.dmask;
-        snprintf(sip_str, NET_BYTES, "%s", inet_ntoa(qos_conf_run->tp.sip));
-        snprintf(smsk_str, NET_BYTES, "%s", inet_ntoa(smask));
-        snprintf(dip_str, NET_BYTES, "%s", inet_ntoa(qos_conf_run->tp.dip));
-        snprintf(dmsk_str, NET_BYTES, "%s", inet_ntoa(dmask));
-
-        if(IPPROTO_TCP == qos_conf_run->tp.proto) {
-            snprintf(pro_str, NET_BYTES, "%s", PROTO_TCP_STR);
-        }
-        else if(IPPROTO_UDP == qos_conf_run->tp.proto) {
-            snprintf(pro_str, NET_BYTES, "%s", PROTO_UDP_STR);
-        }
-        else if(IPPROTO_IP == qos_conf_run->tp.proto) {
-            snprintf(pro_str, NET_BYTES, "%s", PROTO_ANY_STR);
-        }
-        else {
-            snprintf(pro_str, NET_BYTES, "%s", "ERROR");
-        }
-
-        cur += sprintf (cur, "qos session \"%s\" %s %s %s %s %s %d %s %s %d %s\n", qos_conf_run->name,
-             qos_conf_run->session_q_info.sIfName, qos_conf_run->session_q_info.sDir,
-             qos_conf_run->session_q_info.sBand, sip_str, smsk_str, ntohs(qos_conf_run->tp.sport), dip_str, dmsk_str,
-             ntohs(qos_conf_run->tp.dport), pro_str);
 
+    if (qos_session_status == SESSION_ENABLE)
+        cur += sprintf (cur, "qos session_on\n");
+    else
+        cur += sprintf (cur, "qos session_off\n");
+
+    STAILQ_FOREACH(dyn_qos_conf_run, &dyn_session_qos_conf_head, list_entry) {
+        cur += sprintf (cur, "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);
     }
     *length = cur - buffer + 1; /* Add 1 for the NULL character */
     *config_data = buffer;
