]> git.puffer.fish Git - mirror/frr.git/commitdiff
Add replace-as option to remove-private-as
authorDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 20 May 2015 00:57:34 +0000 (17:57 -0700)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 20 May 2015 00:57:34 +0000 (17:57 -0700)
bgpd/bgp_aspath.c
bgpd/bgp_aspath.h
bgpd/bgp_route.c
bgpd/bgp_vty.c
bgpd/bgpd.c
bgpd/bgpd.h

index 8fe5280286406408867babe4ce5c2a895ee944f7..b8bd71b993b907be053654ab4ae6046689f3d83a 100644 (file)
@@ -463,13 +463,11 @@ aspath_highest (struct aspath *aspath)
   struct assegment *seg = aspath->segments;
   as_t highest = 0;
   unsigned int i;
-  
+
   while (seg)
     {
       for (i = 0; i < seg->length; i++)
-        if (seg->as[i] > highest
-            && (seg->as[i] < BGP_PRIVATE_AS_MIN
-                || seg->as[i] > BGP_PRIVATE_AS_MAX))
+        if (seg->as[i] > highest && !BGP_AS_IS_PRIVATE(seg->as[i]))
          highest = seg->as[i];
       seg = seg->next;
     }
@@ -1128,22 +1126,19 @@ int
 aspath_private_as_check (struct aspath *aspath)
 {
   struct assegment *seg;
-  
+
   if ( !(aspath && aspath->segments) )
     return 0;
-    
+
   seg = aspath->segments;
 
   while (seg)
     {
       int i;
-      
+
       for (i = 0; i < seg->length; i++)
        {
-         if ( (seg->as[i] < BGP_PRIVATE_AS_MIN)
-             || (seg->as[i] > BGP_PRIVATE_AS_MAX &&
-                  seg->as[i] < BGP_PRIVATE_AS4_MIN)
-               || (seg->as[i] > BGP_PRIVATE_AS4_MAX))
+         if (!BGP_AS_IS_PRIVATE(seg->as[i]))
            return 0;
        }
       seg = seg->next;
@@ -1151,6 +1146,105 @@ aspath_private_as_check (struct aspath *aspath)
   return 1;
 }
 
+/* Replace all private ASNs with our own ASN */
+struct aspath *
+aspath_replace_private_asns (struct aspath *aspath, as_t asn)
+{
+  struct aspath *new;
+  struct assegment *seg;
+
+  new = aspath_dup(aspath);
+  seg = new->segments;
+
+  while (seg)
+    {
+      int i;
+
+      for (i = 0; i < seg->length; i++)
+       {
+         if (BGP_AS_IS_PRIVATE(seg->as[i]))
+            seg->as[i] = asn;
+       }
+      seg = seg->next;
+    }
+
+  aspath_str_update(new);
+  return new;
+}
+
+/* Remove all private ASNs */
+struct aspath *
+aspath_remove_private_asns (struct aspath *aspath)
+{
+  struct aspath *new;
+  struct assegment *seg;
+  struct assegment *new_seg;
+  struct assegment *last_new_seg;
+  int i;
+  int j;
+  int public = 0;
+
+  new = XCALLOC (MTYPE_AS_PATH, sizeof (struct aspath));
+
+  new_seg = NULL;
+  last_new_seg = NULL;
+  seg = aspath->segments;
+  while (seg)
+    {
+      public = 0;
+      for (i = 0; i < seg->length; i++)
+       {
+          // ASN is public
+         if (!BGP_AS_IS_PRIVATE(seg->as[i]))
+            {
+                public++;
+            }
+        }
+
+      // The entire segment is private so skip it
+      if (!public)
+        {
+          seg = seg->next;
+          continue;
+        }
+
+      // The entire segment is public so copy it
+      else if (public == seg->length)
+        {
+          new_seg = assegment_dup (seg);
+        }
+
+      // The segment is a mix of public and private ASNs. Copy as many spots as
+      // there are public ASNs then come back and fill in only the public ASNs.
+      else
+        {
+          new_seg = assegment_new (seg->type, public);
+          j = 0;
+          for (i = 0; i < seg->length; i++)
+            {
+              // ASN is public
+              if (!BGP_AS_IS_PRIVATE(seg->as[i]))
+                {
+                  new_seg->as[j] = seg->as[i];
+                  j++;
+                }
+            }
+        }
+
+      // This is the first segment so set the aspath segments pointer to this one
+      if (!last_new_seg)
+        new->segments = new_seg;
+      else
+        last_new_seg->next = new_seg;
+
+      last_new_seg = new_seg;
+      seg = seg->next;
+    }
+
+  aspath_str_update(new);
+  return new;
+}
+
 /* AS path confed check.  If aspath contains confed set or sequence then return 1. */
 int
 aspath_confed_check (struct aspath *aspath)
index e455ad217fc113b96634cbfc471cf0f1efef2bd6..23b5da5ab24d3f97708bb86e8f160b181e28b2d5 100644 (file)
@@ -41,6 +41,10 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 /* Transition 16Bit AS as defined by IANA */
 #define BGP_AS_TRANS            23456U
 
+#define BGP_AS_IS_PRIVATE(ASN) \
+    (((ASN) >= BGP_PRIVATE_AS_MIN && (ASN) <= BGP_PRIVATE_AS_MAX) || \
+     ((ASN) >= BGP_PRIVATE_AS4_MIN && (ASN) <= BGP_PRIVATE_AS4_MAX))
+
 /* AS_PATH segment data in abstracted form, no limit is placed on length */
 struct assegment
 {
@@ -93,6 +97,8 @@ extern void aspath_print_all_vty (struct vty *);
 extern unsigned int aspath_key_make (void *);
 extern int aspath_loop_check (struct aspath *, as_t);
 extern int aspath_private_as_check (struct aspath *);
+extern struct aspath *aspath_replace_private_asns(struct aspath *aspath, as_t asn);
+extern struct aspath *aspath_remove_private_asns (struct aspath *aspath);
 extern int aspath_firstas_check (struct aspath *, as_t);
 extern int aspath_confed_check (struct aspath *);
 extern int aspath_left_confed_check (struct aspath *);
index b1c792e4f4060cd8432fb7cae820eee8118335f0..d3f05e8498997fba1fcf6cf31ba5d4d526c3dd90 100644 (file)
@@ -863,6 +863,42 @@ bgp_import_modifier (struct peer *rsclient, struct peer *peer,
   return RMAP_PERMIT;
 }
 
+
+/* If this is an EBGP peer with remove-private-AS */
+void
+bgp_peer_remove_private_as(struct bgp *bgp, afi_t afi, safi_t safi,
+                           struct peer *peer, struct attr *attr)
+{
+  if (peer->sort == BGP_PEER_EBGP &&
+      peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS))
+    {
+      // Take action on the entire aspath
+      if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_ALL))
+        {
+          if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
+            attr->aspath = aspath_replace_private_asns (attr->aspath, bgp->as);
+
+          // The entire aspath consists of private ASNs so create an empty aspath
+          else if (aspath_private_as_check (attr->aspath))
+            attr->aspath = aspath_empty_get ();
+
+          // There are some public and some private ASNs, remove the private ASNs
+          else
+            attr->aspath = aspath_remove_private_asns (attr->aspath);
+        }
+
+      // 'all' was not specified so the entire aspath must be private ASNs
+      // for us to do anything
+      else if (aspath_private_as_check (attr->aspath))
+        {
+          if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
+            attr->aspath = aspath_replace_private_asns (attr->aspath, bgp->as);
+          else
+            attr->aspath = aspath_empty_get ();
+        }
+    }
+}
+
 static int
 bgp_announce_check (struct bgp_info *ri, struct peer *peer, struct prefix *p,
                    struct attr *attr, afi_t afi, safi_t safi)
