diff -upwbrN quagga_original/bgpd/bgp_attr.c quagga_cq/bgpd/bgp_attr.c
--- quagga_original/bgpd/bgp_attr.c	2010-05-11 21:25:09.000000000 +0200
+++ quagga_cq/bgpd/bgp_attr.c	2010-05-11 21:28:22.000000000 +0200
@@ -37,6 +37,8 @@ Software Foundation, Inc., 59 Temple Pla
 #include "bgpd/bgp_debug.h"
 #include "bgpd/bgp_packet.h"
 #include "bgpd/bgp_ecommunity.h"
+#include "bgpd/bgp_qos.h"
+#include "bgpd/bgp_cos.h"
 
 /* Attribute strings for logging. */
 static const struct message attr_str [] = 
@@ -60,6 +62,7 @@ static const struct message attr_str [] 
   { BGP_ATTR_AS4_PATH,         "AS4_PATH" }, 
   { BGP_ATTR_AS4_AGGREGATOR,   "AS4_AGGREGATOR" }, 
   { BGP_ATTR_AS_PATHLIMIT,     "AS_PATHLIMIT" },
+  { BGP_ATTR_COS_PARAMETER,    "COS_PARAMETER" },
 };
 static const int attr_str_max = sizeof(attr_str)/sizeof(attr_str[0]);
 
@@ -386,6 +389,8 @@ attrhash_key_make (void *p)
         key += cluster_hash_key_make (attr->extra->cluster);
       if (attr->extra->transit)
         key += transit_hash_key_make (attr->extra->transit);
+      if (attr->extra->cos_class)
+        key += cos_class_hash_make (attr->extra->cos_class);
 
 #ifdef HAVE_IPV6
       {
@@ -434,7 +439,8 @@ attrhash_cmp (const void *p1, const void
           && IPV4_ADDR_SAME (&ae1->mp_nexthop_global_in, &ae2->mp_nexthop_global_in)
           && ae1->ecommunity == ae2->ecommunity
           && ae1->cluster == ae2->cluster
-          && ae1->transit == ae2->transit)
+          && ae1->transit == ae2->transit
+          && ae1->cos_class == ae2->cos_class)
         return 1;
       else if (ae1 || ae2)
         return 0;
@@ -539,6 +545,13 @@ bgp_attr_intern (struct attr *attr)
           else
             attre->transit->refcnt++;
         }
+      if (attre->cos_class)
+        {
+          if (! attre->cos_class->refcnt)
+            attre->cos_class = cos_class_intern (attre->cos_class);
+          else
+            attre->cos_class->refcnt++;
+        }
     }
 
   find = (struct attr *) hash_get (attrhash, attr, bgp_attr_hash_alloc);
@@ -651,6 +664,7 @@ bgp_attr_unintern (struct attr *attr)
   struct ecommunity *ecommunity = NULL;
   struct cluster_list *cluster = NULL;
   struct transit *transit = NULL;
+  struct cos_class *cos_class = NULL;
 
   /* Decrement attribute reference. */
   attr->refcnt--;
@@ -661,6 +675,7 @@ bgp_attr_unintern (struct attr *attr)
       ecommunity = attr->extra->ecommunity;
       cluster = attr->extra->cluster;
       transit = attr->extra->transit;
+      cos_class = attr->extra->cos_class;
     }
 
   /* If reference becomes zero then free attribute object. */
@@ -683,6 +698,8 @@ bgp_attr_unintern (struct attr *attr)
     cluster_unintern (cluster);
   if (transit)
     transit_unintern (transit);
+  if (cos_class)
+    cos_class_unintern (cos_class);
 }
 
 void
@@ -701,6 +718,8 @@ bgp_attr_flush (struct attr *attr)
         cluster_free (attre->cluster);
       if (attre->transit && ! attre->transit->refcnt)
         transit_free (attre->transit);
+      if (attre->cos_class && ! attre->cos_class->refcnt)
+        cos_class_free (attre->cos_class);
     }
 }
 
@@ -1465,6 +1484,7 @@ static int
 bgp_attr_ext_communities (struct peer *peer, bgp_size_t length, 
 			  struct attr *attr, u_char flag)
 {
+  int ret;
   if (length == 0)
     {
       if (attr->extra)
@@ -1472,8 +1492,30 @@ bgp_attr_ext_communities (struct peer *p
     }
   else
     {
+      /* here used to be: 
       (bgp_attr_extra_get (attr))->ecommunity = 
         ecommunity_parse ((u_int8_t *)stream_pnt (peer->ibuf), length);
+       but to use import_peer_qos_table */
+      struct ecommunity tmp;
+      struct ecommunity *new;
+
+      /* Length check.  */
+      if (length % ECOMMUNITY_SIZE)
+        (bgp_attr_extra_get (attr))->ecommunity = NULL;
+      else
+        {
+          /* Prepare tmporary structure for making a new Extended Communities
+             Attribute.  */
+          tmp.size = length / ECOMMUNITY_SIZE;
+          tmp.val = (u_int8_t *)stream_pnt (peer->ibuf);
+
+          /* Create a new Extended Communities Attribute by uniq and sort each
+             Extended Communities value  */
+          new = ecommunity_uniq_sort (&tmp);
+
+          ret = import_peer_qos_table(peer, new->val, (u_int16_t) length);
+          (bgp_attr_extra_get (attr))->ecommunity = ecommunity_intern (new);
+        }
       stream_forward_getp (peer->ibuf, length);
     }
   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
@@ -1701,6 +1743,9 @@ bgp_attr_parse (struct peer *peer, struc
         case BGP_ATTR_AS_PATHLIMIT:
           ret = bgp_attr_aspathlimit (peer, length, attr, flag, startp);
           break;
+	case BGP_ATTR_COS_PARAMETER:
+	  ret = bgp_attr_cos_parameter (peer, length, attr);
+	  break;
 	default:
 	  ret = bgp_attr_unknown (peer, attr, flag, type, length, startp);
 	  break;
@@ -1732,6 +1777,22 @@ bgp_attr_parse (struct peer *peer, struc
 	}
     }
 
+  /* add global cos-parameter to attr if no new one is in update-message */
+  if (!CHECK_BITMAP(seen, BGP_ATTR_COS_PARAMETER) && (peer->global_cos_in != NULL))
+    {
+      struct cos_class *new = create_cos_class(0);
+      struct phb_val *gphb;
+      int j;
+      for (j=0;j<peer->global_cos_in->size;j++)
+        {
+          gphb = (struct phb_val *) &(peer->global_cos_in->val[j*sizeof(struct phb_val)]);
+          set_cos_val (new, gphb->flags, gphb->phb, gphb->tbr.flt, gphb->tbs.flt,
+                       gphb->pdr.flt, gphb->minpu, gphb->maxps, gphb->as);
+        }
+      (bgp_attr_extra_get (attr))->cos_class = cos_class_intern (new);
+      attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COS_PARAMETER_FLAG);
+    }
+
   /* Check final read pointer is same as end pointer. */
   if (BGP_INPUT_PNT (peer) != endp)
     {
@@ -2147,9 +2208,21 @@ bgp_packet_attribute (struct bgp *bgp, s
       && (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES)))
     {
       struct attr_extra *attre = attr->extra;
-      
+      struct qos_table *qos_table;
+      int i;
       assert (attre);
       
+      qos_table = find_active_table(peer);
+      // need to use temporary variable to check the qos-flags 
+      u_int8_t tmp[attre->ecommunity->size * 8 + 1];
+
+      for (i=0;i<attre->ecommunity->size * 8;i++)
+        {
+          tmp[i] = attre->ecommunity->val[i];
+        }
+
+      qos_flag_check_outgoing(qos_table, tmp, attre->ecommunity->size);
+
       if (peer_sort (peer) == BGP_PEER_IBGP 
           || peer_sort (peer) == BGP_PEER_CONFED)
 	{
@@ -2165,7 +2238,7 @@ bgp_packet_attribute (struct bgp *bgp, s
 	      stream_putc (s, BGP_ATTR_EXT_COMMUNITIES);
 	      stream_putc (s, attre->ecommunity->size * 8);
 	    }
-	  stream_put (s, attre->ecommunity->val, attre->ecommunity->size * 8);
+	  stream_put (s, tmp, attre->ecommunity->size * 8);
 	}
       else
 	{
@@ -2176,7 +2249,7 @@ bgp_packet_attribute (struct bgp *bgp, s
 
 	  for (i = 0; i < attre->ecommunity->size; i++)
 	    {
-	      pnt = attre->ecommunity->val + (i * 8);
+	      pnt = tmp + (i * 8);
 	      tbit = *pnt;
 
 	      if (CHECK_FLAG (tbit, ECOMMUNITY_FLAG_NON_TRANSITIVE))
@@ -2202,7 +2275,7 @@ bgp_packet_attribute (struct bgp *bgp, s
 
 	      for (i = 0; i < attre->ecommunity->size; i++)
 		{
-		  pnt = attre->ecommunity->val + (i * 8);
+		  pnt = tmp + (i * 8);
 		  tbit = *pnt;
 
 		  if (CHECK_FLAG (tbit, ECOMMUNITY_FLAG_NON_TRANSITIVE))
@@ -2273,6 +2346,122 @@ bgp_packet_attribute (struct bgp *bgp, s
       stream_putl (s, as);
     }
   
+  /* CoS Parameter Attribute */
+  if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COS_PARAMETER_FLAG))
+    {
+      struct cos_class *cc, *rmcc;
+      struct cos_class * global_cos_out = peer->global_cos_out;
+      struct phb_val * phb;
+      struct del_node * del;
+      int i;
+      int sum=0, dsum=0;
+
+      if (!global_cos_out)
+        {
+          global_cos_out = XCALLOC(MTYPE_COS_CLASS, sizeof(struct cos_class));
+        }
+
+      assert (attr->extra);
+      cc = attr->extra->cos_class;
+      rmcc = get_cos_class(cc->id);
+
+      // Sum up the size of Attributes, including Delete-Nodes
+      for (i=0; i<cc->size; i++)
+        {
+          phb = (struct phb_val*) &cc->val[i*sizeof(struct phb_val)];
+          if (!(phb->flags & BGP_COS_FLAG_GLOBAL) || (phb->flags & BGP_COS_FLAG_GLOBAL && global_cos_out_check(global_cos_out, phb, 0)==2 ))
+            sum++;
+        }
+      if (cc->delqueue)
+        for (del = cc->delqueue; del; del=del->next)
+          if (test_for_target(rmcc, del->phb, peer->as, 0)>0)
+            dsum++;
+
+      if ((sum+dsum)>0)
+        {
+          if ((sum+dsum)*BGP_COS_PARAMETER_SIZE>255)
+            {
+              stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN);
+              stream_putc (s, BGP_ATTR_COS_PARAMETER);
+              stream_putw (s, (sum+dsum)*BGP_COS_PARAMETER_SIZE);
+            } 
+          else
+            {
+              stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
+              stream_putc (s, BGP_ATTR_COS_PARAMETER);
+              stream_putc (s, (sum+dsum)*BGP_COS_PARAMETER_SIZE);
+            }
+          if (sum>0)
+            for (i = 0; i<cc->size; i++)
+              {
+                phb = (struct phb_val*) &cc->val[i*sizeof(struct phb_val)];
+                if (!(phb->flags & BGP_COS_FLAG_GLOBAL) || (phb->flags & BGP_COS_FLAG_GLOBAL && global_cos_out_check(global_cos_out, phb, 1)==1 ))
+                  {
+                    stream_putw (s, phb->phb);
+                    stream_putc (s, phb->flags);
+                    stream_putc (s, 0);
+                    stream_putl (s, phb->as);
+                    stream_putl (s, phb->tbr.toint);
+                    stream_putl (s, phb->tbs.toint);
+                    stream_putl (s, phb->pdr.toint);
+                    stream_putl (s, phb->minpu);
+                    stream_putl (s, phb->maxps);
+                    add_target_as_to_phb_node(rmcc, phb->phb, peer->as);
+                  }
+              }
+          if (dsum>0)
+            {
+              int ret;
+              struct del_node * pred = NULL, * tmp;
+              del = cc->delqueue;
+              while (del)
+                {
+                  ret = test_for_target(rmcc, del->phb, peer->as, 1);
+                  if (ret>=0)
+                    {
+                      stream_putw (s, del->phb);
+                      stream_putc (s, del->flag);
+                      stream_putc (s, 0);
+                      stream_putl (s, 0);
+                      stream_putl (s, 0);
+                      stream_putl (s, 0);
+                      stream_putl (s, 0);
+                      stream_putl (s, 0);
+                      stream_putl (s, 0);
+                      delete_phb_node(global_cos_out, del->phb);
+
+                      if (ret==1)		// no more targets for this phb -> delete node from delqueue
+                        {
+                          if (pred)
+                            pred->next = del->next;
+                          else
+                            {
+                              cc->delqueue = del->next;
+                              rmcc->delqueue = rmcc->delqueue->next;
+                            }
+                          tmp = del;
+                          del = del->next;
+                          XFREE(MTYPE_TMP, tmp);
+                        }
+                    }
+                  if (ret!=1)
+                    {
+                      pred = del;
+                      del = del->next;
+                    }
+                }
+            }
+        }
+
+        if (global_cos_out->size == 0)
+          {
+            XFREE(MTYPE_COS_CLASS, global_cos_out);
+            peer->global_cos_out = NULL;
+          }
+        else
+          peer->global_cos_out = global_cos_out;
+    }
+  
   /* Unknown transit attribute. */
   if (attr->extra && attr->extra->transit)
     stream_put (s, attr->extra->transit->val, attr->extra->transit->length);
@@ -2337,6 +2526,7 @@ bgp_attr_init (void)
   ecommunity_init ();
   cluster_init ();
   transit_init ();
+  cos_parameter_hash_init ();
 }
 
 void
@@ -2348,6 +2538,7 @@ bgp_attr_finish (void)
   ecommunity_finish ();
   cluster_finish ();
   transit_finish ();
+  cos_parameter_hash_finish ();
 }
 
 /* Make attribute packet. */
diff -upwbrN quagga_original/bgpd/bgp_attr.h quagga_cq/bgpd/bgp_attr.h
--- quagga_original/bgpd/bgp_attr.h	2010-05-11 21:25:09.000000000 +0200
+++ quagga_cq/bgpd/bgp_attr.h	2010-05-11 21:28:22.000000000 +0200
@@ -85,6 +85,9 @@ struct attr_extra
   
   /* MP Nexthop length */
   u_char mp_nexthop_len;
+  
+  /* CoS-Table-Class */
+  struct cos_class * cos_class; 
 };
 
 /* BGP core attribute structure. */
diff -upwbrN quagga_original/bgpd/bgp_cos.c quagga_cq/bgpd/bgp_cos.c
--- quagga_original/bgpd/bgp_cos.c	1970-01-01 01:00:00.000000000 +0100
+++ quagga_cq/bgpd/bgp_cos.c	2010-05-11 23:29:33.000000000 +0200
@@ -0,0 +1,884 @@
+/* BGP CoS-Parameter attribute management routines.
+   http://tools.ietf.org/html/draft-knoll-idr-cos-interconnect
+   written by: Simon Ehnert <ehsi@hrz.tu-chemnitz.de>
+               Thomas M. Knoll <knoll@etit.tu-chemnitz.de>
+*/
+#include <zebra.h>
+
+#include "command.h"
+#include "prefix.h"
+#include "plist.h"
+#include "routemap.h"
+#include "buffer.h"
+#include "linklist.h"
+#include "stream.h"
+#include "thread.h"
+#include "log.h"
+#include "memory.h"
+#include "hash.h"
+
+#include "bgpd/bgpd.h"
+#include "bgpd/bgp_attr.h"
+#include "bgpd/bgp_cos.h"
+#include "bgpd/bgp_route.h"
+#include "bgpd/bgp_vty.h"
+
+static struct hash *cos_class_hash;
+int cos_class_size = sizeof (struct phb_val);
+
+/* delete-queue functions */
+
+/* look through the del-queue if there is a node with the given phb,
+   (delete it if necessary and) return NULL if that's the case, return 
+   the last one if not */
+static struct del_node *
+del_node_lookup (struct cos_class *cos_class, u_int16_t phb, int delete)
+{
+  struct del_node *curr = cos_class->delqueue;
+  struct del_node *pred = NULL;
+
+  while (curr)
+    {
+      if (curr->phb == phb)
+        {
+          if (delete)
+            {
+              if (pred)
+                pred->next = curr->next;
+              else
+                cos_class->delqueue = curr->next;
+              XFREE (MTYPE_TMP, curr);
+            }
+          return NULL;
+        }
+      else
+        {
+          pred = curr;
+          curr = curr->next;
+        }
+    }
+  return pred;
+}
+
+static int
+del_node_add (struct cos_class *cos_class, u_int16_t phb, u_int8_t flag)
+{
+  struct del_node *new;
+  struct del_node *pred;
+  new = XMALLOC (MTYPE_TMP, sizeof (struct del_node));
+
+  new->phb = phb;
+  new->flag = flag;
+  new->next = NULL;
+
+  if (cos_class->delqueue)
+    {
+      pred = del_node_lookup (cos_class, phb, 0);
+      if (pred == NULL)
+        return 1;
+      pred->next = new;
+    }
+  else
+    {
+      cos_class->delqueue = new;
+    }
+  return 0;
+}
+
+/* 'show running-config' for 'cos-parameter'-environment */
+int
+bgp_cos_config_write (struct vty *vty)
+{
+  struct bgp *bgp;
+  struct cos_class *cos_class;
+  struct phb_val *phb;
+
+  int i;
+  bgp = bgp_get_default ();
+  if (bgp->cos_table)
+    {
+      if (bgp->cos_table->head)
+        {
+          cos_class = bgp->cos_table->head;
+          while (cos_class)
+            {
+              vty_out (vty, "cos-parameter %d%s", cos_class->id, VTY_NEWLINE);
+              for (i = 0; i < cos_class->size; i++)
+                {
+                  phb =
+                    (struct phb_val *) &cos_class->val[i * cos_class_size];
+                  vty_out (vty, " set cos-node 0x%04x %s %s %f %f %f %d %d%s",
+                           phb->phb,
+                           ((phb->flags & BGP_COS_FLAG_GLOBAL) ? "global" :
+                            "nlri-specific"),
+                           ((phb->flags & BGP_COS_FLAG_HANDLING) ? "remark" :
+                            "drop"), phb->tbr.flt, phb->tbs.flt, phb->pdr.flt,
+                           phb->minpu, phb->maxps, VTY_NEWLINE);
+                }
+              cos_class = cos_class->next;
+            }
+        }
+    }
+  return 1;
+}
+
+/* memory-allocation: cos_class */
+struct cos_class *
+create_cos_class (int id)
+{
+  struct cos_class *new;
+
+  new = XCALLOC (MTYPE_COS_CLASS, sizeof (struct cos_class));
+  new->id = id;
+  new->next = NULL;
+  new->delqueue = NULL;
+  return new;
+}
+
+/* search for the cos_class - create if necessary - and return it */
+struct cos_class *
+get_cos_class (int id)
+{
+  struct bgp *bgp;
+  struct cos_table *table;
+  struct cos_class *new;
+  struct cos_class *pred = NULL;
+
+  bgp = bgp_get_default ();
+
+  if (bgp)
+    {
+      if (bgp->cos_table == NULL)
+        {
+          bgp->cos_table =
+            XCALLOC (MTYPE_COS_TABLE, sizeof (struct cos_table));
+          bgp->cos_table->head = NULL;
+          bgp->cos_table->tail = NULL;
+        }
+      table = bgp->cos_table;
+
+      if (table->head)
+        {
+          pred = table->head;
+          while (pred != NULL)
+            {
+              if (pred->id == id)
+                {
+                  return pred;
+                }
+              else
+                {
+                  pred = pred->next;
+                }
+            }
+        }
+
+      new = create_cos_class (id);
+
+      if (table->tail)
+        table->tail->next = new;
+      table->tail = new;
+      if (table->head == NULL)
+        table->head = new;
+      return new;
+    }
+  return NULL;
+}
+
+/* Duplicate the CoS-Parameter Attribute structure.  */
+static struct cos_class *
+cosclass_dup (struct cos_class *cc)
+{
+  struct cos_class *new;
+
+  new = create_cos_class (cc->id);
+  new->size = cc->size;
+  if (new->size)
+    {
+      new->val = XMALLOC (MTYPE_COSCLASS_VAL, cc->size * cos_class_size);
+      memcpy (new->val, cc->val, cc->size * cos_class_size);
+    }
+  else
+    new->val = NULL;
+  new->delqueue = cc->delqueue; //delqueue is shared
+  return new;
+}
+
+int
+clear_cos_class (struct cos_class *cos_class)
+{
+  if (cos_class->val)
+    {
+      XFREE (MTYPE_COSCLASS_VAL, cos_class->val);
+      cos_class->val = NULL;
+      return 0;
+    }
+  else
+    return -1;
+}
+
+/* delete the cos_class with given id from local cos-table */
+int
+delete_cos_class (int id)
+{
+  struct bgp *bgp;
+  struct cos_table *table;
+  struct cos_class *curr = NULL;
+  struct cos_class *pred = NULL;
+
+  bgp = bgp_get_default ();
+  if (bgp)
+    {
+      if (bgp->cos_table == NULL)
+        return CMD_ERR_NO_MATCH;
+      table = bgp->cos_table;
+
+      if (table->head)
+        {
+          curr = table->head;
+          while (curr != NULL)
+            {
+              if (curr->id == id)
+                {
+                  if (pred)
+                    {
+                      // delete in list or delete last element in list
+                      pred->next = curr->next;
+                      if (curr->next == NULL)
+                        {
+                          table->tail = pred;
+                        }
+                    }
+                  else
+                    {
+                      // delete first element in list
+                      table->head = curr->next;
+                    }
+                  if (!clear_cos_class (curr))
+                    XFREE (MTYPE_COS_CLASS, curr);
+
+                  if (table->head == NULL)
+                    {           // no elements left
+                      table->tail = NULL;
+                      XFREE (MTYPE_COS_TABLE, table);
+                      bgp->cos_table = NULL;
+                    }
+                  return CMD_SUCCESS;
+                }
+              else
+                {
+                  pred = curr;
+                  curr = curr->next;
+                }
+            }
+        }
+    }
+  return CMD_ERR_NO_MATCH;
+}
+
+/* show the cos-class, e.g. 'show ip bgp A.B.C.D' */
+void
+bgp_cos_class_write (struct vty *vty, struct cos_class *cos_class)
+{
+  struct phb_val *phb;
+  int i;
+
+  if (cos_class)
+    {
+      vty_out (vty,
+               "               Flags     Token Bucket        Peak       Minimum     Maximum %s",
+               VTY_NEWLINE);
+      vty_out (vty,
+               "        PHB    G DR     Rate      Size     Data Rate    Pol.Unit   Pack.Size%s",
+               VTY_NEWLINE);
+      for (i = 0; i < cos_class->size; i++)
+        {
+          phb = (struct phb_val *) &cos_class->val[i * cos_class_size];
+          vty_out (vty,
+                   "       0x%04x  %s  %s   %8.2f  %8.2f   %8.2f    %9d   %9d%s",
+                   phb->phb, ((phb->flags & BGP_COS_FLAG_GLOBAL) ? "G" : "N"),
+                   ((phb->flags & BGP_COS_FLAG_HANDLING) ? "R" : "D"),
+                   phb->tbr.flt, phb->tbs.flt, phb->pdr.flt, phb->minpu,
+                   phb->maxps, VTY_NEWLINE);
+        }
+    }
+}
+
+
+/* add phb-value to cos_class with numerical sorting */
+static int
+cos_class_add_val (struct cos_class *cc, struct phb_val *cval)
+{
+  u_int8_t *p;
+  int ret;
+  int c;
+
+  /* When this is the first value, just add it.  */
+  if (cc->val == NULL)
+    {
+      cc->size++;
+      cc->val = XMALLOC (MTYPE_COSCLASS_VAL, cc->size * cos_class_size);
+      memcpy (cc->val, cval, cos_class_size);
+      return 1;
+    }
+
+  /* If the phb-value already exists in the structure change the value.  */
+  c = 0;
+  for (p = cc->val; c < cc->size; p += cos_class_size, c++)
+    {
+      ret = memcmp (p, cval, 2);
+      if (ret == 0)
+        {
+          memcpy (cc->val + c * cos_class_size, cval, cos_class_size);
+          return 1;
+        }
+      if (ret > 0)
+        break;
+    }
+
+  /* Add the value to the structure with numerical sorting.  */
+  cc->size++;
+  cc->val = XREALLOC (MTYPE_COSCLASS_VAL, cc->val, cc->size * cos_class_size);
+
+  memmove (cc->val + (c + 1) * cos_class_size, cc->val + c * cos_class_size,
+           (cc->size - 1 - c) * cos_class_size);
+  memcpy (cc->val + c * cos_class_size, cval, cos_class_size);
+  return 1;
+}
+
+int
+set_cos_val (struct cos_class *cos_class, u_int8_t flags, u_int16_t phb,
+             float tbr, float tbs, float pdr, u_int32_t minpu,
+             u_int32_t maxps, u_int32_t as)
+{
+  struct phb_val cos_val;
+  cos_val.phb = phb;
+  cos_val.flags = flags;
+  cos_val.as = as;
+  cos_val.zero = 0;
+  cos_val.tbr.flt = tbr;
+  cos_val.tbs.flt = tbs;
+  cos_val.pdr.flt = pdr;
+  cos_val.minpu = minpu;
+  cos_val.maxps = maxps;
+
+  return cos_class_add_val (cos_class, &cos_val);
+}
+
+int
+vty_set_cos_val (struct vty *vty, u_int8_t flags, u_int16_t phb, float tbr,
+                 float tbs, float pdr, u_int32_t minpu, u_int32_t maxps)
+{
+  struct cos_class *cos_class = vty->index;
+  struct bgp *bgp;
+  bgp = bgp_get_default ();
+
+  del_node_lookup (cos_class, phb, 1);
+
+  return set_cos_val (cos_class, flags, phb, tbr, tbs, pdr, minpu, maxps,
+                      (u_int32_t) bgp->as);
+}
+
+/* delete phb-node from cos-parameter-table */
+int
+delete_phb_node (struct cos_class *cos, u_int16_t phb)
+{
+  u_int8_t *p;
+  u_int8_t flag;
+  int ret;
+  int c = 0;
+
+  for (p = cos->val; c < cos->size; p += cos_class_size, c++)
+    {
+      ret = memcmp (p, &phb, 2);
+      if (ret == 0)
+        {
+          flag = p[2];
+          memmove (cos->val + (c) * cos_class_size,
+                   cos->val + (c + 1) * cos_class_size,
+                   (cos->size - 1 - c) * cos_class_size);
+
+          cos->size--;
+          return flag;
+        }
+    }
+  return -1;
+}
+
+int
+vty_delete_phb_node (struct vty *vty, u_int16_t phb_id)
+{
+  struct cos_class *cos_class = vty->index;
+
+  int flag;
+
+  flag = delete_phb_node (cos_class, phb_id);
+  if (flag >= 0)
+    {
+      if (del_node_add (cos_class, phb_id, flag))
+        {
+          vty_out (vty, "PHB-Node 0x%04x is already in the delete-queue%s",
+                   phb_id, VTY_NEWLINE);
+        }
+      if (cos_class->size > 0)
+        cos_class->val =
+          XREALLOC (MTYPE_COSCLASS_VAL, cos_class->val,
+                    cos_class->size * cos_class_size);
+      else if (cos_class->delqueue == NULL)
+        {
+          XFREE (MTYPE_COSCLASS_VAL, cos_class->val);
+          cos_class->val = NULL;
+        }
+      return CMD_SUCCESS;
+    }
+  else
+    {
+      vty_out (vty, "There is no CoS-Node 0x%04x.%s", phb_id, VTY_NEWLINE);
+      return CMD_ERR_NO_MATCH;
+    }
+}
+
+static struct target_as *
+new_target ()
+{
+  struct target_as *new;
+  new = XCALLOC (MTYPE_TARGET_AS, sizeof (struct target_as));
+  return new;
+}
+
+int
+add_target_as_to_phb_node (struct cos_class *cc, u_int16_t phb, u_int32_t as)
+{
+  struct target_as *node, *pred;
+  int i;
+
+  /* When this is the first value, just add it.  */
+  if (cc->targets == NULL)
+    {
+      node = new_target ();
+      node->phb = phb;
+      node->size++;
+      node->target = XCALLOC (MTYPE_TARGET_AS_VAL, node->size * 4);
+      node->target[0] = as;
+      cc->targets = node;
+      return 0;
+    }
+
+  /* the phb-column already exists in the target-structure */
+  for (node = cc->targets; node != NULL; node = node->next)
+    {
+      if (node->phb == phb)
+        {
+          for (i = 0; i < node->size; i++)
+            {
+              if (node->target[i] == as)
+                return 0;
+            }
+          node->size++;
+          node->target =
+            XREALLOC (MTYPE_TARGET_AS_VAL, node->target, node->size * 4);
+          node->target[node->size - 1] = as;
+          return 0;
+        }
+      pred = node;
+    }
+
+  /* Add a new phb-column */
+  node = new_target ();
+  node->phb = phb;
+  node->size++;
+  node->target = XCALLOC (MTYPE_TARGET_AS_VAL, node->size * 4);
+  node->target[0] = as;
+  pred->next = node;
+
+  return 0;
+}
+
+int
+test_for_target (struct cos_class *cc, u_int16_t phb, u_int32_t as,
+                 int change)
+{
+  struct target_as *node, *pred = NULL;
+  u_int32_t *pnt;
+  int i = 0;
+
+  for (node = cc->targets; node; node = node->next)
+    {
+      if (node->phb == phb)
+        {
+          pnt = node->target;
+
+          while (i < node->size)
+            {
+              if (pnt[i] == as)
+                {               // AS received this phb, delete from list
+                  if (change)
+                    {
+                      memmove (pnt + i, pnt + (i) + 1,
+                               (node->size - (i + 1)) * 4);
+                      node->size--;
+
+                      if (node->size > 0)
+                        {
+                          node->target =
+                            XREALLOC (MTYPE_TARGET_AS_VAL, node->target,
+                                      node->size * 4);
+                          return 0;     // there are more targets for this phb --> return 0
+                        }
+                      else
+                        {
+                          XFREE (MTYPE_TARGET_AS_VAL, node->target);
+                          if (pred)
+                            pred->next = node->next;
+                          else
+                            cc->targets = node->next;
+                          XFREE (MTYPE_TARGET_AS, node);
+                          return 1;     // no more targets for the phb --> return 1 (delete del_node from del_stack)
+                        }
+                    }
+                  else
+                    {
+                      return 1; // just counting
+                    }
+                }
+              i++;
+            }
+        }
+      pred = node;
+    }
+  return -1;                    // no targets for given phb --> return -1
+}
+
+/* global-list function */
+int
+global_cos_out_check (struct cos_class *global_cos_out, struct phb_val *phb,
+                      int add)
+{
+  struct phb_val *curr;
+  int i;
+  for (i = 0; i < global_cos_out->size; i++)
+    {
+      curr =
+        (struct phb_val *) &global_cos_out->val[i * sizeof (struct phb_val)];
+      if (curr->phb == phb->phb && curr->tbr.toint == phb->tbr.toint
+          && curr->minpu == phb->minpu)
+        return 0;               // Node was sent before, omitting ->return 0
+    }
+  if (add == 0)                 // don't add the node
+    return 2;                   // not in list, not added ->return 2
+  if (add == 1)                 // add the node ->return 1 (via set_cos_val)
+    return set_cos_val (global_cos_out, phb->flags, phb->phb, phb->tbr.flt,
+                        phb->tbs.flt, phb->pdr.flt, phb->minpu, phb->maxps,
+                        phb->as);
+  return 2;
+}
+
+/* Parser for incoming BGP CoS-Parameter attribute */
+int
+bgp_attr_cos_parameter (struct peer *peer, bgp_size_t length,
+                        struct attr *attr)
+{
+  int i, j;
+  int size = length / BGP_COS_PARAMETER_SIZE;
+  u_int8_t *pnt;
+  u_int8_t flag = 0x00;
+  u_int16_t phb = 0x0000;
+  u_int32_t as = 0x00000000;
+  union
+  {
+    float flt;
+    u_int32_t toint;
+  } tbr;
+  union
+  {
+    float flt;
+    u_int32_t toint;
+  } tbs;
+  union
+  {
+    float flt;
+    u_int32_t toint;
+  } pdr;
+  u_int32_t minpu, maxps;
+
+  if (length == 0)
+    {
+      if (attr->extra)
+        attr->extra->cos_class = NULL;
+    }
+  else
+    {
+      struct cos_class *new = create_cos_class (0);
+      struct cos_class *global_cos_in = peer->global_cos_in;
+      struct phb_val *nphb, *gphb;
+
+      if (global_cos_in == NULL)
+        global_cos_in = XCALLOC (MTYPE_COS_CLASS, sizeof (struct cos_class));
+
+      /* Length check.  */
+      if (length % BGP_COS_PARAMETER_SIZE)
+        (bgp_attr_extra_get (attr))->cos_class = NULL;
+      else
+        {
+          pnt = (u_int8_t *) stream_pnt (peer->ibuf);
+
+          for (i = 0; i < size; i++)
+            {
+              phb =
+                ((((u_int16_t) pnt[i * BGP_COS_PARAMETER_SIZE + 0]) << 8) &
+                 0xff00) | (0x00ff & pnt[i * BGP_COS_PARAMETER_SIZE + 1]);
+              flag = pnt[i * BGP_COS_PARAMETER_SIZE + 2];
+              as =
+                ((((u_int32_t) pnt[i * BGP_COS_PARAMETER_SIZE + 4]) << 24) &
+                 0xff000000) |
+                ((((u_int32_t) pnt[i * BGP_COS_PARAMETER_SIZE + 5]) << 16) &
+                 0x00ff0000) |
+                ((((u_int32_t) pnt[i * BGP_COS_PARAMETER_SIZE + 6]) << 8) &
+                 0x0000ff00) |
+                ((((u_int32_t) pnt[i * BGP_COS_PARAMETER_SIZE + 7])) &
+                 0x000000ff);
+              tbr.toint =
+                ((((u_int32_t) pnt[i * BGP_COS_PARAMETER_SIZE + 8]) << 24) &
+                 0xff000000) |
+                ((((u_int32_t) pnt[i * BGP_COS_PARAMETER_SIZE + 9]) << 16) &
+                 0x00ff0000) |
+                ((((u_int32_t) pnt[i * BGP_COS_PARAMETER_SIZE + 10]) << 8) &
+                 0x0000ff00) |
+                ((((u_int32_t) pnt[i * BGP_COS_PARAMETER_SIZE + 11])) &
+                 0x000000ff);
+              if (tbr.toint == 0)
+                {
+                  // rate-zero-update -> delete from global_cos_in if flag = global
+                  if (flag & BGP_COS_FLAG_GLOBAL)
+                    {
+                      delete_phb_node (global_cos_in, phb);
+                    }
+                  continue;
+                }
+              tbs.toint =
+                ((((u_int32_t) pnt[i * BGP_COS_PARAMETER_SIZE + 12]) << 24) &
+                 0xff000000) |
+                ((((u_int32_t) pnt[i * BGP_COS_PARAMETER_SIZE + 13]) << 16) &
+                 0x00ff0000) |
+                ((((u_int32_t) pnt[i * BGP_COS_PARAMETER_SIZE + 14]) << 8) &
+                 0x0000ff00) |
+                ((((u_int32_t) pnt[i * BGP_COS_PARAMETER_SIZE + 15])) &
+                 0x000000ff);
+              pdr.toint =
+                ((((u_int32_t) pnt[i * BGP_COS_PARAMETER_SIZE + 16]) << 24) &
+                 0xff000000) |
+                ((((u_int32_t) pnt[i * BGP_COS_PARAMETER_SIZE + 17]) << 16) &
+                 0x00ff0000) |
+                ((((u_int32_t) pnt[i * BGP_COS_PARAMETER_SIZE + 18]) << 8) &
+                 0x0000ff00) |
+                ((((u_int32_t) pnt[i * BGP_COS_PARAMETER_SIZE + 19])) &
+                 0x000000ff);
+              minpu =
+                ((((u_int32_t) pnt[i * BGP_COS_PARAMETER_SIZE + 20]) << 24) &
+                 0xff000000) |
+                ((((u_int32_t) pnt[i * BGP_COS_PARAMETER_SIZE + 21]) << 16) &
+                 0x00ff0000) |
+                ((((u_int32_t) pnt[i * BGP_COS_PARAMETER_SIZE + 22]) << 8) &
+                 0x0000ff00) |
+                ((((u_int32_t) pnt[i * BGP_COS_PARAMETER_SIZE + 23])) &
+                 0x000000ff);
+              maxps =
+                ((((u_int32_t) pnt[i * BGP_COS_PARAMETER_SIZE + 24]) << 24) &
+                 0xff000000) |
+                ((((u_int32_t) pnt[i * BGP_COS_PARAMETER_SIZE + 25]) << 16) &
+                 0x00ff0000) |
+                ((((u_int32_t) pnt[i * BGP_COS_PARAMETER_SIZE + 26]) << 8) &
+                 0x0000ff00) |
+                ((((u_int32_t) pnt[i * BGP_COS_PARAMETER_SIZE + 27])) &
+                 0x000000ff);
+              set_cos_val (new, flag, phb, tbr.flt, tbs.flt, pdr.flt, minpu,
+                           maxps, as);
+              if (flag & BGP_COS_FLAG_GLOBAL)
+                {               // if parameter has global scope -> add this to global_cos_in
+                  set_cos_val (global_cos_in, flag, phb, tbr.flt, tbs.flt,
+                               pdr.flt, minpu, maxps, as);
+                }
+            }
+          i = 0;
+          j = 0;
+
+          /* add previously received global cos-parameter to the received routes,
+             but the new cos-parameters will not be replaced */
+          while (i < new->size && j < global_cos_in->size)
+            {
+              nphb =
+                (struct phb_val *) &new->val[i * sizeof (struct phb_val)];
+              gphb =
+                (struct phb_val *) &global_cos_in->val[j *
+                                                       sizeof (struct
+                                                               phb_val)];
+              if (nphb->phb < gphb->phb)
+                {
+                  i++;
+                }
+              else if (nphb->phb == gphb->phb)
+                {
+                  i++;
+                  j++;
+                }
+              else if (nphb->phb > gphb->phb)
+                {
+                  set_cos_val (new, gphb->flags, gphb->phb, gphb->tbr.flt,
+                               gphb->tbs.flt, gphb->pdr.flt, gphb->minpu,
+                               gphb->maxps, gphb->as);
+                  j++;
+                }
+            }
+          for (; j < global_cos_in->size; j++)
+            {
+              gphb =
+                (struct phb_val *) &global_cos_in->val[j *
+                                                       sizeof (struct
+                                                               phb_val)];
+              set_cos_val (new, gphb->flags, gphb->phb, gphb->tbr.flt,
+                           gphb->tbs.flt, gphb->pdr.flt, gphb->minpu,
+                           gphb->maxps, gphb->as);
+            }
+          (bgp_attr_extra_get (attr))->cos_class = cos_class_intern (new);
+        }
+      stream_forward_getp (peer->ibuf, length);
+      if (global_cos_in->size == 0)
+        XFREE (MTYPE_COS_CLASS, global_cos_in);
+      else
+        peer->global_cos_in = global_cos_in;
+    }
+  attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COS_PARAMETER_FLAG);
+
+  return 0;
+}
+
+/* route-map functions for `set cos-parameter COSCLASS' */
+
+/* For cos-parameter set. */
+route_map_result_t
+route_set_cos_parameter (void *rule, struct prefix * prefix,
+                         route_map_object_t type, void *object)
+{
+  struct bgp_info *bgp_info;
+  struct cos_class *cos_class;
+
+  if (type == RMAP_BGP)
+    {
+      cos_class = rule;
+      bgp_info = object;
+
+      bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COS_PARAMETER_FLAG);
+      (bgp_attr_extra_get (bgp_info->attr))->cos_class =
+        cosclass_dup (cos_class);
+    }
+  return RMAP_OKAY;
+}
+
+/* Compile function for cos-parameter set. */
+void *
+route_set_cos_parameter_compile (const char *arg)
+{
+  unsigned int id;
+  struct cos_class *cos_class;
+
+  id = (int) strtoul (arg, NULL, 10);
+  cos_class = get_cos_class (id);
+
+  return cos_class;
+}
+
+/* Free route map's compiled `cos-parameter' value. */
+void
+route_set_cos_parameter_free (void *rule)
+{
+  struct cos_class *cos = rule;
+  cos_class_free (cos);
+}
+
+/* Hash-Functions for CoS-Parameter-Attribute */
+/* Initialize CoS-Parameter related hash. */
+void
+cos_parameter_hash_init (void)
+{
+  cos_class_hash = hash_create (cos_class_hash_make, cos_class_cmp);
+}
+
+void
+cos_parameter_hash_finish (void)
+{
+  hash_free (cos_class_hash);
+  cos_class_hash = NULL;
+}
+
+/* Utility function to make hash key.  */
+unsigned int
+cos_class_hash_make (void *arg)
+{
+  const struct cos_class *cos_class = arg;
+  u_int8_t *pnt;
+  int i;
+  unsigned int key = 0;
+
+  pnt = cos_class->val;
+  for (i = 0; i < cos_class->size * cos_class_size; i++)
+    {
+      key += pnt[i];
+    }
+  return key;
+}
+
+/* Compare two CoS-Class Attribute structure.  */
+int
+cos_class_cmp (const void *arg1, const void *arg2)
+{
+  const struct cos_class *cc1 = arg1;
+  const struct cos_class *cc2 = arg2;
+
+  return (cc1->size == cc2->size
+          && memcmp (cc1->val, cc2->val, cc1->size * cos_class_size) == 0);
+}
+
+/* Intern CoS-Parameter Attribute.  */
+struct cos_class *
+cos_class_intern (struct cos_class *cos_class)
+{
+  struct cos_class *find;
+  assert (cos_class->refcnt == 0);
+  find =
+    (struct cos_class *) hash_get (cos_class_hash, cos_class,
+                                   hash_alloc_intern);
+  if (find != cos_class)
+    {
+      cos_class_free (cos_class);
+    }
+  find->refcnt++;
+  return find;
+}
+
+/* Unintern CoS-Parameter Attribute.  */
+void
+cos_class_unintern (struct cos_class *cos_class)
+{
+  struct cos_class *ret;
+
+  if (cos_class->refcnt)
+    cos_class->refcnt--;
+
+  /* Pull off from hash.  */
+  if (cos_class->refcnt == 0)
+    {
+      /* CoS-Class must be in the hash.  */
+      ret = (struct cos_class *) hash_release (cos_class_hash, cos_class);
+      assert (ret != NULL);
+
+      cos_class_free (cos_class);
+    }
+}
+
+void
+cos_class_free (struct cos_class *cos_class)
+{
+  if (cos_class->val)
+    XFREE (MTYPE_COSCLASS_VAL, cos_class->val);
+  XFREE (MTYPE_COS_CLASS, cos_class);
+}
diff -upwbrN quagga_original/bgpd/bgp_cos.h quagga_cq/bgpd/bgp_cos.h
--- quagga_original/bgpd/bgp_cos.h	1970-01-01 01:00:00.000000000 +0100
+++ quagga_cq/bgpd/bgp_cos.h	2010-05-11 21:28:22.000000000 +0200
@@ -0,0 +1,127 @@
+/* BGP CoS-Parameter attribute management routines.
+   http://tools.ietf.org/html/draft-knoll-idr-cos-interconnect
+   written by: Simon Ehnert <ehsi@hrz.tu-chemnitz.de>
+               Thomas M. Knoll <knoll@etit.tu-chemnitz.de>
+*/
+#ifndef _QUAGGA_BGP_COS_H
+#define _QUAGGA_BGP_COS_H
+
+#define BGP_COS_PARAMETER_SIZE        28
+
+#include "routemap.h"
+
+struct target_as
+{
+  u_int16_t phb;                // PHB-ID
+  int size;
+  u_int32_t *target;            // Target-AS
+  struct target_as *next;
+};
+
+struct phb_val
+{
+  u_int16_t phb;
+  u_int8_t flags;
+#define BGP_COS_FLAG_GLOBAL                   (1<<7)
+#define BGP_COS_FLAG_HANDLING                 (1<<6)
+  u_int8_t zero;
+  u_int32_t as;
+  union
+  {
+    float flt;
+    u_int32_t toint;
+  } tbr;
+  union
+  {
+    float flt;
+    u_int32_t toint;
+  } tbs;
+  union
+  {
+    float flt;
+    u_int32_t toint;
+  } pdr;
+  u_int32_t minpu, maxps;
+};
+
+struct cos_class
+{
+  int id;
+  int size;
+  unsigned long refcnt;
+  u_int8_t *val;
+  struct target_as *targets;
+  struct cos_class *next;
+  struct del_node *delqueue;
+};
+
+struct del_node
+{
+  u_int16_t phb;
+  u_int8_t flag;
+  struct del_node *next;
+};
+
+struct cos_table
+{
+  struct cos_class *head;
+  struct cos_class *tail;
+};
+
+/* Add a new CoS-Parameter value to the given CoS-Class */
+extern int set_cos_val (struct cos_class *cos_class, u_int8_t flags,
+                        u_int16_t phb, float tbr, float tbs, float pdr,
+                        u_int32_t minpu, u_int32_t maxps, u_int32_t as);
+/* Writes out the current cos-parameter-configuration (show running-config) */
+extern int bgp_cos_config_write (struct vty *vty);
+
+/* Memory-allocation*/
+extern struct cos_class *create_cos_class (int id);
+/* Lookup the Cos-Class with the given ID, create if necessary */
+extern struct cos_class *get_cos_class (int id);
+/* Remove all values from the CoS-Class */
+extern int clear_cos_class (struct cos_class *cos_class);
+/* Delete the CoS-Class with the given ID */
+extern int delete_cos_class (int id);
+/* Print the current CoS-Class of a specified Prefix (show route) */
+extern void bgp_cos_class_write (struct vty *vty,
+                                 struct cos_class *cos_class);
+/* VTY-function to add a new CoS-Parameter value from vty-configuration */
+extern int vty_set_cos_val (struct vty *vty, u_int8_t flags, u_int16_t phb,
+                            float tbr, float tbs, float pdr, u_int32_t minpu,
+                            u_int32_t maxps);
+/* Delete a CoS-Parameter value with the given PHB from CoS-Class */
+extern int delete_phb_node (struct cos_class *cos, u_int16_t phb);
+/* delete-function called from VTY */
+extern int vty_delete_phb_node (struct vty *vty, u_int16_t phb_id);
+
+/* delete-list functions */
+extern int add_target_as_to_phb_node (struct cos_class *cc, u_int16_t phb,
+                                      u_int32_t as);
+extern int test_for_target (struct cos_class *cos_class, u_int16_t phb,
+                            u_int32_t as, int change);
+
+/* global-list function */
+extern int global_cos_out_check (struct cos_class *global_cos_out,
+                                 struct phb_val *phb, int add);
+/* Parser for incoming CoS-Parameter attribute */
+extern int bgp_attr_cos_parameter (struct peer *peer, bgp_size_t length,
+                                   struct attr *attr);
+
+/* route-map functions for `set cos-parameter COSCLASS' */
+extern route_map_result_t route_set_cos_parameter (void *rule,
+                                                   struct prefix *prefix,
+                                                   route_map_object_t type,
+                                                   void *object);
+extern void *route_set_cos_parameter_compile (const char *arg);
+extern void route_set_cos_parameter_free (void *rule);
+
+/* Hash-Functions for CoS-Parameter-Attribute */
+extern void cos_parameter_hash_init (void);
+extern void cos_parameter_hash_finish (void);
+extern unsigned int cos_class_hash_make (void *arg);
+extern int cos_class_cmp (const void *arg1, const void *arg2);
+extern struct cos_class *cos_class_intern (struct cos_class *cos_class);
+extern void cos_class_unintern (struct cos_class *cos_class);
+extern void cos_class_free (struct cos_class *cos_class);
+#endif
diff -upwbrN quagga_original/bgpd/bgpd.c quagga_cq/bgpd/bgpd.c
--- quagga_original/bgpd/bgpd.c	2010-05-11 21:25:09.000000000 +0200
+++ quagga_cq/bgpd/bgpd.c	2010-05-11 21:28:22.000000000 +0200
@@ -57,6 +57,7 @@ Software Foundation, Inc., 59 Temple Pla
 #include "bgpd/bgp_advertise.h"
 #include "bgpd/bgp_network.h"
 #include "bgpd/bgp_vty.h"
