]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_routemap.c
bgpd: lcommunity: fix whitespace & copyright
[mirror_frr.git] / bgpd / bgp_routemap.c
index 5b170f88f4fca462a91b138bfde7eb0ec948e8ec..58d9b20f908febf644311be2cc5b518e25cc030c 100644 (file)
@@ -22,6 +22,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 
 #include "prefix.h"
 #include "filter.h"
+#include "vty.h"
 #include "routemap.h"
 #include "command.h"
 #include "linklist.h"
@@ -31,11 +32,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 #ifdef HAVE_LIBPCREPOSIX
 # include <pcreposix.h>
 #else
-# ifdef HAVE_GNU_REGEX
-#  include <regex.h>
-# else
-#  include "regex-gnu.h"
-# endif /* HAVE_GNU_REGEX */
+# include <regex.h>
 #endif /* HAVE_LIBPCREPOSIX */
 #include "buffer.h"
 #include "sockunion.h"
@@ -55,9 +52,13 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 #include "bgpd/bgp_filter.h"
 #include "bgpd/bgp_mplsvpn.h"
 #include "bgpd/bgp_ecommunity.h"
+#include "bgpd/bgp_lcommunity.h"
 #include "bgpd/bgp_vty.h"
 #include "bgpd/bgp_debug.h"
 
+#if ENABLE_BGP_VNC
+# include "bgpd/rfapi/bgp_rfapi_cfg.h"
+#endif
 
 /* Memo of route-map commands.
 
@@ -84,6 +85,8 @@ o Cisco route-map
       as-path tag       :  Not yet
       automatic-tag     :  (This will not be implemented by bgpd)
       community         :  Done
+      large-community   :  Done
+      large-comm-list   :  Done
       comm-list         :  Not yet
       dampning          :  Not yet
       default           :  (This will not be implemented by bgpd)
@@ -107,7 +110,7 @@ o Local extensions
   set ipv6 next-hop local : Done
   set as-path exclude     : Done
 
-*/ 
+*/
 
  /* generic value manipulation to be shared in multiple rules */
 
@@ -329,7 +332,7 @@ struct route_map_rule_cmd route_match_peer_cmd =
 /* Match function should return 1 if match is success else return
    zero. */
 static route_map_result_t