@@ -1128,11 +1164,7 @@ bgp_announce_check (struct bgp_info *ri, struct peer *peer, struct prefix *p,
     }
 #endif /* HAVE_IPV6 */
 
-  /* If this is EBGP peer and remove-private-AS is set.  */
-  if (peer->sort == BGP_PEER_EBGP
-      && peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS)
-      && aspath_private_as_check (attr->aspath))
-    attr->aspath = aspath_empty_get ();
+  bgp_peer_remove_private_as(bgp, afi, safi, peer, attr);
 
   /* Route map & unsuppress-map apply. */
   if (ROUTE_MAP_OUT_NAME (filter)
@@ -1184,9 +1216,11 @@ bgp_announce_check_rsclient (struct bgp_info *ri, struct peer *rsclient,
   struct bgp_info info;
   struct peer *from;
   struct attr *riattr;
+  struct bgp *bgp;
 
   from = ri->peer;
   filter = &rsclient->filter[afi][safi];
+  bgp = rsclient->bgp;
   riattr = bgp_info_mpath_count (ri) ? bgp_info_mpath_attr (ri) : ri->attr;
 
   if (DISABLE_BGP_ANNOUNCE)
@@ -1340,12 +1374,7 @@ bgp_announce_check_rsclient (struct bgp_info *ri, struct peer *rsclient,
     }
 #endif /* HAVE_IPV6 */
 
-
-  /* If this is EBGP peer and remove-private-AS is set.  */
-  if (rsclient->sort == BGP_PEER_EBGP
-      && peer_af_flag_check (rsclient, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS)
-      && aspath_private_as_check (attr->aspath))
-    attr->aspath = aspath_empty_get ();
+  bgp_peer_remove_private_as(bgp, afi, safi, rsclient, attr);
 
   /* Route map & unsuppress-map apply. */
   if (ROUTE_MAP_OUT_NAME (filter) || (ri->extra && ri->extra->suppress) )
index ecb638f6a31a3f16bb97ad6349f78525b95dfc75..e045c3a9c073bacb985be01a16ec2668f79b22d9 100644 (file)
@@ -215,7 +215,7 @@ bgp_vty_return (struct vty *vty, int ret)
       str = "Invalid command. Not an internal neighbor";
       break;
     case BGP_ERR_REMOVE_PRIVATE_AS:
-      str = "Private AS cannot be removed for IBGP peers";
+      str = "remove-private-AS cannot be configured for IBGP peers";
       break;
     case BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP:
       str = "Local-AS allowed only for EBGP peers";
@@ -2663,26 +2663,111 @@ DEFUN (neighbor_remove_private_as,
        NEIGHBOR_CMD2 "remove-private-AS",
        NEIGHBOR_STR
        NEIGHBOR_ADDR_STR2
-       "Remove private AS number from outbound updates\n")
+       "Remove private ASNs in outbound updates\n")
 {
+  peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
+                         bgp_node_safi (vty),
+                          PEER_FLAG_REMOVE_PRIVATE_AS_ALL|
+                          PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE);
   return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
                               bgp_node_safi (vty),
                               PEER_FLAG_REMOVE_PRIVATE_AS);
 }
 