+#include "bgpd/bgp_qos.h"
 #ifdef HAVE_SNMP
 #include "bgpd/bgp_snmp.h"
 #endif /* HAVE_SNMP */
@@ -875,6 +876,11 @@ peer_create (union sockunion *su, struct
   if (! active && peer_active (peer))
     bgp_timer_set (peer);
 
+  /* QoS-Table for peer */
+  peer->qos_table = NULL;
+  peer->global_cos_in = NULL;
+  peer->global_cos_out = NULL;
+
   return peer;
 }
 
@@ -1956,6 +1962,10 @@ bgp_create (as_t *as, const char *name)
   if (name)
     bgp->name = strdup (name);
 
+  /* CoS-Table for BGP-Struct */
+  bgp->cos = 0;
+  bgp->cos_table = NULL;
+  
   return bgp;
 }
 
@@ -4724,6 +4734,21 @@ bgp_config_write_peer (struct vty *vty, 
 		vty_out (vty, " no neighbor %s activate%s", addr, VTY_NEWLINE);
 	    }
 	}
+
+      if (peer->qos_pbit==1)
+        vty_out (vty, " neighbor %s preserve-qos%s", addr, VTY_NEWLINE);
+
+      if (peer->dscp_reset)
+        {
+          struct dscp_res * dscp_reset = peer->dscp_reset;
+          vty_out (vty, " neighbor %s reset-dscp", addr);
+          while (dscp_reset)
+            {
+              vty_out (vty, " 0x%02x", dscp_reset->dscp);
+              dscp_reset = dscp_reset->next;
+            }
+          vty_out (vty, "%s", VTY_NEWLINE);
+        }
     }
 
 
@@ -5022,6 +5047,34 @@ bgp_config_write (struct vty *vty)
 	vty_out (vty, " bgp default local-preference %d%s",
 		 bgp->default_local_pref, VTY_NEWLINE);
 
+      /* BGP CoS-Capability */
+      if (bgp->cos > (u_int8_t) 0x00)
+        {
+          int first = 1;
+          vty_out (vty, " bgp cos-capability ");
+          if (bgp->cos & (u_int8_t) 0x80)
+            {
+              vty_out (vty, "BE");
+              first = 0;
+            }
+          if (bgp->cos & (u_int8_t) 0x40)
+            {
+              vty_out (vty, "%sEF", (first)? "" : ",");
+              first = 0;
+            }
+          if (bgp->cos & (u_int8_t) 0x20)
+            {
+              vty_out (vty, "%sAF", (first)? "" : ",");
+              first = 0;
+            }
+          if (bgp->cos & (u_int8_t) 0x10)
+            {
+              vty_out (vty, "%sLE", (first)? "" : ",");
+              first = 0;
+            }
+          vty_out (vty, "%s", VTY_NEWLINE);
+        }
+
       /* BGP client-to-client reflection. */
       if (bgp_flag_check (bgp, BGP_FLAG_NO_CLIENT_TO_CLIENT))
 	vty_out (vty, " no bgp client-to-client reflection%s", VTY_NEWLINE);
diff -upwbrN quagga_original/bgpd/bgpd.h quagga_cq/bgpd/bgpd.h
--- quagga_original/bgpd/bgpd.h	2010-05-11 21:25:09.000000000 +0200
+++ quagga_cq/bgpd/bgpd.h	2010-05-11 21:28:22.000000000 +0200
@@ -24,6 +24,14 @@ Software Foundation, Inc., 59 Temple Pla
 /* For union sockunion.  */
 #include "sockunion.h"
 
+struct qos_table
+{
+  char* name;
+  struct qos_table *next;
+  struct techtype *techhead;
+  struct qos_set *head;
+};
+
 /* Typedef BGP specific types.  */
 typedef u_int32_t as_t;
 typedef u_int16_t as16_t; /* we may still encounter 16 Bit asnums */
@@ -162,6 +170,15 @@ struct bgp 
   /* BGP graceful restart */
   u_int32_t restart_time;
   u_int32_t stalepath_time;
+  
+  /* BGP CoS-Capability and Parameter-Table */
+  u_int8_t cos;
+#define BGP_COS_CAPABILITY_EF             (1 << 6)
+#define BGP_COS_CAPABILITY_AF             (1 << 5)
+#define BGP_COS_CAPABILITY_BE             (1 << 7)
+#define BGP_COS_CAPABILITY_LE             (1 << 4)
+
+  struct cos_table * cos_table; 
 };
 
 /* BGP peer-group support. */