-route_match_ip_address (void *rule, struct prefix *prefix, 
+route_match_ip_address (void *rule, struct prefix *prefix,
                        route_map_object_t type, void *object)
 {
   struct access_list *alist;
@@ -340,7 +343,7 @@ route_match_ip_address (void *rule, struct prefix *prefix,
       alist = access_list_lookup (AFI_IP, (char *) rule);
       if (alist == NULL)
        return RMAP_NOMATCH;
-    
+
       return (access_list_apply (alist, prefix) == FILTER_DENY ?
              RMAP_NOMATCH : RMAP_MATCH);
     }
@@ -375,7 +378,7 @@ struct route_map_rule_cmd route_match_ip_address_cmd =
 
 /* Match function return 1 if match is success else return zero. */
 static route_map_result_t
-route_match_ip_next_hop (void *rule, struct prefix *prefix, 
+route_match_ip_next_hop (void *rule, struct prefix *prefix,
                         route_map_object_t type, void *object)
 {
   struct access_list *alist;
@@ -427,7 +430,7 @@ struct route_map_rule_cmd route_match_ip_next_hop_cmd =
 
 /* Match function return 1 if match is success else return zero. */
 static route_map_result_t
-route_match_ip_route_source (void *rule, struct prefix *prefix, 
+route_match_ip_route_source (void *rule, struct prefix *prefix,
                             route_map_object_t type, void *object)
 {
   struct access_list *alist;
@@ -484,7 +487,7 @@ struct route_map_rule_cmd route_match_ip_route_source_cmd =
 /* `match ip address prefix-list PREFIX_LIST' */
 
 static route_map_result_t
-route_match_ip_address_prefix_list (void *rule, struct prefix *prefix, 
+route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,
                                    route_map_object_t type, void *object)
 {
   struct prefix_list *plist;
@@ -494,7 +497,7 @@ route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,
       plist = prefix_list_lookup (AFI_IP, (char *) rule);
       if (plist == NULL)
        return RMAP_NOMATCH;
-    
+
       return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
              RMAP_NOMATCH : RMAP_MATCH);
     }
@@ -691,7 +694,7 @@ struct route_map_rule_cmd route_match_local_pref_cmd =
 
 /* Match function return 1 if match is success else return zero. */
 static route_map_result_t
-route_match_metric (void *rule, struct prefix *prefix, 
+route_match_metric (void *rule, struct prefix *prefix,
                    route_map_object_t type, void *object)
 {
   struct rmap_value *rv;
@@ -719,10 +722,10 @@ struct route_map_rule_cmd route_match_metric_cmd =
 
 /* Match function for as-path match.  I assume given object is */
 static route_map_result_t
-route_match_aspath (void *rule, struct prefix *prefix, 
+route_match_aspath (void *rule, struct prefix *prefix,
                    route_map_object_t type, void *object)
 {
-  
+
   struct as_list *as_list;
   struct bgp_info *bgp_info;
 
@@ -755,7 +758,7 @@ route_match_aspath_free (void *rule)
 }
 
 /* Route map commands for aspath matching. */
-struct route_map_rule_cmd route_match_aspath_cmd = 
+struct route_map_rule_cmd route_match_aspath_cmd =
 {
   "as-path",
   route_match_aspath,
@@ -772,14 +775,14 @@ struct rmap_community
 
 /* Match function for community match. */
 static route_map_result_t
-route_match_community (void *rule, struct prefix *prefix, 
+route_match_community (void *rule, struct prefix *prefix,
                       route_map_object_t type, void *object)
 {
   struct community_list *list;
   struct bgp_info *bgp_info;
   struct rmap_community *rcom;
 
-  if (type == RMAP_BGP) 
+  if (type == RMAP_BGP)
     {
       bgp_info = object;
       rcom = rule;
@@ -834,12 +837,12 @@ route_match_community_free (void *rule)
 {
   struct rmap_community *rcom = rule;
 
-  XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name); 
+  XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name);
   XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom);
 }
 
 /* Route map commands for community matching. */
-struct route_map_rule_cmd route_match_community_cmd = 
+struct route_map_rule_cmd route_match_community_cmd =
 {
   "community",
   route_match_community,
@@ -847,21 +850,93 @@ struct route_map_rule_cmd route_match_community_cmd =
   route_match_community_free
 };
 
+/* Match function for lcommunity match. */
+static route_map_result_t
+route_match_lcommunity (void *rule, struct prefix *prefix,
+                       route_map_object_t type, void *object)
+{
+  struct community_list *list;
+  struct bgp_info *bgp_info;
+  struct rmap_community *rcom;
+
+  if (type == RMAP_BGP)
+    {
+      bgp_info = object;
+      rcom = rule;
+
+      list = community_list_lookup (bgp_clist, rcom->name,
+                                    LARGE_COMMUNITY_LIST_MASTER);
+      if (! list)
+        return RMAP_NOMATCH;
+
+      if (bgp_info->attr->extra &&
+          lcommunity_list_match (bgp_info->attr->extra->lcommunity, list))
+        return RMAP_MATCH;
+
+    }
+  return RMAP_NOMATCH;
+}
+
+/* Compile function for community match. */
+static void *
+route_match_lcommunity_compile (const char *arg)
+{
+  struct rmap_community *rcom;
+  int len;
+  char *p;
+
+  rcom = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_community));
+
+  p = strchr (arg, ' ');
+  if (p)
+    {
+      len = p - arg;
+      rcom->name = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
+      memcpy (rcom->name, arg, len);
+    }
+  else
+    {
+      rcom->name = XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
+      rcom->exact = 0;
+    }
+  return rcom;
+}
+
+/* Compile function for community match. */
+static void
+route_match_lcommunity_free (void *rule)
+{
+  struct rmap_community *rcom = rule;
+
+  XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name);
+  XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom);
+}
+
+/* Route map commands for community matching. */
+struct route_map_rule_cmd route_match_lcommunity_cmd =
+{
+  "large-community",
+  route_match_lcommunity,
+  route_match_lcommunity_compile,
+  route_match_lcommunity_free
+};
+
+
 /* Match function for extcommunity match. */
 static route_map_result_t
-route_match_ecommunity (void *rule, struct prefix *prefix, 
+route_match_ecommunity (void *rule, struct prefix *prefix,
                        route_map_object_t type, void *object)
 {
   struct community_list *list;
   struct bgp_info *bgp_info;
 
-  if (type == RMAP_BGP) 
+  if (type == RMAP_BGP)
     {
       bgp_info = object;
-      
+
       if (!bgp_info->attr->extra)
         return RMAP_NOMATCH;
-      
+
       list = community_list_lookup (bgp_clist, (char *) rule,
                                    EXTCOMMUNITY_LIST_MASTER);
       if (! list)
@@ -888,7 +963,7 @@ route_match_ecommunity_free (void *rule)
 }
 
 /* Route map commands for community matching. */
-struct route_map_rule_cmd route_match_ecommunity_cmd = 
+struct route_map_rule_cmd route_match_ecommunity_cmd =
 {
   "extcommunity",
   route_match_ecommunity,
@@ -901,7 +976,7 @@ struct route_map_rule_cmd route_match_ecommunity_cmd =
 
 /* `match origin' */
 static route_map_result_t
-route_match_origin (void *rule, struct prefix *prefix, 
+route_match_origin (void *rule, struct prefix *prefix,
                    route_map_object_t type, void *object)
 {
   u_char *origin;
@@ -911,7 +986,7 @@ route_match_origin (void *rule, struct prefix *prefix,
     {
       origin = rule;
       bgp_info = object;
-    
+
       if (bgp_info->attr->origin == *origin)
        return RMAP_MATCH;
     }
@@ -1067,7 +1142,7 @@ static route_map_result_t
 route_match_tag (void *rule, struct prefix *prefix,
                  route_map_object_t type, void *object)
 {
-  u_short *tag;
+  route_tag_t *tag;
   struct bgp_info *bgp_info;
 
   if (type == RMAP_BGP)
@@ -1085,46 +1160,13 @@ route_match_tag (void *rule, struct prefix *prefix,
 }
 
 
-/*  Route map `match tag' match statement. `arg' is TAG value */
-static void *
-route_match_tag_compile (const char *arg)
-{
-  u_short *tag;
-  u_short tmp;
-
-  /* tag value shoud be integer. */
-  if (! all_digit (arg))
-    return NULL;
-
-  tmp = atoi(arg);
-  if (tmp < 1)
-    return NULL;
-
-  tag = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_short));
-
-  if (!tag)
-    return tag;
-
-  *tag = tmp;
-
-  return tag;
-}
-
-
-/* Free route map's compiled 'match tag' value. */
-static void
-route_match_tag_free (void *rule)
-{
-  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
-}
-
 /* Route map commands for tag matching. */
-struct route_map_rule_cmd route_match_tag_cmd =
+static struct route_map_rule_cmd route_match_tag_cmd =
 {
   "tag",
   route_match_tag,
-  route_match_tag_compile,
-  route_match_tag_free,
+  route_map_rule_tag_compile,
+  route_map_rule_tag_free,
 };
 
 
@@ -1158,7 +1200,7 @@ route_set_ip_nexthop (void *rule, struct prefix *prefix,
        {
          if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
            CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
-             && peer->su_remote 
+             && peer->su_remote
              && sockunion_family (peer->su_remote) == AF_INET)
            {
              bgp_info->attr->nexthop.s_addr = sockunion2ip (peer->su_remote);
@@ -1232,7 +1274,7 @@ route_set_ip_nexthop_free (void *rule)
 
   if (rins->address)
     XFREE (MTYPE_ROUTE_MAP_COMPILED, rins->address);
-    
+
   XFREE (MTYPE_ROUTE_MAP_COMPILED, rins);
 }
 
@@ -1261,8 +1303,8 @@ route_set_local_pref (void *rule, struct prefix *prefix,
       /* Fetch routemap's rule information. */
       rv = rule;
       bgp_info = object;
-    
-      /* Set local preference value. */ 
+
+      /* Set local preference value. */
       if (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
        locpref = bgp_info->attr->local_pref;
 
@@ -1274,7 +1316,7 @@ route_set_local_pref (void *rule, struct prefix *prefix,
 }
 
 /* Set local preference rule structure. */
-struct route_map_rule_cmd route_set_local_pref_cmd = 
+struct route_map_rule_cmd route_set_local_pref_cmd =
 {
   "local-preference",
   route_set_local_pref,
@@ -1298,8 +1340,8 @@ route_set_weight (void *rule, struct prefix *prefix, route_map_object_t type,
       /* Fetch routemap's rule information. */
       rv = rule;
       bgp_info = object;
-    
-      /* Set weight value. */ 
+
+      /* Set weight value. */
       weight = route_value_adjust(rv, 0, bgp_info->peer);
       if (weight)
         (bgp_attr_extra_get (bgp_info->attr))->weight = weight;
@@ -1311,7 +1353,7 @@ route_set_weight (void *rule, struct prefix *prefix, route_map_object_t type,
 }
 
 /* Set local preference rule structure. */
-struct route_map_rule_cmd route_set_weight_cmd = 
+struct route_map_rule_cmd route_set_weight_cmd =
 {
   "weight",
   route_set_weight,
@@ -1323,7 +1365,7 @@ struct route_map_rule_cmd route_set_weight_cmd =
 
 /* Set metric to attribute. */
 static route_map_result_t
-route_set_metric (void *rule, struct prefix *prefix, 
+route_set_metric (void *rule, struct prefix *prefix,
                  route_map_object_t type, void *object)
 {
   struct rmap_value *rv;
@@ -1346,7 +1388,7 @@ route_set_metric (void *rule, struct prefix *prefix,
 }
 
 /* Set metric rule structure. */
-struct route_map_rule_cmd route_set_metric_cmd = 
+struct route_map_rule_cmd route_set_metric_cmd =
 {
   "metric",
   route_set_metric,
@@ -1367,7 +1409,7 @@ route_set_aspath_prepend (void *rule, struct prefix *prefix, route_map_object_t
   if (type == RMAP_BGP)
     {
       binfo = object;
-    
+
       if (binfo->attr->aspath->refcnt)
        new = aspath_dup (binfo->attr->aspath);
       else
@@ -1411,7 +1453,7 @@ route_set_aspath_prepend_free (void *rule)
 
 
 /* Set as-path prepend rule structure. */
-struct route_map_rule_cmd route_set_aspath_prepend_cmd = 
+struct route_map_rule_cmd route_set_aspath_prepend_cmd =
 {
   "as-path prepend",
   route_set_aspath_prepend,
@@ -1445,7 +1487,7 @@ route_set_aspath_exclude (void *rule, struct prefix *dummy, route_map_object_t t
 }
 
 /* Set ASn exlude rule structure. */
-struct route_map_rule_cmd route_set_aspath_exclude_cmd = 
+struct route_map_rule_cmd route_set_aspath_exclude_cmd =
 {
   "as-path exclude",
   route_set_aspath_exclude,
@@ -1472,7 +1514,7 @@ route_set_community (void *rule, struct prefix *prefix,
   struct community *new = NULL;
   struct community *old;
   struct community *merge;
-  
+
   if (type == RMAP_BGP)
     {
       rcs = rule;
@@ -1495,8 +1537,8 @@ route_set_community (void *rule, struct prefix *prefix,
       if (rcs->additive && old)
        {
          merge = community_merge (community_dup (old), rcs->com);
-         
-         /* HACK: if the old community is not intern'd, 
+
+         /* HACK: if the old community is not intern'd,
            * we should free it here, or all reference to it may be lost.
            * Really need to cleanup attribute caching sometime.
            */
@@ -1507,7 +1549,7 @@ route_set_community (void *rule, struct prefix *prefix,
        }
       else
        new = community_dup (rcs->com);
-      
+
       /* will be interned by caller if required */
       attr->community = new;
 
@@ -1526,7 +1568,7 @@ route_set_community_compile (const char *arg)
   char *sp;
   int additive = 0;
   int none = 0;
-  
+
   if (strcmp (arg, "none") == 0)
     none = 1;
   else
@@ -1548,12 +1590,12 @@ route_set_community_compile (const char *arg)
       if (! com)
        return NULL;
     }
-  
+
   rcs = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
   rcs->com = com;
   rcs->additive = additive;
   rcs->none = none;
-  
+
   return rcs;
 }
 
@@ -1569,7 +1611,7 @@ route_set_community_free (void *rule)
 }
 
 /* Set community rule structure. */
-struct route_map_rule_cmd route_set_community_cmd = 
+struct route_map_rule_cmd route_set_community_cmd =
 {
   "community",
   route_set_community,
@@ -1577,6 +1619,225 @@ struct route_map_rule_cmd route_set_community_cmd =
   route_set_community_free,
 };
 
+/* `set community COMMUNITY' */
+struct rmap_lcom_set
+{
+  struct lcommunity *lcom;
+  int additive;
+  int none;
+};
+
+
+/* For lcommunity set mechanism. */
+static route_map_result_t
+route_set_lcommunity (void *rule, struct prefix *prefix,
+                     route_map_object_t type, void *object)
+{
+  struct rmap_lcom_set *rcs;
+  struct bgp_info *binfo;
+  struct attr *attr;
+  struct lcommunity *new = NULL;
+  struct lcommunity *old;
+  struct lcommunity *merge;
+
+  if (type == RMAP_BGP)
+    {
+      rcs = rule;
+      binfo = object;
+      attr = binfo->attr;
+      old = (attr->extra) ? attr->extra->lcommunity : NULL;
+
+      /* "none" case.  */
+      if (rcs->none)
+        {
+          attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES));
+          if (attr->extra)
+            attr->extra->lcommunity = NULL;
+
+          /* See the longer comment down below. */
+          if (old && old->refcnt == 0)
+            lcommunity_free(&old);
+          return RMAP_OKAY;
+        }
+
+      if (rcs->additive && old)
+        {
+          merge = lcommunity_merge (lcommunity_dup (old), rcs->lcom);
+
+          /* HACK: if the old large-community is not intern'd,
+           * we should free it here, or all reference to it may be lost.
+           * Really need to cleanup attribute caching sometime.
+           */
+          if (old->refcnt == 0)
+            lcommunity_free (&old);
+          new = lcommunity_uniq_sort (merge);
+          lcommunity_free (&merge);
+        }
+      else
+        new = lcommunity_dup (rcs->lcom);
+
+      /* will be interned by caller if required */
+      if (attr->extra)
+        attr->extra->lcommunity = new;
+
+      attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES);
+    }
+
+  return RMAP_OKAY;
+}
+
+/* Compile function for set community. */
+static void *
+route_set_lcommunity_compile (const char *arg)
+{
+  struct rmap_lcom_set *rcs;
+  struct lcommunity *lcom = NULL;
+  char *sp;
+  int additive = 0;
+  int none = 0;
+
+  if (strcmp (arg, "none") == 0)
+    none = 1;
+  else
+    {
+      sp = strstr (arg, "additive");
+
+      if (sp && sp > arg)
+        {
+          /* "additive" keyworkd is included.  */
+          additive = 1;
+          *(sp - 1) = '\0';
+        }
+
+      lcom = lcommunity_str2com (arg);
+
+      if (additive)
+        *(sp - 1) = ' ';
+
+      if (! lcom)
+        return NULL;
+    }
+
+  rcs = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
+  rcs->lcom = lcom;
+  rcs->additive = additive;
+  rcs->none = none;
+
+  return rcs;
+}
+
+/* Free function for set lcommunity. */
+static void
+route_set_lcommunity_free (void *rule)
+{
+  struct rmap_lcom_set *rcs = rule;
+
+  if (rcs->lcom) {
+    lcommunity_free (&rcs->lcom);
+  }
+  XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
+}
+
+/* Set community rule structure. */
+struct route_map_rule_cmd route_set_lcommunity_cmd =
+{
+  "large-community",
+  route_set_lcommunity,
+  route_set_lcommunity_compile,
+  route_set_lcommunity_free,
+};
+
+/* `set large-comm-list (<1-99>|<100-500>|WORD) delete' */
+
+/* For large community set mechanism. */
+static route_map_result_t
+route_set_lcommunity_delete (void *rule, struct prefix *prefix,
+                             route_map_object_t type, void *object)
+{
+  struct community_list *list;
+  struct lcommunity *merge;
+  struct lcommunity *new;
+  struct lcommunity *old;
+  struct bgp_info *binfo;
+
+  if (type == RMAP_BGP)
+    {
+      if (! rule)
+        return RMAP_OKAY;
+
+      binfo = object;
+      list = community_list_lookup (bgp_clist, rule,
+                                    LARGE_COMMUNITY_LIST_MASTER);
+      old = ((binfo->attr->extra) ? binfo->attr->extra->lcommunity : NULL);
+
+      if (list && old)
+        {
+          merge = lcommunity_list_match_delete (lcommunity_dup (old), list);
+          new = lcommunity_uniq_sort (merge);
+          lcommunity_free (&merge);
+
+          /* HACK: if the old community is not intern'd,
+           * we should free it here, or all reference to it may be lost.
+           * Really need to cleanup attribute caching sometime.
+           */
+          if (old->refcnt == 0)
+            lcommunity_free (&old);
+
+          if (new->size == 0)
+            {
+              binfo->attr->extra->lcommunity = NULL;
+              binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES);
+              lcommunity_free (&new);
+            }
+          else
+            {
+              binfo->attr->extra->lcommunity = new;
+              binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES);
+            }
+        }
+    }
+
+  return RMAP_OKAY;
+}
+
+/* Compile function for set lcommunity. */
+static void *
+route_set_lcommunity_delete_compile (const char *arg)
+{
+  char *p;
+  char *str;
+  int len;
+
+  p = strchr (arg, ' ');
+  if (p)
+    {
+      len = p - arg;
+      str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
+      memcpy (str, arg, len);
+    }
+  else
+    str = NULL;
+
+  return str;
+}
+
+/* Free function for set lcommunity. */
+static void
+route_set_lcommunity_delete_free (void *rule)
+{
+  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
+}
+
+/* Set lcommunity rule structure. */
+struct route_map_rule_cmd route_set_lcommunity_delete_cmd =
+{
+  "large-comm-list",
+  route_set_lcommunity_delete,
+  route_set_lcommunity_delete_compile,
+  route_set_lcommunity_delete_free,
+};
+
+
 /* `set comm-list (<1-99>|<100-500>|WORD) delete' */
 
 /* For community set mechanism. */
@@ -1682,10 +1943,10 @@ route_set_ecommunity (void *rule, struct prefix *prefix,
     {
       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;
 
@@ -1730,7 +1991,7 @@ route_set_ecommunity_free (void *rule)
 }
 
 /* Set community rule structure. */
-struct route_map_rule_cmd route_set_ecommunity_rt_cmd = 
+struct route_map_rule_cmd route_set_ecommunity_rt_cmd =
 {
   "extcommunity rt",
   route_set_ecommunity,
@@ -1749,12 +2010,12 @@ route_set_ecommunity_soo_compile (const char *arg)
   ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
   if (! ecom)
     return NULL;
-  
+
   return ecommunity_intern (ecom);
 }
 
 /* Set community rule structure. */
-struct route_map_rule_cmd route_set_ecommunity_soo_cmd = 
+struct route_map_rule_cmd route_set_ecommunity_soo_cmd =
 {
   "extcommunity soo",
   route_set_ecommunity,
@@ -1775,7 +2036,7 @@ route_set_origin (void *rule, struct prefix *prefix, route_map_object_t type, vo
     {
       origin = rule;
       bgp_info = object;
-    
+
       bgp_info->attr->origin = *origin;
     }
 
@@ -1808,7 +2069,7 @@ route_set_origin_free (void *rule)
 }
 
 /* Set origin rule structure. */
-struct route_map_rule_cmd route_set_origin_cmd = 
+struct route_map_rule_cmd route_set_origin_cmd =
 {
   "origin",
   route_set_origin,
@@ -1849,7 +2110,7 @@ route_set_atomic_aggregate_free (void *rule)
 }
 
 /* Set atomic aggregate rule structure. */
-struct route_map_rule_cmd route_set_atomic_aggregate_cmd = 
+struct route_map_rule_cmd route_set_atomic_aggregate_cmd =
 {
   "atomic-aggregate",
   route_set_atomic_aggregate,
@@ -1865,7 +2126,7 @@ struct aggregator
 };
 
 static route_map_result_t
-route_set_aggregator_as (void *rule, struct prefix *prefix, 
+route_set_aggregator_as (void *rule, struct prefix *prefix,
                         route_map_object_t type, void *object)
 {
   struct bgp_info *bgp_info;
@@ -1877,7 +2138,7 @@ route_set_aggregator_as (void *rule, struct prefix *prefix,
       bgp_info = object;
       aggregator = rule;
       ae = bgp_attr_extra_get (bgp_info->attr);
-      
+
       ae->aggregator_as = aggregator->as;
       ae->aggregator_addr = aggregator->address;
       bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
@@ -1908,7 +2169,7 @@ route_set_aggregator_as_free (void *rule)
   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 }
 
-struct route_map_rule_cmd route_set_aggregator_as_cmd = 
+struct route_map_rule_cmd route_set_aggregator_as_cmd =
 {
   "aggregator as",
   route_set_aggregator_as,
@@ -1921,7 +2182,7 @@ static route_map_result_t
 route_set_tag (void *rule, struct prefix *prefix,
                route_map_object_t type, void *object)
 {
-  u_short *tag;
+  route_tag_t *tag;
   struct bgp_info *bgp_info;
   struct attr_extra *ae;
 
@@ -1939,65 +2200,30 @@ route_set_tag (void *rule, struct prefix *prefix,
   return RMAP_OKAY;
 }
 
-/* Route map `tag' compile function.  Given string is converted to u_short. */
-static void *
-route_set_tag_compile (const char *arg)
+/* Route map commands for tag set. */
+static struct route_map_rule_cmd route_set_tag_cmd =
 {
-  u_short *tag;
-  u_short tmp;
-
-  /* tag value shoud be integer. */
-  if (! all_digit (arg))
-    return NULL;
+  "tag",
+  route_set_tag,
+  route_map_rule_tag_compile,
+  route_map_rule_tag_free,
+};
 
-  tmp = atoi(arg);
 
-  if (tmp < 1)
-      return NULL;
+/* `match ipv6 address IP_ACCESS_LIST' */
 
-  tag = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_short));
+static route_map_result_t
+route_match_ipv6_address (void *rule, struct prefix *prefix,
+                         route_map_object_t type, void *object)
+{
+  struct access_list *alist;
 
-  if (!tag)
-    return tag;
+  if (type == RMAP_BGP)
+    {
+      alist = access_list_lookup (AFI_IP6, (char *) rule);
+      if (alist == NULL)
+       return RMAP_NOMATCH;
 
-  *tag = tmp;
-
-  return tag;
-}
-
-/* Free route map's tag value. */
-static void
-route_set_tag_free (void *rule)
-{
-  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
-}
-
-
-/* Route map commands for tag set. */
-struct route_map_rule_cmd route_set_tag_cmd =
-{
-  "tag",
-  route_set_tag,
-  route_set_tag_compile,
-  route_set_tag_free,
-};
-
-
-#ifdef HAVE_IPV6
-/* `match ipv6 address IP_ACCESS_LIST' */
-
-static route_map_result_t
-route_match_ipv6_address (void *rule, struct prefix *prefix, 
-                         route_map_object_t type, void *object)
-{
-  struct access_list *alist;
-
-  if (type == RMAP_BGP)
-    {
-      alist = access_list_lookup (AFI_IP6, (char *) rule);
-      if (alist == NULL)
-       return RMAP_NOMATCH;
-    
       return (access_list_apply (alist, prefix) == FILTER_DENY ?
              RMAP_NOMATCH : RMAP_MATCH);
     }
@@ -2028,7 +2254,7 @@ struct route_map_rule_cmd route_match_ipv6_address_cmd =
 /* `match ipv6 next-hop IP_ADDRESS' */
 
 static route_map_result_t
-route_match_ipv6_next_hop (void *rule, struct prefix *prefix, 
+route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
                           route_map_object_t type, void *object)
 {
   struct in6_addr *addr = rule;
@@ -2037,10 +2263,10 @@ route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
   if (type == RMAP_BGP)
     {
       bgp_info = object;
-      
+
       if (!bgp_info->attr->extra)
         return RMAP_NOMATCH;
-      
+
       if (IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_global, addr))
        return RMAP_MATCH;
 
@@ -2089,7 +2315,7 @@ struct route_map_rule_cmd route_match_ipv6_next_hop_cmd =
 /* `match ipv6 address prefix-list PREFIX_LIST' */
 
 static route_map_result_t
-route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix, 
+route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
                              route_map_object_t type, void *object)
 {
   struct prefix_list *plist;
@@ -2099,7 +2325,7 @@ route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
       plist = prefix_list_lookup (AFI_IP6, (char *) rule);
       if (plist == NULL)
        return RMAP_NOMATCH;
-    
+
       return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
              RMAP_NOMATCH : RMAP_MATCH);
     }
@@ -2130,7 +2356,7 @@ struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
 
 /* Set nexthop to object.  ojbect must be pointer to struct attr. */
 static route_map_result_t
-route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix, 
+route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
                               route_map_object_t type, void *object)
 {
   struct in6_addr *address;
@@ -2141,8 +2367,8 @@ route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
       /* Fetch routemap's rule information. */
       address = rule;
       bgp_info = object;
-    
-      /* Set next hop value. */ 
+
+      /* Set next hop value. */
       (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = *address;
 
       /* Set nexthop length. */
@@ -2258,7 +2484,7 @@ struct route_map_rule_cmd route_set_ipv6_nexthop_prefer_global_cmd =
 
 /* Set nexthop to object.  ojbect must be pointer to struct attr. */
 static route_map_result_t
-route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix, 
+route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
                              route_map_object_t type, void *object)
 {
   struct in6_addr *address;
@@ -2269,10 +2495,10 @@ route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
       /* Fetch routemap's rule information. */
       address = rule;
       bgp_info = object;
-    
-      /* Set next hop value. */ 
+
+      /* Set next hop value. */
       (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = *address;
-    
+
       /* Set nexthop length. */
       if (bgp_info->attr->extra->mp_nexthop_len != BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
        bgp_info->attr->extra->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
@@ -2331,7 +2557,6 @@ route_set_ipv6_nexthop_peer (void *rule, struct prefix *prefix,
   struct in6_addr peer_address;
   struct bgp_info *bgp_info;
   struct peer *peer;
-  char peer_addr_buf[INET6_ADDRSTRLEN];
 
   if (type == RMAP_BGP)
     {
@@ -2344,10 +2569,7 @@ route_set_ipv6_nexthop_peer (void *rule, struct prefix *prefix,
          && peer->su_remote
          && sockunion_family (peer->su_remote) == AF_INET6)
        {
-         inet_pton (AF_INET6, sockunion2str (peer->su_remote,
-                                             peer_addr_buf,
-                                             INET6_ADDRSTRLEN),
-                    &peer_address);
+         peer_address = peer->su_remote->sin6.sin6_addr;
           /* Set next hop value and length in attribute. */
           if (IN6_IS_ADDR_LINKLOCAL(&peer_address))
             {
@@ -2412,12 +2634,10 @@ struct route_map_rule_cmd route_set_ipv6_nexthop_peer_cmd =
   route_set_ipv6_nexthop_peer_free
 };
 
-#endif /* HAVE_IPV6 */
-
 /* `set vpnv4 nexthop A.B.C.D' */
 
 static route_map_result_t
-route_set_vpnv4_nexthop (void *rule, struct prefix *prefix, 
+route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
                         route_map_object_t type, void *object)
 {
   struct in_addr *address;
@@ -2428,8 +2648,8 @@ route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
       /* Fetch routemap's rule information. */
       address = rule;
       bgp_info = object;
-    
-      /* Set next hop value. */ 
+
+      /* Set next hop value. */
       (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global_in = *address;
       (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_len = 4;
     }
@@ -2480,11 +2700,11 @@ route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t t
   struct in_addr *address;
   struct bgp_info *bgp_info;
 
-  if (type == RMAP_BGP) 
+  if (type == RMAP_BGP)
     {
       address = rule;
       bgp_info = object;
-    
+
       bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
       (bgp_attr_extra_get (bgp_info->attr))->originator_id = *address;
     }
@@ -2520,7 +2740,7 @@ route_set_originator_id_free (void *rule)
 }
 
 /* Set originator-id rule structure. */
-struct route_map_rule_cmd route_set_originator_id_cmd = 
+struct route_map_rule_cmd route_set_originator_id_cmd =
 {
   "originator-id",
   route_set_originator_id,
@@ -2530,10 +2750,11 @@ struct route_map_rule_cmd route_set_originator_id_cmd =
 
 /* Add bgp route map rule. */
 static int
-bgp_route_match_add (struct vty *vty, struct route_map_index *index,
+bgp_route_match_add (struct vty *vty,
                     const char *command, const char *arg,
                     route_map_event_t type)
 {
+  VTY_DECLVAR_CONTEXT(route_map_index, index);
   int ret;
 
   ret = route_map_add_match (index, command, arg);
@@ -2560,10 +2781,11 @@ bgp_route_match_add (struct vty *vty, struct route_map_index *index,
 
 /* Delete bgp route map rule. */
 static int
-bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
+bgp_route_match_delete (struct vty *vty,
                        const char *command, const char *arg,
                        route_map_event_t type)
 {
+  VTY_DECLVAR_CONTEXT(route_map_index, index);
   int ret;
   char *dep_name = NULL;
   const char *tmpstr;
@@ -2614,52 +2836,6 @@ bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
   return CMD_SUCCESS;
 }
 
-/* Add bgp route map rule. */
-static int
-bgp_route_set_add (struct vty *vty, struct route_map_index *index,
-                  const char *command, const char *arg)
-{
-  int ret;
-
-  ret = route_map_add_set (index, command, arg);
-  if (ret)
-    {
-      switch (ret)
-       {
-       case RMAP_RULE_MISSING:
-         vty_out (vty, "%% BGP Can't find rule.%s", VTY_NEWLINE);
-         return CMD_WARNING;
-       case RMAP_COMPILE_ERROR:
-         vty_out (vty, "%% BGP Argument is malformed.%s", VTY_NEWLINE);
-         return CMD_WARNING;
-       }
-    }
-  return CMD_SUCCESS;
-}
-
-/* Delete bgp route map rule. */
-static int
-bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
-                     const char *command, const char *arg)
-{
-  int ret;
-
-  ret = route_map_delete_set (index, command, arg);
-  if (ret)
-    {
-      switch (ret)
-       {
-       case RMAP_RULE_MISSING:
-         vty_out (vty, "%% BGP Can't find rule.%s", VTY_NEWLINE);
-         return CMD_WARNING;
-       case RMAP_COMPILE_ERROR:
-         vty_out (vty, "%% BGP Argument is malformed.%s", VTY_NEWLINE);
-         return CMD_WARNING;
-       }
-    }
-  return CMD_SUCCESS;
-}
-
 /*
  * This is the workhorse routine for processing in/out routemap
  * modifications.
@@ -2924,6 +3100,10 @@ bgp_route_map_process_update_cb (char *rmap_name)
   for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
     bgp_route_map_process_update(bgp, rmap_name, 1);
 
+#if ENABLE_BGP_VNC
+  zlog_debug("%s: calling vnc_routemap_update", __func__);
+  vnc_routemap_update(bgp, __func__);
+#endif
   return 0;
 }
 
@@ -2960,6 +3140,10 @@ bgp_route_map_mark_update (const char *rmap_name)
         {
           for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
             bgp_route_map_process_update(bgp, rmap_name, 0);
+ #if ENABLE_BGP_VNC
+          zlog_debug("%s: calling vnc_routemap_update", __func__);
+          vnc_routemap_update(bgp, __func__);
+#endif
         }
     }
 }
@@ -2994,13 +3178,14 @@ bgp_route_map_event (route_map_event_t event, const char *rmap_name)
 
 DEFUN (match_peer,
        match_peer_cmd,
-       "match peer (A.B.C.D|X:X::X:X)",
+       "match peer <A.B.C.D|X:X::X:X>",
        MATCH_STR
        "Match peer address\n"
        "IP address of peer\n"
        "IPv6 address of peer\n")
 {
-  return bgp_route_match_add (vty, vty->index, "peer", argv[2]->arg,
+  int idx_ip = 2;
+  return bgp_route_match_add (vty, "peer", argv[idx_ip]->arg,
                              RMAP_EVENT_MATCH_ADDED);
 }
 
@@ -3011,156 +3196,64 @@ DEFUN (match_peer_local,
         "Match peer address\n"
         "Static or Redistributed routes\n")
 {
-  return bgp_route_match_add (vty, vty->index, "peer", "local",
+  return bgp_route_match_add (vty, "peer", "local",
                              RMAP_EVENT_MATCH_DELETED);
 }
 
-/*
- * CHECK ME - The following ALIASes need to be implemented in this DEFUN
- * "no match peer local",
- *     NO_STR
- *     MATCH_STR
- *     "Match peer address\n"
- *     "Static or Redistributed routes\n"
- *
- * "no match peer (A.B.C.D|X:X::X:X)",
- *     NO_STR
- *     MATCH_STR
- *     "Match peer address\n"
- *     "IP address of peer\n"
- *     "IPv6 address of peer\n"
- *
- */
 DEFUN (no_match_peer,
        no_match_peer_cmd,
-       "no match peer",
-       NO_STR
-       MATCH_STR
-       "Match peer address\n")
-{
- return bgp_route_match_delete (vty, vty->index, "peer", argv[3]->arg,
-                               RMAP_EVENT_MATCH_DELETED);
-}
-
-
-
-DEFUN (match_ip_address,
-       match_ip_address_cmd,
-       "match ip address (<1-199>|<1300-2699>|WORD)",
-       MATCH_STR
-       IP_STR
-       "Match address of route\n"
-       "IP access-list number\n"
-       "IP access-list number (expanded range)\n"
-       "IP Access-list name\n")
-{
-  return bgp_route_match_add (vty, vty->index, "ip address", argv[3]->arg,
-                             RMAP_EVENT_FILTER_ADDED);
-}
-
-/*
- * CHECK ME - The following ALIASes need to be implemented in this DEFUN
- * "no match ip address (<1-199>|<1300-2699>|WORD)",
- *     NO_STR
- *     MATCH_STR
- *     IP_STR
- *     "Match address of route\n"
- *     "IP access-list number\n"
- *     "IP access-list number (expanded range)\n"
- *     "IP Access-list name\n"
- *
- */
-DEFUN (no_match_ip_address,
-       no_match_ip_address_cmd,
-       "no match ip address",
+       "no match peer [<local|A.B.C.D|X:X::X:X>]",
        NO_STR
        MATCH_STR
-       IP_STR
-       "Match address of route\n")
-{
-  return bgp_route_match_delete (vty, vty->index, "ip address", argv[4]->arg,
-                                RMAP_EVENT_FILTER_DELETED);
-}
-
-
-DEFUN (match_ip_next_hop,
-       match_ip_next_hop_cmd,
-       "match ip next-hop (<1-199>|<1300-2699>|WORD)",
-       MATCH_STR
-       IP_STR
-       "Match next-hop address of route\n"
-       "IP access-list number\n"
-       "IP access-list number (expanded range)\n"
-       "IP Access-list name\n")
+       "Match peer address\n"
+       "Static or Redistributed routes\n"
+       "IP address of peer\n"
+       "IPv6 address of peer\n")
 {
-  return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[3]->arg,
-                             RMAP_EVENT_FILTER_ADDED);
-}
+ int idx_peer = 3;
 
-/*
- * CHECK ME - The following ALIASes need to be implemented in this DEFUN
- * "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
- *     NO_STR
- *     MATCH_STR
- *     IP_STR
- *     "Match next-hop address of route\n"
- *     "IP access-list number\n"
- *     "IP access-list number (expanded range)\n"
- *     "IP Access-list name\n"
- *
- */
-DEFUN (no_match_ip_next_hop,
-       no_match_ip_next_hop_cmd,
-       "no match ip next-hop",
-       NO_STR
-       MATCH_STR
-       IP_STR
-       "Match next-hop address of route\n")
-{
-  return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[4]->arg,
-                                RMAP_EVENT_FILTER_DELETED);
+ if (argc <= idx_peer)
+   return bgp_route_match_delete (vty, "peer", NULL,
+                                  RMAP_EVENT_MATCH_DELETED);
+ return bgp_route_match_delete (vty, "peer", argv[idx_peer]->arg,
+                               RMAP_EVENT_MATCH_DELETED);
 }
 
 
-/* match probability { */
-
+/* match probability */
 DEFUN (match_probability,
        match_probability_cmd,
-       "match probability <0-100>",
+       "match probability (0-100)",
        MATCH_STR
        "Match portion of routes defined by percentage value\n"
        "Percentage of routes\n")
 {
-  return bgp_route_match_add (vty, vty->index, "probability", argv[2]->arg,
+  int idx_number = 2;
+  return bgp_route_match_add (vty, "probability", argv[idx_number]->arg,
                              RMAP_EVENT_MATCH_ADDED);
 }
 
-/*
- * CHECK ME - The following ALIASes need to be implemented in this DEFUN
- * "no match probability <1-99>",
- *     NO_STR
- *     MATCH_STR
- *     "Match portion of routes defined by percentage value\n"
- *     "Percentage of routes\n"
- *
- */
+
 DEFUN (no_match_probability,
        no_match_probability_cmd,
-       "no match probability",
+       "no match probability [(1-99)]",
        NO_STR
        MATCH_STR
-       "Match portion of routes defined by percentage value\n")
+       "Match portion of routes defined by percentage value\n"
+       "Percentage of routes\n")
 {
-  return bgp_route_match_delete (vty, vty->index, "probability", argv[2]->arg,
+  int idx_number = 3;
+  if (argc <= idx_number)
+    return bgp_route_match_delete (vty, "probability", NULL,
+                                   RMAP_EVENT_MATCH_DELETED);
+  return bgp_route_match_delete (vty, "probability", argv[idx_number]->arg,
                                 RMAP_EVENT_MATCH_DELETED);
 }
 
 
-/* } */
-
 DEFUN (match_ip_route_source,
        match_ip_route_source_cmd,
-       "match ip route-source (<1-199>|<1300-2699>|WORD)",
+       "match ip route-source <(1-199)|(1300-2699)|WORD>",
        MATCH_STR
        IP_STR
        "Match advertising source address of route\n"
@@ -3168,108 +3261,29 @@ DEFUN (match_ip_route_source,
        "IP access-list number (expanded range)\n"
        "IP standard access-list name\n")
 {
-  return bgp_route_match_add (vty, vty->index, "ip route-source", argv[3]->arg,
+  int idx_acl = 3;
+  return bgp_route_match_add (vty, "ip route-source", argv[idx_acl]->arg,
                              RMAP_EVENT_FILTER_ADDED);
 }
 
-/*
- * CHECK ME - The following ALIASes need to be implemented in this DEFUN
- * "no match ip route-source (<1-199>|<1300-2699>|WORD)",
- *     NO_STR
- *     MATCH_STR
- *     IP_STR
- *     "Match advertising source address of route\n"
- *     "IP access-list number\n"
- *     "IP access-list number (expanded range)\n"
- *     "IP standard access-list name\n"
- *
- */
+
 DEFUN (no_match_ip_route_source,
        no_match_ip_route_source_cmd,
-       "no match ip route-source",
-       NO_STR
-       MATCH_STR
-       IP_STR
-       "Match advertising source address of route\n")
-{
-  return bgp_route_match_delete (vty, vty->index, "ip route-source",
-                                argv[4]->arg, RMAP_EVENT_FILTER_DELETED);
-}
-
-
-DEFUN (match_ip_address_prefix_list,
-       match_ip_address_prefix_list_cmd,
-       "match ip address prefix-list WORD",
-       MATCH_STR
-       IP_STR
-       "Match address of route\n"
-       "Match entries of prefix-lists\n"
-       "IP prefix-list name\n")
-{
-  return bgp_route_match_add (vty, vty->index, "ip address prefix-list",
-                             argv[4]->arg, RMAP_EVENT_PLIST_ADDED);
-}
-
-/*
- * CHECK ME - The following ALIASes need to be implemented in this DEFUN
- * "no match ip address prefix-list WORD",
- *     NO_STR
- *     MATCH_STR
- *     IP_STR
- *     "Match address of route\n"
- *     "Match entries of prefix-lists\n"
- *     "IP prefix-list name\n"
- *
- */
-DEFUN (no_match_ip_address_prefix_list,
-       no_match_ip_address_prefix_list_cmd,
-       "no match ip address prefix-list",
-       NO_STR
-       MATCH_STR
-       IP_STR
-       "Match address of route\n"
-       "Match entries of prefix-lists\n")
-{
-  return bgp_route_match_delete (vty, vty->index, "ip address prefix-list",
-                                argv[5]->arg, RMAP_EVENT_PLIST_DELETED);
-}
-
-
-DEFUN (match_ip_next_hop_prefix_list,
-       match_ip_next_hop_prefix_list_cmd,
-       "match ip next-hop prefix-list WORD",
-       MATCH_STR
-       IP_STR
-       "Match next-hop address of route\n"
-       "Match entries of prefix-lists\n"
-       "IP prefix-list name\n")
-{
-  return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list",
-                             argv[4]->arg, RMAP_EVENT_PLIST_ADDED);
-}
-
-/*
- * CHECK ME - The following ALIASes need to be implemented in this DEFUN
- * "no match ip next-hop prefix-list WORD",
- *     NO_STR
- *     MATCH_STR
- *     IP_STR
- *     "Match next-hop address of route\n"
- *     "Match entries of prefix-lists\n"
- *     "IP prefix-list name\n"
- *
- */
-DEFUN (no_match_ip_next_hop_prefix_list,
-       no_match_ip_next_hop_prefix_list_cmd,
-       "no match ip next-hop prefix-list",
+       "no match ip route-source [<(1-199)|(1300-2699)|WORD>]",
        NO_STR
        MATCH_STR
        IP_STR
-       "Match next-hop address of route\n"
-       "Match entries of prefix-lists\n")
+       "Match advertising source address of route\n"
+       "IP access-list number\n"
+       "IP access-list number (expanded range)\n"
+       "IP standard access-list name\n")
 {
-  return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list",
-                                argv[5]->arg, RMAP_EVENT_PLIST_DELETED);
+  int idx_number = 4;
+  if (argc <= idx_number)
+    return bgp_route_match_delete (vty, "ip route-source",
+                                   NULL, RMAP_EVENT_FILTER_DELETED);
+  return bgp_route_match_delete (vty, "ip route-source",
+                                argv[idx_number]->arg, RMAP_EVENT_FILTER_DELETED);
 }
 
 
@@ -3282,117 +3296,79 @@ DEFUN (match_ip_route_source_prefix_list,
        "Match entries of prefix-lists\n"
        "IP prefix-list name\n")
 {
-  return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list",
-                             argv[4]->arg, RMAP_EVENT_PLIST_ADDED);
+  int idx_word = 4;
+  return bgp_route_match_add (vty, "ip route-source prefix-list",
+                             argv[idx_word]->arg, RMAP_EVENT_PLIST_ADDED);
 }
 
-/*
- * CHECK ME - The following ALIASes need to be implemented in this DEFUN
- * "no match ip route-source prefix-list WORD",
- *     NO_STR
- *     MATCH_STR
- *     IP_STR
- *     "Match advertising source address of route\n"
- *     "Match entries of prefix-lists\n"
- *     "IP prefix-list name\n"
- *
- */
+
 DEFUN (no_match_ip_route_source_prefix_list,
        no_match_ip_route_source_prefix_list_cmd,
-       "no match ip route-source prefix-list",
+       "no match ip route-source prefix-list [WORD]",
        NO_STR
        MATCH_STR
        IP_STR
        "Match advertising source address of route\n"
-       "Match entries of prefix-lists\n")
-{
-  return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list",
-                                argv[5]->arg, RMAP_EVENT_PLIST_DELETED);
-}
-
-
-DEFUN (match_metric,
-       match_metric_cmd,
-       "match metric <0-4294967295>",
-       MATCH_STR
-       "Match metric of route\n"
-       "Metric value\n")
-{
-  return bgp_route_match_add (vty, vty->index, "metric", argv[2]->arg,
-                             RMAP_EVENT_MATCH_ADDED);
-}
-
-/*
- * CHECK ME - The following ALIASes need to be implemented in this DEFUN
- * "no match metric <0-4294967295>",
- *     NO_STR
- *     MATCH_STR
- *     "Match metric of route\n"
- *     "Metric value\n"
- *
- */
-DEFUN (no_match_metric,
-       no_match_metric_cmd,
-       "no match metric",
-       NO_STR
-       MATCH_STR
-       "Match metric of route\n")
+       "Match entries of prefix-lists\n"
+       "IP prefix-list name\n")
 {
-  return bgp_route_match_delete (vty, vty->index, "metric",
-                                argv[3]->arg,
-                                RMAP_EVENT_MATCH_DELETED);
+  int idx_word = 5;
+  if (argc <= idx_word)
+    return bgp_route_match_delete (vty, "ip route-source prefix-list",
+                                   NULL, RMAP_EVENT_PLIST_DELETED);
+  return bgp_route_match_delete (vty, "ip route-source prefix-list",
+                                argv[idx_word]->arg, RMAP_EVENT_PLIST_DELETED);
 }
 
 
 DEFUN (match_local_pref,
        match_local_pref_cmd,
-       "match local-preference <0-4294967295>",
+       "match local-preference (0-4294967295)",
        MATCH_STR
        "Match local-preference of route\n"
        "Metric value\n")
 {
-  return bgp_route_match_add (vty, vty->index, "local-preference", argv[2]->arg,
+  int idx_number = 2;
+  return bgp_route_match_add (vty, "local-preference", argv[idx_number]->arg,
                              RMAP_EVENT_MATCH_ADDED);
 }
 
-/*
- * CHECK ME - The following ALIASes need to be implemented in this DEFUN
- * "no match local-preference <0-4294967295>",
- *     NO_STR
- *     MATCH_STR
- *     "Match local preference of route\n"
- *     "Local preference value\n"
- *
- */
+
 DEFUN (no_match_local_pref,
        no_match_local_pref_cmd,
-       "no match local-preference",
+       "no match local-preference [(0-4294967295)]",
        NO_STR
        MATCH_STR
-       "Match local preference of route\n")
-{
-  return bgp_route_match_delete (vty, vty->index, "local-preference",
-                                argv[3]->arg,
+       "Match local preference of route\n"
+       "Local preference value\n")
+{
+  int idx_localpref = 3;
+  if (argc <= idx_localpref)
+    return bgp_route_match_delete (vty, "local-preference",
+                                   NULL, RMAP_EVENT_MATCH_DELETED);
+  return bgp_route_match_delete (vty, "local-preference",
+                                argv[idx_localpref]->arg,
                                 RMAP_EVENT_MATCH_DELETED);
 }
 
 
 DEFUN (match_community,
        match_community_cmd,
-       "match community (<1-99>|<100-500>|WORD)",
+       "match community <(1-99)|(100-500)|WORD>",
        MATCH_STR
        "Match BGP community list\n"
        "Community-list number (standard)\n"
        "Community-list number (expanded)\n"
        "Community-list name\n")
 {
-  return bgp_route_match_add (vty, vty->index, "community", argv[2]->arg,
+  int idx_comm_list = 2;
+  return bgp_route_match_add (vty, "community", argv[idx_comm_list]->arg,
                              RMAP_EVENT_CLIST_ADDED);
 }
 
 DEFUN (match_community_exact,
        match_community_exact_cmd,
-       "match community (<1-99>|<100-500>|WORD) exact-match",
+       "match community <(1-99)|(100-500)|WORD> exact-match",
        MATCH_STR
        "Match BGP community list\n"
        "Community-list number (standard)\n"
@@ -3400,15 +3376,16 @@ DEFUN (match_community_exact,
        "Community-list name\n"
        "Do exact matching of communities\n")
 {
+  int idx_comm_list = 2;
   int ret;
   char *argstr;
 
   argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
-                   strlen (argv[2]->arg) + strlen ("exact-match") + 2);
+                   strlen (argv[idx_comm_list]->arg) + strlen ("exact-match") + 2);
 
-  sprintf (argstr, "%s exact-match", argv[2]->arg);
+  sprintf (argstr, "%s exact-match", argv[idx_comm_list]->arg);
 
-  ret = bgp_route_match_add (vty, vty->index, "community", argstr,
+  ret = bgp_route_match_add (vty, "community", argstr,
                             RMAP_EVENT_CLIST_ADDED);
 
   XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
@@ -3416,71 +3393,74 @@ DEFUN (match_community_exact,
   return ret;
 }
 
-/*
- * CHECK ME - The following ALIASes need to be implemented in this DEFUN
- * "no match community (<1-99>|<100-500>|WORD)",
- *     NO_STR
- *     MATCH_STR
- *     "Match BGP community list\n"
- *     "Community-list number (standard)\n"
- *     "Community-list number (expanded)\n"
- *     "Community-list name\n"
- *
- * "no match community (<1-99>|<100-500>|WORD) exact-match",
- *     NO_STR
- *     MATCH_STR
- *     "Match BGP community list\n"
- *     "Community-list number (standard)\n"
- *     "Community-list number (expanded)\n"
- *     "Community-list name\n"
- *     "Do exact matching of communities\n"
- *
- */
 DEFUN (no_match_community,
        no_match_community_cmd,
-       "no match community",
+       "no match community [<(1-99)|(100-500)|WORD> [exact-match]]",
        NO_STR
        MATCH_STR
-       "Match BGP community list\n")
+       "Match BGP community list\n"
+       "Community-list number (standard)\n"
+       "Community-list number (expanded)\n"
+       "Community-list name\n"
+       "Do exact matching of communities\n")
 {
-  return bgp_route_match_delete (vty, vty->index, "community", NULL,
+  return bgp_route_match_delete (vty, "community", NULL,
                                 RMAP_EVENT_CLIST_DELETED);
 }
 
+DEFUN (match_lcommunity,
+       match_lcommunity_cmd,
+       "match large-community [<(1-99)|(100-500)|WORD>]",
+       MATCH_STR
+       "Match BGP large community list\n"
+       "Large Community-list number (standard)\n"
+       "Large Community-list number (expanded)\n"
+       "Large Community-list name\n")
+{
+  return bgp_route_match_add (vty, "large-community", argv[2]->arg,
+                              RMAP_EVENT_LLIST_ADDED);
+}
 
+DEFUN (no_match_lcommunity,
+       no_match_lcommunity_cmd,
+       "no match large-community [<(1-99)|(100-500)|WORD>]",
+       NO_STR
+       MATCH_STR
+       "Match BGP large community list\n"
+       "Large Community-list number (standard)\n"
+       "Large Community-list number (expanded)\n"
+       "Large Community-list name\n")
+{
+  return bgp_route_match_delete (vty, "large-community", NULL,
+                                 RMAP_EVENT_LLIST_DELETED);
+}
 
 DEFUN (match_ecommunity,
        match_ecommunity_cmd,
-       "match extcommunity (<1-99>|<100-500>|WORD)",
+       "match extcommunity <(1-99)|(100-500)|WORD>",
        MATCH_STR
        "Match BGP/VPN extended community list\n"
        "Extended community-list number (standard)\n"
        "Extended community-list number (expanded)\n"
        "Extended community-list name\n")
 {
-  return bgp_route_match_add (vty, vty->index, "extcommunity", argv[2]->arg,
+  int idx_comm_list = 2;
+  return bgp_route_match_add (vty, "extcommunity", argv[idx_comm_list]->arg,
                              RMAP_EVENT_ECLIST_ADDED);
 }
 
-/*
- * CHECK ME - The following ALIASes need to be implemented in this DEFUN
- * "no match extcommunity (<1-99>|<100-500>|WORD)",
- *     NO_STR
- *     MATCH_STR
- *     "Match BGP/VPN extended community list\n"
- *     "Extended community-list number (standard)\n"
- *     "Extended community-list number (expanded)\n"
- *     "Extended community-list name\n"
- *
- */
+
 DEFUN (no_match_ecommunity,
        no_match_ecommunity_cmd,
-       "no match extcommunity",
+       "no match extcommunity [<(1-99)|(100-500)|WORD>]",
        NO_STR
        MATCH_STR
-       "Match BGP/VPN extended community list\n")
+       "Match BGP/VPN extended community list\n"
+       "Extended community-list number (standard)\n"
+       "Extended community-list number (expanded)\n"
+       "Extended community-list name\n")
 {
-  return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL,
+  return bgp_route_match_delete (vty, "extcommunity", NULL,
                                 RMAP_EVENT_ECLIST_DELETED);
 }
 
@@ -3492,169 +3472,63 @@ DEFUN (match_aspath,
        "Match BGP AS path list\n"
        "AS path access-list name\n")
 {
-  return bgp_route_match_add (vty, vty->index, "as-path", argv[2]->arg,
+  int idx_word = 2;
+  return bgp_route_match_add (vty, "as-path", argv[idx_word]->arg,
                              RMAP_EVENT_ASLIST_ADDED);
 }
 
-/*
- * CHECK ME - The following ALIASes need to be implemented in this DEFUN
- * "no match as-path WORD",
- *     NO_STR
- *     MATCH_STR
- *     "Match BGP AS path list\n"
- *     "AS path access-list name\n"
- *
- */
+
 DEFUN (no_match_aspath,
        no_match_aspath_cmd,
-       "no match as-path",
+       "no match as-path [WORD]",
        NO_STR
        MATCH_STR
-       "Match BGP AS path list\n")
+       "Match BGP AS path list\n"
+       "AS path access-list name\n")
 {
-  return bgp_route_match_delete (vty, vty->index, "as-path", NULL,
+  return bgp_route_match_delete (vty, "as-path", NULL,
                                 RMAP_EVENT_ASLIST_DELETED);
 }
 
 
 DEFUN (match_origin,
        match_origin_cmd,
-       "match origin (egp|igp|incomplete)",
+       "match origin <egp|igp|incomplete>",
        MATCH_STR
        "BGP origin code\n"
        "remote EGP\n"
        "local IGP\n"
        "unknown heritage\n")
 {
-  if (strncmp (argv[2]->arg, "igp", 2) == 0)
-    return bgp_route_match_add (vty, vty->index, "origin", "igp",
+  int idx_origin = 2;
+  if (strncmp (argv[idx_origin]->arg, "igp", 2) == 0)
+    return bgp_route_match_add (vty, "origin", "igp",
                                RMAP_EVENT_MATCH_ADDED);
-  if (strncmp (argv[2]->arg, "egp", 1) == 0)
-    return bgp_route_match_add (vty, vty->index, "origin", "egp",
+  if (strncmp (argv[idx_origin]->arg, "egp", 1) == 0)
+    return bgp_route_match_add (vty, "origin", "egp",
                                RMAP_EVENT_MATCH_ADDED);
-  if (strncmp (argv[2]->arg, "incomplete", 2) == 0)
-    return bgp_route_match_add (vty, vty->index, "origin", "incomplete",
+  if (strncmp (argv[idx_origin]->arg, "incomplete", 2) == 0)
+    return bgp_route_match_add (vty, "origin", "incomplete",
                                RMAP_EVENT_MATCH_ADDED);
 
   return CMD_WARNING;
 }
 
-/*
- * CHECK ME - The following ALIASes need to be implemented in this DEFUN
- * "no match origin (egp|igp|incomplete)",
- *     NO_STR
- *     MATCH_STR
- *     "BGP origin code\n"
- *     "remote EGP\n"
- *     "local IGP\n"
- *     "unknown heritage\n"
- *
- */
+
 DEFUN (no_match_origin,
        no_match_origin_cmd,
-       "no match origin",
-       NO_STR
-       MATCH_STR
-       "BGP origin code\n")
-{
-  return bgp_route_match_delete (vty, vty->index, "origin", NULL,
-                                RMAP_EVENT_MATCH_DELETED);
-}
-
-
-DEFUN (match_interface,
-       match_interface_cmd,
-       "match interface WORD",
-       MATCH_STR
-       "Match first hop interface of route\n"
-       "Interface name\n")
-{
-  return bgp_route_match_add (vty, vty->index, "interface", argv[2]->arg,
-                             RMAP_EVENT_MATCH_ADDED);
-}
-
-/*
- * CHECK ME - The following ALIASes need to be implemented in this DEFUN
- * "no match interface WORD",
- *     NO_STR
- *     MATCH_STR
- *     "Match first hop interface of route\n"
- *     "Interface name\n"
- *
- */
-DEFUN (no_match_interface,
-       no_match_interface_cmd,
-       "no match interface",
+       "no match origin [<egp|igp|incomplete>]",
        NO_STR
        MATCH_STR
-       "Match first hop interface of route\n")
+       "BGP origin code\n"
+       "remote EGP\n"
+       "local IGP\n"
+       "unknown heritage\n")
 {
-  return bgp_route_match_delete (vty, vty->index, "interface", argv[3]->arg,
+  return bgp_route_match_delete (vty, "origin", NULL,
                                 RMAP_EVENT_MATCH_DELETED);
 }
 
-
-DEFUN (match_tag,
-       match_tag_cmd,
-       "match tag <1-65535>",
-       MATCH_STR
-       "Match tag of route\n"
-       "Tag value\n")
-{
-  return bgp_route_match_add (vty, vty->index, "tag", argv[2]->arg,
-                             RMAP_EVENT_MATCH_ADDED);
-}
-
-/*
- * CHECK ME - The following ALIASes need to be implemented in this DEFUN
- * "no match tag <1-65535>",
- *     NO_STR
- *     MATCH_STR
- *     "Match tag of route\n"
- *     "Tag value\n"
- *
- */
-DEFUN (no_match_tag,
-       no_match_tag_cmd,
-       "no match tag",
-       NO_STR
-       MATCH_STR
-       "Match tag of route\n")
-{
-  return bgp_route_match_delete (vty, vty->index, "tag", argv[3]->arg,
-                                RMAP_EVENT_MATCH_DELETED);
-}
-
-
-
-DEFUN (set_ip_nexthop,
-       set_ip_nexthop_cmd,
-       "set ip next-hop A.B.C.D",
-       SET_STR
-       IP_STR
-       "Next hop address\n"
-       "IP address of next hop\n")
-{
-  union sockunion su;
-  int ret;
-
-  ret = str2sockunion (argv[3]->arg, &su);
-  if (ret < 0)
-    {
-      vty_out (vty, "%% Malformed nexthop address%s", VTY_NEWLINE);
-      return CMD_WARNING;
-    }
-  if (su.sin.sin_addr.s_addr == 0 ||
-      IPV4_CLASS_DE(su.sin.sin_addr.s_addr))
-    {
-      vty_out (vty, "%% nexthop address cannot be 0.0.0.0, multicast "
-               "or reserved%s", VTY_NEWLINE);
-      return CMD_WARNING;
-    }
-  return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[3]->arg);
-}
-
 DEFUN (set_ip_nexthop_peer,
        set_ip_nexthop_peer_cmd,
        "set ip next-hop peer-address",
@@ -3663,7 +3537,8 @@ DEFUN (set_ip_nexthop_peer,
        "Next hop address\n"
        "Use peer address (for BGP only)\n")
 {
-  return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
+  return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+                          "ip next-hop", "peer-address");
 }
 
 DEFUN (set_ip_nexthop_unchanged,
@@ -3674,197 +3549,119 @@ DEFUN (set_ip_nexthop_unchanged,
        "Next hop address\n"
        "Don't modify existing Next hop address\n")
 {
-  return bgp_route_set_add (vty, vty->index, "ip next-hop", "unchanged");
-}
-
-/*
- * CHECK ME - The following ALIASes need to be implemented in this DEFUN
- * "no set ip next-hop peer-address",
- *     NO_STR
- *     SET_STR
- *     IP_STR
- *     "Next hop address\n"
- *     "Use peer address (for BGP only)\n"
- *
- * "no set ip next-hop A.B.C.D",
- *     NO_STR
- *     SET_STR
- *     IP_STR
- *     "Next hop address\n"
- *     "IP address of next hop\n"
- *
- */
-DEFUN (no_set_ip_nexthop,
-       no_set_ip_nexthop_cmd,
-       "no set ip next-hop",
-       NO_STR
-       SET_STR
-       "Next hop address\n")
-{
-  return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[4]->arg);
-}
-
-
-
-/*
- * CHECK ME - The following ALIASes need to be implemented in this DEFUN
- * "set metric (rtt|+rtt|-rtt)",
- *     SET_STR
- *     "Metric value for destination routing protocol\n"
- *     "Assign round trip time\n"
- *     "Add round trip time\n"
- *     "Subtract round trip time\n"
- *
- * "set metric <+/-metric>",
- *     SET_STR
- *     "Metric value for destination routing protocol\n"
- *     "Add or subtract metric\n"
- *
- */
-DEFUN (set_metric,
-       set_metric_cmd,
-       "set metric <0-4294967295>",
-       SET_STR
-       "Metric value for destination routing protocol\n"
-       "Metric value\n")
-{
-  return bgp_route_set_add (vty, vty->index, "metric", argv[2]->arg);
-}
-
-
-
-/*
- * CHECK ME - The following ALIASes need to be implemented in this DEFUN
- * "no set metric <0-4294967295>",
- *     NO_STR
- *     SET_STR
- *     "Metric value for destination routing protocol\n"
- *     "Metric value\n"
- *
- */
-DEFUN (no_set_metric,
-       no_set_metric_cmd,
-       "no set metric",
-       NO_STR
-       SET_STR
-       "Metric value for destination routing protocol\n")
-{
-  return bgp_route_set_delete (vty, vty->index, "metric", argv[3]->arg);
+  return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+                          "ip next-hop", "unchanged");
 }
 
 
 DEFUN (set_local_pref,
        set_local_pref_cmd,
-       "set local-preference <0-4294967295>",
+       "set local-preference (0-4294967295)",
        SET_STR
        "BGP local preference path attribute\n"
        "Preference value\n")
 {
-  return bgp_route_set_add (vty, vty->index, "local-preference", argv[2]->arg);
+  int idx_number = 2;
+  return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+                          "local-preference", argv[idx_number]->arg);
 }
 
-/*
- * CHECK ME - The following ALIASes need to be implemented in this DEFUN
- * "no set local-preference <0-4294967295>",
- *     NO_STR
- *     SET_STR
- *     "BGP local preference path attribute\n"
- *     "Preference value\n"
- *
- */
+
 DEFUN (no_set_local_pref,
        no_set_local_pref_cmd,
-       "no set local-preference",
+       "no set local-preference [(0-4294967295)]",
        NO_STR
        SET_STR
-       "BGP local preference path attribute\n")
+       "BGP local preference path attribute\n"
+       "Preference value\n")
 {
-  return bgp_route_set_delete (vty, vty->index, "local-preference", argv[3]->arg);
+  int idx_localpref = 3;
+  if (argc <= idx_localpref)
+    return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+                               "local-preference", NULL);
+  return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+                             "local-preference", argv[idx_localpref]->arg);
 }
 
 
 DEFUN (set_weight,
        set_weight_cmd,
-       "set weight <0-4294967295>",
+       "set weight (0-4294967295)",
        SET_STR
        "BGP weight for routing table\n"
        "Weight value\n")
 {
-  return bgp_route_set_add (vty, vty->index, "weight", argv[2]->arg);
+  int idx_number = 2;
+  return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index), "weight",
+                          argv[idx_number]->arg);
 }
 
-/*
- * CHECK ME - The following ALIASes need to be implemented in this DEFUN
- * "no set weight <0-4294967295>",
- *     NO_STR
- *     SET_STR
- *     "BGP weight for routing table\n"
- *     "Weight value\n"
- *
- */
+
 DEFUN (no_set_weight,
        no_set_weight_cmd,
-       "no set weight",
+       "no set weight [(0-4294967295)]",
        NO_STR
        SET_STR
-       "BGP weight for routing table\n")
+       "BGP weight for routing table\n"
+       "Weight value\n")
 {
-  return bgp_route_set_delete (vty, vty->index, "weight", argv[3]->arg);
+  int idx_weight = 3;
+  if (argc <= idx_weight)
+    return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+                               "weight", NULL);
+  return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index), "weight",
+                             argv[idx_weight]->arg);
 }
 
 
-/*
- * CHECK ME - The following ALIASes need to be implemented in this DEFUN
- * "set as-path prepend (last-as) <1-10>",
- *     SET_STR
- *     "Transform BGP AS_PATH attribute\n"
- *     "Prepend to the as-path\n"
- *     "Use the peer's AS-number\n"
- *     "Number of times to insert"
- *
- */
-DEFUN (set_aspath_prepend,
-       set_aspath_prepend_cmd,
-       "set as-path prepend ." CMD_AS_RANGE,
+DEFUN (set_aspath_prepend_asn,
+       set_aspath_prepend_asn_cmd,
+       "set as-path prepend (1-4294967295)...",
        SET_STR
        "Transform BGP AS_PATH attribute\n"
        "Prepend to the as-path\n"
        "AS number\n")
 {
+  int idx_asn = 3;
   int ret;
   char *str;
 
-  str = argv_concat (argv, argc, 0);
-  ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
+  str = argv_concat (argv, argc, idx_asn);
+  ret = generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+                         "as-path prepend", str);
   XFREE (MTYPE_TMP, str);
 
   return ret;
 }
 
+DEFUN (set_aspath_prepend_lastas,
+       set_aspath_prepend_lastas_cmd,
+       "set as-path prepend last-as (1-10)",
+       SET_STR
+       "Transform BGP AS_PATH attribute\n"
+       "Prepend to the as-path\n"
+       "Use the peer's AS-number\n"
+       "Number of times to insert")
+{
+  return set_aspath_prepend_asn (self, vty, argc, argv);
+}
 
-/*
- * CHECK ME - The following ALIASes need to be implemented in this DEFUN
- * "no set as-path prepend ." CMD_AS_RANGE,
- *     NO_STR
- *     SET_STR
- *     "Transform BGP AS_PATH attribute\n"
- *     "Prepend to the as-path\n"
- *     "AS number\n"
- *
- */
 DEFUN (no_set_aspath_prepend,
        no_set_aspath_prepend_cmd,
-       "no set as-path prepend",
+       "no set as-path prepend [(1-4294967295)]",
        NO_STR
        SET_STR
        "Transform BGP AS_PATH attribute\n"
-       "Prepend to the as-path\n")
+       "Prepend to the as-path\n"
+       "AS number\n")
 {
+  int idx_asn = 4;
   int ret;
   char *str;
 
-  str = argv_concat (argv, argc, 0);
-  ret = bgp_route_set_delete (vty, vty->index, "as-path prepend", str);
+  str = argv_concat (argv, argc, idx_asn);
+  ret = generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+                            "as-path prepend", str);
   XFREE (MTYPE_TMP, str);
   return ret;
 }
@@ -3872,44 +3669,39 @@ DEFUN (no_set_aspath_prepend,
 
 DEFUN (set_aspath_exclude,
        set_aspath_exclude_cmd,
-       "set as-path exclude ." CMD_AS_RANGE,
+       "set as-path exclude (1-4294967295)...",
        SET_STR
        "Transform BGP AS-path attribute\n"
        "Exclude from the as-path\n"
        "AS number\n")
 {
+  int idx_asn = 3;
   int ret;
   char *str;
 
-  str = argv_concat (argv, argc, 0);
-  ret = bgp_route_set_add (vty, vty->index, "as-path exclude", str);
+  str = argv_concat (argv, argc, idx_asn);
+  ret = generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+                         "as-path exclude", str);
   XFREE (MTYPE_TMP, str);
   return ret;
 }
 
-/*
- * CHECK ME - The following ALIASes need to be implemented in this DEFUN
- * "no set as-path exclude ." CMD_AS_RANGE,
- *     NO_STR
- *     SET_STR
- *     "Transform BGP AS_PATH attribute\n"
- *     "Exclude from the as-path\n"
- *     "AS number\n"
- *
- */
 DEFUN (no_set_aspath_exclude,
        no_set_aspath_exclude_cmd,
-       "no set as-path exclude",
+       "no set as-path exclude (1-4294967295)...",
        NO_STR
        SET_STR
        "Transform BGP AS_PATH attribute\n"
-       "Exclude from the as-path\n")
+       "Exclude from the as-path\n"
+       "AS number\n")
 {
+  int idx_asn = 4;
   int ret;
   char *str;
 
-  str = argv_concat (argv, argc, 0);
-  ret = bgp_route_set_delete (vty, vty->index, "as-path exclude", str);
+  str = argv_concat (argv, argc, idx_asn);
+  ret = generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+                            "as-path exclude", str);
   XFREE (MTYPE_TMP, str);
   return ret;
 }
@@ -3917,11 +3709,12 @@ DEFUN (no_set_aspath_exclude,
 
 DEFUN (set_community,
        set_community_cmd,
-       "set community .AA:NN",
+       "set community AA:NN...",
        SET_STR
        "BGP community attribute\n"
        COMMUNITY_VAL_STR)
 {
+  int idx_aa_nn = 2;
   int i;
   int first = 0;
   int additive = 0;
@@ -3933,7 +3726,7 @@ DEFUN (set_community,
 
   b = buffer_new (1024);
 
-  for (i = 0; i < argc; i++)
+  for (i = idx_aa_nn; i < argc; i++)
     {
       if (strncmp (argv[i]->arg, "additive", strlen (argv[i]->arg)) == 0)
        {
@@ -3997,11 +3790,13 @@ DEFUN (set_community,
       argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
       strcpy (argstr, str);
       strcpy (argstr + strlen (str), " additive");
-      ret =  bgp_route_set_add (vty, vty->index, "community", argstr);
+      ret =  generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+                              "community", argstr);
       XFREE (MTYPE_TMP, argstr);
     }
   else
-    ret =  bgp_route_set_add (vty, vty->index, "community", str);
+    ret =  generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+                            "community", str);
 
   community_free (com);
 
@@ -4015,39 +3810,27 @@ DEFUN (set_community_none,
        "BGP community attribute\n"
        "No community attribute\n")
 {
-  return bgp_route_set_add (vty, vty->index, "community", "none");
+  return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index), "community",
+                          "none");
 }
 
-/*
- * CHECK ME - The following ALIASes need to be implemented in this DEFUN
- * "no set community none",
- *     NO_STR
- *     SET_STR
- *     "BGP community attribute\n"
- *     "No community attribute\n"
- *
- * "no set community .AA:NN",
- *     NO_STR
- *     SET_STR
- *     "BGP community attribute\n"
- *     COMMUNITY_VAL_STR
- *
- */
 DEFUN (no_set_community,
        no_set_community_cmd,
-       "no set community",
+       "no set community AA:NN...",
        NO_STR
        SET_STR
-       "BGP community attribute\n")
+       "BGP community attribute\n"
+       COMMUNITY_VAL_STR)
 {
-  return bgp_route_set_delete (vty, vty->index, "community", NULL);
+  return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+                             "community", NULL);
 }
 
 
 
 DEFUN (set_community_delete,
        set_community_delete_cmd,
-       "set comm-list (<1-99>|<100-500>|WORD) delete",
+       "set comm-list <(1-99)|(100-500)|WORD> delete",
        SET_STR
        "set BGP community list (for deletion)\n"
        "Community-list number (standard)\n"
@@ -4055,158 +3838,228 @@ DEFUN (set_community_delete,
        "Community-list name\n"
        "Delete matching communities\n")
 {
+  int idx_comm_list = 2;
   char *str;
 
-  str = XCALLOC (MTYPE_TMP, strlen (argv[2]->arg) + strlen (" delete") + 1);
-  strcpy (str, argv[2]->arg);
-  strcpy (str + strlen (argv[2]->arg), " delete");
+  str = XCALLOC (MTYPE_TMP, strlen (argv[idx_comm_list]->arg) + strlen (" delete") + 1);
+  strcpy (str, argv[idx_comm_list]->arg);
+  strcpy (str + strlen (argv[idx_comm_list]->arg), " delete");
 
-  bgp_route_set_add (vty, vty->index, "comm-list", str);
+  generic_set_add (vty, VTY_GET_CONTEXT(route_map_index), "comm-list", str);
 
   XFREE (MTYPE_TMP, str);
   return CMD_SUCCESS;
 }
 
-/*
- * CHECK ME - The following ALIASes need to be implemented in this DEFUN
- * "no set comm-list (<1-99>|<100-500>|WORD) delete",
- *     NO_STR
- *     SET_STR
- *     "set BGP community list (for deletion)\n"
- *     "Community-list number (standard)\n"
- *     "Community-list number (expanded)\n"
- *     "Community-list name\n"
- *     "Delete matching communities\n"
- *
- */
 DEFUN (no_set_community_delete,
        no_set_community_delete_cmd,
-       "no set comm-list",
+       "no set comm-list [<(1-99)|(100-500)|WORD> delete]",
+       NO_STR
+       SET_STR
+       "set BGP community list (for deletion)\n"
+       "Community-list number (standard)\n"
+       "Community-list number (expanded)\n"
+       "Community-list name\n"
+       "Delete matching communities\n")
+{
+  return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+                             "comm-list", NULL);
+}
+
+DEFUN (set_lcommunity,
+       set_lcommunity_cmd,
+       "set large-community AA:BB:CC...",
+       SET_STR
+       "BGP large community attribute\n"
+       "Large Community number in aa:bb:cc format or additive\n")
+{
+  int ret;
+  char *str;
+
+  str = argv_concat (argv, argc, 2);
+  ret = generic_set_add (vty, VTY_GET_CONTEXT(route_map_index), "large-community", str);
+  XFREE (MTYPE_TMP, str);
+
+  return ret;
+}
+
+DEFUN (set_lcommunity_none,
+       set_lcommunity_none_cmd,
+       "set large-community none",
+       SET_STR
+       "BGP large community attribute\n"
+       "No large community attribute\n")
+{
+  return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+                          "large-community", "none");
+}
+
+DEFUN (no_set_lcommunity,
+       no_set_lcommunity_cmd,
+       "no set large-community none",
        NO_STR
        SET_STR
-       "set BGP community list (for deletion)\n")
+       "BGP large community attribute\n"
+       "No community attribute\n")
 {
-  return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
+  return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+                             "large-community", NULL);
 }
 
+DEFUN (no_set_lcommunity1,
+       no_set_lcommunity1_cmd,
+       "no set large-community AA:BB:CC...",
+       NO_STR
+       SET_STR
+       "BGP large community attribute\n"
+       "Large community in AA:BB:CC... format or additive\n")
+{
+  return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+                             "large-community", NULL);
+}
+
+DEFUN (set_lcommunity_delete,
+       set_lcommunity_delete_cmd,
+       "set large-comm-list <(1-99)|(100-500)|WORD> delete",
+       SET_STR
+       "set BGP large community list (for deletion)\n"
+       "Large Community-list number (standard)\n"
+       "Large Communitly-list number (expanded)\n"
+       "Large Community-list name\n"
+       "Delete matching large communities\n")
+{
+  char *str;
+
+  str = XCALLOC (MTYPE_TMP, strlen (argv[2]->arg) + strlen (" delete") + 1);
+  strcpy (str, argv[2]->arg);
+  strcpy (str + strlen (argv[2]->arg), " delete");
+
+  generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+                   "large-comm-list", str);
+
+  XFREE (MTYPE_TMP, str);
+  return CMD_SUCCESS;
+}
+
+DEFUN (no_set_lcommunity_delete,
+       no_set_lcommunity_delete_cmd,
+       "no set large-comm-list <(1-99|(100-500)|WORD)> [delete]",
+       NO_STR
+       SET_STR
+       "set BGP large community list (for deletion)\n"
+       "Large Community-list number (standard)\n"
+       "Large Communitly-list number (expanded)\n"
+       "Large Community-list name\n"
+       "Delete matching large communities\n")
+{
+  return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+                             "large-comm-list", NULL);
+}
 
 DEFUN (set_ecommunity_rt,
        set_ecommunity_rt_cmd,
-       "set extcommunity rt .ASN:nn_or_IP-address:nn",
+       "set extcommunity rt ASN:nn_or_IP-address:nn...",
        SET_STR
        "BGP extended community attribute\n"
        "Route Target extended community\n"
        "VPN extended community\n")
 {
+  int idx_asn_nn = 3;
   int ret;
   char *str;
 
-  str = argv_concat (argv, argc, 0);
-  ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
+  str = argv_concat (argv, argc, idx_asn_nn);
+  ret = generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+                         "extcommunity rt", str);
   XFREE (MTYPE_TMP, str);
 
   return ret;
 }
 
-/*
- * CHECK ME - The following ALIASes need to be implemented in this DEFUN
- * "no set extcommunity rt .ASN:nn_or_IP-address:nn",
- *     NO_STR
- *     SET_STR
- *     "BGP extended community attribute\n"
- *     "Route Target extended community\n"
- *     "VPN extended community\n"
- *
- */
 DEFUN (no_set_ecommunity_rt,
        no_set_ecommunity_rt_cmd,
-       "no set extcommunity rt",
+       "no set extcommunity rt ASN:nn_or_IP-address:nn...",
        NO_STR
        SET_STR
        "BGP extended community attribute\n"
-       "Route Target extended community\n")
+       "Route Target extended community\n"
+       "VPN extended community\n")
 {
-  return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
+  return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+                             "extcommunity rt", NULL);
 }
 
 
 DEFUN (set_ecommunity_soo,
        set_ecommunity_soo_cmd,
-       "set extcommunity soo .ASN:nn_or_IP-address:nn",
+       "set extcommunity soo ASN:nn_or_IP-address:nn...",
        SET_STR
        "BGP extended community attribute\n"
        "Site-of-Origin extended community\n"
        "VPN extended community\n")
 {
+  int idx_asn_nn = 3;
   int ret;
   char *str;
 
-  str = argv_concat (argv, argc, 0);
-  ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
+  str = argv_concat (argv, argc, idx_asn_nn);
+  ret = generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+                         "extcommunity soo", str);
   XFREE (MTYPE_TMP, str);
   return ret;
 }
 
-/*
- * CHECK ME - The following ALIASes need to be implemented in this DEFUN
- * "no set extcommunity soo .ASN:nn_or_IP-address:nn",
- *     NO_STR
- *     SET_STR
- *     "BGP extended community attribute\n"
- *     "Site-of-Origin extended community\n"
- *     "VPN extended community\n"
- *
- */
+
 DEFUN (no_set_ecommunity_soo,
        no_set_ecommunity_soo_cmd,
-       "no set extcommunity soo",
+       "no set extcommunity soo ASN:nn_or_IP-address:nn...",
        NO_STR
        SET_STR
        "BGP extended community attribute\n"
-       "Site-of-Origin extended community\n")
+       "Site-of-Origin extended community\n"
+       "VPN extended community\n")
 {
-  return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
+  return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+                             "extcommunity soo", NULL);
 }
 
 
 DEFUN (set_origin,
        set_origin_cmd,
-       "set origin (egp|igp|incomplete)",
+       "set origin <egp|igp|incomplete>",
        SET_STR
        "BGP origin code\n"
        "remote EGP\n"
        "local IGP\n"
        "unknown heritage\n")
 {
-  if (strncmp (argv[2]->arg, "igp", 2) == 0)
-    return bgp_route_set_add (vty, vty->index, "origin", "igp");
-  if (strncmp (argv[2]->arg, "egp", 1) == 0)
-    return bgp_route_set_add (vty, vty->index, "origin", "egp");
-  if (strncmp (argv[2]->arg, "incomplete", 2) == 0)
-    return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
+  int idx_origin = 2;
+  if (strncmp (argv[idx_origin]->arg, "igp", 2) == 0)
+    return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index), "origin",
+                            "igp");
+  if (strncmp (argv[idx_origin]->arg, "egp", 1) == 0)
+    return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index), "origin",
+                            "egp");
+  if (strncmp (argv[idx_origin]->arg, "incomplete", 2) == 0)
+    return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index), "origin",
+                            "incomplete");
 
   return CMD_WARNING;
 }
 
-/*
- * CHECK ME - The following ALIASes need to be implemented in this DEFUN
- * "no set origin (egp|igp|incomplete)",
- *     NO_STR
- *     SET_STR
- *     "BGP origin code\n"
- *     "remote EGP\n"
- *     "local IGP\n"
- *     "unknown heritage\n"
- *
- */
+
 DEFUN (no_set_origin,
        no_set_origin_cmd,
-       "no set origin",
+       "no set origin [<egp|igp|incomplete>]",
        NO_STR
        SET_STR
-       "BGP origin code\n")
+       "BGP origin code\n"
+       "remote EGP\n"
+       "local IGP\n"
+       "unknown heritage\n")
 {
-  return bgp_route_set_delete (vty, vty->index, "origin", NULL);
+  return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index), "origin",
+                             NULL);
 }
 
 