+DEFUN (neighbor_remove_private_as_all,
+       neighbor_remove_private_as_all_cmd,
+       NEIGHBOR_CMD2 "remove-private-AS all",
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       "Remove private ASNs in outbound updates\n"
+       "Apply to all AS numbers")
+{
+  peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
+                         bgp_node_safi (vty),
+                          PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE);
+  return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
+                              bgp_node_safi (vty),
+                              PEER_FLAG_REMOVE_PRIVATE_AS|
+                               PEER_FLAG_REMOVE_PRIVATE_AS_ALL);
+}
+
+DEFUN (neighbor_remove_private_as_replace_as,
+       neighbor_remove_private_as_replace_as_cmd,
+       NEIGHBOR_CMD2 "remove-private-AS replace-AS",
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       "Remove private ASNs in outbound updates\n"
+       "Replace private ASNs with our ASN in outbound updates\n")
+{
+  peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
+                         bgp_node_safi (vty),
+                          PEER_FLAG_REMOVE_PRIVATE_AS_ALL);
+  return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
+                              bgp_node_safi (vty),
+                              PEER_FLAG_REMOVE_PRIVATE_AS|
+                               PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE);
+}
+
+DEFUN (neighbor_remove_private_as_all_replace_as,
+       neighbor_remove_private_as_all_replace_as_cmd,
+       NEIGHBOR_CMD2 "remove-private-AS all replace-AS",
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       "Remove private ASNs in outbound updates\n"
+       "Apply to all AS numbers"
+       "Replace private ASNs with our ASN in outbound updates\n")
+{
+  return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
+                              bgp_node_safi (vty),
+                              PEER_FLAG_REMOVE_PRIVATE_AS|
+                               PEER_FLAG_REMOVE_PRIVATE_AS_ALL|
+                               PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE);
+}
+
 DEFUN (no_neighbor_remove_private_as,
        no_neighbor_remove_private_as_cmd,
        NO_NEIGHBOR_CMD2 "remove-private-AS",
        NO_STR
        NEIGHBOR_STR
        NEIGHBOR_ADDR_STR2
-       "Remove private AS number from outbound updates\n")
+       "Remove private ASNs in outbound updates\n")
 {
   return peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
                                 bgp_node_safi (vty),
-                                PEER_FLAG_REMOVE_PRIVATE_AS);
+                                PEER_FLAG_REMOVE_PRIVATE_AS|
+                                 PEER_FLAG_REMOVE_PRIVATE_AS_ALL|
+                                 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE);
 }
 