@@ -541,6 +558,12 @@ struct peer
 #define PEER_RMAP_TYPE_NOSET          (1 << 5) /* not allow to set commands */
 #define PEER_RMAP_TYPE_IMPORT         (1 << 6) /* neighbor route-map import */
 #define PEER_RMAP_TYPE_EXPORT         (1 << 7) /* neighbor route-map export */
+
+  struct qos_table* qos_table;
+  struct dscp_res * dscp_reset;
+  int qos_pbit;
+  struct cos_class * global_cos_out;
+  struct cos_class * global_cos_in;
 };
 
 #define PEER_PASSWORD_MINLEN	(1)
@@ -615,6 +638,9 @@ struct bgp_nlri
 #define BGP_ATTR_AS4_PATH                       17
 #define BGP_ATTR_AS4_AGGREGATOR                 18
 #define BGP_ATTR_AS_PATHLIMIT                   21
+/* Flags for CoS-Parameter */
+#define BGP_ATTR_COS_PARAMETER_FLAG             32
+#define BGP_ATTR_COS_PARAMETER                 255 
 
 /* BGP update origin.  */
 #define BGP_ORIGIN_IGP                           0
@@ -759,7 +785,8 @@ enum bgp_clear_type
   BGP_CLEAR_SOFT_IN,
   BGP_CLEAR_SOFT_BOTH,
   BGP_CLEAR_SOFT_IN_ORF_PREFIX,
-  BGP_CLEAR_SOFT_RSCLIENT
+  BGP_CLEAR_SOFT_RSCLIENT,
+  BGP_CLEAR_SOFT_PREFIX		// added bgp_clear_type for prefix-specific clearing
 };
 
 /* Macros. */
diff -upwbrN quagga_original/bgpd/bgp_ecommunity.c quagga_cq/bgpd/bgp_ecommunity.c
--- quagga_original/bgpd/bgp_ecommunity.c	2010-05-11 21:25:09.000000000 +0200
+++ quagga_cq/bgpd/bgp_ecommunity.c	2010-05-11 21:28:22.000000000 +0200
@@ -33,7 +33,8 @@ Software Foundation, Inc., 59 Temple Pla
 static struct hash *ecomhash;
 
 /* Allocate a new ecommunities.  */