@@ -4216,7 +4069,8 @@ DEFUN (set_atomic_aggregate,
        SET_STR
        "BGP atomic aggregate attribute\n" )
 {
-  return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
+  return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+                          "atomic-aggregate", NULL);
 }
 
 DEFUN (no_set_atomic_aggregate,
@@ -4226,23 +4080,26 @@ DEFUN (no_set_atomic_aggregate,
        SET_STR
        "BGP atomic aggregate attribute\n" )
 {
-  return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
+  return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+                             "atomic-aggregate", NULL);
 }
 
 DEFUN (set_aggregator_as,
        set_aggregator_as_cmd,
-       "set aggregator as " CMD_AS_RANGE " A.B.C.D",
+       "set aggregator as (1-4294967295) A.B.C.D",
        SET_STR
        "BGP aggregator attribute\n"
        "AS number of aggregator\n"
        "AS number\n"
        "IP address of aggregator\n")
 {
+  int idx_number = 3;
+  int idx_ipv4 = 4;
   int ret;
   struct in_addr address;
   char *argstr;
-  
-  ret = inet_aton (argv[4]->arg, &address);
+
+  ret = inet_aton (argv[idx_ipv4]->arg, &address);
   if (ret == 0)
     {
       vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
@@ -4250,44 +4107,40 @@ DEFUN (set_aggregator_as,
     }
 
   argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
-                   strlen (argv[3]->arg) + strlen (argv[4]->arg) + 2);
+                   strlen (argv[idx_number]->arg) + strlen (argv[idx_ipv4]->arg) + 2);
 