+ALIAS (no_neighbor_remove_private_as,
+       no_neighbor_remove_private_as_all_cmd,
+       NO_NEIGHBOR_CMD2 "remove-private-AS all",
+       NO_STR
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       "Remove private ASNs in outbound updates\n"
+       "Apply to all AS numbers")
+
+ALIAS (no_neighbor_remove_private_as,
+       no_neighbor_remove_private_as_replace_as_cmd,
+       NO_NEIGHBOR_CMD2 "remove-private-AS replace-AS",
+       NO_STR
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       "Remove private ASNs in outbound updates\n"
+       "Replace private ASNs with our ASN in outbound updates\n")
+
+ALIAS (no_neighbor_remove_private_as,
+       no_neighbor_remove_private_as_all_replace_as_cmd,
+       NO_NEIGHBOR_CMD2 "remove-private-AS all replace-AS",
+       NO_STR
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       "Remove private ASNs in outbound updates\n"
+       "Apply to all AS numbers"
+       "Replace private ASNs with our ASN in outbound updates\n")
+
+
 /* neighbor send-community. */
 DEFUN (neighbor_send_community,
        neighbor_send_community_cmd,
@@ -8154,9 +8239,13 @@ bgp_show_peer_afi (struct vty *vty, struct peer *p, afi_t afi, safi_t safi)
     vty_out (vty, "  Route-Server Client%s", VTY_NEWLINE);
   if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
     vty_out (vty, "  Inbound soft reconfiguration allowed%s", VTY_NEWLINE);
-  if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_REMOVE_PRIVATE_AS))
-    vty_out (vty, "  Private AS number removed from updates to this neighbor%s", VTY_NEWLINE);
-  if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_NEXTHOP_SELF))
+  if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
+    vty_out (vty, "  Private AS numbers replaced in updates to this neighbor%s", VTY_NEWLINE);
+  else if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_REMOVE_PRIVATE_AS))
+    vty_out (vty, "  Private AS numbers removed in updates to this neighbor%s", VTY_NEWLINE);
+
+  if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_NEXTHOP_SELF) ||
+      CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_NEXTHOP_SELF_ALL))
     vty_out (vty, "  NEXT_HOP is always this router%s", VTY_NEWLINE);
   if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_AS_PATH_UNCHANGED))
     vty_out (vty, "  AS_PATH is propagated unchanged to this neighbor%s", VTY_NEWLINE);
@@ -10226,16 +10315,52 @@ bgp_vty_init (void)
   /* "neighbor remove-private-AS" commands. */
   install_element (BGP_NODE, &neighbor_remove_private_as_cmd);
   install_element (BGP_NODE, &no_neighbor_remove_private_as_cmd);