-static struct ecommunity *
+/* this function was static, now public for qos */
+struct ecommunity *
 ecommunity_new (void)
 {
   return (struct ecommunity *) XCALLOC (MTYPE_ECOMMUNITY,
@@ -56,7 +57,8 @@ ecommunity_free (struct ecommunity *ecom
    structure, we don't add the value.  Newly added value is sorted by
    numerical order.  When the value is added to the structure return 1
    else return 0.  */
-static int
+/* this function was static, now public for qos */
+int
 ecommunity_add_val (struct ecommunity *ecom, struct ecommunity_val *eval)
 {
   u_int8_t *p;
@@ -98,7 +100,8 @@ ecommunity_add_val (struct ecommunity *e
 /* This function takes pointer to Extended Communites strucutre then
    create a new Extended Communities structure by uniq and sort each
    Extended Communities value.  */
-static struct ecommunity *
+/* this function was static, now public for qos */
+struct ecommunity *
 ecommunity_uniq_sort (struct ecommunity *ecom)
 {
   int i;
@@ -591,6 +594,7 @@ ecommunity_ecom2str (struct ecommunity *
   const char *prefix;
   int len = 0;
   int first = 1;
+  int is_regular_type = 0;
 
   /* For parse Extended Community attribute tupple. */
   struct ecommunity_as
@@ -605,6 +609,11 @@ ecommunity_ecom2str (struct ecommunity *
     u_int16_t val;
   } eip;
 
+  struct ecommunity_cos
+  {
+    u_int8_t capability;
+  } ecos;
+
   if (ecom->size == 0)
     {
       str_buf = XMALLOC (MTYPE_ECOMMUNITY_STR, 1);
@@ -627,8 +636,10 @@ ecommunity_ecom2str (struct ecommunity *
 
       /* High-order octet of type. */
       encode = *pnt++;
+      /* added qos-marking here */
       if (encode != ECOMMUNITY_ENCODE_AS && encode != ECOMMUNITY_ENCODE_IP
-		      && encode != ECOMMUNITY_ENCODE_AS4)
+		      && encode != ECOMMUNITY_ENCODE_AS4 && encode != ECOMMUNITY_QOS_MARKING_TRANS
+		      && encode != ECOMMUNITY_QOS_MARKING_NTRANS && encode != ECOMMUNITY_COS_CAPABILITY)
 	{
 	  len = sprintf (str_buf + str_pnt, "?");
 	  str_pnt += len;
@@ -636,22 +647,36 @@ ecommunity_ecom2str (struct ecommunity *
 	  continue;
 	}
       
+      if (encode == ECOMMUNITY_QOS_MARKING_TRANS || encode == ECOMMUNITY_QOS_MARKING_NTRANS || encode == ECOMMUNITY_COS_CAPABILITY)
+        is_regular_type = 1;
+      else
+        {
       /* Low-order octet of type. */
       type = *pnt++;
-      if (type !=  ECOMMUNITY_ROUTE_TARGET && type != ECOMMUNITY_SITE_ORIGIN)
+          if (type !=  ECOMMUNITY_ROUTE_TARGET && type != ECOMMUNITY_SITE_ORIGIN && is_regular_type!=1)
 	{
 	  len = sprintf (str_buf + str_pnt, "?");
 	  str_pnt += len;
 	  first = 0;
 	  continue;
 	}
-
+        }
       switch (format)
 	{
 	case ECOMMUNITY_FORMAT_COMMUNITY_LIST:
+          if (encode == ECOMMUNITY_QOS_MARKING_TRANS || encode == ECOMMUNITY_QOS_MARKING_NTRANS)
+            prefix = "qos ";
+          else if (encode == ECOMMUNITY_COS_CAPABILITY)
+            prefix = "cos ";
+          else
 	  prefix = (type == ECOMMUNITY_ROUTE_TARGET ? "rt " : "soo ");
 	  break;
 	case ECOMMUNITY_FORMAT_DISPLAY:
+          if (encode == ECOMMUNITY_QOS_MARKING_TRANS || encode == ECOMMUNITY_QOS_MARKING_NTRANS)
+            prefix = "QoS";
+          else if (encode == ECOMMUNITY_COS_CAPABILITY)
+            prefix = "CoS-Cap:";
+          else
 	  prefix = (type == ECOMMUNITY_ROUTE_TARGET ? "RT:" : "SoO:");
 	  break;
 	case ECOMMUNITY_FORMAT_ROUTE_MAP:
@@ -685,6 +710,43 @@ ecommunity_ecom2str (struct ecommunity *
 	  str_pnt += len;
 	  first = 0;
 	}
+      if (encode == ECOMMUNITY_QOS_MARKING_TRANS || encode == ECOMMUNITY_QOS_MARKING_NTRANS)
+        {
+          /* The Lists of QoS-Marking-Ecommunities will be created later */
+          len = sprintf( str_buf + str_pnt, "%s", prefix);
+          str_pnt += len;
+          
+          first = 0;
+        }
+      if (encode == ECOMMUNITY_COS_CAPABILITY)
+        {
+          ecos.capability = (*pnt++);
+          int one=1;
+          len = sprintf (str_buf + str_pnt, "%s", prefix);
+          str_pnt += len;
+          if (ecos.capability & (u_int8_t) 0x80) {
+            len = sprintf (str_buf + str_pnt, "%s", "BE");
+            str_pnt += len;
+            one=0;
+          }
+          if (ecos.capability & (u_int8_t) 0x40) {
+            len = sprintf (str_buf + str_pnt, "%s%s", (one)? "" : ",", "EF");
+            str_pnt += len;
+            one=0;
+          }
+          if (ecos.capability & (u_int8_t) 0x20) {
+            len = sprintf (str_buf + str_pnt, "%s%s", (one)? "" : ",", "AF");
+            str_pnt += len;
+            one=0;
+          }
+          if (ecos.capability & (u_int8_t) 0x10) {
+            len = sprintf (str_buf + str_pnt, "%s%s", (one)? "" : ",", "LE");
+            str_pnt += len;
+            one=0;
+          }
+          str_pnt += len;
+          first = 0;
+        }
       if (encode == ECOMMUNITY_ENCODE_AS)
 	{
 	  eas.as = (*pnt++ << 8);
diff -upwbrN quagga_original/bgpd/bgp_ecommunity.h quagga_cq/bgpd/bgp_ecommunity.h
--- quagga_original/bgpd/bgp_ecommunity.h	2010-05-11 21:25:09.000000000 +0200
+++ quagga_cq/bgpd/bgp_ecommunity.h	2010-05-11 21:28:22.000000000 +0200
@@ -25,6 +25,9 @@ Software Foundation, Inc., 59 Temple Pla
 #define ECOMMUNITY_ENCODE_AS                0x00
 #define ECOMMUNITY_ENCODE_IP                0x01
 #define ECOMMUNITY_ENCODE_AS4               0x02
+#define ECOMMUNITY_QOS_MARKING_TRANS        0x04
+#define ECOMMUNITY_COS_CAPABILITY           0x05
+#define ECOMMUNITY_QOS_MARKING_NTRANS       0x44
 
 /* Low-order octet of the Extended Communityes type field.  */
 #define ECOMMUNITY_ROUTE_TARGET             0x02
@@ -68,6 +71,8 @@ struct ecommunity_val
 extern void ecommunity_init (void);
 extern void ecommunity_finish (void);
 extern void ecommunity_free (struct ecommunity *);
+extern struct ecommunity *ecommunity_uniq_sort (struct ecommunity *ecom);
+extern struct ecommunity *ecommunity_new (void);
 extern struct ecommunity *ecommunity_parse (u_int8_t *, u_short);
 extern struct ecommunity *ecommunity_dup (struct ecommunity *);
 extern struct ecommunity *ecommunity_merge (struct ecommunity *, struct ecommunity *);
@@ -79,5 +84,6 @@ extern struct ecommunity *ecommunity_str
 extern char *ecommunity_ecom2str (struct ecommunity *, int);
 extern int ecommunity_match (const struct ecommunity *, const struct ecommunity *);
 extern char *ecommunity_str (struct ecommunity *);
+extern int ecommunity_add_val (struct ecommunity *ecom, struct ecommunity_val *eval);
 
 #endif /* _QUAGGA_BGP_ECOMMUNITY_H */
diff -upwbrN quagga_original/bgpd/bgp_packet.c quagga_cq/bgpd/bgp_packet.c
--- quagga_original/bgpd/bgp_packet.c	2010-05-11 21:25:09.000000000 +0200
+++ quagga_cq/bgpd/bgp_packet.c	2010-05-11 21:28:22.000000000 +0200
@@ -47,6 +47,7 @@ Software Foundation, Inc., 59 Temple Pla
 #include "bgpd/bgp_mplsvpn.h"
 #include "bgpd/bgp_advertise.h"
 #include "bgpd/bgp_vty.h"
+#include "bgpd/bgp_cos.h"
 
 int stream_put_prefix (struct stream *, struct prefix *);
 
@@ -1795,6 +1796,8 @@ bgp_update_receive (struct peer *peer, b
         cluster_unintern (attr.extra->cluster);
       if (attr.extra->transit)
         transit_unintern (attr.extra->transit);
+      if (attr.extra->cos_class)
+        cos_class_unintern (attr.extra->cos_class);
       bgp_attr_extra_free (&attr);
     }
 
@@ -1842,6 +1845,19 @@ bgp_notify_receive (struct peer *peer, b
       memcpy (peer->notify.data, stream_pnt (peer->ibuf), size - 2);
     }
 
+  /* delete global cos lists by receiving a NOTIFICATION */
+  if (peer->global_cos_in!=NULL) {
+    clear_cos_class (peer->global_cos_in);
+    XFREE(MTYPE_COS_CLASS, peer->global_cos_in);
+    peer->global_cos_in=NULL;
+  }
+
+  if (peer->global_cos_out!=NULL) {
+    clear_cos_class (peer->global_cos_out);
+    XFREE(MTYPE_COS_CLASS, peer->global_cos_out);
+    peer->global_cos_out=NULL;
+  }
+
   /* For debug */
   {
     int i;
diff -upwbrN quagga_original/bgpd/bgp_qos.c quagga_cq/bgpd/bgp_qos.c
--- quagga_original/bgpd/bgp_qos.c	1970-01-01 01:00:00.000000000 +0100
+++ quagga_cq/bgpd/bgp_qos.c	2010-05-11 21:28:22.000000000 +0200
@@ -0,0 +1,1187 @@
+/* BGP CoS-Capability and QoS Marking attribute management routines.
+   http://tools.ietf.org/html/draft-knoll-idr-cos-interconnect
+   http://tools.ietf.org/html/draft-knoll-idr-qos-attribute
+   written by: Simon Ehnert <ehsi@hrz.tu-chemnitz.de>
+               Thomas M. Knoll <knoll@etit.tu-chemnitz.de>
+*/
+#include <zebra.h>
+
+#include "command.h"
+#include "prefix.h"
+#include "plist.h"
+#include "routemap.h"
+#include "buffer.h"
+#include "linklist.h"
+#include "stream.h"
+#include "thread.h"
+#include "log.h"
+#include "memory.h"
+#include "hash.h"
+
+#include "bgpd/bgpd.h"
+#include "bgpd/bgp_attr.h"
+#include "bgpd/bgp_ecommunity.h"
+#include "bgpd/bgp_qos.h"
+#include "bgpd/bgp_route.h"
+#include "bgpd/bgp_vty.h"
+
+/* Head of the QoS-Table of the local router */
+struct qos_local_tables qos_local_tables = { NULL, NULL };
+
+/* 'show running-config' for 'qos-marking'-environment */
+int
+bgp_qos_config_write (struct vty *vty)
+{
+  struct techtype *tech;
+  struct qos_table *index;
+  struct qos_set *qosc;
+  struct marking_node *mnode;
+  const char *trans;
+
+  for (index = qos_local_tables.head; index; index = index->next)
+    {
+      tech = index->techhead;
+      qosc = index->head;
+      if ((tech) || (qosc))
+        vty_out (vty, "qos-marking %s%s", index->name, VTY_NEWLINE);
+      if (tech)
+        while (1)
+          {
+            vty_out (vty, " set technology-type %s 0x%02X%s", tech->name,
+                     tech->tech_id, VTY_NEWLINE);
+            if (tech->next)
+              tech = tech->next;
+            else
+              break;
+          }
+      if (qosc)
+        {
+          while (1)
+            {
+              vty_out (vty, " set qos-set %s 0x%02X%s", qosc->name,
+                       qosc->qos_number, VTY_NEWLINE);
+              mnode = qosc->nodehead;
+              while (mnode)
+                {
+                  if (mnode->transitive)
+                    trans = "transitive";
+                  else
+                    trans = "non-transitive";
+                  vty_out (vty, " set qos-marking %s 0x%02X 0x%02X 0x%04X%s",
+                           trans, qosc->qos_number, mnode->tech_id,
+                           mnode->mark_o, VTY_NEWLINE);
+                  mnode = mnode->next;
+                }
+              if (qosc->next)
+                qosc = qosc->next;
+              else
+                break;
+            }
+        }
+    }
+  return 1;
+}
+
+/* Initialisation of qos-marking for VTY */
+
+int
+qos_marking_init (struct vty *vty, const char *name)
+{
+  struct qos_table *qos_table;
+
+  qos_table = get_qos_table_by_name (name);
+
+  vty->index = qos_table;
+  return CMD_SUCCESS;
+}
+
+/* Clearing the given QoS-Table */
+static int
+clear_qos_table (struct qos_table *qos_table)
+{
+  int ret;
+  assert (qos_table);
+
+  do
+    {
+      ret = techtype_delete (qos_table, qos_table->techhead->tech_id);
+    }
+  while (qos_table->techhead != NULL);
+  while (qos_table->head != NULL)
+    {
+      ret = qos_set_delete (qos_table, qos_table->head->qos_number);
+    }
+  return 0;
+}
+
+/*  */
+int
+qos_marking_delete (const char *name)
+{
+  struct qos_table *qos_table;
+  struct qos_table *pred;
+  char *tmpname;
+  int ret;
+
+  qos_table = qos_local_tables.head;
+
+  if (qos_table == NULL)
+    {                           /* no tables at all */
+      return CMD_ERR_NO_MATCH;
+    }
+  if (strcmp (qos_table->name, name) == 0)
+    {                           /* found qos_table with given name as head */
+      ret = clear_qos_table (qos_table);
+      qos_local_tables.head = (qos_table->next) ? qos_table->next : NULL;
+      /* the next qos_table becomes the new head */
+      tmpname = qos_table->name;
+      XFREE (MTYPE_QOS_TABLE, qos_table);       /* delete */
+      XFREE (MTYPE_QOS_TABLE_NAME, tmpname);    /* delete the name */
+      return CMD_SUCCESS;
+    }
+  pred = qos_table;
+  qos_table = qos_table->next;
+
+  while (qos_table->next != NULL && (strcmp (qos_table->name, name) != 0))
+    {                           /* walk through existing tables */
+      pred = qos_table;
+      qos_table = qos_table->next;
+    }
+  if (strcmp (qos_table->name, name) == 0)
+    {
+      ret = clear_qos_table (qos_table);
+      pred->next = qos_table->next;
+      if (qos_local_tables.tail == qos_table)   /* if qos_table is the last table, */
+        qos_local_tables.tail = pred;   /* pred becomes the new tail */
+
+      tmpname = qos_table->name;        /* delete as above */
+      XFREE (MTYPE_QOS_TABLE, qos_table);
+      XFREE (MTYPE_QOS_TABLE_NAME, tmpname);
+      return CMD_SUCCESS;
+    }
+  else
+    return CMD_ERR_NO_MATCH;    /* there is no table with the given name */
+}
+
+/* Allocate a new qos-node-structure */
+struct qos_table *
+new_qos_table (const char *name)
+{
+  struct qos_table *new;
+
+  new = XCALLOC (MTYPE_QOS_TABLE, sizeof (struct qos_table));
+  new->name = XSTRDUP (MTYPE_QOS_TABLE_NAME, name);
+  new->head = NULL;
+  new->techhead = NULL;
+  return new;
+}
+
+/* find a table with the given name, or create a new one */
+struct qos_table *
+get_qos_table_by_name (const char *name)
+{
+  struct qos_table *ret;
+  int temp;
+  ret = qos_local_tables.head;
+
+  if (ret == NULL)
+    {                           /* no tables, create the first */
+      ret = new_qos_table (name);
+      ret->next = NULL;
+
+      temp = techtype_add (ret, "IP_DiffServ", 0);      /* default technology-types */
+      temp = techtype_add (ret, "Ethernet", 1); /* http://tools.ietf.org/html/draft-knoll-idr-qos-attribute#section-4.3 */
+      temp = techtype_add (ret, "MPLS_E-LSP", 2);
+      temp = techtype_add (ret, "VirtualChannel", 3);
+      temp = techtype_add (ret, "GMPLS_time", 4);
+      temp = techtype_add (ret, "GMPLS_lambda", 5);
+      temp = techtype_add (ret, "GMPLS_fibre", 6);
+
+      qos_local_tables.head = ret;      /* linking in structure */
+      qos_local_tables.tail = ret;
+      return ret;
+    }
+  while (ret)
+    {                           /* walk through existing tables */
+      if (strcmp (ret->name, name) == 0)        /* if table with given name exists, return it */
+        return ret;
+      else                      /* next table */
+        ret = ret->next;
+    }                           /* if there is no table with the given name */
+  ret = new_qos_table (name);   /* create a new one */
+  ret->next = NULL;
+
+  temp = techtype_add (ret, "IP_DiffServ", 0);  /* default technology-types */
+  temp = techtype_add (ret, "Ethernet", 1);     /* http://tools.ietf.org/html/draft-knoll-idr-qos-attribute#section-4.3 */
+  temp = techtype_add (ret, "MPLS_E-LSP", 2);
+  temp = techtype_add (ret, "VirtualChannel", 3);
+  temp = techtype_add (ret, "GMPLS_time", 4);
+  temp = techtype_add (ret, "GMPLS_lambda", 5);
+  temp = techtype_add (ret, "GMPLS_fibre", 6);
+
+  qos_local_tables.tail->next = ret;    /* linking in structure */
+  qos_local_tables.tail = ret;
+  return ret;                   /* return new table */
+}
+
+/* Find Techtype by a given ID */
+struct techtype *
+techtype_lookup_by_id (struct qos_table *list, int id)
+{
+  struct techtype *tech;
+
+  for (tech = list->techhead; tech; tech = tech->next)
+    if (tech->tech_id == id)
+      return tech;
+  return NULL;
+}
+
+/* Find QoS-Set by a given ID */
+struct qos_set *
+qos_set_lookup_by_id (struct qos_table *list, int id)
+{
+  struct qos_set *qosc;
+
+  for (qosc = list->head; qosc; qosc = qosc->next)
+    if (qosc->qos_number == id)
+      return qosc;
+  return NULL;
+}
+
+/* Allocate a new techtype-structure, name and id must be specified */
+struct techtype *
+techtype_new (int id, const char *name)
+{
+  struct techtype *new;
+
+  new = XCALLOC (MTYPE_TECH_TYPE, sizeof (struct techtype));
+  new->name = XSTRDUP (MTYPE_TECH_TYPE_NAME, name);
+  new->tech_id = id;
+  return new;
+}
+
+/* Allocate a new qos-set-structure */
+struct qos_set *
+qos_set_new (int id, const char *name)
+{
+  struct qos_set *new;
+
+  new = XCALLOC (MTYPE_QOS_SET, sizeof (struct qos_set));
+  new->name = XSTRDUP (MTYPE_QOS_SET_NAME, name);
+  new->nodehead = NULL;
+  new->nodetail = NULL;
+  new->qos_number = id;
+  return new;
+}
+
+/* insert a new qos-set to qos_table */
+int
+qos_set_add (struct qos_table *list, const char *name, int id)
+{
+  struct qos_set *new;
+  struct qos_set *qos_node;
+  char name_tmp[7];
+
+  // construct name as "qos_hex", if name pointer == NULL
+  if (!name)
+    {
+      sprintf (name_tmp, "qos_%02x", id);
+      name = strdup (name_tmp);
+    }
+
+  //insertion-sort
+  if (list->head)
+    {
+      qos_node = list->head;
+      while (qos_node)
+        {
+          if ((qos_node->qos_number < id))
+            {                   /* if id of new qos_set is greater */
+              if (qos_node->next)
+                {               /* with ->next */
+                  qos_node = qos_node->next;
+                }
+              else
+                {               /* without ->next */
+                  new = qos_set_new (id, name); /* create a new and add to list */
+                  new->next = NULL;
+                  new->prev = qos_node;
+                  qos_node->next = new;
+                  return 0;
+                }
+            }
+          else if (qos_node->qos_number > id)
+            {                   /* if id of new qos_set is lower */
+              if (qos_node->prev)
+                {               /* with predecessor */
+                  new = qos_set_new (id, name);
+                  new->next = qos_node;
+                  new->prev = qos_node->prev;
+                  new->next->prev = new;
+                  new->prev->next = new;
+                  return 0;
+                }
+              else
+                {               /* without predecessor */
+                  new = qos_set_new (id, name);
+                  new->next = qos_node;
+                  new->prev = NULL;
+                  new->next->prev = new;
+                  list->head = new;
+                  return 0;
+                }
+            }
+          else
+            {                   /* qos_set with given id exists */
+              return -1;
+            }
+        }
+    }
+  else
+    {                           /* list is empty, create the first */
+      new = qos_set_new (id, name);
+      new->next = NULL;
+      list->head = new;
+      return 0;
+    }
+  return -2;
+}
+
+/* delete qos-set from table */
+int
+qos_set_delete (struct qos_table *list, int id)
+{
+  struct qos_set *qosc;
+  char *name;
+  int tmp;
+
+  qosc = qos_set_lookup_by_id (list, id);
+  name = qosc->name;
+
+  while (qosc->nodehead != NULL)
+    {                           /* delete the qos_markings that belong to qos_set */
+      tmp = delete_marking_node (qosc, qosc->nodehead->tech_id);
+    }
+
+  if ((list->head == qosc) && (qosc->next == NULL))
+    {                           /* last qos_set in list */
+      list->head = NULL;
+    }
+  else
+    {
+      if (qosc->next)           /* with successor */
+        qosc->next->prev = qosc->prev;
+      else                      /* without successor */
+        qosc->prev->next = NULL;
+
+      if (qosc->prev)           /* with predecessor */
+        qosc->prev->next = qosc->next;
+      else                      /* without pred */
+        list->head = qosc->next;
+    }
+  XFREE (MTYPE_QOS_SET, qosc);  /* delete */
+  if (name)
+    XFREE (MTYPE_QOS_SET_NAME, name);
+
+  return CMD_SUCCESS;
+}
+
+/* add a new techtype to table */
+int
+techtype_add (struct qos_table *list, const char *name, int id)
+{
+  struct techtype *new;
+  struct techtype *tech;
+
+  //insertion-sort like qos_set_add
+  if (list->techhead)
+    {
+      tech = list->techhead;
+      while (tech)
+        {
+          if ((tech->tech_id < id))
+            {
+              if (tech->next)
+                {
+                  tech = tech->next;
+                }
+              else
+                {
+                  new = techtype_new (id, name);
+                  new->next = NULL;
+                  new->prev = tech;
+                  tech->next = new;
+                  return 0;
+                }
+            }
+          else if (tech->tech_id > id)
+            {
+              if (tech->prev)
+                {
+                  new = techtype_new (id, name);
+                  new->next = tech;
+                  new->prev = tech->prev;
+                  new->next->prev = new;
+                  new->prev->next = new;
+                  return 0;
+                }
+              else
+                {
+                  new = techtype_new (id, name);
+                  new->next = tech;
+                  new->prev = NULL;
+                  new->next->prev = new;
+                  list->techhead = new;
+                  return 0;
+                }
+            }
+          else
+            {
+              return -1;
+            }
+        }
+    }
+  else
+    {
+      new = techtype_new (id, name);
+      new->next = NULL;
+      new->prev = NULL;
+      list->techhead = new;
+      return 0;
+    }
+  return -2;
+}
+
+/* delete technology-type from table */
+int
+techtype_delete (struct qos_table *list, u_int8_t id)
+{
+  struct techtype *tech;
+  struct qos_set *qosc;
+  char *name;
+  int tmp;
+
+  tech = techtype_lookup_by_id (list, id);
+  name = tech->name;
+
+  for (qosc = list->head; qosc != NULL; qosc = qosc->next)
+    {                           /* delete the qos_markings that belong to techtype */
+      tmp = delete_marking_node (qosc, id);
+    }
+
+  /* delete like qos_set_delete */
+  if ((list->techhead == tech) && (tech->next == NULL))
+    {
+      list->techhead = NULL;
+    }
+  else
+    {
+      if (tech->next)
+        tech->next->prev = tech->prev;
+      else
+        tech->prev->next = NULL;
+
+      if (tech->prev)
+        tech->prev->next = tech->next;
+      else
+        list->techhead = tech->next;
+    }
+  XFREE (MTYPE_TECH_TYPE, tech);
+  if (name)
+    XFREE (MTYPE_TECH_TYPE_NAME, name);
+  return CMD_SUCCESS;
+}
+
+/* Allocate a new qos-node-structure */
+struct marking_node *
+new_qosmarking_node (int tech, int trans)
+{
+  struct marking_node *new;
+
+  new = XCALLOC (MTYPE_QOSMARKING_NODE, sizeof (struct marking_node));
+  new->tech_id = tech;
+  new->transitive = trans;
+  new->flag = 0x00;
+  return new;
+}
+
+/* Find the qos-node from a qos-set by technology-id */
+struct marking_node *
+lookup_marking_node_by_tech (struct qos_set *qosc, u_int8_t tech)
+{
+  struct marking_node *ret;
+  ret = qosc->nodehead;
+
+  while (ret)
+    {
+      if (ret->tech_id == tech)
+        return ret;
+      else
+        ret = ret->next;
+    }
+  return NULL;
+}
+
+/* lookup or create a new marking_node in qos_class */
+struct marking_node *
+get_marking_node (struct qos_set *qosc, u_int8_t tech, int trans)
+{
+  struct marking_node *new;
+  new = qosc->nodehead;
+  if (new == NULL)
+    {                           /* if there is no marking node, create the first */
+      new = new_qosmarking_node (tech, trans);
+      new->next = NULL;
+      qosc->nodehead = new;
+      qosc->nodetail = new;
+      return new;
+    }
+  while (new)
+    {                           /* walk through existing nodes */
+      if (new->tech_id == tech) /* if technology-type exists return the marking-node */
+        return new;
+      else                      /* next node */
+        new = new->next;
+    }
+  new = new_qosmarking_node (tech, trans);      /* create a new node */
+  new->next = NULL;
+  qosc->nodetail->next = new;
+  qosc->nodetail = new;
+  return new;                   /* return new node */
+}
+
+/* delete a marking node from qos-set with given technology-type */
+int
+delete_marking_node (struct qos_set *qosc, u_int8_t tech)
+{
+  struct marking_node *tmp;
+  struct marking_node *pred;
+
+  tmp = qosc->nodehead;
+  if (tmp)
+    {
+      if (tmp->tech_id == tech)
+        {
+          qosc->nodehead = tmp->next;
+          XFREE (MTYPE_QOSMARKING_NODE, tmp);
+          return CMD_SUCCESS;
+        }
+      pred = qosc->nodehead;
+      tmp = tmp->next;
+
+      while (tmp->tech_id != tech && tmp->next != NULL)
+        {
+          pred = tmp;
+          tmp = tmp->next;
+        }
+      if (tmp->tech_id == tech)
+        {
+          pred->next = tmp->next;
+          if (qosc->nodetail == tmp)
+            qosc->nodetail = pred;
+
+          XFREE (MTYPE_QOSMARKING_NODE, tmp);
+          return CMD_SUCCESS;
+        }
+    }
+  return CMD_ERR_NO_MATCH;
+}
+
+/* Route-Set */
+
+/* Compile function for set community. */
+void *
+route_set_ecommunity_qos_compile (const char *name)
+{
+  struct ecommunity *ecom = NULL;
+  struct ecommunity_val eval;
+  struct qos_set *qosc;
+  struct marking_node *mnode;
+  ecom = ecommunity_new ();
+  for (qosc = (get_qos_table_by_name (name))->head; qosc; qosc = qosc->next)
+    {
+      for (mnode = qosc->nodehead; mnode; mnode = mnode->next)
+        {
+          if (!mnode->transitive)
+            eval.val[0] = ECOMMUNITY_QOS_MARKING_NTRANS;        /* Typecode for non-transitive markings */
+          else
+            eval.val[0] = ECOMMUNITY_QOS_MARKING_TRANS; /* Typecode for transitive markings */
+          eval.val[1] = 0x00;   /* Flags */
+          eval.val[2] = qosc->qos_number;       /* QoS Set Number */
+          eval.val[3] = mnode->tech_id; /* Technology Type */
+          eval.val[4] = (mnode->mark_o >> 8) & 0xff;    /* QoS Marking Oh */
+          eval.val[5] = mnode->mark_o & 0xff;   /* QoS Marking Ol */
+          eval.val[6] = mnode->mark_a & 0xff;   /* QoS Marking A */
+          eval.val[7] = 0x00;   /* P.Count = 0 */
+          ecommunity_add_val (ecom, &eval);
+        }
+    }
+  if (!ecom)
+    return NULL;
+  return ecom;
+}
+
+/* apply-function for qos-marking-ecoms */
+route_map_result_t
+route_set_ecommunity_qos (void *rule, struct prefix * prefix,
+                          route_map_object_t type, void *object)
+{
+  struct ecommunity *ecom;
+  struct ecommunity *new_ecom;
+  struct ecommunity *old_ecom;
+  struct bgp_info *bgp_info;
+
+  if (type == RMAP_BGP)
+    {
+      ecom = rule;
+      bgp_info = object;
+
+      if (!ecom)
+        return RMAP_OKAY;
+
+      /* We assume additive for Extended Community. */
+      old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
+
+      if (old_ecom)
+        new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
+      else
+        new_ecom = ecommunity_dup (ecom);
+
+      bgp_info->attr->extra->ecommunity = new_ecom;
+
+      if (old_ecom)
+        ecommunity_free (old_ecom);
+
+      bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
+    }
+  return RMAP_OKAY;
+}
+
+/* free-function for qos-marking-ecoms */
+void
+route_set_ecommunity_qos_free (void *rule)
+{
+  struct ecommunity *ecom = rule;
+  ecommunity_free (ecom);
+}
+
+/* Compile function for set community cos-capability. */
+void *
+route_set_ecommunity_cos_compile (const char *name)
+{
+  struct bgp *bgp;
+  struct ecommunity *ecom = NULL;
+  struct ecommunity_val eval;
+  bgp = bgp_get_default ();
+
+  ecom = ecommunity_new ();
+  eval.val[0] = ECOMMUNITY_COS_CAPABILITY;      /* Typecode for cos-capability */
+  eval.val[1] = bgp->cos;       /* cos-code */
+  eval.val[2] = 0;
+  eval.val[3] = 0;
+  eval.val[4] = 0;
+  eval.val[5] = 0;
+  eval.val[6] = 0;
+  eval.val[7] = 0;
+
+  ecommunity_add_val (ecom, &eval);
+
+  if (!ecom)
+    return NULL;
+  return ecom;
+}
+
+/* Apply function for set community cos-capability. */
+route_map_result_t
+route_set_ecommunity_cos (void *rule, struct prefix * prefix,
+                          route_map_object_t type, void *object)
+{
+  struct ecommunity *ecom;
+  struct ecommunity *new_ecom;
+  struct ecommunity *old_ecom;
+  struct bgp_info *bgp_info;
+
+  if (type == RMAP_BGP)
+    {
+      ecom = rule;
+      bgp_info = object;
+
+      if (!ecom)
+        return RMAP_OKAY;
+
+      /* We assume additive for Extended Community. */
+      old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
+
+      if (old_ecom)
+        new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
+      else
+        new_ecom = ecommunity_dup (ecom);
+
+      bgp_info->attr->extra->ecommunity = new_ecom;
+
+      if (old_ecom)
+        ecommunity_free (old_ecom);
+      bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
+    }
+  return RMAP_OKAY;
+}
+
+/* Free function for set community cos-capability. */
+void
+route_set_ecommunity_cos_free (void *rule)
+{
+  struct ecommunity *ecom = rule;
+  ecommunity_free (ecom);
+}
+
+/* Generating qos-Table for VTY (show qos-marking (A.B.C.D)) */
+int
+show_qos_table_vty (struct vty *vty, struct qos_table *qos_table, int local)
+{
+  struct qos_set *qosc;
+  struct marking_node *node;
+  char trans[3];
+  if (local == 1)
+    {                           /* local QoS-Table */
+      for (qos_table = qos_local_tables.head; qos_table;
+           qos_table = qos_table->next)
+        {
+          vty_out (vty, " QoS-Table %s:%s", qos_table->name, VTY_NEWLINE);
+          qosc = qos_table->head;
+          if (qosc)
+            while (qosc)
+              {
+                vty_out (vty, "  QoS-Set: %s (0x%02x)%s", qosc->name,
+                         qosc->qos_number, VTY_NEWLINE);
+                node = qosc->nodehead;
+                if (node)
+                  {
+                    vty_out (vty,
+                             "    Technology Type    Original Marking    Active Marking    transitive%s",
+                             VTY_NEWLINE);
+                    while (node)
+                      {
+                        if (node->transitive)
+                          sprintf (trans, "yes");
+                        else
+                          sprintf (trans, " no");
+                        vty_out (vty,
+                                 "               0x%02x              0x%04x              0x%02x           %s%s",
+                                 node->tech_id, node->mark_o, node->mark_a,
+                                 trans, VTY_NEWLINE);
+                        node = node->next;
+                      }
+                  }
+                else
+                  {
+                    vty_out (vty, "    No QoS-Marking Nodes defined%s",
+                             VTY_NEWLINE);
+                  }
+                vty_out (vty, "%s", VTY_NEWLINE);
+                qosc = qosc->next;
+              }
+          else
+            vty_out (vty, "  No QoS-Sets in QoS-Table %s defined%s",
+                     qos_table->name, VTY_NEWLINE);
+        }
+    }
+  else
+    {                           /* QoS-Table for Remote Peers */
+      qosc = qos_table->head;
+      if (qosc)
+        while (qosc)
+          {
+            vty_out (vty, "  QoS-Set: %s (0x%02x)%s", qosc->name,
+                     qosc->qos_number, VTY_NEWLINE);
+            node = qosc->nodehead;
+            if (node)
+              {
+                vty_out (vty,
+                         "    Flags   Technology Type    Original Marking    Active Marking    transitive%s",
+                         VTY_NEWLINE);
+                while (node)
+                  {
+                    if (node->transitive)
+                      sprintf (trans, "yes");
+                    else
+                      sprintf (trans, " no");
+                    vty_out (vty,
+                             "     %s%s%s%s         0x%02x              0x%04x              0x%02x           %s%s",
+                             (node->flag & BGP_QOS_FLAG_PRESERV) ? "P" : " ",
+                             (node->flag & BGP_QOS_FLAG_REMARK) ? "R" : " ",
+                             (node->flag & BGP_QOS_FLAG_IGNORE) ? "I" : " ",
+                             (node->flag & BGP_QOS_FLAG_AGGREGATION) ? "A" :
+                             " ", node->tech_id, node->mark_o, node->mark_a,
+                             trans, VTY_NEWLINE);
+                    node = node->next;
+                  }
+              }
+            else
+              {
+                vty_out (vty, "    No QoS-Marking Nodes defined%s",
+                         VTY_NEWLINE);
+              }
+            vty_out (vty, "%s", VTY_NEWLINE);
+            qosc = qosc->next;
+          }
+      else
+        vty_out (vty, "  No QoS-Set defined%s", VTY_NEWLINE);
+    }
+  return CMD_SUCCESS;
+}
+
+/* Lookup the DSCP-reset list if marking_a should be set to 0x00 */
+static int
+check_dscp_reset (struct peer *peer, u_int8_t dscp)
+{
+  struct dscp_res *curr;
+  curr = peer->dscp_reset;
+
+  while (curr)
+    {
+      if (curr->dscp == dscp)
+        return 1;
+      else
+        curr = curr->next;
+    }
+  return 0;
+}
+
+/* Flag-Manipulation for outgoing QoS-Marking sets */
+int
+qos_flag_check_outgoing (struct qos_table *table, u_int8_t * ecom, int size)
+{
+  int i;
+  struct marking_node *mnode = NULL;
+  u_int16_t mark_o;
+  for (i = 0; i < size; i++)
+    {
+      if ((ecom[(i * ECOMMUNITY_SIZE) + 0] == ECOMMUNITY_QOS_MARKING_TRANS)
+          || (ecom[(i * ECOMMUNITY_SIZE) + 0] ==
+              ECOMMUNITY_QOS_MARKING_NTRANS))
+        {
+          if (table)
+            {
+              mark_o = 0x0000;
+              mark_o =
+                ((((u_int16_t) ecom[(i * ECOMMUNITY_SIZE) + 4]) << 8) &
+                 0xff00) | (0x00ff & ecom[(i * ECOMMUNITY_SIZE) + 5]);
+              mnode =
+                lookup_local_table_marking (table, mark_o,
+                                            (u_int8_t)
+                                            ecom[(i * ECOMMUNITY_SIZE) + 3]);
+
+              if (mnode == NULL)
+                {
+                  // Marking_O not in local table -> ignore
+                  ecom[(i * ECOMMUNITY_SIZE) + 1] =
+                    ecom[(i * ECOMMUNITY_SIZE) + 1] | BGP_QOS_FLAG_IGNORE;
+                  if (!
+                      (ecom[(i * ECOMMUNITY_SIZE) + 1] &
+                       BGP_QOS_FLAG_PRESERV))
+                    {
+                      // Unpreserved -> Remark to 0x00, set Remarking-Flag
+                      ecom[(i * ECOMMUNITY_SIZE) + 6] = 0x00;
+                      ecom[(i * ECOMMUNITY_SIZE) + 1] =
+                        ecom[(i * ECOMMUNITY_SIZE) + 1] | BGP_QOS_FLAG_REMARK;
+                    }
+                }
+              else if (ecom[(i * ECOMMUNITY_SIZE) + 6] == mnode->mark_a)
+                {
+                  // Marking_O in local table, Marking_A identical -> Preserve
+                  ecom[(i * ECOMMUNITY_SIZE) + 1] =
+                    ecom[(i * ECOMMUNITY_SIZE) + 1] | BGP_QOS_FLAG_PRESERV;
+                }
+              else
+                if (!(ecom[(i * ECOMMUNITY_SIZE) + 1] & BGP_QOS_FLAG_PRESERV)
+                    && ecom[(i * ECOMMUNITY_SIZE) + 6] != mnode->mark_a)
+                {
+                  // Marking_A different, unpreserved -> Remarking to local Mark_A
+                  ecom[(i * ECOMMUNITY_SIZE) + 6] = mnode->mark_a;
+                  ecom[(i * ECOMMUNITY_SIZE) + 1] =
+                    ecom[(i * ECOMMUNITY_SIZE) + 1] | BGP_QOS_FLAG_REMARK;
+                }
+            }
+          else
+            {
+              // no QoS-Table, Ignore every Marking
+              ecom[(i * ECOMMUNITY_SIZE) + 1] =
+                ecom[(i * ECOMMUNITY_SIZE) + 1] | BGP_QOS_FLAG_IGNORE;
+            }
+        }
+    }
+  return 0;
+}
+
+/* Search the local QoS-Table for a marking_node with given marking_o and technology type */
+struct marking_node *
+lookup_local_table_marking (struct qos_table *table, u_int16_t marking_o,
+                            u_int8_t tech)
+{
+  struct qos_set *qset = NULL;
+  struct marking_node *mnode = NULL;
+
+  qset = table->head;
+  while (qset)
+    {
+      mnode = qset->nodehead;
+      while (mnode)
+        {
+          if (mnode->mark_o == marking_o && mnode->tech_id == tech)
+            return mnode;
+          else
+            mnode = mnode->next;
+        }
+      qset = qset->next;
+    }
+  return NULL;
+}
+
+/* "show route" QoS-Table ("show ip bgp A.B.C.D") (QoS-Marking not listed in the usual ecom line)  */
+void
+show_route_qos_table (struct vty *vty, u_int8_t * pnt, int size)
+{
+  struct ecommunity_qos
+  {
+    u_int8_t flags;
+    u_int8_t qos_set;
+    u_int8_t tech_type;
+    u_int16_t marking_o;
+    u_int8_t marking_a;
+  } eqos;
+  int i;
+  int first = 1;
+
+  for (i = 0; i < size; i++)
+    {
+      if ((pnt[(i * ECOMMUNITY_SIZE) + 0] == ECOMMUNITY_QOS_MARKING_TRANS)
+          || (pnt[(i * ECOMMUNITY_SIZE) + 0] ==
+              ECOMMUNITY_QOS_MARKING_NTRANS))
+        {
+          if (first)
+            {
+              vty_out (vty, "       QoS-Marking%s", VTY_NEWLINE);
+              vty_out (vty,
+                       "                 Technology    Original    Active%s",
+                       VTY_NEWLINE);
+              vty_out (vty,
+                       "        Flags       Type       Marking     Marking    transitive%s",
+                       VTY_NEWLINE);
+              //"         PRIA       0x00       0x0000      0x00       yes
+
+              first = 0;
+            }
+          eqos.flags = pnt[(i * ECOMMUNITY_SIZE) + 1];
+          eqos.qos_set = pnt[(i * ECOMMUNITY_SIZE) + 2];
+          eqos.tech_type = pnt[(i * ECOMMUNITY_SIZE) + 3];
+          eqos.marking_o = (pnt[(i * ECOMMUNITY_SIZE) + 4] << 8);
+          eqos.marking_o |= pnt[(i * ECOMMUNITY_SIZE) + 5];
+          eqos.marking_a = pnt[(i * ECOMMUNITY_SIZE) + 6];
+
+          vty_out (vty,
+                   "         %s%s%s%s       0x%02x       0x%04x      0x%02x       %s%s",
+                   (eqos.flags & BGP_QOS_FLAG_PRESERV) ? "P" : " ",
+                   (eqos.flags & BGP_QOS_FLAG_REMARK) ? "R" : " ",
+                   (eqos.flags & BGP_QOS_FLAG_IGNORE) ? "I" : " ",
+                   (eqos.flags & BGP_QOS_FLAG_AGGREGATION) ? "A" : " ",
+                   eqos.tech_type, eqos.marking_o, eqos.marking_a,
+                   (CHECK_FLAG
+                    (pnt[(i * ECOMMUNITY_SIZE) + 0],
+                     ECOMMUNITY_FLAG_NON_TRANSITIVE)) ? "yes" : "no",
+                   VTY_NEWLINE);
+        }
+    }
+}
+
+/* Import function for incoming QoS-Markings and flag manipulation for incoming QoS-Marking sets */
+int
+import_peer_qos_table (struct peer *peer, u_int8_t * pnt, u_int16_t length)
+{
+  int size;
+  int i;
+  int ret;
+  struct marking_node *new;
+  u_int16_t mark_o;
+  struct qos_set *qosc;
+
+  size = length / ECOMMUNITY_SIZE;
+  if (peer->qos_table == NULL)
+    {
+      peer->qos_table = XCALLOC (MTYPE_QOS_TABLE, sizeof (struct qos_table));
+      peer->qos_table->head = NULL;
+      peer->qos_table->techhead = NULL;
+    }
+  for (i = 0; i < size; i++)
+    {
+      if ((pnt[(i * ECOMMUNITY_SIZE) + 0] == ECOMMUNITY_QOS_MARKING_TRANS)
+          || (pnt[(i * ECOMMUNITY_SIZE) + 0] ==
+              ECOMMUNITY_QOS_MARKING_NTRANS))
+        {
+          pnt[(i * ECOMMUNITY_SIZE) + 1] = (pnt[(i * ECOMMUNITY_SIZE) + 1] & ~BGP_QOS_FLAG_PRESERV);    /* always delete the preserve-flag on incoming markings
+                                                                                                           [draft-knoll-idr-qos-attribute#section-4.2]
+                                                                                                           "This flag field is set and cleared
+                                                                                                           by each relaying AS according to its handling of markings -
+                                                                                                           irrespective of the possible ignorance of the particular Marking A
+                                                                                                           in the internal per hop forwarding behaviour."
+                                                                                                         */
+          // Check requested preserval for peer ("bgpd(config-router)# neighbor A.B.C.D preserve-qos")
+          if (peer->qos_pbit == 1)
+            {
+              pnt[(i * ECOMMUNITY_SIZE) + 1] =
+                pnt[(i * ECOMMUNITY_SIZE) + 1] | BGP_QOS_FLAG_PRESERV;
+            }
+          ret =
+            qos_set_add (peer->qos_table, NULL,
+                         pnt[(i * ECOMMUNITY_SIZE) + 2]);
+          qosc =
+            qos_set_lookup_by_id (peer->qos_table,
+                                  pnt[(i * ECOMMUNITY_SIZE) + 2]);
+          mark_o = 0x0000;
+          mark_o =
+            ((((u_int16_t) pnt[(i * ECOMMUNITY_SIZE) + 4]) << 8) & 0xff00) |
+            (0x00ff & pnt[(i * ECOMMUNITY_SIZE) + 5]);
+          new =
+            get_marking_node (qosc, pnt[(i * ECOMMUNITY_SIZE) + 3],
+                              ((pnt[i * ECOMMUNITY_SIZE] ==
+                                ECOMMUNITY_QOS_MARKING_TRANS) ? 1 : 0));
+
+          new->mark_o = mark_o;
+          new->mark_a = pnt[(i * ECOMMUNITY_SIZE) + 6];
+
+          // reset the active marking? (e.g. "bgpd(config-router)# neighbor A.B.C.D reset-dscp 0x2A")
+          // overrides preserval!
+          if (check_dscp_reset
+              (peer, (u_int8_t) pnt[(i * ECOMMUNITY_SIZE) + 6]))
+            {
+              pnt[(i * ECOMMUNITY_SIZE) + 6] = 0x00;
+              pnt[(i * ECOMMUNITY_SIZE) + 1] = (pnt[(i * ECOMMUNITY_SIZE) + 1] & ~BGP_QOS_FLAG_PRESERV) | BGP_QOS_FLAG_REMARK;  // delete p-flag, add r-flag
+            }
+          new->flag = pnt[(i * ECOMMUNITY_SIZE) + 1];
+        }
+    }
+  return 0;
+}
+
+/* Add a new DSCP to reset to the structure */
+void
+dscp_remark_add (struct peer *peer, u_int16_t dscp)
+{
+  struct dscp_res *new;
+  struct dscp_res *curr;
+  curr = peer->dscp_reset;
+
+  new = XCALLOC (MTYPE_DSCP_RESET_NODE, sizeof (struct dscp_res));
+  new->dscp = dscp;
+  new->next = curr;
+  while (curr)
+    {
+      if (curr->dscp == new->dscp)
+        {
+          XFREE (MTYPE_DSCP_RESET_NODE, new);
+          return;
+        }
+      else
+        {
+          curr = curr->next;
+        }
+    }
+  peer->dscp_reset = new;
+}
+
+/* Remove a DSCP to reset from the structure */
+void
+dscp_remark_delete (struct peer *peer, u_int16_t dscp)
+{
+  struct dscp_res *curr;
+  struct dscp_res *pred = NULL;
+
+  curr = peer->dscp_reset;
+  while (curr)
+    {
+      if (curr->dscp == dscp)
+        {
+          if (pred)
+            pred->next = curr->next;
+          else
+            peer->dscp_reset = curr->next;
+          XFREE (MTYPE_DSCP_RESET_NODE, curr);
+          break;
+        }
+      pred = curr;
+      curr = curr->next;
+    }
+}
+
+/******************************************************************************
+ * Find the last QoS-Marking table applied to the route (recursive)
+ * the last route-map-index: last called route-map + highest sequence-number
+ * 
+ * route_map
+ *   -> route_map_index (sequence number of route_map)
+ *        -> route_map_rule (e.g. set extcommunity ...)
+ *        -> nextrm (name of route_map to be called after match/set)
+ *           (re-run this function for nextrm)
+ *****************************************************************************/
+static struct qos_table *
+find_table_from_routemap (struct route_map *map)
+{
+  struct route_map_index *rmindex;
+  struct route_map_rule
+  {
+    /* Rule type. */
+    struct route_map_rule_cmd *cmd;
+    /* For pretty printing. */
+    char *rule_str;
+    /* Pre-compiled match rule. */
+    void *value;
+    /* Linked list. */
+    struct route_map_rule *next;
+    struct route_map_rule *prev;
+  } *rule;
+  struct qos_table *ret = NULL;
+  int recursion = 0;
+
+  for (rmindex = map->head; rmindex; rmindex = rmindex->next)
+    {
+      for (rule = rmindex->set_list.head; rule; rule = rule->next)
+        {
+          if (strcmp (rule->cmd->str, "extcommunity qos-marking") == 0)
+            {
+              ret = get_qos_table_by_name (rule->rule_str);
+            }
+        }
+      if (rmindex->nextrm)
+        {
+          struct route_map *nextrm =
+            route_map_lookup_by_name (rmindex->nextrm);
+
+          if (nextrm)
+            {                   /* Target route-map found, jump to it */
+              recursion++;
+              ret = find_table_from_routemap (nextrm);
+              recursion--;
+            }
+        }
+    }
+  return ret;
+}
+
+/* get the first route_map from the peer-structure */
+struct qos_table *
+find_active_table (struct peer *peer)
+{
+  struct route_map *map;
+
+  struct bgp_filter *filter = &peer->filter[AFI_IP][SAFI_UNICAST];
+
+  if (filter)
+    {
+      if (filter->map[RMAP_OUT].name)
+        {
+          map = filter->map[RMAP_OUT].map;
+          return find_table_from_routemap (map);
+        }
+      return NULL;
+    }
+  return NULL;
+}
diff -upwbrN quagga_original/bgpd/bgp_qos.h quagga_cq/bgpd/bgp_qos.h
--- quagga_original/bgpd/bgp_qos.h	1970-01-01 01:00:00.000000000 +0100
+++ quagga_cq/bgpd/bgp_qos.h	2010-05-11 21:28:22.000000000 +0200
@@ -0,0 +1,130 @@
+/* BGP CoS-Capability and QoS Marking attribute management routines.
+   http://tools.ietf.org/html/draft-knoll-idr-cos-interconnect
+   http://tools.ietf.org/html/draft-knoll-idr-qos-attribute
+   written by: Simon Ehnert <ehsi@hrz.tu-chemnitz.de>
+               Thomas M. Knoll <knoll@etit.tu-chemnitz.de>
+*/
+#ifndef _QUAGGA_BGP_QOS_H
+#define _QUAGGA_BGP_QOS_H
+
+#include "routemap.h"
+
+struct qos_local_tables
+{
+  struct qos_table *head;
+  struct qos_table *tail;
+};
+
+struct marking_node
+{
+  /* Flags */
+  u_int8_t flag;
+#define BGP_QOS_FLAG_AGGREGATION              (1 << 2)
+#define BGP_QOS_FLAG_IGNORE                   (1 << 3)
+#define BGP_QOS_FLAG_REMARK                   (1 << 4)
+#define BGP_QOS_FLAG_PRESERV                  (1 << 5)
+
+  /* Technology Type Number */
+  int tech_id;
+
+  /* QoS-Marking */
+  u_int16_t mark_o;
+  u_int8_t mark_a;
+
+  /* Transitive/Non-Transitive */
+  int transitive;
+
+  /* References */
+  struct marking_node *next;
+};
+
+struct qos_set
+{
+  /* Name of the Class-Set (e.g. EF, AF, BE, ...) */
+  char *name;
+
+  /* QoS Set Number (enumerated) */
+  int qos_number;
+  struct qos_set *next;
+  struct qos_set *prev;
+
+  /* phb-nodes */
+  struct marking_node *nodehead;
+  struct marking_node *nodetail;
+};
+
+struct techtype
+{
+  char *name;
+  int tech_id;
+  struct techtype *next;
+  struct techtype *prev;
+};
+
+struct dscp_res
+{
+  u_int16_t dscp;
+  struct dscp_res *next;
+};
+
+/* Prototypes */
+
+/* show the QoS-Table of a prefix (show route)*/
+extern void show_route_qos_table (struct vty *vty, u_int8_t * pnt, int size);
+/* writes the running QoS-configuration to vty (show running-config) */
+extern int bgp_qos_config_write (struct vty *vty);
+/* Initialization of the QoS-Marking */
+extern int qos_marking_init (struct vty *vty, const char *name);
+/* Delete the QoS-Marking with the given name */
+extern int qos_marking_delete (const char *name);
+extern struct qos_table *new_qos_table (const char *name);
+extern struct qos_table *get_qos_table_by_name (const char *name);
+extern struct techtype *techtype_lookup_by_id (struct qos_table *list,
+                                               int id);
+extern struct qos_set *qos_set_lookup_by_id (struct qos_table *list, int id);
+
+extern struct techtype *techtype_new (int id, const char *name);
+extern struct qos_set *qos_set_new (int id, const char *name);
+extern int qos_set_add (struct qos_table *list, const char *name, int id);
+extern int qos_set_delete (struct qos_table *list, int id);
+extern int techtype_add (struct qos_table *list, const char *name, int id);
+extern int techtype_delete (struct qos_table *list, u_int8_t id);
+extern struct marking_node *new_qosmarking_node (int tech, int trans);
+extern struct marking_node *lookup_marking_node_by_tech (struct qos_set *qosc,
+                                                         u_int8_t tech);
+extern struct marking_node *get_marking_node (struct qos_set *qosc,
+                                              u_int8_t tech, int trans);
+extern int delete_marking_node (struct qos_set *qosc, u_int8_t tech);
+
+/* route-map functions for qos + cos-capability ecommunities */
+extern route_map_result_t route_set_ecommunity_qos (void *rule,
+                                                    struct prefix *prefix,
+                                                    route_map_object_t type,
+                                                    void *object);
+extern void *route_set_ecommunity_qos_compile (const char *name);
+extern void route_set_ecommunity_qos_free (void *rule);
+extern route_map_result_t route_set_ecommunity_cos (void *rule,
+                                                    struct prefix *prefix,
+                                                    route_map_object_t type,
+                                                    void *object);
+extern void *route_set_ecommunity_cos_compile (const char *name);
+extern void route_set_ecommunity_cos_free (void *rule);
+
+extern int show_qos_table_vty (struct vty *vty, struct qos_table *qos_table,
+                               int local);
+extern int import_peer_qos_table (struct peer *peer, u_int8_t * pnt,
+                                  u_int16_t length);
+extern void dscp_remark_add (struct peer *peer, u_int16_t dscp);
+extern void dscp_remark_delete (struct peer *peer, u_int16_t dscp);
+/* search for the current route-map to find the qos-table which is to be used */
+extern struct qos_table *find_active_table (struct peer *peer);
+
+extern struct marking_node *lookup_local_table_marking (struct qos_table
+                                                        *table,
+                                                        u_int16_t marking_o,
+                                                        u_int8_t tech);
+/* check the flags of the qos for outgoing ecommunities */
+extern int qos_flag_check_outgoing (struct qos_table *table, u_int8_t * ecom,
+                                    int size);
+
+#endif
diff -upwbrN quagga_original/bgpd/bgp_route.c quagga_cq/bgpd/bgp_route.c
--- quagga_original/bgpd/bgp_route.c	2010-05-11 21:25:09.000000000 +0200
+++ quagga_cq/bgpd/bgp_route.c	2010-05-11 21:28:22.000000000 +0200
@@ -54,6 +54,8 @@ Software Foundation, Inc., 59 Temple Pla
 #include "bgpd/bgp_advertise.h"
 #include "bgpd/bgp_zebra.h"
 #include "bgpd/bgp_vty.h"
+#include "bgpd/bgp_qos.h"
+#include "bgpd/bgp_cos.h"
 
 /* Extern from bgp_dump.c */
 extern const char *bgp_origin_str[];
@@ -753,7 +755,8 @@ bgp_import_modifier (struct peer *rsclie
   return RMAP_PERMIT;
 }
 
-static int
+// this function was static, now public for vty
+int
 bgp_announce_check (struct bgp_info *ri, struct peer *peer, struct prefix *p,
 		    struct attr *attr, afi_t afi, safi_t safi)
 {
@@ -6106,9 +6109,12 @@ route_vty_out_detail (struct vty *vty, s
 		 VTY_NEWLINE);
 	  
       /* Line 5 display Extended-community */
-      if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))
+      if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
 	vty_out (vty, "      Extended Community: %s%s", 
 	         attr->extra->ecommunity->str, VTY_NEWLINE);
+        // show details of qos-table
+        show_route_qos_table(vty, attr->extra->ecommunity->val, attr->extra->ecommunity->size);
+      }
 	  
       /* Line 6 display Originator, Cluster-id */
       if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) ||
@@ -6144,7 +6150,14 @@ route_vty_out_detail (struct vty *vty, s
       if (binfo->extra && binfo->extra->damp_info)
 	bgp_damp_info_vty (vty, binfo);
 
-      /* Line 7 display Uptime */
+      /* Line 8 display CoS Parameter attribute */
+      if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COS_PARAMETER_FLAG)) {
+        assert (attr->extra);
+        vty_out (vty, "      CoS-Parameter%s", VTY_NEWLINE);
+        bgp_cos_class_write (vty, attr->extra->cos_class);
+      }
+
+      /* Line 9 display Uptime */
       vty_out (vty, "      Last update: %s", ctime (&binfo->uptime));
     }
   vty_out (vty, "%s", VTY_NEWLINE);
diff -upwbrN quagga_original/bgpd/bgp_route.h quagga_cq/bgpd/bgp_route.h
--- quagga_original/bgpd/bgp_route.h	2010-05-11 21:25:09.000000000 +0200
+++ quagga_cq/bgpd/bgp_route.h	2010-05-11 21:28:22.000000000 +0200
@@ -167,6 +167,8 @@ enum bgp_clear_route_type
 };
 
 /* Prototypes. */
+extern int bgp_announce_check (struct bgp_info *ri, struct peer *peer, struct prefix *p,
+		    struct attr *attr, afi_t afi, safi_t safi);
 extern void bgp_route_init (void);
 extern void bgp_route_finish (void);
 extern void bgp_cleanup_routes (void);
diff -upwbrN quagga_original/bgpd/bgp_routemap.c quagga_cq/bgpd/bgp_routemap.c
--- quagga_original/bgpd/bgp_routemap.c	2010-05-11 21:25:09.000000000 +0200
+++ quagga_cq/bgpd/bgp_routemap.c	2010-05-11 21:28:22.000000000 +0200
@@ -51,6 +51,8 @@ Software Foundation, Inc., 59 Temple Pla
 #include "bgpd/bgp_filter.h"
 #include "bgpd/bgp_mplsvpn.h"
 #include "bgpd/bgp_ecommunity.h"
+#include "bgpd/bgp_qos.h"
+#include "bgpd/bgp_cos.h"
 #include "bgpd/bgp_vty.h"
 
 /* Memo of route-map commands.
@@ -2191,7 +2193,7 @@ route_set_originator_id_free (void *rule
   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 }
 
-/* Set metric rule structure. */
+/* Set originator-id rule structure. */
 struct route_map_rule_cmd route_set_originator_id_cmd = 
 {
   "originator-id",
@@ -2200,6 +2202,33 @@ struct route_map_rule_cmd route_set_orig
   route_set_originator_id_free,
 };
 
+/* Set extcommunity-qos rule structure. */
+struct route_map_rule_cmd route_set_ecommunity_qos_cmd =
+{
+  "extcommunity qos-marking",
+  route_set_ecommunity_qos,
+  route_set_ecommunity_qos_compile,
+  route_set_ecommunity_qos_free,
+};
+
+/* Set extcommunity-cos rule structure. */
+struct route_map_rule_cmd route_set_ecommunity_cos_cmd =
+{
+  "extcommunity cos-capability",
+  route_set_ecommunity_cos,
+  route_set_ecommunity_cos_compile,
+  route_set_ecommunity_cos_free,
+};
+
+/* Set cos parameter rule structure. */
+struct route_map_rule_cmd route_set_cos_parameter_cmd =
+{
+  "cos-parameter",
+  route_set_cos_parameter,
+  route_set_cos_parameter_compile,
+  route_set_cos_parameter_free,
+};
+
 /* Add bgp route map rule. */
 static int
 bgp_route_match_add (struct vty *vty, struct route_map_index *index,
@@ -3807,6 +3836,72 @@ ALIAS (no_match_pathlimit_as,
        "BGP AS-Pathlimit attribute\n"
        "Match Pathlimit ASN\n")
 
+/* DEFUNs for route-maps set qos */
+
+DEFUN (set_ecommunity_qos,
+       set_ecommunity_qos_cmd,
+       "set extcommunity qos-marking WORD",
+       SET_STR
+       "BGP extended community attribute\n"
+       "QoS-Marking attributes\n"
+       "Name of QoS-Table\n")
+{
+  return bgp_route_set_add (vty, vty->index, "extcommunity qos-marking", argv[0]);
+}
+
+DEFUN (no_set_ecommunity_qos,
+       no_set_ecommunity_qos_cmd,
+       "no set extcommunity qos-marking",
+       NO_STR
+       SET_STR
+       "BGP extended community attribute\n"
+       "QoS-Marking attributes\n")
+{
+  return bgp_route_set_delete (vty, vty->index, "extcommunity qos-marking", NULL);
+}
+
+DEFUN (set_ecommunity_cos,
+       set_ecommunity_cos_cmd,
+       "set extcommunity cos-capability",
+       SET_STR
+       "BGP extended community attribute\n"
+       "CoS-Capability\n")
+{
+  return bgp_route_set_add (vty, vty->index, "extcommunity cos-capability", NULL);
+}
+
+DEFUN (no_set_ecommunity_cos,
+       no_set_ecommunity_cos_cmd,
+       "no set extcommunity cos-capability",
+       NO_STR
+       SET_STR
+       "BGP extended community attribute\n"
+       "CoS-Capability\n")
+{
+  return bgp_route_set_delete (vty, vty->index, "extcommunity cos-capability", NULL);
+}
+
+DEFUN (set_cos_parameter,
+       set_cos_parameter_cmd,
+       "set cos-parameter <0-4294967295>",
+       SET_STR
+       "CoS-Parameter for destination routing protocol\n"
+       "CoS-Class number\n")
+{
+  return bgp_route_set_add (vty, vty->index, "cos-parameter", argv[0]);
+}
+
+DEFUN (no_set_cos_parameter,
+       no_set_cos_parameter_cmd,
+       "no set cos-parameter <0-4294967295>",
+       NO_STR
+       SET_STR
+       "CoS-Parameter for destination routing protocol\n"
+       "CoS-Class number\n")
+{
+  return bgp_route_set_delete (vty, vty->index, "cos-parameter", argv[0]);
+} 
+
 
 /* Initialization of route map. */
 void
@@ -3830,6 +3925,11 @@ bgp_route_map_init (void)
   route_map_install_match (&route_match_metric_cmd);
   route_map_install_match (&route_match_origin_cmd);
 
+/* route-map install for qos- and cos-ecommunities */
+  route_map_install_set (&route_set_ecommunity_qos_cmd);
+  route_map_install_set (&route_set_ecommunity_cos_cmd);
+  route_map_install_set (&route_set_cos_parameter_cmd);
+
   route_map_install_set (&route_set_ip_nexthop_cmd);
   route_map_install_set (&route_set_local_pref_cmd);
   route_map_install_set (&route_set_weight_cmd);
@@ -3846,6 +3946,14 @@ bgp_route_map_init (void)
   route_map_install_set (&route_set_ecommunity_rt_cmd);
   route_map_install_set (&route_set_ecommunity_soo_cmd);
 
+/* install DEFUNs for qos- and cos-ecommunities and cos-parameter */
+  install_element (RMAP_NODE, &set_ecommunity_qos_cmd);
+  install_element (RMAP_NODE, &no_set_ecommunity_qos_cmd);
+  install_element (RMAP_NODE, &set_ecommunity_cos_cmd);
+  install_element (RMAP_NODE, &no_set_ecommunity_cos_cmd);
+  install_element (RMAP_NODE, &set_cos_parameter_cmd);
+  install_element (RMAP_NODE, &no_set_cos_parameter_cmd);
+ 
   install_element (RMAP_NODE, &match_peer_cmd);
   install_element (RMAP_NODE, &match_peer_local_cmd);
   install_element (RMAP_NODE, &no_match_peer_cmd);
diff -upwbrN quagga_original/bgpd/bgp_vty.c quagga_cq/bgpd/bgp_vty.c
--- quagga_original/bgpd/bgp_vty.c	2010-05-11 21:25:09.000000000 +0200
+++ quagga_cq/bgpd/bgp_vty.c	2010-05-11 21:28:22.000000000 +0200
@@ -43,6 +43,8 @@ Software Foundation, Inc., 59 Temple Pla
 #include "bgpd/bgp_mplsvpn.h"
 #include "bgpd/bgp_nexthop.h"
 #include "bgpd/bgp_open.h"
+#include "bgpd/bgp_qos.h"
+#include "bgpd/bgp_cos.h"
 #include "bgpd/bgp_regex.h"
 #include "bgpd/bgp_route.h"
 #include "bgpd/bgp_zebra.h"
@@ -4070,9 +4072,11 @@ bgp_clear_vty_error (struct vty *vty, st
 }
 
 /* `clear ip bgp' functions. */
+
 static int
 bgp_clear (struct vty *vty, struct bgp *bgp,  afi_t afi, safi_t safi,
-           enum clear_sort sort,enum bgp_clear_type stype, const char *arg)
+           enum clear_sort sort,enum bgp_clear_type stype, const char *arg,
+           const char *prefix)
 {
   int ret;
   struct peer *peer;
@@ -4083,8 +4087,51 @@ bgp_clear (struct vty *vty, struct bgp *
     {
       for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
 	{
-	  if (stype == BGP_CLEAR_SOFT_NONE)
+    	  if (stype == BGP_CLEAR_SOFT_NONE) {
 	    ret = peer_clear (peer);
+            /* delete global cos lists by 'CLEAR IP BGP *' */
+            if (peer->global_cos_out)
+              {
+                clear_cos_class (peer->global_cos_out);
+                XFREE(MTYPE_COS_CLASS, peer->global_cos_out);
+                peer->global_cos_out=NULL;
+              }
+            if (peer->global_cos_in)
+              {
+                clear_cos_class (peer->global_cos_in);
+                XFREE(MTYPE_COS_CLASS, peer->global_cos_in);
+                peer->global_cos_in=NULL;
+              }
+    	  } else if (stype == BGP_CLEAR_SOFT_PREFIX)
+    	    {
+              struct prefix p;
+              struct bgp_node *rn;
+              struct bgp_info *ri;
+              struct attr attr = { 0 };
+
+              ret = str2prefix (prefix, &p);
+              if (! ret)
+                {
+                  vty_out (vty, "%% Malformed prefix%s", VTY_NEWLINE);
+                  return CMD_WARNING;
+                }
+              apply_mask (&p);
+              // got a clean prefix
+
+              rn = bgp_node_lookup(bgp->rib[AFI_IP][SAFI_UNICAST], &p);
+
+              for (ri = rn->info; ri; ri = ri->next)
+                {
+                  if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED) && ri->peer != peer)
+                    {
+                      if (bgp_announce_check (ri, peer, &rn->p, &attr, AFI_IP, SAFI_UNICAST))
+                        bgp_adj_out_set (rn, peer, &rn->p, &attr, AFI_IP, SAFI_UNICAST, ri);
+                      else
+                        bgp_adj_out_unset (rn, peer, &rn->p, AFI_IP, SAFI_UNICAST);
+                      bgp_attr_extra_free (&attr);
+                    }
+                }
+            } 
 	  else
 	    ret = peer_clear_soft (peer, afi, safi, stype);
 
@@ -4114,8 +4161,51 @@ bgp_clear (struct vty *vty, struct bgp *
 	  return CMD_WARNING;
 	}
 
-      if (stype == BGP_CLEAR_SOFT_NONE)
+      if (stype == BGP_CLEAR_SOFT_NONE) {
 	ret = peer_clear (peer);
+        /* delete global cos lists by 'CLEAR IP BGP *' */
+        if (peer->global_cos_out)
+          {
+            clear_cos_class (peer->global_cos_out);
+            XFREE(MTYPE_COS_CLASS, peer->global_cos_out);
+            peer->global_cos_out=NULL;
+          }
+        if (peer->global_cos_in)
+          {
+            clear_cos_class (peer->global_cos_in);
+            XFREE(MTYPE_COS_CLASS, peer->global_cos_in);
+                  peer->global_cos_in=NULL;
+          }
+      } else if (stype == BGP_CLEAR_SOFT_PREFIX)
+        {
+          struct prefix p;
+          struct bgp_node *rn;
+          struct bgp_info *ri;
+          struct attr attr = { 0 };
+		
+          ret = str2prefix (prefix, &p);
+          if (! ret)
+            {
+              vty_out (vty, "%% Malformed prefix%s", VTY_NEWLINE);
+              return CMD_WARNING;
+            }
+          apply_mask (&p);
+          // got a clean prefix
+  
+          rn = bgp_node_lookup(bgp->rib[AFI_IP][SAFI_UNICAST], &p);
+
+          for (ri = rn->info; ri; ri = ri->next)
+            {
+              if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED) && ri->peer != peer)
+                {
+                  if (bgp_announce_check (ri, peer, &rn->p, &attr, AFI_IP, SAFI_UNICAST))
+                    bgp_adj_out_set (rn, peer, &rn->p, &attr, AFI_IP, SAFI_UNICAST, ri);
+                  else
+                    bgp_adj_out_unset (rn, peer, &rn->p, AFI_IP, SAFI_UNICAST);
+                 bgp_attr_extra_free (&attr);
+                }
+            }
+        }
       else
 	ret = peer_clear_soft (peer, afi, safi, stype);
 
@@ -4145,6 +4235,40 @@ bgp_clear (struct vty *vty, struct bgp *
 	      continue;
 	    }
 
+          if (stype == BGP_CLEAR_SOFT_PREFIX)
+            {
+              struct prefix p;
+              struct bgp_node *rn;
+              struct bgp_info *ri;
+              struct attr attr = { 0 };
+
+              ret = str2prefix (prefix, &p);
+              if (! ret)
+                {
+                  vty_out (vty, "%% Malformed prefix%s", VTY_NEWLINE);
+                  return CMD_WARNING;
+                }
+              apply_mask (&p);
+              // got a clean prefix
+
+              rn = bgp_node_lookup (bgp->rib[AFI_IP][SAFI_UNICAST], &p);
+  
+              for (ri = rn->info; ri; ri = ri->next)
+                {
+                  if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED) && ri->peer != peer)
+                    {
+                      if (bgp_announce_check (ri, peer, &rn->p, &attr, AFI_IP,
+                                              SAFI_UNICAST))
+                        bgp_adj_out_set (rn, peer, &rn->p, &attr, AFI_IP,
+                                         SAFI_UNICAST, ri);
+                      else
+                        bgp_adj_out_unset (rn, peer, &rn->p, AFI_IP, SAFI_UNICAST);
+                      bgp_attr_extra_free (&attr);
+                    }
+                }
+              continue;
+            }
+
 	  if (! peer->af_group[afi][safi])
 	    continue;
 
@@ -4215,7 +4339,7 @@ bgp_clear (struct vty *vty, struct bgp *
 static int
 bgp_clear_vty (struct vty *vty, const char *name, afi_t afi, safi_t safi,
                enum clear_sort sort, enum bgp_clear_type stype, 
-               const char *arg)
+               const char *arg, const char *prefix)
 {
   struct bgp *bgp;
 
@@ -4239,7 +4363,7 @@ bgp_clear_vty (struct vty *vty, const ch
         }
     }
 
-  return bgp_clear (vty, bgp, afi, safi, sort, stype, arg);
+  return bgp_clear (vty, bgp, afi, safi, sort, stype, arg, prefix);
 }
   
 DEFUN (clear_ip_bgp_all,
@@ -4251,9 +4375,9 @@ DEFUN (clear_ip_bgp_all,
        "Clear all peers\n")
 {
   if (argc == 1)
-    return bgp_clear_vty (vty, argv[0], 0, 0, clear_all, BGP_CLEAR_SOFT_NONE, NULL);    
+    return bgp_clear_vty (vty, argv[0], 0, 0, clear_all, BGP_CLEAR_SOFT_NONE, NULL, NULL);    
 
-  return bgp_clear_vty (vty, NULL, 0, 0, clear_all, BGP_CLEAR_SOFT_NONE, NULL);
+  return bgp_clear_vty (vty, NULL, 0, 0, clear_all, BGP_CLEAR_SOFT_NONE, NULL, NULL);
 }
 
 ALIAS (clear_ip_bgp_all,
@@ -4299,7 +4423,7 @@ DEFUN (clear_ip_bgp_peer,
        "BGP neighbor IP address to clear\n"
        "BGP IPv6 neighbor to clear\n")
 {
-  return bgp_clear_vty (vty, NULL, 0, 0, clear_peer, BGP_CLEAR_SOFT_NONE, argv[0]);
+  return bgp_clear_vty (vty, NULL, 0, 0, clear_peer, BGP_CLEAR_SOFT_NONE, argv[0], NULL);
 }
 
 ALIAS (clear_ip_bgp_peer,
@@ -4328,7 +4452,7 @@ DEFUN (clear_ip_bgp_peer_group,
        "Clear all members of peer-group\n"
        "BGP peer-group name\n")
 {
-  return bgp_clear_vty (vty, NULL, 0, 0, clear_group, BGP_CLEAR_SOFT_NONE, argv[0]);
+  return bgp_clear_vty (vty, NULL, 0, 0, clear_group, BGP_CLEAR_SOFT_NONE, argv[0], NULL);
 }
 
 ALIAS (clear_ip_bgp_peer_group,
@@ -4356,7 +4480,7 @@ DEFUN (clear_ip_bgp_external,
        BGP_STR
        "Clear all external peers\n")
 {
-  return bgp_clear_vty (vty, NULL, 0, 0, clear_external, BGP_CLEAR_SOFT_NONE, NULL);
+  return bgp_clear_vty (vty, NULL, 0, 0, clear_external, BGP_CLEAR_SOFT_NONE, NULL, NULL);
 }
 
 ALIAS (clear_ip_bgp_external,
@@ -4382,7 +4506,7 @@ DEFUN (clear_ip_bgp_as,
        BGP_STR
        "Clear peers with the AS number\n")
 {
-  return bgp_clear_vty (vty, NULL, 0, 0, clear_as, BGP_CLEAR_SOFT_NONE, argv[0]);
+  return bgp_clear_vty (vty, NULL, 0, 0, clear_as, BGP_CLEAR_SOFT_NONE, argv[0], NULL);
 }       
 
 ALIAS (clear_ip_bgp_as,
@@ -4413,10 +4537,10 @@ DEFUN (clear_ip_bgp_all_soft_out,
 {
   if (argc == 1)
     return bgp_clear_vty (vty, argv[0], AFI_IP, SAFI_UNICAST, clear_all,
-                          BGP_CLEAR_SOFT_OUT, NULL);
+                          BGP_CLEAR_SOFT_OUT, NULL, NULL);
 
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_all,
-			BGP_CLEAR_SOFT_OUT, NULL);
+			BGP_CLEAR_SOFT_OUT, NULL, NULL);
 }
 
 ALIAS (clear_ip_bgp_all_soft_out,
@@ -4455,10 +4579,10 @@ DEFUN (clear_ip_bgp_all_ipv4_soft_out,
 {
   if (strncmp (argv[0], "m", 1) == 0)
     return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_MULTICAST, clear_all,
-			  BGP_CLEAR_SOFT_OUT, NULL);
+			  BGP_CLEAR_SOFT_OUT, NULL, NULL);
 
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_all,
-			BGP_CLEAR_SOFT_OUT, NULL);
+			BGP_CLEAR_SOFT_OUT, NULL, NULL);
 }
 
 ALIAS (clear_ip_bgp_all_ipv4_soft_out,
@@ -4473,6 +4597,187 @@ ALIAS (clear_ip_bgp_all_ipv4_soft_out,
        "Address Family modifier\n"
        "Soft reconfig outbound update\n")
 
+       
+/* prefix-specific outbound soft-reconfiguration */
+
+
+DEFUN (clear_ip_bgp_peer_soft_out_prefix,
+       clear_ip_bgp_peer_soft_out_prefix_cmd,
+       "clear ip bgp A.B.C.D soft out A.B.C.D/M",
+       CLEAR_STR
+       IP_STR
+       BGP_STR
+       "BGP neighbor IP address to clear\n"
+       "Soft reconfig\n"
+       "Soft reconfig outbound update\n"
+       "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
+{
+  return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_peer,
+                        BGP_CLEAR_SOFT_PREFIX, argv[0], argv[1]);
+}
+
+ALIAS (clear_ip_bgp_peer_soft_out_prefix,
+       clear_ip_bgp_peer_out_prefix_cmd,
+       "clear ip bgp A.B.C.D out A.B.C.D/M",
+       CLEAR_STR
+       IP_STR
+       BGP_STR
+       "BGP neighbor address to clear\n"
+       "Soft reconfig outbound update\n"
+       "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
+
+DEFUN (clear_ip_bgp_all_soft_out_prefix,
+       clear_ip_bgp_all_soft_out_prefix_cmd,
+       "clear ip bgp * soft out A.B.C.D/M",
+       CLEAR_STR
+       IP_STR
+       BGP_STR
+       "Clear all peers\n"
+       "Soft reconfig\n"
+       "Soft reconfig outbound update\n"
+       "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
+{
+  if (argc == 2)
+    return bgp_clear_vty (vty, argv[0], AFI_IP, SAFI_UNICAST, clear_all,
+                          BGP_CLEAR_SOFT_PREFIX, NULL, argv[1]);
+  
+  return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_all,
+                        BGP_CLEAR_SOFT_PREFIX, NULL, argv[0]);
+}
+
+ALIAS (clear_ip_bgp_all_soft_out_prefix,
+       clear_ip_bgp_all_out_prefix_cmd,
+       "clear ip bgp * out A.B.C.D/M",
+       CLEAR_STR
+       IP_STR
+       BGP_STR
+       "Clear all peers\n"
+       "Soft reconfig outbound update\n"
+       "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
+	   
+ALIAS (clear_ip_bgp_all_soft_out_prefix,
+       clear_ip_bgp_instance_all_soft_out_prefix_cmd,
+       "clear ip bgp view WORD * soft out A.B.C.D/M",
+       CLEAR_STR
+       IP_STR
+       BGP_STR
+       "BGP view\n"
+       "view name\n"
+       "Clear all peers\n"
+       "Soft reconfig\n"
+       "Soft reconfig outbound update\n"
+       "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
+	   
+DEFUN (clear_bgp_all_soft_out_prefix,
+       clear_bgp_all_soft_out_prefix_cmd,
+       "clear bgp * soft out A.B.C.D/M",
+       CLEAR_STR
+       BGP_STR
+       "Clear all peers\n"
+       "Soft reconfig\n"
+       "Soft reconfig outbound update\n"
+       "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
+{
+  if (argc == 2)
+    return bgp_clear_vty (vty, argv[0], AFI_IP6, SAFI_UNICAST, clear_all,
+                          BGP_CLEAR_SOFT_PREFIX, NULL, argv[1]);
+
+  return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_all,
+                        BGP_CLEAR_SOFT_PREFIX, NULL, argv[0]);
+}
+
+ALIAS (clear_bgp_all_soft_out_prefix,
+       clear_bgp_instance_all_soft_out_prefix_cmd,
+       "clear bgp view WORD * soft out A.B.C.D/M",
+       CLEAR_STR
+       BGP_STR
+       "BGP view\n"
+       "view name\n"
+       "Clear all peers\n"
+       "Soft reconfig\n"
+       "Soft reconfig outbound update\n"
+       "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
+
+ALIAS (clear_bgp_all_soft_out_prefix,
+       clear_bgp_all_out_prefix_cmd,
+       "clear bgp * out A.B.C.D/M",
+       CLEAR_STR
+       BGP_STR
+       "Clear all peers\n"
+       "Soft reconfig outbound update\n"
+       "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
+
+ALIAS (clear_bgp_all_soft_out_prefix,
+       clear_bgp_ipv6_all_soft_out_prefix_cmd,
+       "clear bgp ipv6 * soft out A.B.C.D/M",
+       CLEAR_STR
+       BGP_STR
+       "Address family\n"
+       "Clear all peers\n"
+       "Soft reconfig\n"
+       "Soft reconfig outbound update\n"
+       "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
+
+ALIAS (clear_bgp_all_soft_out_prefix,
+       clear_bgp_ipv6_all_out_prefix_cmd,
+       "clear bgp ipv6 * out A.B.C.D/M",
+       CLEAR_STR
+       BGP_STR
+       "Address family\n"
+       "Clear all peers\n"
+       "Soft reconfig outbound update\n"
+       "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
+	   
+DEFUN (clear_bgp_peer_soft_out_prefix,
+       clear_bgp_peer_soft_out_prefix_cmd,
+       "clear bgp (A.B.C.D|X:X::X:X) soft out A.B.C.D/M",
+       CLEAR_STR
+       BGP_STR
+       "BGP neighbor address to clear\n"
+       "BGP IPv6 neighbor to clear\n"
+       "Soft reconfig\n"
+       "Soft reconfig outbound update\n"
+       "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
+{
+  return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_peer,
+                        BGP_CLEAR_SOFT_OUT, argv[0], argv[1]);
+}
+
+ALIAS (clear_bgp_peer_soft_out_prefix,
+       clear_bgp_ipv6_peer_soft_out_prefix_cmd,
+       "clear bgp ipv6 (A.B.C.D|X:X::X:X) soft out A.B.C.D/M",
+       CLEAR_STR
+       BGP_STR
+       "Address family\n"
+       "BGP neighbor address to clear\n"
+       "BGP IPv6 neighbor to clear\n"
+       "Soft reconfig\n"
+       "Soft reconfig outbound update\n"
+       "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
+
+ALIAS (clear_bgp_peer_soft_out_prefix,
+       clear_bgp_peer_out_prefix_cmd,
+       "clear bgp (A.B.C.D|X:X::X:X) out A.B.C.D/M",
+       CLEAR_STR
+       BGP_STR
+       "BGP neighbor address to clear\n"
+       "BGP IPv6 neighbor to clear\n"
+       "Soft reconfig outbound update\n"
+       "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
+
+ALIAS (clear_bgp_peer_soft_out_prefix,
+       clear_bgp_ipv6_peer_out_prefix_cmd,
+       "clear bgp ipv6 (A.B.C.D|X:X::X:X) out A.B.C.D/M",
+       CLEAR_STR
+       BGP_STR
+       "Address family\n"
+       "BGP neighbor address to clear\n"
+       "BGP IPv6 neighbor to clear\n"
+       "Soft reconfig outbound update\n"
+       "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
+
+/* End of prefix-specific soft-reconfiguration */
+
 DEFUN (clear_ip_bgp_instance_all_ipv4_soft_out,
        clear_ip_bgp_instance_all_ipv4_soft_out_cmd,
        "clear ip bgp view WORD * ipv4 (unicast|multicast) soft out",
@@ -4489,10 +4794,10 @@ DEFUN (clear_ip_bgp_instance_all_ipv4_so
 {
   if (strncmp (argv[1], "m", 1) == 0)
     return bgp_clear_vty (vty, argv[0], AFI_IP, SAFI_MULTICAST, clear_all,
-                          BGP_CLEAR_SOFT_OUT, NULL);
+                          BGP_CLEAR_SOFT_OUT, NULL, NULL);
 
   return bgp_clear_vty (vty, argv[0], AFI_IP, SAFI_UNICAST, clear_all,
-                        BGP_CLEAR_SOFT_OUT, NULL);
+                        BGP_CLEAR_SOFT_OUT, NULL, NULL);
 }
 
 DEFUN (clear_ip_bgp_all_vpnv4_soft_out,
@@ -4508,7 +4813,7 @@ DEFUN (clear_ip_bgp_all_vpnv4_soft_out,
        "Soft reconfig outbound update\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_MPLS_VPN, clear_all,
-			BGP_CLEAR_SOFT_OUT, NULL);
+			BGP_CLEAR_SOFT_OUT, NULL, NULL);
 }
 
 ALIAS (clear_ip_bgp_all_vpnv4_soft_out,
@@ -4533,10 +4838,10 @@ DEFUN (clear_bgp_all_soft_out,
 {
   if (argc == 1)
     return bgp_clear_vty (vty, argv[0], AFI_IP6, SAFI_UNICAST, clear_all,
-                          BGP_CLEAR_SOFT_OUT, NULL);
+                          BGP_CLEAR_SOFT_OUT, NULL, NULL);
 
   return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_all,
-			BGP_CLEAR_SOFT_OUT, NULL);
+			BGP_CLEAR_SOFT_OUT, NULL, NULL);
 }
 
 ALIAS (clear_bgp_all_soft_out,
@@ -4588,7 +4893,7 @@ DEFUN (clear_ip_bgp_peer_soft_out,
        "Soft reconfig outbound update\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_peer,
-			BGP_CLEAR_SOFT_OUT, argv[0]);
+			BGP_CLEAR_SOFT_OUT, argv[0], NULL);
 }
 
 ALIAS (clear_ip_bgp_peer_soft_out,
@@ -4615,10 +4920,10 @@ DEFUN (clear_ip_bgp_peer_ipv4_soft_out,
 {
   if (strncmp (argv[1], "m", 1) == 0)
     return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_MULTICAST, clear_peer,
-			  BGP_CLEAR_SOFT_OUT, argv[0]);
+			  BGP_CLEAR_SOFT_OUT, argv[0], NULL);
 
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_peer,
-			BGP_CLEAR_SOFT_OUT, argv[0]);
+			BGP_CLEAR_SOFT_OUT, argv[0], NULL);
 }
 
 ALIAS (clear_ip_bgp_peer_ipv4_soft_out,
@@ -4646,7 +4951,7 @@ DEFUN (clear_ip_bgp_peer_vpnv4_soft_out,
        "Soft reconfig outbound update\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_MPLS_VPN, clear_peer,
-			BGP_CLEAR_SOFT_OUT, argv[0]);
+			BGP_CLEAR_SOFT_OUT, argv[0], NULL);
 }
 
 ALIAS (clear_ip_bgp_peer_vpnv4_soft_out,
@@ -4671,7 +4976,7 @@ DEFUN (clear_bgp_peer_soft_out,
        "Soft reconfig outbound update\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_peer,
-			BGP_CLEAR_SOFT_OUT, argv[0]);
+			BGP_CLEAR_SOFT_OUT, argv[0], NULL);
 }
 
 ALIAS (clear_bgp_peer_soft_out,
@@ -4716,7 +5021,7 @@ DEFUN (clear_ip_bgp_peer_group_soft_out,
        "Soft reconfig outbound update\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_group,
-			BGP_CLEAR_SOFT_OUT, argv[0]);
+			BGP_CLEAR_SOFT_OUT, argv[0], NULL);
 }
 
 ALIAS (clear_ip_bgp_peer_group_soft_out,
@@ -4745,10 +5050,10 @@ DEFUN (clear_ip_bgp_peer_group_ipv4_soft
 {
   if (strncmp (argv[1], "m", 1) == 0)
     return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_MULTICAST, clear_group,
-			  BGP_CLEAR_SOFT_OUT, argv[0]);
+			  BGP_CLEAR_SOFT_OUT, argv[0], NULL);
 
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_group,
-			BGP_CLEAR_SOFT_OUT, argv[0]);
+			BGP_CLEAR_SOFT_OUT, argv[0], NULL);
 }
 
 ALIAS (clear_ip_bgp_peer_group_ipv4_soft_out,
@@ -4775,7 +5080,7 @@ DEFUN (clear_bgp_peer_group_soft_out,
        "Soft reconfig outbound update\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_group,
-			BGP_CLEAR_SOFT_OUT, argv[0]);
+			BGP_CLEAR_SOFT_OUT, argv[0], NULL);
 }
 
 ALIAS (clear_bgp_peer_group_soft_out,
@@ -4819,7 +5124,7 @@ DEFUN (clear_ip_bgp_external_soft_out,
        "Soft reconfig outbound update\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_external,
-			BGP_CLEAR_SOFT_OUT, NULL);
+			BGP_CLEAR_SOFT_OUT, NULL, NULL);
 }
 
 ALIAS (clear_ip_bgp_external_soft_out,
@@ -4846,10 +5151,10 @@ DEFUN (clear_ip_bgp_external_ipv4_soft_o
 {
   if (strncmp (argv[0], "m", 1) == 0)
     return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_MULTICAST, clear_external,
-			  BGP_CLEAR_SOFT_OUT, NULL);
+			  BGP_CLEAR_SOFT_OUT, NULL, NULL);
 
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_external,
-			BGP_CLEAR_SOFT_OUT, NULL);
+			BGP_CLEAR_SOFT_OUT, NULL, NULL);
 }
 
 ALIAS (clear_ip_bgp_external_ipv4_soft_out,
@@ -4874,7 +5179,7 @@ DEFUN (clear_bgp_external_soft_out,
        "Soft reconfig outbound update\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_external,
-			BGP_CLEAR_SOFT_OUT, NULL);
+			BGP_CLEAR_SOFT_OUT, NULL, NULL);
 }
 
 ALIAS (clear_bgp_external_soft_out,
@@ -4915,7 +5220,7 @@ DEFUN (clear_ip_bgp_as_soft_out,
        "Soft reconfig outbound update\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_as,
-			BGP_CLEAR_SOFT_OUT, argv[0]);
+			BGP_CLEAR_SOFT_OUT, argv[0], NULL);
 }
 
 ALIAS (clear_ip_bgp_as_soft_out,
@@ -4942,10 +5247,10 @@ DEFUN (clear_ip_bgp_as_ipv4_soft_out,
 {
   if (strncmp (argv[1], "m", 1) == 0)
     return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_MULTICAST, clear_as,
-			  BGP_CLEAR_SOFT_OUT, argv[0]);
+			  BGP_CLEAR_SOFT_OUT, argv[0], NULL);
 
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_as,
-			BGP_CLEAR_SOFT_OUT, argv[0]);
+			BGP_CLEAR_SOFT_OUT, argv[0], NULL);
 }
 
 ALIAS (clear_ip_bgp_as_ipv4_soft_out,
@@ -4973,7 +5278,7 @@ DEFUN (clear_ip_bgp_as_vpnv4_soft_out,
        "Soft reconfig outbound update\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_MPLS_VPN, clear_as,
-			BGP_CLEAR_SOFT_OUT, argv[0]);
+			BGP_CLEAR_SOFT_OUT, argv[0], NULL);
 }
 
 ALIAS (clear_ip_bgp_as_vpnv4_soft_out,
@@ -4997,7 +5302,7 @@ DEFUN (clear_bgp_as_soft_out,
        "Soft reconfig outbound update\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_as,
-			BGP_CLEAR_SOFT_OUT, argv[0]);
+			BGP_CLEAR_SOFT_OUT, argv[0], NULL);
 }
 
 ALIAS (clear_bgp_as_soft_out,
@@ -5040,10 +5345,10 @@ DEFUN (clear_ip_bgp_all_soft_in,
 {
   if (argc == 1)
     return bgp_clear_vty (vty, argv[0], AFI_IP, SAFI_UNICAST, clear_all,
-                          BGP_CLEAR_SOFT_IN, NULL);
+                          BGP_CLEAR_SOFT_IN, NULL, NULL);
 
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_all,
-			BGP_CLEAR_SOFT_IN, NULL);
+			BGP_CLEAR_SOFT_IN, NULL, NULL);
 }
 
 ALIAS (clear_ip_bgp_all_soft_in,
@@ -5079,10 +5384,10 @@ DEFUN (clear_ip_bgp_all_in_prefix_filter
 {
   if (argc== 1)
     return bgp_clear_vty (vty, argv[0], AFI_IP, SAFI_UNICAST, clear_all,
-                          BGP_CLEAR_SOFT_IN_ORF_PREFIX, NULL);
+                          BGP_CLEAR_SOFT_IN_ORF_PREFIX, NULL, NULL);
 
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_all,
-			BGP_CLEAR_SOFT_IN_ORF_PREFIX, NULL);
+			BGP_CLEAR_SOFT_IN_ORF_PREFIX, NULL, NULL);
 }
 
 ALIAS (clear_ip_bgp_all_in_prefix_filter,
@@ -5113,10 +5418,10 @@ DEFUN (clear_ip_bgp_all_ipv4_soft_in,
 {
   if (strncmp (argv[0], "m", 1) == 0)
     return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_MULTICAST, clear_all,
-			  BGP_CLEAR_SOFT_IN, NULL);
+			  BGP_CLEAR_SOFT_IN, NULL, NULL);
 
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_all,
-			BGP_CLEAR_SOFT_IN, NULL);
+			BGP_CLEAR_SOFT_IN, NULL, NULL);
 }
 
 ALIAS (clear_ip_bgp_all_ipv4_soft_in,
@@ -5148,10 +5453,10 @@ DEFUN (clear_ip_bgp_instance_all_ipv4_so
 {
   if (strncmp (argv[1], "m", 1) == 0)
     return bgp_clear_vty (vty, argv[0], AFI_IP, SAFI_MULTICAST, clear_all,
-                          BGP_CLEAR_SOFT_IN, NULL);
+                          BGP_CLEAR_SOFT_IN, NULL, NULL);
 
   return bgp_clear_vty (vty, argv[0], AFI_IP, SAFI_UNICAST, clear_all,
-                        BGP_CLEAR_SOFT_IN, NULL);
+                        BGP_CLEAR_SOFT_IN, NULL, NULL);
 }
 
 DEFUN (clear_ip_bgp_all_ipv4_in_prefix_filter,
@@ -5169,10 +5474,10 @@ DEFUN (clear_ip_bgp_all_ipv4_in_prefix_f
 {
   if (strncmp (argv[0], "m", 1) == 0)
     return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_MULTICAST, clear_all,
-			  BGP_CLEAR_SOFT_IN_ORF_PREFIX, NULL);
+			  BGP_CLEAR_SOFT_IN_ORF_PREFIX, NULL, NULL);
 
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_all,
-			BGP_CLEAR_SOFT_IN_ORF_PREFIX, NULL);
+			BGP_CLEAR_SOFT_IN_ORF_PREFIX, NULL, NULL);
 }
 
 DEFUN (clear_ip_bgp_instance_all_ipv4_in_prefix_filter,
@@ -5190,10 +5495,10 @@ DEFUN (clear_ip_bgp_instance_all_ipv4_in
 {
   if (strncmp (argv[1], "m", 1) == 0)
     return bgp_clear_vty (vty, argv[0], AFI_IP, SAFI_MULTICAST, clear_all,
-                          BGP_CLEAR_SOFT_IN_ORF_PREFIX, NULL);
+                          BGP_CLEAR_SOFT_IN_ORF_PREFIX, NULL, NULL);
 
   return bgp_clear_vty (vty, argv[0], AFI_IP, SAFI_UNICAST, clear_all,
-                        BGP_CLEAR_SOFT_IN_ORF_PREFIX, NULL);
+                        BGP_CLEAR_SOFT_IN_ORF_PREFIX, NULL, NULL);
 }
 
 DEFUN (clear_ip_bgp_all_vpnv4_soft_in,
@@ -5209,7 +5514,7 @@ DEFUN (clear_ip_bgp_all_vpnv4_soft_in,
        "Soft reconfig inbound update\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_MPLS_VPN, clear_all,
-			BGP_CLEAR_SOFT_IN, NULL);
+			BGP_CLEAR_SOFT_IN, NULL, NULL);
 }
 
 ALIAS (clear_ip_bgp_all_vpnv4_soft_in,
@@ -5234,10 +5539,10 @@ DEFUN (clear_bgp_all_soft_in,
 {
   if (argc == 1)
     return bgp_clear_vty (vty, argv[0], AFI_IP6, SAFI_UNICAST, clear_all,
-                        BGP_CLEAR_SOFT_IN, NULL);
+                        BGP_CLEAR_SOFT_IN, NULL, NULL);
 
   return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_all,
-			BGP_CLEAR_SOFT_IN, NULL);
+			BGP_CLEAR_SOFT_IN, NULL, NULL);
 }
 
 ALIAS (clear_bgp_all_soft_in,
@@ -5288,7 +5593,7 @@ DEFUN (clear_bgp_all_in_prefix_filter,
        "Push out prefix-list ORF and do inbound soft reconfig\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_all,
-			BGP_CLEAR_SOFT_IN_ORF_PREFIX, NULL);
+			BGP_CLEAR_SOFT_IN_ORF_PREFIX, NULL, NULL);
 }
 
 ALIAS (clear_bgp_all_in_prefix_filter,
@@ -5312,7 +5617,7 @@ DEFUN (clear_ip_bgp_peer_soft_in,
        "Soft reconfig inbound update\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_peer,
-			BGP_CLEAR_SOFT_IN, argv[0]);
+			BGP_CLEAR_SOFT_IN, argv[0], NULL);
 }
 
 ALIAS (clear_ip_bgp_peer_soft_in,
@@ -5335,7 +5640,7 @@ DEFUN (clear_ip_bgp_peer_in_prefix_filte
        "Push out the existing ORF prefix-list\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_peer,
-			BGP_CLEAR_SOFT_IN_ORF_PREFIX, argv[0]);
+			BGP_CLEAR_SOFT_IN_ORF_PREFIX, argv[0], NULL);
 }
 
 DEFUN (clear_ip_bgp_peer_ipv4_soft_in,
@@ -5353,10 +5658,10 @@ DEFUN (clear_ip_bgp_peer_ipv4_soft_in,
 {
   if (strncmp (argv[1], "m", 1) == 0)
     return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_MULTICAST, clear_peer,
-			  BGP_CLEAR_SOFT_IN, argv[0]);
+			  BGP_CLEAR_SOFT_IN, argv[0], NULL);
 
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_peer,
-			BGP_CLEAR_SOFT_IN, argv[0]);
+			BGP_CLEAR_SOFT_IN, argv[0], NULL);
 }
 
 ALIAS (clear_ip_bgp_peer_ipv4_soft_in,
@@ -5386,10 +5691,10 @@ DEFUN (clear_ip_bgp_peer_ipv4_in_prefix_
 {
   if (strncmp (argv[1], "m", 1) == 0)
     return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_MULTICAST, clear_peer,
-			  BGP_CLEAR_SOFT_IN_ORF_PREFIX, argv[0]);
+			  BGP_CLEAR_SOFT_IN_ORF_PREFIX, argv[0], NULL);
 
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_peer,
-			BGP_CLEAR_SOFT_IN_ORF_PREFIX, argv[0]);
+			BGP_CLEAR_SOFT_IN_ORF_PREFIX, argv[0], NULL);
 }
 
 DEFUN (clear_ip_bgp_peer_vpnv4_soft_in,
@@ -5405,7 +5710,7 @@ DEFUN (clear_ip_bgp_peer_vpnv4_soft_in,
        "Soft reconfig inbound update\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_MPLS_VPN, clear_peer,
-			BGP_CLEAR_SOFT_IN, argv[0]);
+			BGP_CLEAR_SOFT_IN, argv[0], NULL);
 }
 
 ALIAS (clear_ip_bgp_peer_vpnv4_soft_in,
@@ -5430,7 +5735,7 @@ DEFUN (clear_bgp_peer_soft_in,
        "Soft reconfig inbound update\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_peer,
-			BGP_CLEAR_SOFT_IN, argv[0]);
+			BGP_CLEAR_SOFT_IN, argv[0], NULL);
 }
 
 ALIAS (clear_bgp_peer_soft_in,
@@ -5474,7 +5779,7 @@ DEFUN (clear_bgp_peer_in_prefix_filter,
        "Push out the existing ORF prefix-list\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_peer,
-			BGP_CLEAR_SOFT_IN_ORF_PREFIX, argv[0]);
+			BGP_CLEAR_SOFT_IN_ORF_PREFIX, argv[0], NULL);
 }
 
 ALIAS (clear_bgp_peer_in_prefix_filter,
@@ -5500,7 +5805,7 @@ DEFUN (clear_ip_bgp_peer_group_soft_in,
        "Soft reconfig inbound update\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_group,
-			BGP_CLEAR_SOFT_IN, argv[0]);
+			BGP_CLEAR_SOFT_IN, argv[0], NULL);
 }
 
 ALIAS (clear_ip_bgp_peer_group_soft_in,
@@ -5525,7 +5830,7 @@ DEFUN (clear_ip_bgp_peer_group_in_prefix
        "Push out prefix-list ORF and do inbound soft reconfig\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_group,
-			BGP_CLEAR_SOFT_IN_ORF_PREFIX, argv[0]);
+			BGP_CLEAR_SOFT_IN_ORF_PREFIX, argv[0], NULL);
 }
 
 DEFUN (clear_ip_bgp_peer_group_ipv4_soft_in,
@@ -5544,10 +5849,10 @@ DEFUN (clear_ip_bgp_peer_group_ipv4_soft
 {
   if (strncmp (argv[1], "m", 1) == 0)
     return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_MULTICAST, clear_group,
-			  BGP_CLEAR_SOFT_IN, argv[0]);
+			  BGP_CLEAR_SOFT_IN, argv[0], NULL);
 
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_group,
-			BGP_CLEAR_SOFT_IN, argv[0]);
+			BGP_CLEAR_SOFT_IN, argv[0], NULL);
 }
 
 ALIAS (clear_ip_bgp_peer_group_ipv4_soft_in,
@@ -5579,10 +5884,10 @@ DEFUN (clear_ip_bgp_peer_group_ipv4_in_p
 {
   if (strncmp (argv[1], "m", 1) == 0)
     return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_MULTICAST, clear_group,
-			  BGP_CLEAR_SOFT_IN_ORF_PREFIX, argv[0]);
+			  BGP_CLEAR_SOFT_IN_ORF_PREFIX, argv[0], NULL);
 
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_group,
-			BGP_CLEAR_SOFT_IN_ORF_PREFIX, argv[0]);
+			BGP_CLEAR_SOFT_IN_ORF_PREFIX, argv[0], NULL);
 }
 
 DEFUN (clear_bgp_peer_group_soft_in,
@@ -5596,7 +5901,7 @@ DEFUN (clear_bgp_peer_group_soft_in,
        "Soft reconfig inbound update\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_group,
-			BGP_CLEAR_SOFT_IN, argv[0]);
+			BGP_CLEAR_SOFT_IN, argv[0], NULL);
 }
 
 ALIAS (clear_bgp_peer_group_soft_in,
@@ -5640,7 +5945,7 @@ DEFUN (clear_bgp_peer_group_in_prefix_fi
        "Push out prefix-list ORF and do inbound soft reconfig\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_group,
-			BGP_CLEAR_SOFT_IN_ORF_PREFIX, argv[0]);
+			BGP_CLEAR_SOFT_IN_ORF_PREFIX, argv[0], NULL);
 }
 
 ALIAS (clear_bgp_peer_group_in_prefix_filter,
@@ -5665,7 +5970,7 @@ DEFUN (clear_ip_bgp_external_soft_in,
        "Soft reconfig inbound update\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_external,
-			BGP_CLEAR_SOFT_IN, NULL);
+			BGP_CLEAR_SOFT_IN, NULL, NULL);
 }
 
 ALIAS (clear_ip_bgp_external_soft_in,
@@ -5688,7 +5993,7 @@ DEFUN (clear_ip_bgp_external_in_prefix_f
        "Push out prefix-list ORF and do inbound soft reconfig\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_external,
-			BGP_CLEAR_SOFT_IN_ORF_PREFIX, NULL);
+			BGP_CLEAR_SOFT_IN_ORF_PREFIX, NULL, NULL);
 }
 
 DEFUN (clear_ip_bgp_external_ipv4_soft_in,
@@ -5706,10 +6011,10 @@ DEFUN (clear_ip_bgp_external_ipv4_soft_i
 {
   if (strncmp (argv[0], "m", 1) == 0)
     return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_MULTICAST, clear_external,
-			  BGP_CLEAR_SOFT_IN, NULL);
+			  BGP_CLEAR_SOFT_IN, NULL, NULL);
 
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_external,
-			BGP_CLEAR_SOFT_IN, NULL);
+			BGP_CLEAR_SOFT_IN, NULL, NULL);
 }
 
 ALIAS (clear_ip_bgp_external_ipv4_soft_in,
@@ -5739,10 +6044,10 @@ DEFUN (clear_ip_bgp_external_ipv4_in_pre
 {
   if (strncmp (argv[0], "m", 1) == 0)
     return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_MULTICAST, clear_external,
-			  BGP_CLEAR_SOFT_IN_ORF_PREFIX, NULL);
+			  BGP_CLEAR_SOFT_IN_ORF_PREFIX, NULL, NULL);
 
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_external,
-			BGP_CLEAR_SOFT_IN_ORF_PREFIX, NULL);
+			BGP_CLEAR_SOFT_IN_ORF_PREFIX, NULL, NULL);
 }
 
 DEFUN (clear_bgp_external_soft_in,
@@ -5755,7 +6060,7 @@ DEFUN (clear_bgp_external_soft_in,
        "Soft reconfig inbound update\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_external,
-			BGP_CLEAR_SOFT_IN, NULL);
+			BGP_CLEAR_SOFT_IN, NULL, NULL);
 }
 
 ALIAS (clear_bgp_external_soft_in,
@@ -5795,7 +6100,7 @@ DEFUN (clear_bgp_external_in_prefix_filt
        "Push out prefix-list ORF and do inbound soft reconfig\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_external,
-			BGP_CLEAR_SOFT_IN_ORF_PREFIX, NULL);
+			BGP_CLEAR_SOFT_IN_ORF_PREFIX, NULL, NULL);
 }
 
 ALIAS (clear_bgp_external_in_prefix_filter,
@@ -5819,7 +6124,7 @@ DEFUN (clear_ip_bgp_as_soft_in,
        "Soft reconfig inbound update\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_as,
-			BGP_CLEAR_SOFT_IN, argv[0]);
+			BGP_CLEAR_SOFT_IN, argv[0], NULL);
 }
 
 ALIAS (clear_ip_bgp_as_soft_in,
@@ -5842,7 +6147,7 @@ DEFUN (clear_ip_bgp_as_in_prefix_filter,
        "Push out prefix-list ORF and do inbound soft reconfig\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_as,
-			BGP_CLEAR_SOFT_IN_ORF_PREFIX, argv[0]);
+			BGP_CLEAR_SOFT_IN_ORF_PREFIX, argv[0], NULL);
 }
 
 DEFUN (clear_ip_bgp_as_ipv4_soft_in,
@@ -5860,10 +6165,10 @@ DEFUN (clear_ip_bgp_as_ipv4_soft_in,
 {
   if (strncmp (argv[1], "m", 1) == 0)
     return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_MULTICAST, clear_as,
-			  BGP_CLEAR_SOFT_IN, argv[0]);
+			  BGP_CLEAR_SOFT_IN, argv[0], NULL);
 
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_as,
-			BGP_CLEAR_SOFT_IN, argv[0]);
+			BGP_CLEAR_SOFT_IN, argv[0], NULL);
 }
 
 ALIAS (clear_ip_bgp_as_ipv4_soft_in,
@@ -5893,10 +6198,10 @@ DEFUN (clear_ip_bgp_as_ipv4_in_prefix_fi
 {
   if (strncmp (argv[1], "m", 1) == 0)
     return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_MULTICAST, clear_as,
-			  BGP_CLEAR_SOFT_IN_ORF_PREFIX, argv[0]);
+			  BGP_CLEAR_SOFT_IN_ORF_PREFIX, argv[0], NULL);
 
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_as,
-			BGP_CLEAR_SOFT_IN_ORF_PREFIX, argv[0]);
+			BGP_CLEAR_SOFT_IN_ORF_PREFIX, argv[0], NULL);
 }
 
 DEFUN (clear_ip_bgp_as_vpnv4_soft_in,
@@ -5912,7 +6217,7 @@ DEFUN (clear_ip_bgp_as_vpnv4_soft_in,
        "Soft reconfig inbound update\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_MPLS_VPN, clear_as,
-			BGP_CLEAR_SOFT_IN, argv[0]);
+			BGP_CLEAR_SOFT_IN, argv[0], NULL);
 }
 
 ALIAS (clear_ip_bgp_as_vpnv4_soft_in,
@@ -5936,7 +6241,7 @@ DEFUN (clear_bgp_as_soft_in,
        "Soft reconfig inbound update\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_as,
-			BGP_CLEAR_SOFT_IN, argv[0]);
+			BGP_CLEAR_SOFT_IN, argv[0], NULL);
 }
 
 ALIAS (clear_bgp_as_soft_in,
@@ -5976,7 +6281,7 @@ DEFUN (clear_bgp_as_in_prefix_filter,
        "Push out prefix-list ORF and do inbound soft reconfig\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_as,
-			BGP_CLEAR_SOFT_IN_ORF_PREFIX, argv[0]);
+			BGP_CLEAR_SOFT_IN_ORF_PREFIX, argv[0], NULL);
 }
 
 ALIAS (clear_bgp_as_in_prefix_filter,
@@ -6001,10 +6306,10 @@ DEFUN (clear_ip_bgp_all_soft,
 {
   if (argc == 1)
     return bgp_clear_vty (vty, argv[0], AFI_IP, SAFI_UNICAST, clear_all,
-                        BGP_CLEAR_SOFT_BOTH, NULL);
+                        BGP_CLEAR_SOFT_BOTH, NULL, NULL);
 
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_all,
-			BGP_CLEAR_SOFT_BOTH, NULL);
+			BGP_CLEAR_SOFT_BOTH, NULL, NULL);
 }
 
 ALIAS (clear_ip_bgp_all_soft,
@@ -6033,10 +6338,10 @@ DEFUN (clear_ip_bgp_all_ipv4_soft,
 {
   if (strncmp (argv[0], "m", 1) == 0)
     return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_MULTICAST, clear_all,
-			  BGP_CLEAR_SOFT_BOTH, NULL);
+			  BGP_CLEAR_SOFT_BOTH, NULL, NULL);
 
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_all,
-			BGP_CLEAR_SOFT_BOTH, NULL);
+			BGP_CLEAR_SOFT_BOTH, NULL, NULL);
 }
 
 DEFUN (clear_ip_bgp_instance_all_ipv4_soft,
@@ -6055,10 +6360,10 @@ DEFUN (clear_ip_bgp_instance_all_ipv4_so
 {
   if (strncmp (argv[1], "m", 1) == 0)
     return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_MULTICAST, clear_all,
-                          BGP_CLEAR_SOFT_BOTH, NULL);
+                          BGP_CLEAR_SOFT_BOTH, NULL, NULL);
 
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_all,
-                        BGP_CLEAR_SOFT_BOTH, NULL);
+                        BGP_CLEAR_SOFT_BOTH, NULL, NULL);
 }
 
 DEFUN (clear_ip_bgp_all_vpnv4_soft,
@@ -6073,7 +6378,7 @@ DEFUN (clear_ip_bgp_all_vpnv4_soft,
        "Soft reconfig\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_MPLS_VPN, clear_all,
-			BGP_CLEAR_SOFT_BOTH, argv[0]);
+			BGP_CLEAR_SOFT_BOTH, argv[0], NULL);
 }
 
 DEFUN (clear_bgp_all_soft,
@@ -6086,10 +6391,10 @@ DEFUN (clear_bgp_all_soft,
 {
   if (argc == 1)
     return bgp_clear_vty (vty, argv[0], AFI_IP6, SAFI_UNICAST, clear_all,
-                        BGP_CLEAR_SOFT_BOTH, argv[0]);
+                        BGP_CLEAR_SOFT_BOTH, argv[0], NULL);
  
   return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_all,
-			BGP_CLEAR_SOFT_BOTH, argv[0]);
+			BGP_CLEAR_SOFT_BOTH, argv[0], NULL);
 }
 
 ALIAS (clear_bgp_all_soft,
@@ -6121,7 +6426,7 @@ DEFUN (clear_ip_bgp_peer_soft,
        "Soft reconfig\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_peer,
-			BGP_CLEAR_SOFT_BOTH, argv[0]);
+			BGP_CLEAR_SOFT_BOTH, argv[0], NULL);
 }
 
 DEFUN (clear_ip_bgp_peer_ipv4_soft,
@@ -6138,10 +6443,10 @@ DEFUN (clear_ip_bgp_peer_ipv4_soft,
 {
   if (strncmp (argv[1], "m", 1) == 0)
     return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_MULTICAST, clear_peer,
-			  BGP_CLEAR_SOFT_BOTH, argv[0]);
+			  BGP_CLEAR_SOFT_BOTH, argv[0], NULL);
 
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_peer,
-			BGP_CLEAR_SOFT_BOTH, argv[0]);
+			BGP_CLEAR_SOFT_BOTH, argv[0], NULL);
 }
 
 DEFUN (clear_ip_bgp_peer_vpnv4_soft,
@@ -6156,7 +6461,7 @@ DEFUN (clear_ip_bgp_peer_vpnv4_soft,
        "Soft reconfig\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_MPLS_VPN, clear_peer,
-			BGP_CLEAR_SOFT_BOTH, argv[0]);
+			BGP_CLEAR_SOFT_BOTH, argv[0], NULL);
 }
 
 DEFUN (clear_bgp_peer_soft,
@@ -6169,7 +6474,7 @@ DEFUN (clear_bgp_peer_soft,
        "Soft reconfig\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_peer,
-			BGP_CLEAR_SOFT_BOTH, argv[0]);
+			BGP_CLEAR_SOFT_BOTH, argv[0], NULL);
 }
 
 ALIAS (clear_bgp_peer_soft,
@@ -6193,7 +6498,7 @@ DEFUN (clear_ip_bgp_peer_group_soft,
        "Soft reconfig\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_group,
-			BGP_CLEAR_SOFT_BOTH, argv[0]);
+			BGP_CLEAR_SOFT_BOTH, argv[0], NULL);
 }
 
 DEFUN (clear_ip_bgp_peer_group_ipv4_soft,
@@ -6211,10 +6516,10 @@ DEFUN (clear_ip_bgp_peer_group_ipv4_soft
 {
   if (strncmp (argv[1], "m", 1) == 0)
     return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_MULTICAST, clear_group,
-			  BGP_CLEAR_SOFT_BOTH, argv[0]);
+			  BGP_CLEAR_SOFT_BOTH, argv[0], NULL);
 
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_group,
-			BGP_CLEAR_SOFT_BOTH, argv[0]);
+			BGP_CLEAR_SOFT_BOTH, argv[0], NULL);
 }
 
 DEFUN (clear_bgp_peer_group_soft,
@@ -6227,7 +6532,7 @@ DEFUN (clear_bgp_peer_group_soft,
        "Soft reconfig\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_group,
-			BGP_CLEAR_SOFT_BOTH, argv[0]);
+			BGP_CLEAR_SOFT_BOTH, argv[0], NULL);
 }
 
 ALIAS (clear_bgp_peer_group_soft,
@@ -6250,7 +6555,7 @@ DEFUN (clear_ip_bgp_external_soft,
        "Soft reconfig\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_external,
-			BGP_CLEAR_SOFT_BOTH, NULL);
+			BGP_CLEAR_SOFT_BOTH, NULL, NULL);
 }
 
 DEFUN (clear_ip_bgp_external_ipv4_soft,
@@ -6267,10 +6572,10 @@ DEFUN (clear_ip_bgp_external_ipv4_soft,
 {
   if (strncmp (argv[0], "m", 1) == 0)
     return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_MULTICAST, clear_external,
-			  BGP_CLEAR_SOFT_BOTH, NULL);
+			  BGP_CLEAR_SOFT_BOTH, NULL, NULL);
 
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_external,
-			BGP_CLEAR_SOFT_BOTH, NULL);
+			BGP_CLEAR_SOFT_BOTH, NULL, NULL);
 }
 
 DEFUN (clear_bgp_external_soft,
@@ -6282,7 +6587,7 @@ DEFUN (clear_bgp_external_soft,
        "Soft reconfig\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_external,
-			BGP_CLEAR_SOFT_BOTH, NULL);
+			BGP_CLEAR_SOFT_BOTH, NULL, NULL);
 }
 
 ALIAS (clear_bgp_external_soft,
@@ -6304,7 +6609,7 @@ DEFUN (clear_ip_bgp_as_soft,
        "Soft reconfig\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_as,
-			BGP_CLEAR_SOFT_BOTH, argv[0]);
+			BGP_CLEAR_SOFT_BOTH, argv[0], NULL);
 }
 
 DEFUN (clear_ip_bgp_as_ipv4_soft,
@@ -6321,10 +6626,10 @@ DEFUN (clear_ip_bgp_as_ipv4_soft,
 {
   if (strncmp (argv[1], "m", 1) == 0)
     return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_MULTICAST, clear_as,
-			  BGP_CLEAR_SOFT_BOTH, argv[0]);
+			  BGP_CLEAR_SOFT_BOTH, argv[0], NULL);
 
   return bgp_clear_vty (vty, NULL,AFI_IP, SAFI_UNICAST, clear_as,
-			BGP_CLEAR_SOFT_BOTH, argv[0]);
+			BGP_CLEAR_SOFT_BOTH, argv[0], NULL);
 }
 
 DEFUN (clear_ip_bgp_as_vpnv4_soft,
@@ -6339,7 +6644,7 @@ DEFUN (clear_ip_bgp_as_vpnv4_soft,
        "Soft reconfig\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_MPLS_VPN, clear_as,
-			BGP_CLEAR_SOFT_BOTH, argv[0]);
+			BGP_CLEAR_SOFT_BOTH, argv[0], NULL);
 }
 
 DEFUN (clear_bgp_as_soft,
@@ -6351,7 +6656,7 @@ DEFUN (clear_bgp_as_soft,
        "Soft reconfig\n")
 {
   return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_as,
-			BGP_CLEAR_SOFT_BOTH, argv[0]);
+			BGP_CLEAR_SOFT_BOTH, argv[0], NULL);
 }
 
 ALIAS (clear_bgp_as_soft,
@@ -6375,10 +6680,10 @@ DEFUN (clear_bgp_all_rsclient,
 {
   if (argc == 1)
     return bgp_clear_vty (vty, argv[0], AFI_IP6, SAFI_UNICAST, clear_all,
-                          BGP_CLEAR_SOFT_RSCLIENT, NULL);
+                          BGP_CLEAR_SOFT_RSCLIENT, NULL, NULL);
 
   return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_all,
-                        BGP_CLEAR_SOFT_RSCLIENT, NULL);
+                        BGP_CLEAR_SOFT_RSCLIENT, NULL, NULL);
 }
 
 ALIAS (clear_bgp_all_rsclient,
@@ -6423,10 +6728,10 @@ DEFUN (clear_ip_bgp_all_rsclient,
 {
   if (argc == 1)
     return bgp_clear_vty (vty, argv[0], AFI_IP, SAFI_UNICAST, clear_all,
-                          BGP_CLEAR_SOFT_RSCLIENT, NULL);
+                          BGP_CLEAR_SOFT_RSCLIENT, NULL, NULL);
 
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_all,
-                        BGP_CLEAR_SOFT_RSCLIENT, NULL);
+                        BGP_CLEAR_SOFT_RSCLIENT, NULL, NULL);
 }
 
 ALIAS (clear_ip_bgp_all_rsclient,
@@ -6452,10 +6757,10 @@ DEFUN (clear_bgp_peer_rsclient,
 {
   if (argc == 2)
     return bgp_clear_vty (vty, argv[0], AFI_IP6, SAFI_UNICAST, clear_peer,
-                          BGP_CLEAR_SOFT_RSCLIENT, argv[1]);
+                          BGP_CLEAR_SOFT_RSCLIENT, argv[1], NULL);
 
   return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_peer,
-                        BGP_CLEAR_SOFT_RSCLIENT, argv[0]);
+                        BGP_CLEAR_SOFT_RSCLIENT, argv[0], NULL);
 }
 
 ALIAS (clear_bgp_peer_rsclient,
@@ -6504,10 +6809,10 @@ DEFUN (clear_ip_bgp_peer_rsclient,
 {
   if (argc == 2)
     return bgp_clear_vty (vty, argv[0], AFI_IP, SAFI_UNICAST, clear_peer,
-                          BGP_CLEAR_SOFT_RSCLIENT, argv[1]);
+                          BGP_CLEAR_SOFT_RSCLIENT, argv[1], NULL);
 
   return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_peer,
-                        BGP_CLEAR_SOFT_RSCLIENT, argv[0]);
+                        BGP_CLEAR_SOFT_RSCLIENT, argv[0], NULL);
 }
 
 ALIAS (clear_ip_bgp_peer_rsclient,
@@ -8787,6 +9092,577 @@ bgp_config_write_redistribute (struct vt
   return *write;
 }
 
+/* CoS-Capability */
+DEFUN (cos_capability,
+       cos_capability_cmd,
+       "bgp cos-capability WORD",
+       BGP_STR
+       "Enable CoS-Capability\n"
+       "Enabled Classes, Comma-separated (e.g. BE,EF,AF,LE)\n")
+{
+  struct bgp *bgp;
+  char * sep;
+  u_int8_t value;
+
+  bgp = vty->index;
+
+  value = bgp->cos;
+  if (value == 0) 
+    value |= 0x80;
+
+  sep = strtok (argv[0]," ,");
+  while (sep!=NULL)
+    {
+      vty_out (vty, "%s%s", sep, VTY_NEWLINE);
+      if (sep[0] == 'E' || sep[0] == 'e')
+        value |= 0x40;
+      else if (sep[0] == 'A' || sep[0] == 'a')
+        value |= 0x20;
+      else if (sep[0] == 'L' || sep[0] == 'l')
+        value |= 0x10; 
+      else if (sep[0] == 'B' || sep[0] == 'b')
+        value |= 0x80;
+      sep = strtok (NULL, " ,");
+    }
+  bgp->cos = value;
+
+  return 0;
+}
+
+DEFUN (no_cos_capability,
+       no_cos_capability_cmd,
+       "no bgp cos-capability WORD",
+       NO_STR
+       BGP_STR
+       "Disable CoS-Capability\n"
+       "Disabled Classes, Comma-separated (e.g. EF,AF,LE)\n")
+{
+  struct bgp *bgp;
+  char *sep;
+  u_int8_t value;
+
+  bgp = vty->index;
+
+  value = bgp->cos;
+
+  sep = strtok (argv[0], " ,");
+  while (sep!=NULL)
+    {
+      if (sep[0] == 'E' || sep[0] == 'e')
+        value &= 0xB0;
+      else if (sep[0] == 'A' || sep[0] == 'a')
+        value &= 0xD0;
+      else if (sep[0] == 'L' || sep[0] == 'l')
+        value &= 0xE0; 
+      else if (sep[0] == 'B' || sep[0] == 'b')
+        value &= 0x70;
+      sep = strtok (NULL, " ,");
+    }
+  bgp->cos = value;
+
+  return 0;
+}
+
+/* CoS-Parameter commands */
+DEFUN (cos_parameter,
+       cos_parameter_cmd,
+       "cos-parameter <1-65535>",
+       "Enter CoS-Parameter environment\n"
+       "Number of Class to delete\n")
+{
+  int id = 0;
+  struct cos_class * cos_class;
+  
+  VTY_GET_INTEGER ("CoS Class ID", id, argv[0]);
+  
+  cos_class = get_cos_class (id);
+  if (cos_class)
+    vty->index = cos_class;
+  else
+    {
+      return CMD_WARNING;
+    }
+  vty->node = BGP_COS_NODE;
+  
+  return CMD_SUCCESS;
+}
+
+DEFUN (no_cos_parameter,
+       no_cos_parameter_cmd,
+       "no cos-parameter <1-65535>",
+       NO_STR
+       "Enter CoS-Parameter environment\n"
+       "Number of Class to delete\n")
+{
+  int id=0;
+  int ret;
+  
+  VTY_GET_INTEGER ("CoS Class ID", id, argv[0]);
+  
+  ret = delete_cos_class (id);
+  if (ret)
+    {
+      vty_out (vty, "There is no CoS-Class #%d%s", id, VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+  return CMD_SUCCESS;
+}
+
+DEFUN (no_set_cos_node,
+       no_set_cos_node_cmd,
+       "no set cos-node HEX",
+       NO_STR
+       SET_STR
+       "PHB-specific settings\n"
+       "PHB-ID (0x**)\n")
+{
+  u_int16_t phb;
+
+  phb = (u_int16_t) strtol (argv[0], NULL, 16);
+
+  return vty_delete_phb_node (vty, phb);
+}
+
+DEFUN (set_cos_node,
+       set_cos_node_cmd,
+       "set cos-node HEX (global|nlri-specific) (drop|remark) FLOAT FLOAT FLOAT <1-4294967295> <1-4294967295>",
+       SET_STR
+       "PHB-specific settings\n"
+       "PHB-ID (0x**)\n"
+       "global scope\n"
+       "NLRI-Specific\n"
+       "Dropping of exceeding traffic\n"
+       "Remarking of exceeding traffic\n"
+       "Token Bucket Rate\n"
+       "Token Bucket Size\n"
+       "Peak Data Rate\n"
+       "Minimum Policed Unit\n"
+       "Maximum Packet Size\n")
+{
+  u_int16_t phb;
+  u_int32_t mpu, mps;
+  float tbr, tbs, pdr;
+  u_int8_t flags = 0x00;
+  int ret;
+
+  // PHB-ID
+  phb = (u_int16_t) strtol (argv[0], NULL, 16);
+
+  // global-flag
+  if (argv[1][0] == 'g')
+    flags |= BGP_COS_FLAG_GLOBAL;
+  else if (argv[1][0] == 'n')
+    flags &= BGP_COS_FLAG_HANDLING;
+  else
+    vty_out (vty, "Error with parameter 2%s", VTY_NEWLINE);
+
+  // dr-flag
+  if (argv[2][0] == 'd')
+    flags &= BGP_COS_FLAG_GLOBAL;
+  else if (argv[2][0] == 'r')
+    flags |= BGP_COS_FLAG_HANDLING;
+  else
+    vty_out (vty, "Error with parameter 3%s", VTY_NEWLINE);
+
+  tbr = (float) atof (argv[3]);
+  tbs = (float) atof (argv[4]);
+  pdr = (float) atof (argv[5]);
+
+  VTY_GET_INTEGER ("Minimum Policed Unit", mpu, argv[6]);
+  VTY_GET_INTEGER ("Maximum Packet Size", mps, argv[7]);
+
+  ret = vty_set_cos_val (vty, flags, phb, tbr, tbs, pdr, mpu, mps);
+  return 0;
+}
+
+/* QoS-Marking commands */
+DEFUN (qos_marking,
+       qos_marking_cmd,
+       "qos-marking WORD",
+       "Enter QoS-Marking environment\n"
+       "Name of QoS-Marking table\n")
+{
+  int ret=0;
+  ret = qos_marking_init (vty, argv[0]);
+  vty->node = BGP_QOS_NODE;
+  return ret;
+}
+
+DEFUN (no_qos_marking,
+       no_qos_marking_cmd,
+       "no qos-marking WORD",
+       NO_STR
+       "QoS-Marking\n"
+       "Name of QoS-Marking table\n")
+{
+  return qos_marking_delete(argv[0]);
+}
+
+DEFUN (set_techtype,
+       set_techtype_cmd,
+       "set technology-type WORD HEX",
+       SET_STR
+       "Technology Type of QoS\n"
+       "Name of Technology\n"
+       "Unique-ID <0x00-0xFF>\n")
+{
+  int id;
+  int ret;
+
+  id = (int) strtol (argv[1], NULL, 16);
+  if (id>255 || id<0)
+    {
+      vty_out (vty, "Error: ID must be <0x00-0xFF>%s", VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+  ret = techtype_add (vty->index, argv[0], id);
+
+  if (ret == 0)
+    return CMD_SUCCESS;
+  if (ret == -1)
+    vty_out (vty, "ID (0x%02X) is already defined%s", id, VTY_NEWLINE);
+
+  return CMD_WARNING;
+}
+
+DEFUN (no_set_techtype,
+       no_set_techtype_cmd,
+       "no set technology-type HEX",
+       NO_STR
+       SET_STR
+       "Technology Type of QoS\n"
+       "Unique-ID <0x00-0xFF>\n")
+{
+  int id;
+
+  id = (int) strtol (argv[0], NULL, 16);
+  if (id>255 || id<0)
+    {
+      vty_out (vty, "Error: ID must be <0x00-0xFF>%s", VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+  return techtype_delete (vty->index, id);
+}
+
+DEFUN (show_techtype,
+       show_techtype_cmd,
+       "show technology-type",
+       SHOW_STR
+       "Technology Types\n")
+{
+  struct techtype *tech;
+  struct qos_table *index;
+  index = vty->index;  
+  tech = index->techhead;
+  if (tech)
+    {
+      vty_out (vty, "Technology ID\t| Name of Technology%s", VTY_NEWLINE);
+      while(1)
+        {
+          vty_out (vty, "\t0x%02X\t| %s%s", tech->tech_id, tech->name, VTY_NEWLINE);
+          if (tech->next)
+            tech=tech->next;
+          else
+            break;
+        }
+    }
+  else
+    vty_out (vty, "No Techtypes defined%s", VTY_NEWLINE);
+  return CMD_SUCCESS;
+}
+
+DEFUN (set_qos_set,
+       set_qos_set_cmd,
+       "set qos-set WORD HEX",
+       SET_STR
+       "QoS-Set\n"
+       "Name of QoS-Set\n"
+       "Unique-ID <0x00-0xFF>\n")
+{
+  int id;
+  int ret;
+
+  id = (int) strtol (argv[1], NULL, 16);
+  if (id>255 || id<0)
+    {
+      vty_out (vty, "Error: ID must be <0x00-0xFF>%s", VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+  ret = qos_set_add (vty->index, argv[0], id);
+
+  if (ret == 0)
+    return CMD_SUCCESS;
+  if (ret == -1)
+    vty_out (vty, "QoS-ID (0x%02X) is already defined%s", id, VTY_NEWLINE);
+
+  return CMD_WARNING;
+}
+
+DEFUN (no_set_qos_set,
+       no_set_qos_set_cmd,
+       "no set qos-set HEX",
+       NO_STR
+       SET_STR
+       "QoS-Set\n"
+       "Unique-ID <0x00-0xFF>\n")
+{
+  int id;
+
+  id = (int) strtol (argv[0], NULL, 16);
+  if (id>255 || id<0)
+    {
+      vty_out (vty, "Error: ID must be <0x00-0xFF>%s", VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+  return qos_set_delete (vty->index, id);
+}
+
+DEFUN (show_qos_set,
+       show_qos_set_cmd,
+       "show qos-set",
+       SHOW_STR
+       "QoS-Set\n")
+{
+  struct qos_set *qosc;
+  struct qos_table *index;
+  index = vty->index;
+  qosc = index->head;
+  if (qosc)
+    while (1)
+      {
+        vty_out (vty, "0x%02X\t| %s%s", qosc->qos_number, qosc->name, VTY_NEWLINE);
+        if (qosc->next)
+          qosc=qosc->next;
+        else
+          break;
+      }
+  else
+    vty_out (vty, "No QoS-Sets defined%s", VTY_NEWLINE);
+  return CMD_SUCCESS;
+}
+
+DEFUN (set_qos_marking,
+       set_qos_marking_cmd,
+       "set qos-marking (transitive|non-transitive) HEX HEX HEX",
+       SET_STR
+       "Set-Up QoS-Marking Value\n"
+       "Set QoS-Marking value as transitive\n"
+       "Set QoS-Marking value as non-transitive\n"
+       "QoS-Set <0x00-0xFF>\n"
+       "Technology Type <0x00-0xFF>\n"
+       "QoS-Marking original value <0x0000-0xFFFF>\n")
+{
+  u_int8_t qid;
+  u_int8_t tid;
+  u_int16_t mark_o;
+  int trans;
+  struct qos_set *qosc;
+  struct marking_node *new;
+
+  qid = (u_int8_t) strtol (argv[1], NULL, 16);
+  tid = (u_int8_t) strtol (argv[2], NULL, 16);
+  mark_o = (u_int16_t) strtol (argv[3], NULL, 16);
+  
+  qosc = qos_set_lookup_by_id (vty->index, qid);
+  if (qosc==NULL)
+    {
+      vty_out (vty, "QoS-Set is not yet defined%s", VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+  if (techtype_lookup_by_id (vty->index, tid) == NULL)
+    {
+      vty_out (vty, "Techtype is not yet defined%s", VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+
+  if (argv[0][0]=='t')
+    trans = 1;
+  else
+    trans = 0;
+
+  new = get_marking_node (qosc, tid, trans);
+  new->mark_o = mark_o;
+  /* transformation for ip_dscp */
+  if (tid==0)
+    {
+      mark_o = mark_o >> 9;
+      mark_o = mark_o & 0x3f;
+    }
+  new->mark_a = (u_int8_t) mark_o;
+  
+  return CMD_SUCCESS;
+}
+
+DEFUN (no_set_qos_marking,
+       no_set_qos_marking_cmd,
+       "no set qos-marking HEX HEX",
+       NO_STR
+       SET_STR
+       "QoS-Marking Value·\n"
+       "QoS-Set <0x00-0xFF>\n"
+       "Technology Type <0x00-0xFF>\n")
+{
+  u_int8_t qid;
+  u_int8_t tid;
+  struct qos_set *qosc;
+  struct marking_node *node;
+ 
+  qid = (u_int8_t) strtol (argv[0], NULL, 16);
+  tid = (u_int8_t) strtol (argv[1], NULL, 16);
+
+  qosc = qos_set_lookup_by_id (vty->index, qid);
+  if (qosc==NULL)
+    {
+      vty_out (vty, "QoS-Set is not defined%s", VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+  if (techtype_lookup_by_id(vty->index, tid)==NULL)
+    {
+      vty_out (vty, "Techtype is not defined%s", VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+  node = lookup_marking_node_by_tech (qosc, tid);
+  if (node==NULL)
+    {
+      vty_out (vty, "Marking-Node is not defined%s", VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+  else
+    return delete_marking_node (qosc, tid);
+}
+
+
+DEFUN (show_qos_marking,
+       show_qos_marking_cmd,
+       "show qos-marking",
+       SHOW_STR
+       "QoS-Marking Value·\n")
+{
+  struct peer * peer;
+  if (argc==1)
+    {
+      peer = peer_lookup_vty (vty, argv[0]);
+      if (peer)
+        {
+          if (peer->qos_table)
+            {
+              vty_out (vty, "QoS-Marking Table of Remote-AS %d (%s)%s", peer->as, peer->host, VTY_NEWLINE);
+              return show_qos_table_vty (vty, peer->qos_table, 0);
+            }
+          else
+            {
+              vty_out (vty, "No QoS-Marking Table for Remote-AS %d.%s", peer->as, VTY_NEWLINE);
+              return CMD_SUCCESS;
+            }
+        }
+      else
+        return CMD_WARNING;
+    }
+  vty_out(vty, "QoS-Marking Table of local AS%s", VTY_NEWLINE);
+  return show_qos_table_vty (vty, NULL, 1);
+}
+
+ALIAS (show_qos_marking,
+       show_qos_marking_view_cmd,
+       "show qos-marking (A.B.C.D|X:X::X:X)",
+       SHOW_STR
+       "QoS-Marking Values\n"
+       "IP address\n"
+       "IPv6 address\n")  
+
+DEFUN (neighbor_preserve_qos,
+       neighbor_preserve_qos_cmd,
+       NEIGHBOR_CMD2 "preserve-qos",
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       "Enable preservation of unknown QoS-Markings\n")
+{
+  struct peer * peer;
+  peer = peer_lookup_vty (vty, argv[0]);
+
+  if (peer)
+    {
+      peer->qos_pbit = 1;
+      vty_out (vty, "Enabled preservation for incoming QoS-Markings of %s.%s", peer->host, VTY_NEWLINE);
+      return CMD_SUCCESS;
+    }
+  return CMD_WARNING;
+}
+
+DEFUN (no_neighbor_preserve_qos,
+       no_neighbor_preserve_qos_cmd,
+       "no " NEIGHBOR_CMD2 "preserve-qos ",
+       NO_STR
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       "Enable preservation of unknown QoS-Markings\n")
+{
+  struct peer * peer;
+  peer = peer_lookup_vty (vty, argv[0]);
+
+  if (peer)
+    {
+      peer->qos_pbit = 0;
+      vty_out (vty, "Disabled preservation for incoming QoS-Markings of %s.%s", peer->host, VTY_NEWLINE);
+      return CMD_SUCCESS;
+    }
+  return CMD_WARNING;
+}
+
+DEFUN (neighbor_reset_dscp_qos,
+       neighbor_reset_dscp_qos_cmd,
+       NEIGHBOR_CMD2 "reset-dscp .HEX",
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       "Reset QoS-DSCPs\n"
+       "Hex-value <0x00-0xFF> of incoming DSCPs\n")
+{
+  struct peer * peer;
+  u_int16_t dscp;
+	
+  peer = peer_lookup_vty (vty, argv[0]);
+
+  if (peer)
+    {
+      for (int i=1;i<argc;i++)
+        {
+          dscp = (u_int16_t) strtol (argv[i], NULL, 16);
+          dscp_remark_add (peer, dscp);
+          vty_out (vty, "DSCP to remark: 0x%02x from neighbor %s%s", dscp, peer->host, VTY_NEWLINE);
+        }
+      return CMD_SUCCESS;
+    }
+  return CMD_WARNING;
+}
+
+DEFUN (no_neighbor_reset_dscp_qos,
+       no_neighbor_reset_dscp_qos_cmd,
+       "no " NEIGHBOR_CMD2 "reset-dscp .HEX",
+       NO_STR
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       "Reset QoS-DSCPs\n"
+       "Hex-value (0x**) of incoming DSCPs\n")
+{
+  struct peer * peer;
+  u_int16_t dscp;
+	
+  peer = peer_lookup_vty (vty, argv[0]);
+
+  if (peer)
+    {
+      for (int i=1;i<argc;i++)
+        {
+          dscp = (u_int16_t) strtol (argv[i], NULL, 16);
+          dscp_remark_delete (peer, dscp);
+          vty_out (vty, "DSCP to remark: 0x%02x from neighbor %s deleted%s", dscp, peer->host, VTY_NEWLINE);
+        }
+      return CMD_SUCCESS;
+    }
+  return CMD_WARNING;
+}
+
+
 /* BGP node structure. */
 static struct cmd_node bgp_node =
 {
@@ -8830,6 +9706,20 @@ static struct cmd_node bgp_vpnv4_node =
   1
 };
 
+static struct cmd_node bgp_qos_node =
+{
+  BGP_QOS_NODE,
+  "%s(config-qos)# ",
+  1
+};
+
+static struct cmd_node bgp_cos_node =
+{
+  BGP_COS_NODE,
+  "%s(config-cos)# ",
+  1
+}; 
+
 static void community_list_vty (void);
 
 void
@@ -8842,6 +9732,8 @@ bgp_vty_init (void)
   install_node (&bgp_ipv6_unicast_node, NULL);
   install_node (&bgp_ipv6_multicast_node, NULL);
   install_node (&bgp_vpnv4_node, NULL);
+  install_node (&bgp_qos_node, bgp_qos_config_write);
+  install_node (&bgp_cos_node, bgp_cos_config_write);
 
   /* Install default VTY commands to new nodes.  */
   install_default (BGP_NODE);
@@ -8850,6 +9742,8 @@ bgp_vty_init (void)
   install_default (BGP_IPV6_NODE);
   install_default (BGP_IPV6M_NODE);
   install_default (BGP_VPNV4_NODE);
+  install_default (BGP_QOS_NODE);
+  install_default (BGP_COS_NODE);
   
   /* "bgp multiple-instance" commands. */
   install_element (CONFIG_NODE, &bgp_multiple_instance_cmd);
@@ -8863,6 +9757,33 @@ bgp_vty_init (void)
   install_element (BGP_NODE, &no_synchronization_cmd);
   install_element (BGP_NODE, &no_auto_summary_cmd);
 
+  /* "qos-marking" command. */
+  install_element (CONFIG_NODE, &qos_marking_cmd);
+  install_element (CONFIG_NODE, &no_qos_marking_cmd);
+  install_element (BGP_QOS_NODE, &set_techtype_cmd);
+  install_element (BGP_QOS_NODE, &no_set_techtype_cmd);
+  install_element (BGP_QOS_NODE, &show_techtype_cmd);
+  install_element (BGP_QOS_NODE, &set_qos_set_cmd);
+  install_element (BGP_QOS_NODE, &no_set_qos_set_cmd);
+  install_element (BGP_QOS_NODE, &show_qos_set_cmd);
+  install_element (BGP_QOS_NODE, &set_qos_marking_cmd);
+  install_element (BGP_QOS_NODE, &no_set_qos_marking_cmd);
+  install_element (BGP_QOS_NODE, &show_qos_marking_cmd);
+  install_element (ENABLE_NODE, &show_qos_marking_cmd);
+  install_element (ENABLE_NODE, &show_qos_marking_view_cmd);
+  install_element (BGP_NODE, &neighbor_preserve_qos_cmd);
+  install_element (BGP_NODE, &neighbor_reset_dscp_qos_cmd);
+  install_element (BGP_NODE, &no_neighbor_preserve_qos_cmd);
+  install_element (BGP_NODE, &no_neighbor_reset_dscp_qos_cmd);
+
+  /* cos-capability commands. */
+  install_element (BGP_NODE, &cos_capability_cmd);
+  install_element (BGP_NODE, &no_cos_capability_cmd);
+  install_element (CONFIG_NODE, &cos_parameter_cmd);
+  install_element (CONFIG_NODE, &no_cos_parameter_cmd);
+  install_element (BGP_COS_NODE, &set_cos_node_cmd); 
+  install_element (BGP_COS_NODE, &no_set_cos_node_cmd);
+
   /* "router bgp" commands. */
   install_element (CONFIG_NODE, &router_bgp_cmd);
   install_element (CONFIG_NODE, &router_bgp_view_cmd);
@@ -9678,7 +10599,23 @@ bgp_vty_init (void)
   install_element (ENABLE_NODE, &clear_ip_bgp_peer_vpnv4_out_cmd);
   install_element (ENABLE_NODE, &clear_ip_bgp_as_vpnv4_soft_out_cmd);
   install_element (ENABLE_NODE, &clear_ip_bgp_as_vpnv4_out_cmd);
+  /* outbound prefix-specific soft-reconfiguration */
+  install_element (ENABLE_NODE, &clear_ip_bgp_peer_soft_out_prefix_cmd);
+  install_element (ENABLE_NODE, &clear_ip_bgp_peer_out_prefix_cmd);
+  install_element (ENABLE_NODE, &clear_ip_bgp_all_soft_out_prefix_cmd);
+  install_element (ENABLE_NODE, &clear_ip_bgp_all_out_prefix_cmd);
+  install_element (ENABLE_NODE, &clear_ip_bgp_instance_all_soft_out_prefix_cmd);
 #ifdef HAVE_IPV6
+  install_element (ENABLE_NODE, &clear_bgp_all_soft_out_prefix_cmd);
+  install_element (ENABLE_NODE, &clear_bgp_instance_all_soft_out_prefix_cmd);
+  install_element (ENABLE_NODE, &clear_bgp_all_out_prefix_cmd);
+  install_element (ENABLE_NODE, &clear_bgp_ipv6_all_soft_out_prefix_cmd);
+  install_element (ENABLE_NODE, &clear_bgp_ipv6_all_out_prefix_cmd);
+  install_element (ENABLE_NODE, &clear_bgp_peer_soft_out_prefix_cmd);
+  install_element (ENABLE_NODE, &clear_bgp_ipv6_peer_soft_out_prefix_cmd);
+  install_element (ENABLE_NODE, &clear_bgp_peer_out_prefix_cmd);
+  install_element (ENABLE_NODE, &clear_bgp_ipv6_peer_out_prefix_cmd);
+
   install_element (ENABLE_NODE, &clear_bgp_all_soft_out_cmd);
   install_element (ENABLE_NODE, &clear_bgp_instance_all_soft_out_cmd);
   install_element (ENABLE_NODE, &clear_bgp_all_out_cmd);
diff -upwbrN quagga_original/bgpd/Makefile.am quagga_cq/bgpd/Makefile.am
--- quagga_original/bgpd/Makefile.am	2010-05-11 21:25:09.000000000 +0200
+++ quagga_cq/bgpd/Makefile.am	2010-05-11 21:28:22.000000000 +0200
@@ -15,14 +15,15 @@ libbgp_a_SOURCES = \
 	bgp_debug.c bgp_route.c bgp_zebra.c bgp_open.c bgp_routemap.c \
 	bgp_packet.c bgp_network.c bgp_filter.c bgp_regex.c bgp_clist.c \
 	bgp_dump.c bgp_snmp.c bgp_ecommunity.c bgp_mplsvpn.c bgp_nexthop.c \
-	bgp_damp.c bgp_table.c bgp_advertise.c bgp_vty.c
+	bgp_damp.c bgp_table.c bgp_advertise.c bgp_vty.c bgp_qos.c \
+	bgp_cos.c
 
 noinst_HEADERS = \
 	bgp_aspath.h bgp_attr.h bgp_community.h bgp_debug.h bgp_fsm.h \
 	bgp_network.h bgp_open.h bgp_packet.h bgp_regex.h bgp_route.h \
 	bgpd.h bgp_filter.h bgp_clist.h bgp_dump.h bgp_zebra.h \
 	bgp_ecommunity.h bgp_mplsvpn.h bgp_nexthop.h bgp_damp.h bgp_table.h \
-	bgp_advertise.h bgp_snmp.h bgp_vty.h
+	bgp_advertise.h bgp_snmp.h bgp_vty.h bgp_qos.h bgp_cos.h
 
 bgpd_SOURCES = bgp_main.c
 bgpd_LDADD = libbgp.a ../lib/libzebra.la @LIBCAP@ @LIBM@
diff -upwbrN quagga_original/lib/command.c quagga_cq/lib/command.c
--- quagga_original/lib/command.c	2010-05-11 21:25:09.000000000 +0200
+++ quagga_cq/lib/command.c	2010-05-11 21:28:22.000000000 +0200
@@ -1994,6 +1994,8 @@ node_parent ( enum node_type node )
     case KEYCHAIN_KEY_NODE:
       ret = KEYCHAIN_NODE;
       break;
+    case BGP_QOS_NODE:
+    case BGP_COS_NODE:
     default:
       ret = CONFIG_NODE;
     }
@@ -2400,6 +2402,8 @@ DEFUN (config_exit,
     case INTERFACE_NODE:
     case ZEBRA_NODE:
     case BGP_NODE:
+    case BGP_QOS_NODE:
+    case BGP_COS_NODE:
     case RIP_NODE:
     case RIPNG_NODE:
     case OSPF_NODE:
@@ -2452,6 +2456,8 @@ DEFUN (config_end,
     case RIP_NODE:
     case RIPNG_NODE:
     case BGP_NODE:
+    case BGP_QOS_NODE:
+    case BGP_COS_NODE:
     case BGP_VPNV4_NODE:
     case BGP_IPV4_NODE:
     case BGP_IPV4M_NODE:
diff -upwbrN quagga_original/lib/command.h quagga_cq/lib/command.h
--- quagga_original/lib/command.h	2010-05-11 21:25:09.000000000 +0200
+++ quagga_cq/lib/command.h	2010-05-11 21:28:22.000000000 +0200
@@ -79,6 +79,8 @@ enum node_type 
   RIP_NODE,			/* RIP protocol mode node. */ 
   RIPNG_NODE,			/* RIPng protocol mode node. */
   BGP_NODE,			/* BGP protocol mode which includes BGP4+ */
+  BGP_QOS_NODE,			/* BGP QoS node */
+  BGP_COS_NODE,			/* BGP CoS node */
   BGP_VPNV4_NODE,		/* BGP MPLS-VPN PE exchange. */
   BGP_IPV4_NODE,		/* BGP IPv4 unicast address family.  */
   BGP_IPV4M_NODE,		/* BGP IPv4 multicast address family.  */
diff -upwbrN quagga_original/lib/memtypes.c quagga_cq/lib/memtypes.c
--- quagga_original/lib/memtypes.c	2010-05-11 21:25:09.000000000 +0200
+++ quagga_cq/lib/memtypes.c	2010-05-11 21:32:55.000000000 +0200
@@ -150,6 +150,21 @@ struct memory_list memory_list_bgp[] =
   { MTYPE_BGP_DAMP_ARRAY,	"BGP Dampening array"		},
   { MTYPE_BGP_REGEXP,		"BGP regexp"			},
   { MTYPE_BGP_AGGREGATE,	"BGP aggregate"			},
+  { 0, NULL },
+  { MTYPE_TECH_TYPE,		"Technology Type"		},
+  { MTYPE_TECH_TYPE_NAME,	"Technology Name"		},
+  { MTYPE_QOS_SET,		"QoS-Set for Marking"		},
+  { MTYPE_QOS_SET_NAME,		"Name of QoS-Set"		},
+  { MTYPE_QOSMARKING_NODE,	"Marking Node"			},
+  { MTYPE_QOS_TABLE,		"QoS-Table"			},
+  { MTYPE_QOS_TABLE_NAME,	"Name of QoS-Table"		},
+  { MTYPE_DSCP_RESET_NODE,	"DSCPs to Reset"		},
+  { 0, NULL },
+  { MTYPE_COS_TABLE,		"CoS table"			},
+  { MTYPE_COS_CLASS,		"CoS parameter class"		},
+  { MTYPE_COSCLASS_VAL,		"CoS class value"		},
+  { MTYPE_TARGET_AS,		"CoS target as"			},
+  { MTYPE_TARGET_AS_VAL,	"CoS target as value"		},
   { -1, NULL }
 };
 
diff -upwbrN quagga_original/lib/vty.c quagga_cq/lib/vty.c
--- quagga_original/lib/vty.c	2010-05-11 21:25:09.000000000 +0200
+++ quagga_cq/lib/vty.c	2010-05-11 21:28:22.000000000 +0200
@@ -705,6 +705,8 @@ vty_end_config (struct vty *vty)
     case BGP_IPV4M_NODE:
     case BGP_IPV6_NODE:
     case BGP_IPV6M_NODE:
+    case BGP_QOS_NODE:
+    case BGP_COS_NODE:
     case RMAP_NODE:
     case OSPF_NODE:
     case OSPF6_NODE:
@@ -1109,6 +1111,8 @@ vty_stop_input (struct vty *vty)
     case RIPNG_NODE:
     case BGP_NODE:
     case RMAP_NODE:
+    case BGP_QOS_NODE:
+    case BGP_COS_NODE:
     case OSPF_NODE:
     case OSPF6_NODE:
     case ISIS_NODE:
diff -upwbrN quagga_original/vtysh/vtysh.c quagga_cq/vtysh/vtysh.c
--- quagga_original/vtysh/vtysh.c	2010-05-11 21:25:09.000000000 +0200
+++ quagga_cq/vtysh/vtysh.c	2010-05-11 21:28:22.000000000 +0200
@@ -755,6 +755,18 @@ static struct cmd_node bgp_vpnv4_node =
   "%s(config-router-af)# "
 };
 
+static struct cmd_node bgp_qos_node =
+{
+  BGP_QOS_NODE,
+  "%s(config-qos)# "
+};
+
+static struct cmd_node bgp_cos_node =
+{
+  BGP_COS_NODE,
+  "%s(config-cos)# "
+};
+
 static struct cmd_node bgp_ipv4_node =
 {
   BGP_IPV4_NODE,
@@ -829,6 +841,34 @@ vtysh_end (void)
   return CMD_SUCCESS;
 }
 
+DEFUNSH (VTYSH_BGPD,
+	 qos_marking,
+	 qos_marking_cmd,
+	 "qos-marking",
+	 "Enter QoS-Marking environment\n")
+{
+  vty->node = BGP_QOS_NODE;
+  return CMD_SUCCESS;
+}
+
+DEFUNSH (VTYSH_BGPD,
+	 cos_parameter,
+	 cos_parameter_cmd,
+	 "cos-parameter",
+	 "Enter CoS-Parameter environment\n")
+{
+  vty->node = BGP_COS_NODE;
+  return CMD_SUCCESS;
+}
+
+ALIAS_SH (VTYSH_BGPD,
+	  cos_parameter_num,
+	  cos_parameter_num_cmd,
+	  "cos-parameter <1-65535>",
+	  "Enter CoS-Parameter environment\n"
+
+	  "Number of Class to open\n")
+
 DEFUNSH (VTYSH_ALL,
 	 vtysh_end_all,
 	 vtysh_end_all_cmd,
@@ -1102,6 +1142,8 @@ vtysh_exit (struct vty *vty)
     case RMAP_NODE:
     case VTY_NODE:
     case KEYCHAIN_NODE:
+    case BGP_QOS_NODE:
+    case BGP_COS_NODE:
       vtysh_execute("end");
       vtysh_execute("configure terminal");
       vty->node = CONFIG_NODE;
@@ -2243,6 +2285,8 @@ vtysh_init_vty (void)
   install_node (&bgp_vpnv4_node, NULL);
   install_node (&bgp_ipv4_node, NULL);
   install_node (&bgp_ipv4m_node, NULL);
+  install_node (&bgp_qos_node, NULL);
+  install_node (&bgp_cos_node, NULL);
 /* #ifdef HAVE_IPV6 */
   install_node (&bgp_ipv6_node, NULL);
   install_node (&bgp_ipv6m_node, NULL);
@@ -2270,6 +2314,7 @@ vtysh_init_vty (void)
   vtysh_install_default (BGP_IPV4M_NODE);
   vtysh_install_default (BGP_IPV6_NODE);
   vtysh_install_default (BGP_IPV6M_NODE);
+  vtysh_install_default (BGP_QOS_NODE);
   vtysh_install_default (OSPF_NODE);
   vtysh_install_default (RIPNG_NODE);
   vtysh_install_default (OSPF6_NODE);
@@ -2299,6 +2344,10 @@ vtysh_init_vty (void)
   install_element (OSPF6_NODE, &vtysh_quit_ospf6d_cmd);
   install_element (BGP_NODE, &vtysh_exit_bgpd_cmd);
   install_element (BGP_NODE, &vtysh_quit_bgpd_cmd);
+  install_element (BGP_QOS_NODE, &vtysh_exit_bgpd_cmd);
+  install_element (BGP_QOS_NODE, &vtysh_quit_bgpd_cmd);
+  install_element (BGP_COS_NODE, &vtysh_exit_bgpd_cmd);
+  install_element (BGP_COS_NODE, &vtysh_quit_bgpd_cmd);
   install_element (BGP_VPNV4_NODE, &vtysh_exit_bgpd_cmd);
   install_element (BGP_VPNV4_NODE, &vtysh_quit_bgpd_cmd);
   install_element (BGP_IPV4_NODE, &vtysh_exit_bgpd_cmd);
@@ -2328,6 +2377,8 @@ vtysh_init_vty (void)
   install_element (OSPF_NODE, &vtysh_end_all_cmd);
   install_element (OSPF6_NODE, &vtysh_end_all_cmd);
   install_element (BGP_NODE, &vtysh_end_all_cmd);
+  install_element (BGP_QOS_NODE, &vtysh_end_all_cmd);
+  install_element (BGP_COS_NODE, &vtysh_end_all_cmd);
   install_element (BGP_IPV4_NODE, &vtysh_end_all_cmd);
   install_element (BGP_IPV4M_NODE, &vtysh_end_all_cmd);
   install_element (BGP_VPNV4_NODE, &vtysh_end_all_cmd);