-  sprintf (argstr, "%s %s", argv[3]->arg, argv[4]->arg);
+  sprintf (argstr, "%s %s", argv[idx_number]->arg, argv[idx_ipv4]->arg);
 
-  ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
+  ret = generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+                         "aggregator as", argstr);
 
   XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
 
   return ret;
 }
 
-/*
- * CHECK ME - The following ALIASes need to be implemented in this DEFUN
- * "no set aggregator as " CMD_AS_RANGE " A.B.C.D",
- *     NO_STR
- *     SET_STR
- *     "BGP aggregator attribute\n"
- *     "AS number of aggregator\n"
- *     "AS number\n"
- *     "IP address of aggregator\n"
- *
- */
+
 DEFUN (no_set_aggregator_as,
        no_set_aggregator_as_cmd,
-       "no set aggregator as",
+       "no set aggregator as [(1-4294967295) A.B.C.D]",
        NO_STR
        SET_STR
        "BGP aggregator attribute\n"
-       "AS number of aggregator\n")
+       "AS number of aggregator\n"
+       "AS number\n"
+       "IP address of aggregator\n")
 {
+  int idx_asn = 4;
+  int idx_ip = 5;
   int ret;
   struct in_addr address;
   char *argstr;
 
-  if (argv == 0)
-    return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
-  
-  ret = inet_aton (argv[5]->arg, &address);
+  if (argc <= idx_asn)
+    return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+                               "aggregator as", NULL);
+
+  ret = inet_aton (argv[idx_ip]->arg, &address);
   if (ret == 0)
     {
       vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
@@ -4295,75 +4148,18 @@ DEFUN (no_set_aggregator_as,
     }
 
   argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
-                   strlen (argv[4]->arg) + strlen (argv[5]->arg) + 2);
+                   strlen (argv[idx_asn]->arg) + strlen (argv[idx_ip]->arg) + 2);
 