+  install_element (BGP_NODE, &neighbor_remove_private_as_all_cmd);
+  install_element (BGP_NODE, &no_neighbor_remove_private_as_all_cmd);
+  install_element (BGP_NODE, &neighbor_remove_private_as_replace_as_cmd);
+  install_element (BGP_NODE, &no_neighbor_remove_private_as_replace_as_cmd);
+  install_element (BGP_NODE, &neighbor_remove_private_as_all_replace_as_cmd);
+  install_element (BGP_NODE, &no_neighbor_remove_private_as_all_replace_as_cmd);
   install_element (BGP_IPV4_NODE, &neighbor_remove_private_as_cmd);
   install_element (BGP_IPV4_NODE, &no_neighbor_remove_private_as_cmd);
+  install_element (BGP_IPV4_NODE, &neighbor_remove_private_as_all_cmd);
+  install_element (BGP_IPV4_NODE, &no_neighbor_remove_private_as_all_cmd);
+  install_element (BGP_IPV4_NODE, &neighbor_remove_private_as_replace_as_cmd);
+  install_element (BGP_IPV4_NODE, &no_neighbor_remove_private_as_replace_as_cmd);
+  install_element (BGP_IPV4_NODE, &neighbor_remove_private_as_all_replace_as_cmd);
+  install_element (BGP_IPV4_NODE, &no_neighbor_remove_private_as_all_replace_as_cmd);
   install_element (BGP_IPV4M_NODE, &neighbor_remove_private_as_cmd);
   install_element (BGP_IPV4M_NODE, &no_neighbor_remove_private_as_cmd);
+  install_element (BGP_IPV4M_NODE, &neighbor_remove_private_as_all_cmd);
+  install_element (BGP_IPV4M_NODE, &no_neighbor_remove_private_as_all_cmd);
+  install_element (BGP_IPV4M_NODE, &neighbor_remove_private_as_replace_as_cmd);
+  install_element (BGP_IPV4M_NODE, &no_neighbor_remove_private_as_replace_as_cmd);
+  install_element (BGP_IPV4M_NODE, &neighbor_remove_private_as_all_replace_as_cmd);
+  install_element (BGP_IPV4M_NODE, &no_neighbor_remove_private_as_all_replace_as_cmd);
   install_element (BGP_IPV6_NODE, &neighbor_remove_private_as_cmd);
   install_element (BGP_IPV6_NODE, &no_neighbor_remove_private_as_cmd);
+  install_element (BGP_IPV6_NODE, &neighbor_remove_private_as_all_cmd);
+  install_element (BGP_IPV6_NODE, &no_neighbor_remove_private_as_all_cmd);
+  install_element (BGP_IPV6_NODE, &neighbor_remove_private_as_replace_as_cmd);
+  install_element (BGP_IPV6_NODE, &no_neighbor_remove_private_as_replace_as_cmd);
+  install_element (BGP_IPV6_NODE, &neighbor_remove_private_as_all_replace_as_cmd);
+  install_element (BGP_IPV6_NODE, &no_neighbor_remove_private_as_all_replace_as_cmd);
   install_element (BGP_IPV6M_NODE, &neighbor_remove_private_as_cmd);
   install_element (BGP_IPV6M_NODE, &no_neighbor_remove_private_as_cmd);
+  install_element (BGP_IPV6M_NODE, &neighbor_remove_private_as_all_cmd);
+  install_element (BGP_IPV6M_NODE, &no_neighbor_remove_private_as_all_cmd);
+  install_element (BGP_IPV6M_NODE, &neighbor_remove_private_as_replace_as_cmd);
+  install_element (BGP_IPV6M_NODE, &no_neighbor_remove_private_as_replace_as_cmd);
+  install_element (BGP_IPV6M_NODE, &neighbor_remove_private_as_all_replace_as_cmd);
+  install_element (BGP_IPV6M_NODE, &no_neighbor_remove_private_as_all_replace_as_cmd);
   install_element (BGP_VPNV4_NODE, &neighbor_remove_private_as_cmd);
   install_element (BGP_VPNV4_NODE, &no_neighbor_remove_private_as_cmd);