-  sprintf (argstr, "%s %s", argv[4]->arg, argv[5]->arg);
+  sprintf (argstr, "%s %s", argv[idx_asn]->arg, argv[idx_ip]->arg);
 
-  ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
+  ret = generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+                            "aggregator as", argstr);
 
   XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
 
   return ret;
 }
 
-
-DEFUN (set_tag,
-       set_tag_cmd,
-       "set tag <1-65535>",
-       SET_STR
-       "Tag value for routing protocol\n"
-       "Tag value\n")
-{
-  return bgp_route_set_add (vty, vty->index, "tag", argv[2]->arg);
-}
-
-/*
- * CHECK ME - The following ALIASes need to be implemented in this DEFUN
- * "no set tag <1-65535>",
- *     NO_STR
- *     SET_STR
- *     "Tag value for routing protocol\n"
- *     "Tag value\n"
- *
- */
-DEFUN (no_set_tag,
-       no_set_tag_cmd,
-       "no set tag",
-       NO_STR
-       SET_STR
-       "Tag value for routing protocol\n")
-{
-  return bgp_route_set_delete (vty, vty->index, "tag", argv[3]->arg);
-}
-
-
-
-#ifdef HAVE_IPV6
-DEFUN (match_ipv6_address,
-       match_ipv6_address_cmd,
-       "match ipv6 address WORD",
-       MATCH_STR
-       IPV6_STR
-       "Match IPv6 address of route\n"
-       "IPv6 access-list name\n")
-{
-  return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[3]->arg,
-                             RMAP_EVENT_FILTER_ADDED);
-}
-
-DEFUN (no_match_ipv6_address,
-       no_match_ipv6_address_cmd,
-       "no match ipv6 address WORD",
-       NO_STR
-       MATCH_STR
-       IPV6_STR
-       "Match IPv6 address of route\n"
-       "IPv6 access-list name\n")
-{
-  return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[4]->arg,
-                                RMAP_EVENT_FILTER_DELETED);
-}
-
 DEFUN (match_ipv6_next_hop,
        match_ipv6_next_hop_cmd,
        "match ipv6 next-hop X:X::X:X",
@@ -4372,7 +4168,8 @@ DEFUN (match_ipv6_next_hop,
        "Match IPv6 next-hop address of route\n"
        "IPv6 address of next hop\n")
 {
-  return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[3]->arg,
+  int idx_ipv6 = 3;
+  return bgp_route_match_add (vty, "ipv6 next-hop", argv[idx_ipv6]->arg,
                              RMAP_EVENT_MATCH_ADDED);
 }
 
@@ -4385,36 +4182,11 @@ DEFUN (no_match_ipv6_next_hop,
        "Match IPv6 next-hop address of route\n"
        "IPv6 address of next hop\n")
 {
-  return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[4]->arg,
+  int idx_ipv6 = 4;
+  return bgp_route_match_delete (vty, "ipv6 next-hop", argv[idx_ipv6]->arg,
                                 RMAP_EVENT_MATCH_DELETED);
 }
 
-DEFUN (match_ipv6_address_prefix_list,
-       match_ipv6_address_prefix_list_cmd,
-       "match ipv6 address prefix-list WORD",
-       MATCH_STR
-       IPV6_STR
-       "Match address of route\n"
-       "Match entries of prefix-lists\n"
-       "IP prefix-list name\n")
-{
-  return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list",
-                             argv[4]->arg, RMAP_EVENT_PLIST_ADDED);
-}
-
-DEFUN (no_match_ipv6_address_prefix_list,
-       no_match_ipv6_address_prefix_list_cmd,
-       "no match ipv6 address prefix-list WORD",
-       NO_STR
-       MATCH_STR
-       IPV6_STR
-       "Match address of route\n"
-       "Match entries of prefix-lists\n"
-       "IP prefix-list name\n")
-{
-  return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list",
-                                argv[5]->arg, RMAP_EVENT_PLIST_DELETED);
-}
 
 DEFUN (set_ipv6_nexthop_peer,
        set_ipv6_nexthop_peer_cmd,
@@ -4424,7 +4196,8 @@ DEFUN (set_ipv6_nexthop_peer,
        "Next hop address\n"
        "Use peer address (for BGP only)\n")
 {
-  return bgp_route_set_add (vty, vty->index, "ipv6 next-hop peer-address", NULL);
+  return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+                          "ipv6 next-hop peer-address", NULL);
 }
 
 DEFUN (no_set_ipv6_nexthop_peer,
@@ -4436,7 +4209,8 @@ DEFUN (no_set_ipv6_nexthop_peer,
        "IPv6 next-hop address\n"
        "Use peer address (for BGP only)\n")
 {
-  return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop peer-address", NULL);
+  return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+                             "ipv6 next-hop peer-address", NULL);
 }
 
 DEFUN (set_ipv6_nexthop_prefer_global,
@@ -4447,7 +4221,8 @@ DEFUN (set_ipv6_nexthop_prefer_global,
        "IPv6 next-hop address\n"
        "Prefer global over link-local if both exist\n")
 {
-  return bgp_route_set_add (vty, vty->index, "ipv6 next-hop prefer-global", NULL);;
+  return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+                          "ipv6 next-hop prefer-global", NULL);;
 }
 
 DEFUN (no_set_ipv6_nexthop_prefer_global,
@@ -4459,7 +4234,8 @@ DEFUN (no_set_ipv6_nexthop_prefer_global,
        "IPv6 next-hop address\n"
        "Prefer global over link-local if both exist\n")
 {
-  return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop prefer-global", NULL);
+  return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+                             "ipv6 next-hop prefer-global", NULL);
 }
 
 DEFUN (set_ipv6_nexthop_global,
@@ -4471,10 +4247,11 @@ DEFUN (set_ipv6_nexthop_global,
        "IPv6 global address\n"
        "IPv6 address of next hop\n")
 {
+  int idx_ipv6 = 4;
   struct in6_addr addr;
   int ret;
 
-  ret = inet_pton (AF_INET6, argv[4]->arg, &addr);
+  ret = inet_pton (AF_INET6, argv[idx_ipv6]->arg, &addr);
   if (!ret)
     {
       vty_out (vty, "%% Malformed nexthop address%s", VTY_NEWLINE);
@@ -4489,85 +4266,29 @@ DEFUN (set_ipv6_nexthop_global,
       return CMD_WARNING;
     }
 
-  return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[4]->arg);
+  return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+                          "ipv6 next-hop global", argv[idx_ipv6]->arg);
 }
 
-/*
- * CHECK ME - The following ALIASes need to be implemented in this DEFUN
- * "no set ipv6 next-hop global X:X::X:X",
- *     NO_STR
- *     SET_STR
- *     IPV6_STR
- *     "IPv6 next-hop address\n"
- *     "IPv6 global address\n"
- *     "IPv6 address of next hop\n"
- *
- */
+
 DEFUN (no_set_ipv6_nexthop_global,
        no_set_ipv6_nexthop_global_cmd,
-       "no set ipv6 next-hop global",
+       "no set ipv6 next-hop global X:X::X:X",
        NO_STR
        SET_STR
        IPV6_STR
        "IPv6 next-hop address\n"
-       "IPv6 global address\n")
-{
-  return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[5]->arg);
-}
-
-
-DEFUN (set_ipv6_nexthop_local,
-       set_ipv6_nexthop_local_cmd,
-       "set ipv6 next-hop local X:X::X:X",
-       SET_STR
-       IPV6_STR
-       "IPv6 next-hop address\n"
-       "IPv6 local address\n"
+       "IPv6 global address\n"
        "IPv6 address of next hop\n")
 {
-  struct in6_addr addr;
-  int ret;
-
-  ret = inet_pton (AF_INET6, argv[4]->arg, &addr);
-  if (!ret)
-    {
-      vty_out (vty, "%% Malformed nexthop address%s", VTY_NEWLINE);
-      return CMD_WARNING;
-    }
-  if (!IN6_IS_ADDR_LINKLOCAL(&addr))
-    {
-      vty_out (vty, "%% Invalid link-local nexthop address%s", VTY_NEWLINE);
-      return CMD_WARNING;
-    }
-
-  return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[4]->arg);
+  int idx_ipv6 = 5;
+  if (argc <= idx_ipv6)
+    return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+                               "ipv6 next-hop global", NULL);
+  return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+                             "ipv6 next-hop global", argv[idx_ipv6]->arg);
 }
 