+  install_element (BGP_VPNV4_NODE, &neighbor_remove_private_as_all_cmd);
+  install_element (BGP_VPNV4_NODE, &no_neighbor_remove_private_as_all_cmd);
+  install_element (BGP_VPNV4_NODE, &neighbor_remove_private_as_replace_as_cmd);
+  install_element (BGP_VPNV4_NODE, &no_neighbor_remove_private_as_replace_as_cmd);
+  install_element (BGP_VPNV4_NODE, &neighbor_remove_private_as_all_replace_as_cmd);
+  install_element (BGP_VPNV4_NODE, &no_neighbor_remove_private_as_all_replace_as_cmd);
 
   /* "neighbor send-community" commands.*/
   install_element (BGP_NODE, &neighbor_send_community_cmd);
index 77cb5d1fe63008482b35303a5272f5dec4b96408..653630e29aab620e07e5cf6f39475e85eb7b4b52 100644 (file)
@@ -2643,6 +2643,8 @@ static const struct peer_flag_action peer_af_flag_action_list[] =
     { PEER_FLAG_NEXTHOP_UNCHANGED,        1, peer_change_reset_out },
     { PEER_FLAG_MED_UNCHANGED,            1, peer_change_reset_out },
     { PEER_FLAG_REMOVE_PRIVATE_AS,        1, peer_change_reset_out },
+    { PEER_FLAG_REMOVE_PRIVATE_AS_ALL,    1, peer_change_reset_out },
+    { PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE,1, peer_change_reset_out },
     { PEER_FLAG_ALLOWAS_IN,               0, peer_change_reset_in },
     { PEER_FLAG_ORF_PREFIX_SM,            1, peer_change_reset },
     { PEER_FLAG_ORF_PREFIX_RM,            1, peer_change_reset },
@@ -5440,11 +5442,22 @@ bgp_config_write_peer (struct vty *vty, struct bgp *bgp,
             peer_af_flag_check (peer, afi, safi, PEER_FLAG_NEXTHOP_SELF_ALL) ?
             " all" : "", VTY_NEWLINE);
 
-  /* Remove private AS. */
-  if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS)
-      && ! peer->af_group[afi][safi])
-    vty_out (vty, " neighbor %s remove-private-AS%s",
-            addr, VTY_NEWLINE);
+  /* remove-private-AS */
+  if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS) && !peer->af_group[afi][safi])
+    {
+      if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_ALL) &&
+          peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
+        vty_out (vty, " neighbor %s remove-private-AS all replace-AS%s", addr, VTY_NEWLINE);
+
+      else if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
+        vty_out (vty, " neighbor %s remove-private-AS replace-AS%s", addr, VTY_NEWLINE);
+
+      else if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_ALL))
+        vty_out (vty, " neighbor %s remove-private-AS all%s", addr, VTY_NEWLINE);
+
+      else
+        vty_out (vty, " neighbor %s remove-private-AS%s", addr, VTY_NEWLINE);
+    }
 
   /* send-community print. */
   if (! peer->af_group[afi][safi])
index beecef5256e52df1c23f10e71c3b5ea5142f6b44..3d4e03e5f1453c28e3815d42aaa0f431b0f906c8 100644 (file)
@@ -482,6 +482,8 @@ struct peer
 #define PEER_FLAG_MAX_PREFIX_WARNING        (1 << 15) /* maximum prefix warning-only */
 #define PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED   (1 << 16) /* leave link-local nexthop unchanged */
 #define PEER_FLAG_NEXTHOP_SELF_ALL          (1 << 17) /* next-hop-self all */
+#define PEER_FLAG_REMOVE_PRIVATE_AS_ALL     (1 << 18) /* remove-private-as all */
+#define PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE (1 << 19) /* remove-private-as replace-as */
 
   /* MD5 password */
   char *password;