-/*
- * CHECK ME - The following ALIASes need to be implemented in this DEFUN
- * "no set ipv6 next-hop local X:X::X:X",
- *     NO_STR
- *     SET_STR
- *     IPV6_STR
- *     "IPv6 next-hop address\n"
- *     "IPv6 local address\n"
- *     "IPv6 address of next hop\n"
- *
- */
-DEFUN (no_set_ipv6_nexthop_local,
-       no_set_ipv6_nexthop_local_cmd,
-       "no set ipv6 next-hop local",
-       NO_STR
-       SET_STR
-       IPV6_STR
-       "IPv6 next-hop address\n"
-       "IPv6 local address\n")
-{
-  return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[5]->arg);
-}
-
-#endif /* HAVE_IPV6 */
-
 DEFUN (set_vpnv4_nexthop,
        set_vpnv4_nexthop_cmd,
        "set vpnv4 next-hop A.B.C.D",
@@ -4576,28 +4297,27 @@ DEFUN (set_vpnv4_nexthop,
        "VPNv4 next-hop address\n"
        "IP address of next hop\n")
 {
-  return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[3]->arg);
+  int idx_ipv4 = 3;
+  return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+                          "vpnv4 next-hop", argv[idx_ipv4]->arg);
 }
 
-/*
- * CHECK ME - The following ALIASes need to be implemented in this DEFUN
- * "no set vpnv4 next-hop A.B.C.D",
- *     NO_STR
- *     SET_STR
- *     "VPNv4 information\n"
- *     "VPNv4 next-hop address\n"
- *     "IP address of next hop\n"
- *
- */
+
 DEFUN (no_set_vpnv4_nexthop,
        no_set_vpnv4_nexthop_cmd,
-       "no set vpnv4 next-hop",
+       "no set vpnv4 next-hop [A.B.C.D]",
        NO_STR
        SET_STR
        "VPNv4 information\n"
-       "VPNv4 next-hop address\n")
+       "VPNv4 next-hop address\n"
+       "IP address of next hop\n")
 {
-  return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[4]->arg);
+  int idx_ipv4 = 4;
+  if (argc <= idx_ipv4)
+    return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+                               "vpnv4 next-hop", NULL);
+  return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+                             "vpnv4 next-hop", argv[idx_ipv4]->arg);
 }
 
 
@@ -4608,26 +4328,26 @@ DEFUN (set_originator_id,
        "BGP originator ID attribute\n"
        "IP address of originator\n")
 {
-  return bgp_route_set_add (vty, vty->index, "originator-id", argv[2]->arg);
+  int idx_ipv4 = 2;
+  return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+                          "originator-id", argv[idx_ipv4]->arg);
 }
 
-/*
- * CHECK ME - The following ALIASes need to be implemented in this DEFUN
- * "no set originator-id A.B.C.D",
- *     NO_STR
- *     SET_STR
- *     "BGP originator ID attribute\n"
- *     "IP address of originator\n"
- *
- */
+
 DEFUN (no_set_originator_id,
        no_set_originator_id_cmd,
-       "no set originator-id",
+       "no set originator-id [A.B.C.D]",
        NO_STR
        SET_STR
-       "BGP originator ID attribute\n")
+       "BGP originator ID attribute\n"
+       "IP address of originator\n")
 {
-  return bgp_route_set_delete (vty, vty->index, "originator-id", argv[3]->arg);
+  int idx_id = 3;
+  if (argc < idx_id)
+    return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+                               "originator-id", NULL);
+  return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+                             "originator-id", argv[idx_id]->arg);
 }
 
 
@@ -4636,11 +4356,50 @@ void
 bgp_route_map_init (void)
 {
   route_map_init ();
-  route_map_init_vty ();
+
   route_map_add_hook (bgp_route_map_add);
   route_map_delete_hook (bgp_route_map_delete);
   route_map_event_hook (bgp_route_map_event);
 
+  route_map_match_interface_hook (generic_match_add);
+  route_map_no_match_interface_hook (generic_match_delete);
+
+  route_map_match_ip_address_hook (generic_match_add);
+  route_map_no_match_ip_address_hook (generic_match_delete);
+
+  route_map_match_ip_address_prefix_list_hook (generic_match_add);
+  route_map_no_match_ip_address_prefix_list_hook (generic_match_delete);
+
+  route_map_match_ip_next_hop_hook (generic_match_add);
+  route_map_no_match_ip_next_hop_hook (generic_match_delete);
+
+  route_map_match_ip_next_hop_prefix_list_hook (generic_match_add);
+  route_map_no_match_ip_next_hop_prefix_list_hook (generic_match_delete);
+
+  route_map_match_ipv6_address_hook (generic_match_add);
+  route_map_no_match_ipv6_address_hook (generic_match_delete);
+
+  route_map_match_ipv6_address_prefix_list_hook (generic_match_add);
+  route_map_no_match_ipv6_address_prefix_list_hook (generic_match_delete);
+
+  route_map_match_metric_hook (generic_match_add);
+  route_map_no_match_metric_hook (generic_match_delete);
+
+  route_map_match_tag_hook (generic_match_add);
+  route_map_no_match_tag_hook (generic_match_delete);
+
+  route_map_set_ip_nexthop_hook (generic_set_add);
+  route_map_no_set_ip_nexthop_hook (generic_set_delete);
+
+  route_map_set_ipv6_nexthop_local_hook (generic_set_add);
+  route_map_no_set_ipv6_nexthop_local_hook (generic_set_delete);
+
+  route_map_set_metric_hook (generic_set_add);
+  route_map_no_set_metric_hook (generic_set_delete);
+
+  route_map_set_tag_hook (generic_set_add);
+  route_map_no_set_tag_hook (generic_set_delete);
+
   route_map_install_match (&route_match_peer_cmd);
   route_map_install_match (&route_match_local_pref_cmd);
   route_map_install_match (&route_match_ip_address_cmd);
@@ -4651,6 +4410,7 @@ bgp_route_map_init (void)
   route_map_install_match (&route_match_ip_route_source_prefix_list_cmd);
   route_map_install_match (&route_match_aspath_cmd);
   route_map_install_match (&route_match_community_cmd);
+  route_map_install_match (&route_match_lcommunity_cmd);
   route_map_install_match (&route_match_ecommunity_cmd);
   route_map_install_match (&route_match_local_pref_cmd);
   route_map_install_match (&route_match_metric_cmd);
@@ -4670,6 +4430,8 @@ bgp_route_map_init (void)
   route_map_install_set (&route_set_aggregator_as_cmd);
   route_map_install_set (&route_set_community_cmd);
   route_map_install_set (&route_set_community_delete_cmd);
+  route_map_install_set (&route_set_lcommunity_cmd);
+  route_map_install_set (&route_set_lcommunity_delete_cmd);
   route_map_install_set (&route_set_vpnv4_nexthop_cmd);
   route_map_install_set (&route_set_originator_id_cmd);
   route_map_install_set (&route_set_ecommunity_rt_cmd);
@@ -4679,50 +4441,35 @@ bgp_route_map_init (void)
   install_element (RMAP_NODE, &match_peer_cmd);
   install_element (RMAP_NODE, &match_peer_local_cmd);
   install_element (RMAP_NODE, &no_match_peer_cmd);
-  install_element (RMAP_NODE, &match_ip_address_cmd);
-  install_element (RMAP_NODE, &no_match_ip_address_cmd);
-  install_element (RMAP_NODE, &match_ip_next_hop_cmd);
-  install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
   install_element (RMAP_NODE, &match_ip_route_source_cmd);
   install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
-  install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
-  install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
-  install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
-  install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
   install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
   install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
 
   install_element (RMAP_NODE, &match_aspath_cmd);
   install_element (RMAP_NODE, &no_match_aspath_cmd);
-  install_element (RMAP_NODE, &match_metric_cmd);
-  install_element (RMAP_NODE, &no_match_metric_cmd);
   install_element (RMAP_NODE, &match_local_pref_cmd);
   install_element (RMAP_NODE, &no_match_local_pref_cmd);
   install_element (RMAP_NODE, &match_community_cmd);
   install_element (RMAP_NODE, &match_community_exact_cmd);
   install_element (RMAP_NODE, &no_match_community_cmd);
+  install_element (RMAP_NODE, &match_lcommunity_cmd);
+  install_element (RMAP_NODE, &no_match_lcommunity_cmd);
   install_element (RMAP_NODE, &match_ecommunity_cmd);
   install_element (RMAP_NODE, &no_match_ecommunity_cmd);
   install_element (RMAP_NODE, &match_origin_cmd);
   install_element (RMAP_NODE, &no_match_origin_cmd);
   install_element (RMAP_NODE, &match_probability_cmd);
   install_element (RMAP_NODE, &no_match_probability_cmd);
-  install_element (RMAP_NODE, &match_interface_cmd);
-  install_element (RMAP_NODE, &no_match_interface_cmd);
-  install_element (RMAP_NODE, &match_tag_cmd);
-  install_element (RMAP_NODE, &no_match_tag_cmd);
 
-  install_element (RMAP_NODE, &set_ip_nexthop_cmd);
   install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
   install_element (RMAP_NODE, &set_ip_nexthop_unchanged_cmd);
-  install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
   install_element (RMAP_NODE, &set_local_pref_cmd);
   install_element (RMAP_NODE, &no_set_local_pref_cmd);
   install_element (RMAP_NODE, &set_weight_cmd);
   install_element (RMAP_NODE, &no_set_weight_cmd);
-  install_element (RMAP_NODE, &set_metric_cmd);
-  install_element (RMAP_NODE, &no_set_metric_cmd);
-  install_element (RMAP_NODE, &set_aspath_prepend_cmd);
+  install_element (RMAP_NODE, &set_aspath_prepend_asn_cmd);
+  install_element (RMAP_NODE, &set_aspath_prepend_lastas_cmd);
   install_element (RMAP_NODE, &set_aspath_exclude_cmd);
   install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
   install_element (RMAP_NODE, &no_set_aspath_exclude_cmd);
@@ -4737,6 +4484,12 @@ bgp_route_map_init (void)
   install_element (RMAP_NODE, &no_set_community_cmd);
   install_element (RMAP_NODE, &set_community_delete_cmd);
   install_element (RMAP_NODE, &no_set_community_delete_cmd);
+  install_element (RMAP_NODE, &set_lcommunity_cmd);
+  install_element (RMAP_NODE, &set_lcommunity_none_cmd);
+  install_element (RMAP_NODE, &no_set_lcommunity_cmd);
+  install_element (RMAP_NODE, &no_set_lcommunity1_cmd);
+  install_element (RMAP_NODE, &set_lcommunity_delete_cmd);
+  install_element (RMAP_NODE, &no_set_lcommunity_delete_cmd);
   install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
   install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
   install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
@@ -4745,10 +4498,7 @@ bgp_route_map_init (void)
   install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
   install_element (RMAP_NODE, &set_originator_id_cmd);
   install_element (RMAP_NODE, &no_set_originator_id_cmd);
-  install_element (RMAP_NODE, &set_tag_cmd);
-  install_element (RMAP_NODE, &no_set_tag_cmd);
 
-#ifdef HAVE_IPV6
   route_map_install_match (&route_match_ipv6_address_cmd);
   route_map_install_match (&route_match_ipv6_next_hop_cmd);
   route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
@@ -4757,21 +4507,14 @@ bgp_route_map_init (void)
   route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
   route_map_install_set (&route_set_ipv6_nexthop_peer_cmd);
 
-  install_element (RMAP_NODE, &match_ipv6_address_cmd);
-  install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
   install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
   install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
-  install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
-  install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
   install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
   install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
   install_element (RMAP_NODE, &set_ipv6_nexthop_prefer_global_cmd);
   install_element (RMAP_NODE, &no_set_ipv6_nexthop_prefer_global_cmd);
-  install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
-  install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
   install_element (RMAP_NODE, &set_ipv6_nexthop_peer_cmd);
   install_element (RMAP_NODE, &no_set_ipv6_nexthop_peer_cmd);
-#endif /* HAVE_IPV6 */
 }
 
 void