Initial revision
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
new file mode 100644
index 0000000..87d305c
--- /dev/null
+++ b/bgpd/bgp_route.c
@@ -0,0 +1,9053 @@
+/* BGP routing information
+ Copyright (C) 1996, 97, 98, 99 Kunihiro Ishiguro
+
+This file is part of GNU Zebra.
+
+GNU Zebra is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+GNU Zebra is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Zebra; see the file COPYING. If not, write to the Free
+Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include <zebra.h>
+
+#include "prefix.h"
+#include "linklist.h"
+#include "memory.h"
+#include "command.h"
+#include "stream.h"
+#include "filter.h"
+#include "str.h"
+#include "log.h"
+#include "routemap.h"
+#include "buffer.h"
+#include "sockunion.h"
+#include "plist.h"
+#include "thread.h"
+
+#include "bgpd/bgpd.h"
+#include "bgpd/bgp_table.h"
+#include "bgpd/bgp_route.h"
+#include "bgpd/bgp_attr.h"
+#include "bgpd/bgp_debug.h"
+#include "bgpd/bgp_aspath.h"
+#include "bgpd/bgp_regex.h"
+#include "bgpd/bgp_community.h"
+#include "bgpd/bgp_ecommunity.h"
+#include "bgpd/bgp_clist.h"
+#include "bgpd/bgp_packet.h"
+#include "bgpd/bgp_filter.h"
+#include "bgpd/bgp_fsm.h"
+#include "bgpd/bgp_mplsvpn.h"
+#include "bgpd/bgp_nexthop.h"
+#include "bgpd/bgp_damp.h"
+#include "bgpd/bgp_advertise.h"
+#include "bgpd/bgp_zebra.h"
+
+/* Extern from bgp_dump.c */
+extern char *bgp_origin_str[];
+extern char *bgp_origin_long_str[];
+
+struct bgp_node *
+bgp_afi_node_get (struct bgp *bgp, afi_t afi, safi_t safi, struct prefix *p,
+ struct prefix_rd *prd)
+{
+ struct bgp_node *rn;
+ struct bgp_node *prn = NULL;
+ struct bgp_table *table;
+
+ if (safi == SAFI_MPLS_VPN)
+ {
+ prn = bgp_node_get (bgp->rib[afi][safi], (struct prefix *) prd);
+
+ if (prn->info == NULL)
+ prn->info = bgp_table_init ();
+ else
+ bgp_unlock_node (prn);
+ table = prn->info;
+ }
+ else
+ table = bgp->rib[afi][safi];
+
+ rn = bgp_node_get (table, p);
+
+ if (safi == SAFI_MPLS_VPN)
+ rn->prn = prn;
+
+ return rn;
+}
+
+/* Allocate new bgp info structure. */
+struct bgp_info *
+bgp_info_new ()
+{
+ struct bgp_info *new;
+
+ new = XMALLOC (MTYPE_BGP_ROUTE, sizeof (struct bgp_info));
+ memset (new, 0, sizeof (struct bgp_info));
+
+ return new;
+}
+
+/* Free bgp route information. */
+void
+bgp_info_free (struct bgp_info *binfo)
+{
+ if (binfo->attr)
+ bgp_attr_unintern (binfo->attr);
+
+ if (binfo->damp_info)
+ bgp_damp_info_free (binfo->damp_info, 0);
+
+ XFREE (MTYPE_BGP_ROUTE, binfo);
+}
+
+void
+bgp_info_add (struct bgp_node *rn, struct bgp_info *ri)
+{
+ struct bgp_info *top;
+
+ top = rn->info;
+
+ ri->next = rn->info;
+ ri->prev = NULL;
+ if (top)
+ top->prev = ri;
+ rn->info = ri;
+}
+
+void
+bgp_info_delete (struct bgp_node *rn, struct bgp_info *ri)
+{
+ if (ri->next)
+ ri->next->prev = ri->prev;
+ if (ri->prev)
+ ri->prev->next = ri->next;
+ else
+ rn->info = ri->next;
+}
+
+/* Get MED value. If MED value is missing and "bgp bestpath
+ missing-as-worst" is specified, treat it as the worst value. */
+u_int32_t
+bgp_med_value (struct attr *attr, struct bgp *bgp)
+{
+ if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
+ return attr->med;
+ else
+ {
+ if (bgp_flag_check (bgp, BGP_FLAG_MED_MISSING_AS_WORST))
+ return 4294967295ul;
+ else
+ return 0;
+ }
+}
+
+/* Compare two bgp route entity. br is preferable then return 1. */
+int
+bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist)
+{
+ u_int32_t new_pref;
+ u_int32_t exist_pref;
+ u_int32_t new_med;
+ u_int32_t exist_med;
+ struct in_addr new_id;
+ struct in_addr exist_id;
+ int new_cluster;
+ int exist_cluster;
+ int internal_as_route = 0;
+ int confed_as_route = 0;
+ int ret;
+
+ /* 0. Null check. */
+ if (new == NULL)
+ return 0;
+ if (exist == NULL)
+ return 1;
+
+ /* 1. Weight check. */
+ if (new->attr->weight > exist->attr->weight)
+ return 1;
+ if (new->attr->weight < exist->attr->weight)
+ return 0;
+
+ /* 2. Local preference check. */
+ if (new->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
+ new_pref = new->attr->local_pref;
+ else
+ new_pref = bgp->default_local_pref;
+
+ if (exist->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
+ exist_pref = exist->attr->local_pref;
+ else
+ exist_pref = bgp->default_local_pref;
+
+ if (new_pref > exist_pref)
+ return 1;
+ if (new_pref < exist_pref)
+ return 0;
+
+ /* 3. Local route check. */
+ if (new->sub_type == BGP_ROUTE_STATIC)
+ return 1;
+ if (exist->sub_type == BGP_ROUTE_STATIC)
+ return 0;
+
+ if (new->sub_type == BGP_ROUTE_REDISTRIBUTE)
+ return 1;
+ if (exist->sub_type == BGP_ROUTE_REDISTRIBUTE)
+ return 0;
+
+ if (new->sub_type == BGP_ROUTE_AGGREGATE)
+ return 1;
+ if (exist->sub_type == BGP_ROUTE_AGGREGATE)
+ return 0;
+
+ /* 4. AS path length check. */
+ if (! bgp_flag_check (bgp, BGP_FLAG_ASPATH_IGNORE))
+ {
+ if (new->attr->aspath->count < exist->attr->aspath->count)
+ return 1;
+ if (new->attr->aspath->count > exist->attr->aspath->count)
+ return 0;
+ }
+
+ /* 5. Origin check. */
+ if (new->attr->origin < exist->attr->origin)
+ return 1;
+ if (new->attr->origin > exist->attr->origin)
+ return 0;
+
+ /* 6. MED check. */
+ internal_as_route = (new->attr->aspath->length == 0
+ && exist->attr->aspath->length == 0);
+ confed_as_route = (new->attr->aspath->length > 0
+ && exist->attr->aspath->length > 0
+ && new->attr->aspath->count == 0
+ && exist->attr->aspath->count == 0);
+
+ if (bgp_flag_check (bgp, BGP_FLAG_ALWAYS_COMPARE_MED)
+ || (bgp_flag_check (bgp, BGP_FLAG_MED_CONFED)
+ && confed_as_route)
+ || aspath_cmp_left (new->attr->aspath, exist->attr->aspath)
+ || aspath_cmp_left_confed (new->attr->aspath, exist->attr->aspath)
+ || internal_as_route)
+ {
+ new_med = bgp_med_value (new->attr, bgp);
+ exist_med = bgp_med_value (exist->attr, bgp);
+
+ if (new_med < exist_med)
+ return 1;
+ if (new_med > exist_med)
+ return 0;
+ }
+
+ /* 7. Peer type check. */
+ if (peer_sort (new->peer) == BGP_PEER_EBGP
+ && peer_sort (exist->peer) == BGP_PEER_IBGP)
+ return 1;
+ if (peer_sort (new->peer) == BGP_PEER_EBGP
+ && peer_sort (exist->peer) == BGP_PEER_CONFED)
+ return 1;
+ if (peer_sort (new->peer) == BGP_PEER_IBGP
+ && peer_sort (exist->peer) == BGP_PEER_EBGP)
+ return 0;
+ if (peer_sort (new->peer) == BGP_PEER_CONFED
+ && peer_sort (exist->peer) == BGP_PEER_EBGP)
+ return 0;
+
+ /* 8. IGP metric check. */
+ if (new->igpmetric < exist->igpmetric)
+ return 1;
+ if (new->igpmetric > exist->igpmetric)
+ return 0;
+
+ /* 9. Maximum path check. */
+
+ /* 10. If both paths are external, prefer the path that was received
+ first (the oldest one). This step minimizes route-flap, since a
+ newer path won't displace an older one, even if it was the
+ preferred route based on the additional decision criteria below. */
+ if (! bgp_flag_check (bgp, BGP_FLAG_COMPARE_ROUTER_ID)
+ && peer_sort (new->peer) == BGP_PEER_EBGP
+ && peer_sort (exist->peer) == BGP_PEER_EBGP)
+ {
+ if (CHECK_FLAG (new->flags, BGP_INFO_SELECTED))
+ return 1;
+ if (CHECK_FLAG (exist->flags, BGP_INFO_SELECTED))
+ return 0;
+ }
+
+ /* 11. Rourter-ID comparision. */
+ if (new->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
+ new_id.s_addr = new->attr->originator_id.s_addr;
+ else
+ new_id.s_addr = new->peer->remote_id.s_addr;
+ if (exist->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
+ exist_id.s_addr = exist->attr->originator_id.s_addr;
+ else
+ exist_id.s_addr = exist->peer->remote_id.s_addr;
+
+ if (ntohl (new_id.s_addr) < ntohl (exist_id.s_addr))
+ return 1;
+ if (ntohl (new_id.s_addr) > ntohl (exist_id.s_addr))
+ return 0;
+
+ /* 12. Cluster length comparision. */
+ if (new->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))
+ new_cluster = new->attr->cluster->length;
+ else
+ new_cluster = 0;
+ if (exist->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))
+ exist_cluster = exist->attr->cluster->length;
+ else
+ exist_cluster = 0;
+
+ if (new_cluster < exist_cluster)
+ return 1;
+ if (new_cluster > exist_cluster)
+ return 0;
+
+ /* 13. Neighbor address comparision. */
+ ret = sockunion_cmp (new->peer->su_remote, exist->peer->su_remote);
+
+ if (ret == 1)
+ return 0;
+ if (ret == -1)
+ return 1;
+
+ return 1;
+}
+
+enum filter_type
+bgp_input_filter (struct peer *peer, struct prefix *p, struct attr *attr,
+ afi_t afi, safi_t safi)
+{
+ struct bgp_filter *filter;
+
+ filter = &peer->filter[afi][safi];
+
+ if (DISTRIBUTE_IN_NAME (filter))
+ if (access_list_apply (DISTRIBUTE_IN (filter), p) == FILTER_DENY)
+ return FILTER_DENY;
+
+ if (PREFIX_LIST_IN_NAME (filter))
+ if (prefix_list_apply (PREFIX_LIST_IN (filter), p) == PREFIX_DENY)
+ return FILTER_DENY;
+
+ if (FILTER_LIST_IN_NAME (filter))
+ if (as_list_apply (FILTER_LIST_IN (filter), attr->aspath)== AS_FILTER_DENY)
+ return FILTER_DENY;
+
+ return FILTER_PERMIT;
+}
+
+enum filter_type
+bgp_output_filter (struct peer *peer, struct prefix *p, struct attr *attr,
+ afi_t afi, safi_t safi)
+{
+ struct bgp_filter *filter;
+
+ filter = &peer->filter[afi][safi];
+
+ if (DISTRIBUTE_OUT_NAME (filter))
+ if (access_list_apply (DISTRIBUTE_OUT (filter), p) == FILTER_DENY)
+ return FILTER_DENY;
+
+ if (PREFIX_LIST_OUT_NAME (filter))
+ if (prefix_list_apply (PREFIX_LIST_OUT (filter), p) == PREFIX_DENY)
+ return FILTER_DENY;
+
+ if (FILTER_LIST_OUT_NAME (filter))
+ if (as_list_apply (FILTER_LIST_OUT (filter), attr->aspath) == AS_FILTER_DENY)
+ return FILTER_DENY;
+
+ return FILTER_PERMIT;
+}
+
+/* If community attribute includes no_export then return 1. */
+int
+bgp_community_filter (struct peer *peer, struct attr *attr)
+{
+ if (attr->community)
+ {
+ /* NO_ADVERTISE check. */
+ if (community_include (attr->community, COMMUNITY_NO_ADVERTISE))
+ return 1;
+
+ /* NO_EXPORT check. */
+ if (peer_sort (peer) == BGP_PEER_EBGP &&
+ community_include (attr->community, COMMUNITY_NO_EXPORT))
+ return 1;
+
+ /* NO_EXPORT_SUBCONFED check. */
+ if (peer_sort (peer) == BGP_PEER_EBGP
+ || peer_sort (peer) == BGP_PEER_CONFED)
+ if (community_include (attr->community, COMMUNITY_NO_EXPORT_SUBCONFED))
+ return 1;
+ }
+ return 0;
+}
+
+/* Route reflection loop check. */
+static int
+bgp_cluster_filter (struct peer *peer, struct attr *attr)
+{
+ struct in_addr cluster_id;
+
+ if (attr->cluster)
+ {
+ if (peer->bgp->config & BGP_CONFIG_CLUSTER_ID)
+ cluster_id = peer->bgp->cluster_id;
+ else
+ cluster_id = peer->bgp->router_id;
+
+ if (cluster_loop_check (attr->cluster, cluster_id))
+ return 1;
+ }
+ return 0;
+}
+
+int
+bgp_input_modifier (struct peer *peer, struct prefix *p, struct attr *attr,
+ afi_t afi, safi_t safi)
+{
+ struct bgp_filter *filter;
+ struct bgp_info info;
+ route_map_result_t ret;
+
+ filter = &peer->filter[afi][safi];
+
+ /* Apply default weight value. */
+ attr->weight = peer->weight;
+
+ /* Route map apply. */
+ if (ROUTE_MAP_IN_NAME (filter))
+ {
+ /* Duplicate current value to new strucutre for modification. */
+ info.peer = peer;
+ info.attr = attr;
+
+ /* Apply BGP route map to the attribute. */
+ ret = route_map_apply (ROUTE_MAP_IN (filter), p, RMAP_BGP, &info);
+ if (ret == RMAP_DENYMATCH)
+ {
+ /* Free newly generated AS path and community by route-map. */
+ bgp_attr_flush (attr);
+ return RMAP_DENY;
+ }
+ }
+ return RMAP_PERMIT;
+}
+
+int
+bgp_announce_check (struct bgp_info *ri, struct peer *peer, struct prefix *p,
+ struct attr *attr, afi_t afi, safi_t safi)
+{
+ int ret;
+ char buf[SU_ADDRSTRLEN];
+ struct bgp_filter *filter;
+ struct bgp_info info;
+ struct peer *from;
+ struct bgp *bgp;
+ struct attr dummy_attr;
+ int transparent;
+ int reflect;
+
+ from = ri->peer;
+ filter = &peer->filter[afi][safi];
+ bgp = peer->bgp;
+
+#ifdef DISABLE_BGP_ANNOUNCE
+ return 0;
+#endif
+
+ /* Do not send back route to sender. */
+ if (from == peer)
+ return 0;
+
+ /* Aggregate-address suppress check. */
+ if (ri->suppress)
+ if (! UNSUPPRESS_MAP_NAME (filter))
+ return 0;
+
+ /* Default route check. */
+ if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_DEFAULT_ORIGINATE))
+ {
+ if (p->family == AF_INET && p->u.prefix4.s_addr == INADDR_ANY)
+ return 0;
+#ifdef HAVE_IPV6
+ else if (p->family == AF_INET6 && p->prefixlen == 0)
+ return 0;
+#endif /* HAVE_IPV6 */
+ }
+
+ /* If community is not disabled check the no-export and local. */
+ if (bgp_community_filter (peer, ri->attr))
+ return 0;
+
+ /* If the attribute has originator-id and it is same as remote
+ peer's id. */
+ if (ri->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID))
+ {
+ if (IPV4_ADDR_SAME (&peer->remote_id, &ri->attr->originator_id))
+ {
+ if (BGP_DEBUG (filter, FILTER))
+ zlog (peer->log, LOG_INFO,
+ "%s [Update:SEND] %s/%d originator-id is same as remote router-id",
+ peer->host,
+ inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
+ p->prefixlen);
+ return 0;
+ }
+ }
+
+ /* ORF prefix-list filter check */
+ if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV)
+ && (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
+ || CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_OLD_RCV)))
+ if (peer->orf_plist[afi][safi])
+ {
+ if (prefix_list_apply (peer->orf_plist[afi][safi], p) == PREFIX_DENY)
+ return 0;
+ }
+
+ /* Output filter check. */
+ if (bgp_output_filter (peer, p, ri->attr, afi, safi) == FILTER_DENY)
+ {
+ if (BGP_DEBUG (filter, FILTER))
+ zlog (peer->log, LOG_INFO,
+ "%s [Update:SEND] %s/%d is filtered",
+ peer->host,
+ inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
+ p->prefixlen);
+ return 0;
+ }
+
+#ifdef BGP_SEND_ASPATH_CHECK
+ /* AS path loop check. */
+ if (aspath_loop_check (ri->attr->aspath, peer->as))
+ {
+ if (BGP_DEBUG (filter, FILTER))
+ zlog (peer->log, LOG_INFO,
+ "%s [Update:SEND] suppress announcement to peer AS %d is AS path.",
+ peer->host, peer->as);
+ return 0;
+ }
+#endif /* BGP_SEND_ASPATH_CHECK */
+
+ /* If we're a CONFED we need to loop check the CONFED ID too */
+ if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION))
+ {
+ if (aspath_loop_check(ri->attr->aspath, bgp->confed_id))
+ {
+ if (BGP_DEBUG (filter, FILTER))
+ zlog (peer->log, LOG_INFO,
+ "%s [Update:SEND] suppress announcement to peer AS %d is AS path.",
+ peer->host,
+ bgp->confed_id);
+ return 0;
+ }
+ }
+
+ /* Route-Reflect check. */
+ if (peer_sort (from) == BGP_PEER_IBGP && peer_sort (peer) == BGP_PEER_IBGP)
+ reflect = 1;
+ else
+ reflect = 0;
+
+ /* IBGP reflection check. */
+ if (reflect)
+ {
+ /* A route from a Client peer. */
+ if (CHECK_FLAG (from->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT))
+ {
+ /* Reflect to all the Non-Client peers and also to the
+ Client peers other than the originator. Originator check
+ is already done. So there is noting to do. */
+ /* no bgp client-to-client reflection check. */
+ if (bgp_flag_check (bgp, BGP_FLAG_NO_CLIENT_TO_CLIENT))
+ if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT))
+ return 0;
+ }
+ else
+ {
+ /* A route from a Non-client peer. Reflect to all other
+ clients. */
+ if (! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT))
+ return 0;
+ }
+ }
+
+ /* For modify attribute, copy it to temporary structure. */
+ *attr = *ri->attr;
+
+ /* If local-preference is not set. */
+ if ((peer_sort (peer) == BGP_PEER_IBGP
+ || peer_sort (peer) == BGP_PEER_CONFED)
+ && (! (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))))
+ {
+ attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
+ attr->local_pref = bgp->default_local_pref;
+ }
+
+ /* Transparency check. */
+ if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
+ && CHECK_FLAG (from->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
+ transparent = 1;
+ else
+ transparent = 0;
+
+ /* Remove MED if its an EBGP peer - will get overwritten by route-maps */
+ if (peer_sort (peer) == BGP_PEER_EBGP
+ && attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
+ {
+ if (ri->peer != bgp->peer_self && ! transparent
+ && ! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MED_UNCHANGED))
+ attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC));
+ }
+
+ /* next-hop-set */
+ if (transparent || reflect
+ || (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED)
+ && ((p->family == AF_INET && attr->nexthop.s_addr)
+ || (p->family == AF_INET6 && ri->peer != bgp->peer_self))))
+ {
+ /* NEXT-HOP Unchanged. */
+ }
+ else if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_SELF)
+ || (p->family == AF_INET && attr->nexthop.s_addr == 0)
+#ifdef HAVE_IPV6
+ || (p->family == AF_INET6 && ri->peer == bgp->peer_self)
+#endif /* HAVE_IPV6 */
+ || (peer_sort (peer) == BGP_PEER_EBGP
+ && bgp_multiaccess_check_v4 (attr->nexthop, peer->host) == 0))
+ {
+ /* Set IPv4 nexthop. */
+ if (p->family == AF_INET)
+ {
+ if (safi == SAFI_MPLS_VPN)
+ memcpy (&attr->mp_nexthop_global_in, &peer->nexthop.v4, IPV4_MAX_BYTELEN);
+ else
+ memcpy (&attr->nexthop, &peer->nexthop.v4, IPV4_MAX_BYTELEN);
+ }
+#ifdef HAVE_IPV6
+ /* Set IPv6 nexthop. */
+ if (p->family == AF_INET6)
+ {
+ /* IPv6 global nexthop must be included. */
+ memcpy (&attr->mp_nexthop_global, &peer->nexthop.v6_global,
+ IPV6_MAX_BYTELEN);
+ attr->mp_nexthop_len = 16;
+ }
+#endif /* HAVE_IPV6 */
+ }
+
+#ifdef HAVE_IPV6
+ if (p->family == AF_INET6)
+ {
+ /* Link-local address should not be transit to different peer. */
+ attr->mp_nexthop_len = 16;
+
+ /* Set link-local address for shared network peer. */
+ if (peer->shared_network
+ && ! IN6_IS_ADDR_UNSPECIFIED (&peer->nexthop.v6_local))
+ {
+ memcpy (&attr->mp_nexthop_local, &peer->nexthop.v6_local,
+ IPV6_MAX_BYTELEN);
+ attr->mp_nexthop_len = 32;
+ }
+
+ /* If bgpd act as BGP-4+ route-reflector, do not send link-local
+ address.*/
+ if (reflect)
+ attr->mp_nexthop_len = 16;
+
+ /* If BGP-4+ link-local nexthop is not link-local nexthop. */
+ if (! IN6_IS_ADDR_LINKLOCAL (&peer->nexthop.v6_local))
+ attr->mp_nexthop_len = 16;
+ }
+#endif /* HAVE_IPV6 */
+
+ /* If this is EBGP peer and remove-private-AS is set. */
+ if (peer_sort (peer) == 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 ();
+
+ /* Route map & unsuppress-map apply. */
+ if (ROUTE_MAP_OUT_NAME (filter)
+ || ri->suppress)
+ {
+ info.peer = peer;
+ info.attr = attr;
+
+ /* The route reflector is not allowed to modify the attributes
+ of the reflected IBGP routes. */
+ if (peer_sort (from) == BGP_PEER_IBGP
+ && peer_sort (peer) == BGP_PEER_IBGP)
+ {
+ dummy_attr = *attr;
+ info.attr = &dummy_attr;
+ }
+
+ if (ri->suppress)
+ ret = route_map_apply (UNSUPPRESS_MAP (filter), p, RMAP_BGP, &info);
+ else
+ ret = route_map_apply (ROUTE_MAP_OUT (filter), p, RMAP_BGP, &info);
+
+ if (ret == RMAP_DENYMATCH)
+ {
+ bgp_attr_flush (attr);
+ return 0;
+ }
+ }
+ return 1;
+}
+
+int
+bgp_process (struct bgp *bgp, struct bgp_node *rn, afi_t afi, safi_t safi)
+{
+ struct prefix *p;
+ struct bgp_info *ri;
+ struct bgp_info *new_select;
+ struct bgp_info *old_select;
+ struct listnode *nn;
+ struct peer *peer;
+ struct attr attr;
+ struct bgp_info *ri1;
+ struct bgp_info *ri2;
+
+ p = &rn->p;
+
+ /* bgp deterministic-med */
+ new_select = NULL;
+ if (bgp_flag_check (bgp, BGP_FLAG_DETERMINISTIC_MED))
+ for (ri1 = rn->info; ri1; ri1 = ri1->next)
+ {
+ if (CHECK_FLAG (ri1->flags, BGP_INFO_DMED_CHECK))
+ continue;
+ if (BGP_INFO_HOLDDOWN (ri1))
+ continue;
+
+ new_select = ri1;
+ if (ri1->next)
+ for (ri2 = ri1->next; ri2; ri2 = ri2->next)
+ {
+ if (CHECK_FLAG (ri2->flags, BGP_INFO_DMED_CHECK))
+ continue;
+ if (BGP_INFO_HOLDDOWN (ri2))
+ continue;
+
+ if (aspath_cmp_left (ri1->attr->aspath, ri2->attr->aspath)
+ || aspath_cmp_left_confed (ri1->attr->aspath,
+ ri2->attr->aspath))
+ {
+ if (bgp_info_cmp (bgp, ri2, new_select))
+ {
+ UNSET_FLAG (new_select->flags, BGP_INFO_DMED_SELECTED);
+ new_select = ri2;
+ }
+
+ SET_FLAG (ri2->flags, BGP_INFO_DMED_CHECK);
+ }
+ }
+ SET_FLAG (new_select->flags, BGP_INFO_DMED_CHECK);
+ SET_FLAG (new_select->flags, BGP_INFO_DMED_SELECTED);
+ }
+
+ /* Check old selected route and new selected route. */
+ old_select = NULL;
+ new_select = NULL;
+ for (ri = rn->info; ri; ri = ri->next)
+ {
+ if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED))
+ old_select = ri;
+
+ if (BGP_INFO_HOLDDOWN (ri))
+ continue;
+
+ if (bgp_flag_check (bgp, BGP_FLAG_DETERMINISTIC_MED)
+ && (! CHECK_FLAG (ri->flags, BGP_INFO_DMED_SELECTED)))
+ {
+ UNSET_FLAG (ri->flags, BGP_INFO_DMED_CHECK);
+ continue;
+ }
+ UNSET_FLAG (ri->flags, BGP_INFO_DMED_CHECK);
+ UNSET_FLAG (ri->flags, BGP_INFO_DMED_SELECTED);
+
+ if (bgp_info_cmp (bgp, ri, new_select))
+ new_select = ri;
+ }
+
+ /* Nothing to do. */
+ if (old_select && old_select == new_select)
+ {
+ if (! CHECK_FLAG (old_select->flags, BGP_INFO_ATTR_CHANGED))
+ {
+ if (CHECK_FLAG (old_select->flags, BGP_INFO_IGP_CHANGED))
+ bgp_zebra_announce (p, old_select, bgp);
+ return 0;
+ }
+ }
+
+ if (old_select)
+ UNSET_FLAG (old_select->flags, BGP_INFO_SELECTED);
+ if (new_select)
+ {
+ SET_FLAG (new_select->flags, BGP_INFO_SELECTED);
+ UNSET_FLAG (new_select->flags, BGP_INFO_ATTR_CHANGED);
+ }
+
+ /* Check each BGP peer. */
+ LIST_LOOP (bgp->peer, peer, nn)
+ {
+ /* Announce route to Established peer. */
+ if (peer->status != Established)
+ continue;
+
+ /* Address family configuration check. */
+ if (! peer->afc_nego[afi][safi])
+ continue;
+
+ /* First update is deferred until ORF or ROUTE-REFRESH is received */
+ if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH))
+ continue;
+
+ /* Announcement to peer->conf. If the route is filtered,
+ withdraw it. */
+ if (new_select
+ && bgp_announce_check (new_select, peer, p, &attr, afi, safi))
+ bgp_adj_out_set (rn, peer, p, &attr, afi, safi, new_select);
+ else
+ bgp_adj_out_unset (rn, peer, p, afi, safi);
+ }
+
+ /* FIB update. */
+ if (safi == SAFI_UNICAST && ! bgp->name &&
+ ! bgp_option_check (BGP_OPT_NO_FIB))
+ {
+ if (new_select
+ && new_select->type == ZEBRA_ROUTE_BGP
+ && new_select->sub_type == BGP_ROUTE_NORMAL)
+ bgp_zebra_announce (p, new_select, bgp);
+ else
+ {
+ /* Withdraw the route from the kernel. */
+ if (old_select
+ && old_select->type == ZEBRA_ROUTE_BGP
+ && old_select->sub_type == BGP_ROUTE_NORMAL)
+ bgp_zebra_withdraw (p, old_select);
+ }
+ }
+ return 0;
+}
+
+int
+bgp_maximum_prefix_overflow (struct peer *peer, afi_t afi, safi_t safi)
+{
+ if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX)
+ && peer->pcount[afi][safi] >= peer->pmax[afi][safi])
+ {
+ zlog (peer->log, LOG_INFO,
+ "MAXPFXEXCEED: No. of prefix received from %s (afi %d): %ld exceed limit %ld",
+ peer->host, afi, peer->pcount[afi][safi], peer->pmax[afi][safi]);
+ if (! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING))
+ {
+ char ndata[7];
+
+ ndata[0] = (u_char)(afi >> 8);
+ ndata[1] = (u_char) afi;
+ ndata[3] = (u_char)(peer->pmax[afi][safi] >> 24);
+ ndata[4] = (u_char)(peer->pmax[afi][safi] >> 16);
+ ndata[5] = (u_char)(peer->pmax[afi][safi] >> 8);
+ ndata[6] = (u_char)(peer->pmax[afi][safi]);
+
+ if (safi == SAFI_MPLS_VPN)
+ safi = BGP_SAFI_VPNV4;
+ ndata[2] = (u_char) safi;
+
+ bgp_notify_send_with_data (peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_MAX_PREFIX,
+ ndata, 7);
+ SET_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+void
+bgp_rib_remove (struct bgp_node *rn, struct bgp_info *ri, struct peer *peer,
+ afi_t afi, safi_t safi)
+{
+ if (! CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
+ {
+ peer->pcount[afi][safi]--;
+ bgp_aggregate_decrement (peer->bgp, &rn->p, ri, afi, safi);
+ UNSET_FLAG (ri->flags, BGP_INFO_VALID);
+ bgp_process (peer->bgp, rn, afi, safi);
+ }
+ bgp_info_delete (rn, ri);
+ bgp_info_free (ri);
+ bgp_unlock_node (rn);
+}
+
+void
+bgp_rib_withdraw (struct bgp_node *rn, struct bgp_info *ri, struct peer *peer,
+ afi_t afi, safi_t safi, int force)
+{
+ int valid;
+ int status = BGP_DAMP_NONE;
+
+ if (! CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
+ {
+ peer->pcount[afi][safi]--;
+ bgp_aggregate_decrement (peer->bgp, &rn->p, ri, afi, safi);
+ }
+
+ if (! force)
+ {
+ if (CHECK_FLAG (peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
+ && peer_sort (peer) == BGP_PEER_EBGP)
+ status = bgp_damp_withdraw (ri, rn, afi, safi, 0);
+
+ if (status == BGP_DAMP_SUPPRESSED)
+ return;
+ }
+
+ valid = CHECK_FLAG (ri->flags, BGP_INFO_VALID);
+ UNSET_FLAG (ri->flags, BGP_INFO_VALID);
+ bgp_process (peer->bgp, rn, afi, safi);
+
+ if (valid)
+ SET_FLAG (ri->flags, BGP_INFO_VALID);
+
+ if (status != BGP_DAMP_USED)
+ {
+ bgp_info_delete (rn, ri);
+ bgp_info_free (ri);
+ bgp_unlock_node (rn);
+ }
+}
+
+int
+bgp_update (struct peer *peer, struct prefix *p, struct attr *attr,
+ afi_t afi, safi_t safi, int type, int sub_type,
+ struct prefix_rd *prd, u_char *tag, int soft_reconfig)
+{
+ int ret;
+ int aspath_loop_count = 0;
+ struct bgp_node *rn;
+ struct bgp *bgp;
+ struct attr new_attr;
+ struct attr *attr_new;
+ struct bgp_info *ri;
+ struct bgp_info *new;
+ char *reason;
+ char buf[SU_ADDRSTRLEN];
+
+ bgp = peer->bgp;
+ rn = bgp_afi_node_get (bgp, afi, safi, p, prd);
+
+ /* When peer's soft reconfiguration enabled. Record input packet in
+ Adj-RIBs-In. */
+ if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
+ && peer != bgp->peer_self && ! soft_reconfig)
+ bgp_adj_in_set (rn, peer, attr);
+
+ /* Check previously received route. */
+ for (ri = rn->info; ri; ri = ri->next)
+ if (ri->peer == peer && ri->type == type && ri->sub_type == sub_type)
+ break;
+
+ /* AS path local-as loop check. */
+ if (peer->change_local_as)
+ {
+ if (! CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND))
+ aspath_loop_count = 1;
+
+ if (aspath_loop_check (attr->aspath, peer->change_local_as) > aspath_loop_count)
+ {
+ reason = "as-path contains our own AS;";
+ goto filtered;
+ }
+ }
+
+ /* AS path loop check. */
+ if (aspath_loop_check (attr->aspath, bgp->as) > peer->allowas_in[afi][safi]
+ || (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)
+ && aspath_loop_check(attr->aspath, bgp->confed_id)
+ > peer->allowas_in[afi][safi]))
+ {
+ reason = "as-path contains our own AS;";
+ goto filtered;
+ }
+
+ /* Route reflector originator ID check. */
+ if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID)
+ && IPV4_ADDR_SAME (&bgp->router_id, &attr->originator_id))
+ {
+ reason = "originator is us;";
+ goto filtered;
+ }
+
+ /* Route reflector cluster ID check. */
+ if (bgp_cluster_filter (peer, attr))
+ {
+ reason = "reflected from the same cluster;";
+ goto filtered;
+ }
+
+ /* Apply incoming filter. */
+ if (bgp_input_filter (peer, p, attr, afi, safi) == FILTER_DENY)
+ {
+ reason = "filter;";
+ goto filtered;
+ }
+
+ /* Apply incoming route-map. */
+ new_attr = *attr;
+
+ if (bgp_input_modifier (peer, p, &new_attr, afi, safi) == RMAP_DENY)
+ {
+ reason = "route-map;";
+ goto filtered;
+ }
+
+ /* IPv4 unicast next hop check. */
+ if (afi == AFI_IP && safi == SAFI_UNICAST)
+ {
+ /* If the peer is EBGP and nexthop is not on connected route,
+ discard it. */
+ if (peer_sort (peer) == BGP_PEER_EBGP && peer->ttl == 1
+ && ! bgp_nexthop_check_ebgp (afi, &new_attr)
+ && ! CHECK_FLAG (peer->flags, PEER_FLAG_ENFORCE_MULTIHOP))
+ {
+ reason = "non-connected next-hop;";
+ goto filtered;
+ }
+
+ /* Next hop must not be 0.0.0.0 nor Class E address. Next hop
+ must not be my own address. */
+ if (bgp_nexthop_self (afi, &new_attr)
+ || new_attr.nexthop.s_addr == 0
+ || ntohl (new_attr.nexthop.s_addr) >= 0xe0000000)
+ {
+ reason = "martian next-hop;";
+ goto filtered;
+ }
+ }
+
+ attr_new = bgp_attr_intern (&new_attr);
+
+ /* If the update is implicit withdraw. */
+ if (ri)
+ {
+ ri->uptime = time (NULL);
+
+ /* Same attribute comes in. */
+ if (attrhash_cmp (ri->attr, attr_new))
+ {
+ UNSET_FLAG (ri->flags, BGP_INFO_ATTR_CHANGED);
+
+ if (CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
+ && peer_sort (peer) == BGP_PEER_EBGP
+ && CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
+ {
+ if (BGP_DEBUG (update, UPDATE_IN))
+ zlog (peer->log, LOG_INFO, "%s rcvd %s/%d",
+ peer->host,
+ inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
+ p->prefixlen);
+
+ peer->pcount[afi][safi]++;
+ ret = bgp_damp_update (ri, rn, afi, safi);
+ if (ret != BGP_DAMP_SUPPRESSED)
+ {
+ bgp_aggregate_increment (bgp, p, ri, afi, safi);
+ bgp_process (bgp, rn, afi, safi);
+ }
+ }
+ else
+ {
+ if (BGP_DEBUG (update, UPDATE_IN))
+ zlog (peer->log, LOG_INFO,
+ "%s rcvd %s/%d...duplicate ignored",
+ peer->host,
+ inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
+ p->prefixlen);
+ }
+
+ bgp_unlock_node (rn);
+ bgp_attr_unintern (attr_new);
+ return 0;
+ }
+
+ /* Received Logging. */
+ if (BGP_DEBUG (update, UPDATE_IN))
+ zlog (peer->log, LOG_INFO, "%s rcvd %s/%d",
+ peer->host,
+ inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
+ p->prefixlen);
+
+ /* The attribute is changed. */
+ SET_FLAG (ri->flags, BGP_INFO_ATTR_CHANGED);
+
+ /* Update bgp route dampening information. */
+ if (CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
+ && peer_sort (peer) == BGP_PEER_EBGP)
+ {
+ /* This is implicit withdraw so we should update dampening
+ information. */
+ if (! CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
+ bgp_damp_withdraw (ri, rn, afi, safi, 1);
+ else
+ peer->pcount[afi][safi]++;
+ }
+
+ bgp_aggregate_decrement (bgp, p, ri, afi, safi);
+
+ /* Update to new attribute. */
+ bgp_attr_unintern (ri->attr);
+ ri->attr = attr_new;
+
+ /* Update MPLS tag. */
+ if (safi == SAFI_MPLS_VPN)
+ memcpy (ri->tag, tag, 3);
+
+ /* Update bgp route dampening information. */
+ if (CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
+ && peer_sort (peer) == BGP_PEER_EBGP)
+ {
+ /* Now we do normal update dampening. */
+ ret = bgp_damp_update (ri, rn, afi, safi);
+ if (ret == BGP_DAMP_SUPPRESSED)
+ {
+ bgp_unlock_node (rn);
+ return 0;
+ }
+ }
+
+ /* Nexthop reachability check. */
+ if ((afi == AFI_IP || afi == AFI_IP6)
+ && safi == SAFI_UNICAST
+ && (peer_sort (peer) == BGP_PEER_IBGP
+ || (peer_sort (peer) == BGP_PEER_EBGP && peer->ttl != 1)
+ || CHECK_FLAG (peer->flags, PEER_FLAG_ENFORCE_MULTIHOP)))
+ {
+ if (bgp_nexthop_lookup (afi, peer, ri, NULL, NULL))
+ SET_FLAG (ri->flags, BGP_INFO_VALID);
+ else
+ UNSET_FLAG (ri->flags, BGP_INFO_VALID);
+ }
+ else
+ SET_FLAG (ri->flags, BGP_INFO_VALID);
+
+ /* Process change. */
+ bgp_aggregate_increment (bgp, p, ri, afi, safi);
+
+ bgp_process (bgp, rn, afi, safi);
+ bgp_unlock_node (rn);
+ return 0;
+ }
+
+ /* Received Logging. */
+ if (BGP_DEBUG (update, UPDATE_IN))
+ {
+ zlog (peer->log, LOG_INFO, "%s rcvd %s/%d",
+ peer->host,
+ inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
+ p->prefixlen);
+ }
+
+ /* Increment prefix counter */
+ peer->pcount[afi][safi]++;
+
+ /* Make new BGP info. */
+ new = bgp_info_new ();
+ new->type = type;
+ new->sub_type = sub_type;
+ new->peer = peer;
+ new->attr = attr_new;
+ new->uptime = time (NULL);
+
+ /* Update MPLS tag. */
+ if (safi == SAFI_MPLS_VPN)
+ memcpy (new->tag, tag, 3);
+
+ /* Nexthop reachability check. */
+ if ((afi == AFI_IP || afi == AFI_IP6)
+ && safi == SAFI_UNICAST
+ && (peer_sort (peer) == BGP_PEER_IBGP
+ || (peer_sort (peer) == BGP_PEER_EBGP && peer->ttl != 1)
+ || CHECK_FLAG (peer->flags, PEER_FLAG_ENFORCE_MULTIHOP)))
+ {
+ if (bgp_nexthop_lookup (afi, peer, new, NULL, NULL))
+ SET_FLAG (new->flags, BGP_INFO_VALID);
+ else
+ UNSET_FLAG (new->flags, BGP_INFO_VALID);
+ }
+ else
+ SET_FLAG (new->flags, BGP_INFO_VALID);
+
+ /* Aggregate address increment. */
+ bgp_aggregate_increment (bgp, p, new, afi, safi);
+
+ /* Register new BGP information. */
+ bgp_info_add (rn, new);
+
+ /* If maximum prefix count is configured and current prefix
+ count exeed it. */
+ if (! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING))
+ if (bgp_maximum_prefix_overflow (peer, afi, safi))
+ return -1;
+
+ /* Process change. */
+ bgp_process (bgp, rn, afi, safi);
+
+ return 0;
+
+ /* This BGP update is filtered. Log the reason then update BGP
+ entry. */
+ filtered:
+ if (BGP_DEBUG (update, UPDATE_IN))
+ zlog (peer->log, LOG_INFO,
+ "%s rcvd UPDATE about %s/%d -- DENIED due to: %s",
+ peer->host,
+ inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
+ p->prefixlen, reason);
+
+ if (ri)
+ bgp_rib_withdraw (rn, ri, peer, afi, safi, 1);
+
+ bgp_unlock_node (rn);
+
+ return 0;
+}
+
+int
+bgp_withdraw (struct peer *peer, struct prefix *p, struct attr *attr,
+ int afi, int safi, int type, int sub_type, struct prefix_rd *prd,
+ u_char *tag)
+{
+ struct bgp *bgp;
+ char buf[SU_ADDRSTRLEN];
+ struct bgp_node *rn;
+ struct bgp_info *ri;
+
+ bgp = peer->bgp;
+
+ /* Logging. */
+ if (BGP_DEBUG (update, UPDATE_IN))
+ zlog (peer->log, LOG_INFO, "%s rcvd UPDATE about %s/%d -- withdrawn",
+ peer->host,
+ inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
+ p->prefixlen);
+
+ /* Lookup node. */
+ rn = bgp_afi_node_get (bgp, afi, safi, p, prd);
+
+ /* If peer is soft reconfiguration enabled. Record input packet for
+ further calculation. */
+ if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
+ && peer != bgp->peer_self)
+ bgp_adj_in_unset (rn, peer);
+
+ /* Lookup withdrawn route. */
+ for (ri = rn->info; ri; ri = ri->next)
+ if (ri->peer == peer && ri->type == type && ri->sub_type == sub_type)
+ break;
+
+ /* Withdraw specified route from routing table. */
+ if (ri && ! CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
+ bgp_rib_withdraw (rn, ri, peer, afi, safi, 0);
+ else if (BGP_DEBUG (update, UPDATE_IN))
+ zlog (peer->log, LOG_INFO,
+ "%s Can't find the route %s/%d", peer->host,
+ inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
+ p->prefixlen);
+
+ /* Unlock bgp_node_get() lock. */
+ bgp_unlock_node (rn);
+
+ return 0;
+}
+
+void
+bgp_default_originate (struct peer *peer, afi_t afi, safi_t safi, int withdraw)
+{
+ struct bgp *bgp;
+ struct attr attr;
+ struct aspath *aspath;
+ struct prefix p;
+ struct bgp_info binfo;
+ struct peer *from;
+ int ret = RMAP_DENYMATCH;
+
+ bgp = peer->bgp;
+ from = bgp->peer_self;
+
+ bgp_attr_default_set (&attr, BGP_ORIGIN_IGP);
+ aspath = attr.aspath;
+ attr.local_pref = bgp->default_local_pref;
+ memcpy (&attr.nexthop, &peer->nexthop.v4, IPV4_MAX_BYTELEN);
+
+ if (afi == AFI_IP)
+ str2prefix ("0.0.0.0/0", &p);
+#ifdef HAVE_IPV6
+ else if (afi == AFI_IP6)
+ {
+ str2prefix ("::/0", &p);
+
+ /* IPv6 global nexthop must be included. */
+ memcpy (&attr.mp_nexthop_global, &peer->nexthop.v6_global,
+ IPV6_MAX_BYTELEN);
+ attr.mp_nexthop_len = 16;
+
+ /* If the peer is on shared nextwork and we have link-local
+ nexthop set it. */
+ if (peer->shared_network
+ && !IN6_IS_ADDR_UNSPECIFIED (&peer->nexthop.v6_local))
+ {
+ memcpy (&attr.mp_nexthop_local, &peer->nexthop.v6_local,
+ IPV6_MAX_BYTELEN);
+ attr.mp_nexthop_len = 32;
+ }
+ }
+#endif /* HAVE_IPV6 */
+ else
+ return;
+
+ if (peer->default_rmap[afi][safi].name)
+ {
+ binfo.peer = bgp->peer_self;
+ binfo.attr = &attr;
+
+ ret = route_map_apply (peer->default_rmap[afi][safi].map, &p,
+ RMAP_BGP, &binfo);
+
+ if (ret == RMAP_DENYMATCH)
+ {
+ bgp_attr_flush (&attr);
+ withdraw = 1;
+ }
+ }
+
+ if (withdraw)
+ {
+ if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_DEFAULT_ORIGINATE))
+ bgp_default_withdraw_send (peer, afi, safi);
+ UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_DEFAULT_ORIGINATE);
+ }
+ else
+ {
+ SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_DEFAULT_ORIGINATE);
+ bgp_default_update_send (peer, &attr, afi, safi, from);
+ }
+
+ aspath_unintern (aspath);
+}
+
+static void
+bgp_announce_table (struct peer *peer, afi_t afi, safi_t safi,
+ struct bgp_table *table)
+{
+ struct bgp_node *rn;
+ struct bgp_info *ri;
+ struct attr attr;
+
+ if (! table)
+ table = peer->bgp->rib[afi][safi];
+
+ if (safi != SAFI_MPLS_VPN
+ && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE))
+ bgp_default_originate (peer, afi, safi, 0);
+
+ for (rn = bgp_table_top (table); rn; rn = bgp_route_next(rn))
+ for (ri = rn->info; ri; ri = ri->next)
+ if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED) && ri->peer != peer)
+ {
+ if (bgp_announce_check (ri, peer, &rn->p, &attr, afi, safi))
+ bgp_adj_out_set (rn, peer, &rn->p, &attr, afi, safi, ri);
+ else
+ bgp_adj_out_unset (rn, peer, &rn->p, afi, safi);
+ }
+}
+
+void
+bgp_announce_route (struct peer *peer, afi_t afi, safi_t safi)
+{
+ struct bgp_node *rn;
+ struct bgp_table *table;
+
+ if (peer->status != Established)
+ return;
+
+ if (! peer->afc_nego[afi][safi])
+ return;
+
+ /* First update is deferred until ORF or ROUTE-REFRESH is received */
+ if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH))
+ return;
+
+ if (safi != SAFI_MPLS_VPN)
+ bgp_announce_table (peer, afi, safi, NULL);
+ else
+ for (rn = bgp_table_top (peer->bgp->rib[afi][safi]); rn;
+ rn = bgp_route_next(rn))
+ if ((table = (rn->info)) != NULL)
+ bgp_announce_table (peer, afi, safi, table);
+}
+
+void
+bgp_announce_route_all (struct peer *peer)
+{
+ afi_t afi;
+ safi_t safi;
+
+ for (afi = AFI_IP; afi < AFI_MAX; afi++)
+ for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
+ bgp_announce_route (peer, afi, safi);
+}
+
+static void
+bgp_soft_reconfig_table (struct peer *peer, afi_t afi, safi_t safi,
+ struct bgp_table *table)
+{
+ int ret;
+ struct bgp_node *rn;
+ struct bgp_adj_in *ain;
+
+ if (! table)
+ table = peer->bgp->rib[afi][safi];
+
+ for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
+ for (ain = rn->adj_in; ain; ain = ain->next)
+ {
+ if (ain->peer == peer)
+ {
+ ret = bgp_update (peer, &rn->p, ain->attr, afi, safi,
+ ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
+ NULL, NULL, 1);
+ if (ret < 0)
+ {
+ bgp_unlock_node (rn);
+ return;
+ }
+ continue;
+ }
+ }
+}
+
+void
+bgp_soft_reconfig_in (struct peer *peer, afi_t afi, safi_t safi)
+{
+ struct bgp_node *rn;
+ struct bgp_table *table;
+
+ if (peer->status != Established)
+ return;
+
+ if (safi != SAFI_MPLS_VPN)
+ bgp_soft_reconfig_table (peer, afi, safi, NULL);
+ else
+ for (rn = bgp_table_top (peer->bgp->rib[afi][safi]); rn;
+ rn = bgp_route_next (rn))
+ if ((table = rn->info) != NULL)
+ bgp_soft_reconfig_table (peer, afi, safi, table);
+}
+
+static void
+bgp_clear_route_table (struct peer *peer, afi_t afi, safi_t safi,
+ struct bgp_table *table)
+{
+ struct bgp_node *rn;
+ struct bgp_adj_in *ain;
+ struct bgp_adj_out *aout;
+ struct bgp_info *ri;
+
+ if (! table)
+ table = peer->bgp->rib[afi][safi];
+
+ for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
+ {
+ for (ri = rn->info; ri; ri = ri->next)
+ if (ri->peer == peer)
+ {
+ bgp_rib_remove (rn, ri, peer, afi, safi);
+ break;
+ }
+ for (ain = rn->adj_in; ain; ain = ain->next)
+ if (ain->peer == peer)
+ {
+ bgp_adj_in_remove (rn, ain);
+ bgp_unlock_node (rn);
+ break;
+ }
+ for (aout = rn->adj_out; aout; aout = aout->next)
+ if (aout->peer == peer)
+ {
+ bgp_adj_out_remove (rn, aout, peer, afi, safi);
+ bgp_unlock_node (rn);
+ break;
+ }
+ }
+}
+
+void
+bgp_clear_route (struct peer *peer, afi_t afi, safi_t safi)
+{
+ struct bgp_node *rn;
+ struct bgp_table *table;
+
+ if (! peer->afc[afi][safi])
+ return;
+
+ if (safi != SAFI_MPLS_VPN)
+ bgp_clear_route_table (peer, afi, safi, NULL);
+ else
+ for (rn = bgp_table_top (peer->bgp->rib[afi][safi]); rn;
+ rn = bgp_route_next (rn))
+ if ((table = rn->info) != NULL)
+ bgp_clear_route_table (peer, afi, safi, table);
+}
+
+void
+bgp_clear_route_all (struct peer *peer)
+{
+ afi_t afi;
+ safi_t safi;
+
+ for (afi = AFI_IP; afi < AFI_MAX; afi++)
+ for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
+ bgp_clear_route (peer, afi, safi);
+}
+
+void
+bgp_clear_adj_in (struct peer *peer, afi_t afi, safi_t safi)
+{
+ struct bgp_table *table;
+ struct bgp_node *rn;
+ struct bgp_adj_in *ain;
+
+ table = peer->bgp->rib[afi][safi];
+
+ for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
+ for (ain = rn->adj_in; ain ; ain = ain->next)
+ if (ain->peer == peer)
+ {
+ bgp_adj_in_remove (rn, ain);
+ bgp_unlock_node (rn);
+ break;
+ }
+}
+
+/* Delete all kernel routes. */
+void
+bgp_terminate ()
+{
+ struct bgp *bgp;
+ struct listnode *nn;
+ struct bgp_node *rn;
+ struct bgp_table *table;
+ struct bgp_info *ri;
+
+ LIST_LOOP (bm->bgp, bgp, nn)
+ {
+ table = bgp->rib[AFI_IP][SAFI_UNICAST];
+
+ for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
+ for (ri = rn->info; ri; ri = ri->next)
+ if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED)
+ && ri->type == ZEBRA_ROUTE_BGP
+ && ri->sub_type == BGP_ROUTE_NORMAL)
+ bgp_zebra_withdraw (&rn->p, ri);
+
+ table = bgp->rib[AFI_IP6][SAFI_UNICAST];
+
+ for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
+ for (ri = rn->info; ri; ri = ri->next)
+ if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED)
+ && ri->type == ZEBRA_ROUTE_BGP
+ && ri->sub_type == BGP_ROUTE_NORMAL)
+ bgp_zebra_withdraw (&rn->p, ri);
+ }
+}
+
+void
+bgp_reset ()
+{
+ vty_reset ();
+ bgp_zclient_reset ();
+ access_list_reset ();
+ prefix_list_reset ();
+}
+
+/* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
+ value. */
+int
+bgp_nlri_parse (struct peer *peer, struct attr *attr, struct bgp_nlri *packet)
+{
+ u_char *pnt;
+ u_char *lim;
+ struct prefix p;
+ int psize;
+ int ret;
+
+ /* Check peer status. */
+ if (peer->status != Established)
+ return 0;
+
+ pnt = packet->nlri;
+ lim = pnt + packet->length;
+
+ for (; pnt < lim; pnt += psize)
+ {
+ /* Clear prefix structure. */
+ memset (&p, 0, sizeof (struct prefix));
+
+ /* Fetch prefix length. */
+ p.prefixlen = *pnt++;
+ p.family = afi2family (packet->afi);
+
+ /* Already checked in nlri_sanity_check(). We do double check
+ here. */
+ if ((packet->afi == AFI_IP && p.prefixlen > 32)
+ || (packet->afi == AFI_IP6 && p.prefixlen > 128))
+ return -1;
+
+ /* Packet size overflow check. */
+ psize = PSIZE (p.prefixlen);
+
+ /* When packet overflow occur return immediately. */
+ if (pnt + psize > lim)
+ return -1;
+
+ /* Fetch prefix from NLRI packet. */
+ memcpy (&p.u.prefix, pnt, psize);
+
+ /* Check address. */
+ if (packet->afi == AFI_IP && packet->safi == SAFI_UNICAST)
+ {
+ if (IN_CLASSD (ntohl (p.u.prefix4.s_addr)))
+ {
+ zlog (peer->log, LOG_ERR,
+ "IPv4 unicast NLRI is multicast address %s",
+ inet_ntoa (p.u.prefix4));
+ bgp_notify_send (peer,
+ BGP_NOTIFY_UPDATE_ERR,
+ BGP_NOTIFY_UPDATE_INVAL_NETWORK);
+ return -1;
+ }
+ }
+
+#ifdef HAVE_IPV6
+ /* Check address. */
+ if (packet->afi == AFI_IP6 && packet->safi == SAFI_UNICAST)
+ {
+ if (IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))
+ {
+ char buf[BUFSIZ];
+
+ zlog (peer->log, LOG_WARNING,
+ "IPv6 link-local NLRI received %s ignore this NLRI",
+ inet_ntop (AF_INET6, &p.u.prefix6, buf, BUFSIZ));
+
+ continue;
+ }
+ }
+#endif /* HAVE_IPV6 */
+
+ /* Normal process. */
+ if (attr)
+ ret = bgp_update (peer, &p, attr, packet->afi, packet->safi,
+ ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, NULL, 0);
+ else
+ ret = bgp_withdraw (peer, &p, attr, packet->afi, packet->safi,
+ ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, NULL);
+
+ /* Address family configuration mismatch or maximum-prefix count
+ overflow. */
+ if (ret < 0)
+ return -1;
+ }
+
+ /* Packet length consistency check. */
+ if (pnt != lim)
+ return -1;
+
+ return 0;
+}
+
+/* NLRI encode syntax check routine. */
+int
+bgp_nlri_sanity_check (struct peer *peer, int afi, u_char *pnt,
+ bgp_size_t length)
+{
+ u_char *end;
+ u_char prefixlen;
+ int psize;
+
+ end = pnt + length;
+
+ /* RFC1771 6.3 The NLRI field in the UPDATE message is checked for
+ syntactic validity. If the field is syntactically incorrect,
+ then the Error Subcode is set to Invalid Network Field. */
+
+ while (pnt < end)
+ {
+ prefixlen = *pnt++;
+
+ /* Prefix length check. */
+ if ((afi == AFI_IP && prefixlen > 32)
+ || (afi == AFI_IP6 && prefixlen > 128))
+ {
+ plog_err (peer->log,
+ "%s [Error] Update packet error (wrong prefix length %d)",
+ peer->host, prefixlen);
+ bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
+ BGP_NOTIFY_UPDATE_INVAL_NETWORK);
+ return -1;
+ }
+
+ /* Packet size overflow check. */
+ psize = PSIZE (prefixlen);
+
+ if (pnt + psize > end)
+ {
+ plog_err (peer->log,
+ "%s [Error] Update packet error"
+ " (prefix data overflow prefix size is %d)",
+ peer->host, psize);
+ bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
+ BGP_NOTIFY_UPDATE_INVAL_NETWORK);
+ return -1;
+ }
+
+ pnt += psize;
+ }
+
+ /* Packet length consistency check. */
+ if (pnt != end)
+ {
+ plog_err (peer->log,
+ "%s [Error] Update packet error"
+ " (prefix length mismatch with total length)",
+ peer->host);
+ bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
+ BGP_NOTIFY_UPDATE_INVAL_NETWORK);
+ return -1;
+ }
+ return 0;
+}
+
+struct bgp_static *
+bgp_static_new ()
+{
+ struct bgp_static *new;
+ new = XMALLOC (MTYPE_BGP_STATIC, sizeof (struct bgp_static));
+ memset (new, 0, sizeof (struct bgp_static));
+ return new;
+}
+
+void
+bgp_static_free (struct bgp_static *bgp_static)
+{
+ if (bgp_static->rmap.name)
+ free (bgp_static->rmap.name);
+ XFREE (MTYPE_BGP_STATIC, bgp_static);
+}
+
+void
+bgp_static_update (struct bgp *bgp, struct prefix *p,
+ struct bgp_static *bgp_static, afi_t afi, safi_t safi)
+{
+ struct bgp_node *rn;
+ struct bgp_info *ri;
+ struct bgp_info *new;
+ struct bgp_info info;
+ struct attr attr;
+ struct attr *attr_new;
+ int ret;
+
+ rn = bgp_afi_node_get (bgp, afi, safi, p, NULL);
+
+ bgp_attr_default_set (&attr, BGP_ORIGIN_IGP);
+ if (bgp_static)
+ {
+ attr.nexthop = bgp_static->igpnexthop;
+ attr.med = bgp_static->igpmetric;
+ attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
+ }
+
+ /* Apply route-map. */
+ if (bgp_static->rmap.name)
+ {
+ info.peer = bgp->peer_self;
+ info.attr = &attr;
+
+ ret = route_map_apply (bgp_static->rmap.map, p, RMAP_BGP, &info);
+ if (ret == RMAP_DENYMATCH)
+ {
+ /* Free uninterned attribute. */
+ bgp_attr_flush (&attr);
+
+ /* Unintern original. */
+ aspath_unintern (attr.aspath);
+ bgp_static_withdraw (bgp, p, afi, safi);
+ return;
+ }
+ }
+
+ attr_new = bgp_attr_intern (&attr);
+
+ for (ri = rn->info; ri; ri = ri->next)
+ if (ri->peer == bgp->peer_self && ri->type == ZEBRA_ROUTE_BGP
+ && ri->sub_type == BGP_ROUTE_STATIC)
+ break;
+
+ if (ri)
+ {
+ if (attrhash_cmp (ri->attr, attr_new))
+ {
+ bgp_unlock_node (rn);
+ bgp_attr_unintern (attr_new);
+ aspath_unintern (attr.aspath);
+ return;
+ }
+ else
+ {
+ /* The attribute is changed. */
+ SET_FLAG (ri->flags, BGP_INFO_ATTR_CHANGED);
+
+ /* Rewrite BGP route information. */
+ bgp_aggregate_decrement (bgp, p, ri, afi, safi);
+ bgp_attr_unintern (ri->attr);
+ ri->attr = attr_new;
+ ri->uptime = time (NULL);
+
+ /* Process change. */
+ bgp_aggregate_increment (bgp, p, ri, afi, safi);
+ bgp_process (bgp, rn, afi, safi);
+ bgp_unlock_node (rn);
+ aspath_unintern (attr.aspath);
+ return;
+ }
+ }
+
+ /* Make new BGP info. */
+ new = bgp_info_new ();
+ new->type = ZEBRA_ROUTE_BGP;
+ new->sub_type = BGP_ROUTE_STATIC;
+ new->peer = bgp->peer_self;
+ SET_FLAG (new->flags, BGP_INFO_VALID);
+ new->attr = attr_new;
+ new->uptime = time (NULL);
+
+ /* Aggregate address increment. */
+ bgp_aggregate_increment (bgp, p, new, afi, safi);
+
+ /* Register new BGP information. */
+ bgp_info_add (rn, new);
+
+ /* Process change. */
+ bgp_process (bgp, rn, afi, safi);
+
+ /* Unintern original. */
+ aspath_unintern (attr.aspath);
+}
+
+void
+bgp_static_update_vpnv4 (struct bgp *bgp, struct prefix *p, u_int16_t afi,
+ u_char safi, struct prefix_rd *prd, u_char *tag)
+{
+ struct bgp_node *rn;
+ struct bgp_info *new;
+
+ rn = bgp_afi_node_get (bgp, afi, safi, p, prd);
+
+ /* Make new BGP info. */
+ new = bgp_info_new ();
+ new->type = ZEBRA_ROUTE_BGP;
+ new->sub_type = BGP_ROUTE_STATIC;
+ new->peer = bgp->peer_self;
+ new->attr = bgp_attr_default_intern (BGP_ORIGIN_IGP);
+ SET_FLAG (new->flags, BGP_INFO_VALID);
+ new->uptime = time (NULL);
+ memcpy (new->tag, tag, 3);
+
+ /* Aggregate address increment. */
+ bgp_aggregate_increment (bgp, p, (struct bgp_info *) new, afi, safi);
+
+ /* Register new BGP information. */
+ bgp_info_add (rn, (struct bgp_info *) new);
+
+ /* Process change. */
+ bgp_process (bgp, rn, afi, safi);
+}
+
+void
+bgp_static_withdraw (struct bgp *bgp, struct prefix *p, afi_t afi,
+ safi_t safi)
+{
+ struct bgp_node *rn;
+ struct bgp_info *ri;
+
+ rn = bgp_afi_node_get (bgp, afi, safi, p, NULL);
+
+ /* Check selected route and self inserted route. */
+ for (ri = rn->info; ri; ri = ri->next)
+ if (ri->peer == bgp->peer_self
+ && ri->type == ZEBRA_ROUTE_BGP
+ && ri->sub_type == BGP_ROUTE_STATIC)
+ break;
+
+ /* Withdraw static BGP route from routing table. */
+ if (ri)
+ {
+ bgp_aggregate_decrement (bgp, p, ri, afi, safi);
+ UNSET_FLAG (ri->flags, BGP_INFO_VALID);
+ bgp_process (bgp, rn, afi, safi);
+ bgp_info_delete (rn, ri);
+ bgp_info_free (ri);
+ bgp_unlock_node (rn);
+ }
+
+ /* Unlock bgp_node_lookup. */
+ bgp_unlock_node (rn);
+}
+
+void
+bgp_static_withdraw_vpnv4 (struct bgp *bgp, struct prefix *p, u_int16_t afi,
+ u_char safi, struct prefix_rd *prd, u_char *tag)
+{
+ struct bgp_node *rn;
+ struct bgp_info *ri;
+
+ rn = bgp_afi_node_get (bgp, afi, safi, p, prd);
+
+ /* Check selected route and self inserted route. */
+ for (ri = rn->info; ri; ri = ri->next)
+ if (ri->peer == bgp->peer_self
+ && ri->type == ZEBRA_ROUTE_BGP
+ && ri->sub_type == BGP_ROUTE_STATIC)
+ break;
+
+ /* Withdraw static BGP route from routing table. */
+ if (ri)
+ {
+ bgp_aggregate_decrement (bgp, p, ri, afi, safi);
+ UNSET_FLAG (ri->flags, BGP_INFO_VALID);
+ bgp_process (bgp, rn, afi, safi);
+ bgp_info_delete (rn, ri);
+ bgp_info_free (ri);
+ bgp_unlock_node (rn);
+ }
+
+ /* Unlock bgp_node_lookup. */
+ bgp_unlock_node (rn);
+}
+
+/* Configure static BGP network. When user don't run zebra, static
+ route should be installed as valid. */
+int
+bgp_static_set (struct vty *vty, struct bgp *bgp, char *ip_str, u_int16_t afi,
+ u_char safi, char *rmap, int backdoor)
+{
+ int ret;
+ struct prefix p;
+ struct bgp_static *bgp_static;
+ struct bgp_node *rn;
+ int need_update = 0;
+
+ /* Convert IP prefix string to struct prefix. */
+ ret = str2prefix (ip_str, &p);
+ if (! ret)
+ {
+ vty_out (vty, "%% Malformed prefix%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+#ifdef HAVE_IPV6
+ if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))
+ {
+ vty_out (vty, "%% Malformed prefix (link-local address)%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+#endif /* HAVE_IPV6 */
+
+ apply_mask (&p);
+
+ /* Set BGP static route configuration. */
+ rn = bgp_node_get (bgp->route[afi][safi], &p);
+
+ if (rn->info)
+ {
+ /* Configuration change. */
+ bgp_static = rn->info;
+
+ /* Check previous routes are installed into BGP. */
+ if (! bgp_static->backdoor && bgp_static->valid)
+ need_update = 1;
+
+ bgp_static->backdoor = backdoor;
+ if (rmap)
+ {
+ if (bgp_static->rmap.name)
+ free (bgp_static->rmap.name);
+ bgp_static->rmap.name = strdup (rmap);
+ bgp_static->rmap.map = route_map_lookup_by_name (rmap);
+ }
+ else
+ {
+ if (bgp_static->rmap.name)
+ free (bgp_static->rmap.name);
+ bgp_static->rmap.name = NULL;
+ bgp_static->rmap.map = NULL;
+ bgp_static->valid = 0;
+ }
+ bgp_unlock_node (rn);
+ }
+ else
+ {
+ /* New configuration. */
+ bgp_static = bgp_static_new ();
+ bgp_static->backdoor = backdoor;
+ bgp_static->valid = 0;
+ bgp_static->igpmetric = 0;
+ bgp_static->igpnexthop.s_addr = 0;
+ if (rmap)
+ {
+ if (bgp_static->rmap.name)
+ free (bgp_static->rmap.name);
+ bgp_static->rmap.name = strdup (rmap);
+ bgp_static->rmap.map = route_map_lookup_by_name (rmap);
+ }
+ rn->info = bgp_static;
+ }
+
+ /* If BGP scan is not enabled, we should install this route here. */
+ if (! bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK))
+ {
+ bgp_static->valid = 1;
+
+ if (need_update)
+ bgp_static_withdraw (bgp, &p, afi, safi);
+
+ if (! bgp_static->backdoor)
+ bgp_static_update (bgp, &p, bgp_static, afi, safi);
+ }
+
+ return CMD_SUCCESS;
+}
+
+/* Configure static BGP network. */
+int
+bgp_static_unset (struct vty *vty, struct bgp *bgp, char *ip_str,
+ u_int16_t afi, u_char safi)
+{
+ int ret;
+ struct prefix p;
+ struct bgp_static *bgp_static;
+ struct bgp_node *rn;
+
+ /* Convert IP prefix string to struct prefix. */
+ ret = str2prefix (ip_str, &p);
+ if (! ret)
+ {
+ vty_out (vty, "%% Malformed prefix%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+#ifdef HAVE_IPV6
+ if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))
+ {
+ vty_out (vty, "%% Malformed prefix (link-local address)%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+#endif /* HAVE_IPV6 */
+
+ apply_mask (&p);
+
+ rn = bgp_node_lookup (bgp->route[afi][safi], &p);
+ if (! rn)
+ {
+ vty_out (vty, "%% Can't find specified static route configuration.%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ bgp_static = rn->info;
+
+ /* Update BGP RIB. */
+ if (! bgp_static->backdoor)
+ bgp_static_withdraw (bgp, &p, afi, safi);
+
+ /* Clear configuration. */
+ bgp_static_free (bgp_static);
+ rn->info = NULL;
+ bgp_unlock_node (rn);
+ bgp_unlock_node (rn);
+
+ return CMD_SUCCESS;
+}
+
+/* Called from bgp_delete(). Delete all static routes from the BGP
+ instance. */
+void
+bgp_static_delete (struct bgp *bgp)
+{
+ afi_t afi;
+ safi_t safi;
+ struct bgp_node *rn;
+ struct bgp_node *rm;
+ struct bgp_table *table;
+ struct bgp_static *bgp_static;
+
+ for (afi = AFI_IP; afi < AFI_MAX; afi++)
+ for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
+ for (rn = bgp_table_top (bgp->route[afi][safi]); rn; rn = bgp_route_next (rn))
+ if (rn->info != NULL)
+ {
+ if (safi == SAFI_MPLS_VPN)
+ {
+ table = rn->info;
+
+ for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
+ {
+ bgp_static = rn->info;
+ bgp_static_withdraw_vpnv4 (bgp, &rm->p,
+ AFI_IP, SAFI_MPLS_VPN,
+ (struct prefix_rd *)&rn->p,
+ bgp_static->tag);
+ bgp_static_free (bgp_static);
+ rn->info = NULL;
+ bgp_unlock_node (rn);
+ }
+ }
+ else
+ {
+ bgp_static = rn->info;
+ bgp_static_withdraw (bgp, &rn->p, afi, safi);
+ bgp_static_free (bgp_static);
+ rn->info = NULL;
+ bgp_unlock_node (rn);
+ }
+ }
+}
+
+int
+bgp_static_set_vpnv4 (struct vty *vty, char *ip_str, char *rd_str,
+ char *tag_str)
+{
+ int ret;
+ struct prefix p;
+ struct prefix_rd prd;
+ struct bgp *bgp;
+ struct bgp_node *prn;
+ struct bgp_node *rn;
+ struct bgp_table *table;
+ struct bgp_static *bgp_static;
+ u_char tag[3];
+
+ bgp = vty->index;
+
+ ret = str2prefix (ip_str, &p);
+ if (! ret)
+ {
+ vty_out (vty, "%% Malformed prefix%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ apply_mask (&p);
+
+ ret = str2prefix_rd (rd_str, &prd);
+ if (! ret)
+ {
+ vty_out (vty, "%% Malformed rd%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ ret = str2tag (tag_str, tag);
+ if (! ret)
+ {
+ vty_out (vty, "%% Malformed tag%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ prn = bgp_node_get (bgp->route[AFI_IP][SAFI_MPLS_VPN],
+ (struct prefix *)&prd);
+ if (prn->info == NULL)
+ prn->info = bgp_table_init ();
+ else
+ bgp_unlock_node (prn);
+ table = prn->info;
+
+ rn = bgp_node_get (table, &p);
+
+ if (rn->info)
+ {
+ vty_out (vty, "%% Same network configuration exists%s", VTY_NEWLINE);
+ bgp_unlock_node (rn);
+ }
+ else
+ {
+ /* New configuration. */
+ bgp_static = bgp_static_new ();
+ bgp_static->valid = 1;
+ memcpy (bgp_static->tag, tag, 3);
+ rn->info = bgp_static;
+
+ bgp_static_update_vpnv4 (bgp, &p, AFI_IP, SAFI_MPLS_VPN, &prd, tag);
+ }
+
+ return CMD_SUCCESS;
+}
+
+/* Configure static BGP network. */
+int
+bgp_static_unset_vpnv4 (struct vty *vty, char *ip_str, char *rd_str,
+ char *tag_str)
+{
+ int ret;
+ struct bgp *bgp;
+ struct prefix p;
+ struct prefix_rd prd;
+ struct bgp_node *prn;
+ struct bgp_node *rn;
+ struct bgp_table *table;
+ struct bgp_static *bgp_static;
+ u_char tag[3];
+
+ bgp = vty->index;
+
+ /* Convert IP prefix string to struct prefix. */
+ ret = str2prefix (ip_str, &p);
+ if (! ret)
+ {
+ vty_out (vty, "%% Malformed prefix%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ apply_mask (&p);
+
+ ret = str2prefix_rd (rd_str, &prd);
+ if (! ret)
+ {
+ vty_out (vty, "%% Malformed rd%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ ret = str2tag (tag_str, tag);
+ if (! ret)
+ {
+ vty_out (vty, "%% Malformed tag%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ prn = bgp_node_get (bgp->route[AFI_IP][SAFI_MPLS_VPN],
+ (struct prefix *)&prd);
+ if (prn->info == NULL)
+ prn->info = bgp_table_init ();
+ else
+ bgp_unlock_node (prn);
+ table = prn->info;
+
+ rn = bgp_node_lookup (table, &p);
+
+ if (rn)
+ {
+ bgp_static_withdraw_vpnv4 (bgp, &p, AFI_IP, SAFI_MPLS_VPN, &prd, tag);
+
+ bgp_static = rn->info;
+ bgp_static_free (bgp_static);
+ rn->info = NULL;
+ bgp_unlock_node (rn);
+ bgp_unlock_node (rn);
+ }
+ else
+ vty_out (vty, "%% Can't find the route%s", VTY_NEWLINE);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (bgp_network,
+ bgp_network_cmd,
+ "network A.B.C.D/M",
+ "Specify a network to announce via BGP\n"
+ "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
+{
+ return bgp_static_set (vty, vty->index, argv[0],
+ AFI_IP, bgp_node_safi (vty), NULL, 0);
+}
+
+DEFUN (bgp_network_route_map,
+ bgp_network_route_map_cmd,
+ "network A.B.C.D/M route-map WORD",
+ "Specify a network to announce via BGP\n"
+ "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
+ "Route-map to modify the attributes\n"
+ "Name of the route map\n")
+{
+ return bgp_static_set (vty, vty->index, argv[0],
+ AFI_IP, bgp_node_safi (vty), argv[1], 0);
+}
+
+DEFUN (bgp_network_backdoor,
+ bgp_network_backdoor_cmd,
+ "network A.B.C.D/M backdoor",
+ "Specify a network to announce via BGP\n"
+ "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
+ "Specify a BGP backdoor route\n")
+{
+ return bgp_static_set (vty, vty->index, argv[0], AFI_IP, SAFI_UNICAST, NULL, 1);
+}
+
+DEFUN (bgp_network_mask,
+ bgp_network_mask_cmd,
+ "network A.B.C.D mask A.B.C.D",
+ "Specify a network to announce via BGP\n"
+ "Network number\n"
+ "Network mask\n"
+ "Network mask\n")
+{
+ int ret;
+ char prefix_str[BUFSIZ];
+
+ ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
+ if (! ret)
+ {
+ vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return bgp_static_set (vty, vty->index, prefix_str,
+ AFI_IP, bgp_node_safi (vty), NULL, 0);
+}
+
+DEFUN (bgp_network_mask_route_map,
+ bgp_network_mask_route_map_cmd,
+ "network A.B.C.D mask A.B.C.D route-map WORD",
+ "Specify a network to announce via BGP\n"
+ "Network number\n"
+ "Network mask\n"
+ "Network mask\n"
+ "Route-map to modify the attributes\n"
+ "Name of the route map\n")
+{
+ int ret;
+ char prefix_str[BUFSIZ];
+
+ ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
+ if (! ret)
+ {
+ vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return bgp_static_set (vty, vty->index, prefix_str,
+ AFI_IP, bgp_node_safi (vty), argv[2], 0);
+}
+
+DEFUN (bgp_network_mask_backdoor,
+ bgp_network_mask_backdoor_cmd,
+ "network A.B.C.D mask A.B.C.D backdoor",
+ "Specify a network to announce via BGP\n"
+ "Network number\n"
+ "Network mask\n"
+ "Network mask\n"
+ "Specify a BGP backdoor route\n")
+{
+ int ret;
+ char prefix_str[BUFSIZ];
+
+ ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
+ if (! ret)
+ {
+ vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return bgp_static_set (vty, vty->index, prefix_str, AFI_IP, SAFI_UNICAST, NULL, 1);
+}
+
+DEFUN (bgp_network_mask_natural,
+ bgp_network_mask_natural_cmd,
+ "network A.B.C.D",
+ "Specify a network to announce via BGP\n"
+ "Network number\n")
+{
+ int ret;
+ char prefix_str[BUFSIZ];
+
+ ret = netmask_str2prefix_str (argv[0], NULL, prefix_str);
+ if (! ret)
+ {
+ vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return bgp_static_set (vty, vty->index, prefix_str,
+ AFI_IP, bgp_node_safi (vty), NULL, 0);
+}
+
+DEFUN (bgp_network_mask_natural_route_map,
+ bgp_network_mask_natural_route_map_cmd,
+ "network A.B.C.D route-map WORD",
+ "Specify a network to announce via BGP\n"
+ "Network number\n"
+ "Route-map to modify the attributes\n"
+ "Name of the route map\n")
+{
+ int ret;
+ char prefix_str[BUFSIZ];
+
+ ret = netmask_str2prefix_str (argv[0], NULL, prefix_str);
+ if (! ret)
+ {
+ vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return bgp_static_set (vty, vty->index, prefix_str,
+ AFI_IP, bgp_node_safi (vty), argv[1], 0);
+}
+
+DEFUN (bgp_network_mask_natural_backdoor,
+ bgp_network_mask_natural_backdoor_cmd,
+ "network A.B.C.D backdoor",
+ "Specify a network to announce via BGP\n"
+ "Network number\n"
+ "Specify a BGP backdoor route\n")
+{
+ int ret;
+ char prefix_str[BUFSIZ];
+
+ ret = netmask_str2prefix_str (argv[0], NULL, prefix_str);
+ if (! ret)
+ {
+ vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return bgp_static_set (vty, vty->index, prefix_str, AFI_IP, SAFI_UNICAST, NULL, 1);
+}
+
+DEFUN (no_bgp_network,
+ no_bgp_network_cmd,
+ "no network A.B.C.D/M",
+ NO_STR
+ "Specify a network to announce via BGP\n"
+ "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
+{
+ return bgp_static_unset (vty, vty->index, argv[0], AFI_IP,
+ bgp_node_safi (vty));
+}
+
+ALIAS (no_bgp_network,
+ no_bgp_network_route_map_cmd,
+ "no network A.B.C.D/M route-map WORD",
+ NO_STR
+ "Specify a network to announce via BGP\n"
+ "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
+ "Route-map to modify the attributes\n"
+ "Name of the route map\n")
+
+ALIAS (no_bgp_network,
+ no_bgp_network_backdoor_cmd,
+ "no network A.B.C.D/M backdoor",
+ NO_STR
+ "Specify a network to announce via BGP\n"
+ "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
+ "Specify a BGP backdoor route\n")
+
+DEFUN (no_bgp_network_mask,
+ no_bgp_network_mask_cmd,
+ "no network A.B.C.D mask A.B.C.D",
+ NO_STR
+ "Specify a network to announce via BGP\n"
+ "Network number\n"
+ "Network mask\n"
+ "Network mask\n")
+{
+ int ret;
+ char prefix_str[BUFSIZ];
+
+ ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
+ if (! ret)
+ {
+ vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return bgp_static_unset (vty, vty->index, prefix_str, AFI_IP,
+ bgp_node_safi (vty));
+}
+
+ALIAS (no_bgp_network_mask,
+ no_bgp_network_mask_route_map_cmd,
+ "no network A.B.C.D mask A.B.C.D route-map WORD",
+ NO_STR
+ "Specify a network to announce via BGP\n"
+ "Network number\n"
+ "Network mask\n"
+ "Network mask\n"
+ "Route-map to modify the attributes\n"
+ "Name of the route map\n")
+
+ALIAS (no_bgp_network_mask,
+ no_bgp_network_mask_backdoor_cmd,
+ "no network A.B.C.D mask A.B.C.D backdoor",
+ NO_STR
+ "Specify a network to announce via BGP\n"
+ "Network number\n"
+ "Network mask\n"
+ "Network mask\n"
+ "Specify a BGP backdoor route\n")
+
+DEFUN (no_bgp_network_mask_natural,
+ no_bgp_network_mask_natural_cmd,
+ "no network A.B.C.D",
+ NO_STR
+ "Specify a network to announce via BGP\n"
+ "Network number\n")
+{
+ int ret;
+ char prefix_str[BUFSIZ];
+
+ ret = netmask_str2prefix_str (argv[0], NULL, prefix_str);
+ if (! ret)
+ {
+ vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return bgp_static_unset (vty, vty->index, prefix_str, AFI_IP,
+ bgp_node_safi (vty));
+}
+
+ALIAS (no_bgp_network_mask_natural,
+ no_bgp_network_mask_natural_route_map_cmd,
+ "no network A.B.C.D route-map WORD",
+ NO_STR
+ "Specify a network to announce via BGP\n"
+ "Network number\n"
+ "Route-map to modify the attributes\n"
+ "Name of the route map\n")
+
+ALIAS (no_bgp_network_mask_natural,
+ no_bgp_network_mask_natural_backdoor_cmd,
+ "no network A.B.C.D backdoor",
+ NO_STR
+ "Specify a network to announce via BGP\n"
+ "Network number\n"
+ "Specify a BGP backdoor route\n")
+
+#ifdef HAVE_IPV6
+DEFUN (ipv6_bgp_network,
+ ipv6_bgp_network_cmd,
+ "network X:X::X:X/M",
+ "Specify a network to announce via BGP\n"
+ "IPv6 prefix <network>/<length>\n")
+{
+ return bgp_static_set (vty, vty->index, argv[0], AFI_IP6, SAFI_UNICAST, NULL, 0);
+}
+
+DEFUN (ipv6_bgp_network_route_map,
+ ipv6_bgp_network_route_map_cmd,
+ "network X:X::X:X/M route-map WORD",
+ "Specify a network to announce via BGP\n"
+ "IPv6 prefix <network>/<length>\n"
+ "Route-map to modify the attributes\n"
+ "Name of the route map\n")
+{
+ return bgp_static_set (vty, vty->index, argv[0], AFI_IP6,
+ bgp_node_safi (vty), argv[1], 0);
+}
+
+DEFUN (no_ipv6_bgp_network,
+ no_ipv6_bgp_network_cmd,
+ "no network X:X::X:X/M",
+ NO_STR
+ "Specify a network to announce via BGP\n"
+ "IPv6 prefix <network>/<length>\n")
+{
+ return bgp_static_unset (vty, vty->index, argv[0], AFI_IP6, SAFI_UNICAST);
+}
+
+ALIAS (no_ipv6_bgp_network,
+ no_ipv6_bgp_network_route_map_cmd,
+ "no network X:X::X:X/M route-map WORD",
+ NO_STR
+ "Specify a network to announce via BGP\n"
+ "IPv6 prefix <network>/<length>\n"
+ "Route-map to modify the attributes\n"
+ "Name of the route map\n")
+
+ALIAS (ipv6_bgp_network,
+ old_ipv6_bgp_network_cmd,
+ "ipv6 bgp network X:X::X:X/M",
+ IPV6_STR
+ BGP_STR
+ "Specify a network to announce via BGP\n"
+ "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n")
+
+ALIAS (no_ipv6_bgp_network,
+ old_no_ipv6_bgp_network_cmd,
+ "no ipv6 bgp network X:X::X:X/M",
+ NO_STR
+ IPV6_STR
+ BGP_STR
+ "Specify a network to announce via BGP\n"
+ "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n")
+#endif /* HAVE_IPV6 */
+
+/* Aggreagete address:
+
+ advertise-map Set condition to advertise attribute
+ as-set Generate AS set path information
+ attribute-map Set attributes of aggregate
+ route-map Set parameters of aggregate
+ summary-only Filter more specific routes from updates
+ suppress-map Conditionally filter more specific routes from updates
+ <cr>
+ */
+struct bgp_aggregate
+{
+ /* Summary-only flag. */
+ u_char summary_only;
+
+ /* AS set generation. */
+ u_char as_set;
+
+ /* Route-map for aggregated route. */
+ struct route_map *map;
+
+ /* Suppress-count. */
+ unsigned long count;
+
+ /* SAFI configuration. */
+ safi_t safi;
+};
+
+struct bgp_aggregate *
+bgp_aggregate_new ()
+{
+ struct bgp_aggregate *new;
+ new = XMALLOC (MTYPE_BGP_AGGREGATE, sizeof (struct bgp_aggregate));
+ memset (new, 0, sizeof (struct bgp_aggregate));
+ return new;
+}
+
+void
+bgp_aggregate_free (struct bgp_aggregate *aggregate)
+{
+ XFREE (MTYPE_BGP_AGGREGATE, aggregate);
+}
+
+void
+bgp_aggregate_route (struct bgp *bgp, struct prefix *p, struct bgp_info *rinew,
+ afi_t afi, safi_t safi, struct bgp_info *del,
+ struct bgp_aggregate *aggregate)
+{
+ struct bgp_table *table;
+ struct bgp_node *top;
+ struct bgp_node *rn;
+ u_char origin;
+ struct aspath *aspath = NULL;
+ struct aspath *asmerge = NULL;
+ struct community *community = NULL;
+ struct community *commerge = NULL;
+ struct in_addr nexthop;
+ u_int32_t med = 0;
+ struct bgp_info *ri;
+ struct bgp_info *new;
+ int first = 1;
+ unsigned long match = 0;
+
+ /* Record adding route's nexthop and med. */
+ if (rinew)
+ {
+ nexthop = rinew->attr->nexthop;
+ med = rinew->attr->med;
+ }
+
+ /* ORIGIN attribute: If at least one route among routes that are
+ aggregated has ORIGIN with the value INCOMPLETE, then the
+ aggregated route must have the ORIGIN attribute with the value
+ INCOMPLETE. Otherwise, if at least one route among routes that
+ are aggregated has ORIGIN with the value EGP, then the aggregated
+ route must have the origin attribute with the value EGP. In all
+ other case the value of the ORIGIN attribute of the aggregated
+ route is INTERNAL. */
+ origin = BGP_ORIGIN_IGP;
+
+ table = bgp->rib[afi][safi];
+
+ top = bgp_node_get (table, p);
+ for (rn = bgp_node_get (table, p); rn; rn = bgp_route_next_until (rn, top))
+ if (rn->p.prefixlen > p->prefixlen)
+ {
+ match = 0;
+
+ for (ri = rn->info; ri; ri = ri->next)
+ {
+ if (BGP_INFO_HOLDDOWN (ri))
+ continue;
+
+ if (del && ri == del)
+ continue;
+
+ if (! rinew && first)
+ {
+ nexthop = ri->attr->nexthop;
+ med = ri->attr->med;
+ first = 0;
+ }
+
+#ifdef AGGREGATE_NEXTHOP_CHECK
+ if (! IPV4_ADDR_SAME (&ri->attr->nexthop, &nexthop)
+ || ri->attr->med != med)
+ {
+ if (aspath)
+ aspath_free (aspath);
+ if (community)
+ community_free (community);
+ bgp_unlock_node (rn);
+ bgp_unlock_node (top);
+ return;
+ }
+#endif /* AGGREGATE_NEXTHOP_CHECK */
+
+ if (ri->sub_type != BGP_ROUTE_AGGREGATE)
+ {
+ if (aggregate->summary_only)
+ {
+ ri->suppress++;
+ SET_FLAG (ri->flags, BGP_INFO_ATTR_CHANGED);
+ match++;
+ }
+
+ aggregate->count++;
+
+ if (aggregate->as_set)
+ {
+ if (origin < ri->attr->origin)
+ origin = ri->attr->origin;
+
+ if (aspath)
+ {
+ asmerge = aspath_aggregate (aspath, ri->attr->aspath);
+ aspath_free (aspath);
+ aspath = asmerge;
+ }
+ else
+ aspath = aspath_dup (ri->attr->aspath);
+
+ if (ri->attr->community)
+ {
+ if (community)
+ {
+ commerge = community_merge (community,
+ ri->attr->community);
+ community = community_uniq_sort (commerge);
+ community_free (commerge);
+ }
+ else
+ community = community_dup (ri->attr->community);
+ }
+ }
+ }
+ }
+ if (match)
+ bgp_process (bgp, rn, afi, safi);
+ }
+ bgp_unlock_node (top);
+
+ if (rinew)
+ {
+ aggregate->count++;
+
+ if (aggregate->summary_only)
+ rinew->suppress++;
+
+ if (aggregate->as_set)
+ {
+ if (origin < rinew->attr->origin)
+ origin = rinew->attr->origin;
+
+ if (aspath)
+ {
+ asmerge = aspath_aggregate (aspath, rinew->attr->aspath);
+ aspath_free (aspath);
+ aspath = asmerge;
+ }
+ else
+ aspath = aspath_dup (rinew->attr->aspath);
+
+ if (rinew->attr->community)
+ {
+ if (community)
+ {
+ commerge = community_merge (community,
+ rinew->attr->community);
+ community = community_uniq_sort (commerge);
+ community_free (commerge);
+ }
+ else
+ community = community_dup (rinew->attr->community);
+ }
+ }
+ }
+
+ if (aggregate->count > 0)
+ {
+ rn = bgp_node_get (table, p);
+ new = bgp_info_new ();
+ new->type = ZEBRA_ROUTE_BGP;
+ new->sub_type = BGP_ROUTE_AGGREGATE;
+ new->peer = bgp->peer_self;
+ SET_FLAG (new->flags, BGP_INFO_VALID);
+ new->attr = bgp_attr_aggregate_intern (bgp, origin, aspath, community, aggregate->as_set);
+ new->uptime = time (NULL);
+
+ bgp_info_add (rn, new);
+ bgp_process (bgp, rn, afi, safi);
+ }
+ else
+ {
+ if (aspath)
+ aspath_free (aspath);
+ if (community)
+ community_free (community);
+ }
+}
+
+void bgp_aggregate_delete (struct bgp *, struct prefix *, afi_t, safi_t,
+ struct bgp_aggregate *);
+
+void
+bgp_aggregate_increment (struct bgp *bgp, struct prefix *p,
+ struct bgp_info *ri, afi_t afi, safi_t safi)
+{
+ struct bgp_node *child;
+ struct bgp_node *rn;
+ struct bgp_aggregate *aggregate;
+
+ /* MPLS-VPN aggregation is not yet supported. */
+ if (safi == SAFI_MPLS_VPN)
+ return;
+
+ if (p->prefixlen == 0)
+ return;
+
+ if (BGP_INFO_HOLDDOWN (ri))
+ return;
+
+ child = bgp_node_get (bgp->aggregate[afi][safi], p);
+
+ /* Aggregate address configuration check. */
+ for (rn = child; rn; rn = rn->parent)
+ if ((aggregate = rn->info) != NULL && rn->p.prefixlen < p->prefixlen)
+ {
+ bgp_aggregate_delete (bgp, &rn->p, afi, safi, aggregate);
+ bgp_aggregate_route (bgp, &rn->p, ri, safi, safi, NULL, aggregate);
+ }
+ bgp_unlock_node (child);
+}
+
+void
+bgp_aggregate_decrement (struct bgp *bgp, struct prefix *p,
+ struct bgp_info *del, afi_t afi, safi_t safi)
+{
+ struct bgp_node *child;
+ struct bgp_node *rn;
+ struct bgp_aggregate *aggregate;
+
+ /* MPLS-VPN aggregation is not yet supported. */
+ if (safi == SAFI_MPLS_VPN)
+ return;
+
+ if (p->prefixlen == 0)
+ return;
+
+ child = bgp_node_get (bgp->aggregate[afi][safi], p);
+
+ /* Aggregate address configuration check. */
+ for (rn = child; rn; rn = rn->parent)
+ if ((aggregate = rn->info) != NULL && rn->p.prefixlen < p->prefixlen)
+ {
+ bgp_aggregate_delete (bgp, &rn->p, afi, safi, aggregate);
+ bgp_aggregate_route (bgp, &rn->p, NULL, safi, safi, del, aggregate);
+ }
+ bgp_unlock_node (child);
+}
+
+void
+bgp_aggregate_add (struct bgp *bgp, struct prefix *p, afi_t afi, safi_t safi,
+ struct bgp_aggregate *aggregate)
+{
+ struct bgp_table *table;
+ struct bgp_node *top;
+ struct bgp_node *rn;
+ struct bgp_info *new;
+ struct bgp_info *ri;
+ unsigned long match;
+ u_char origin = BGP_ORIGIN_IGP;
+ struct aspath *aspath = NULL;
+ struct aspath *asmerge = NULL;
+ struct community *community = NULL;
+ struct community *commerge = NULL;
+
+ table = bgp->rib[afi][safi];
+
+ /* Sanity check. */
+ if (afi == AFI_IP && p->prefixlen == IPV4_MAX_BITLEN)
+ return;
+ if (afi == AFI_IP6 && p->prefixlen == IPV6_MAX_BITLEN)
+ return;
+
+ /* If routes exists below this node, generate aggregate routes. */
+ top = bgp_node_get (table, p);
+ for (rn = bgp_node_get (table, p); rn; rn = bgp_route_next_until (rn, top))
+ if (rn->p.prefixlen > p->prefixlen)
+ {
+ match = 0;
+
+ for (ri = rn->info; ri; ri = ri->next)
+ {
+ if (BGP_INFO_HOLDDOWN (ri))
+ continue;
+
+ if (ri->sub_type != BGP_ROUTE_AGGREGATE)
+ {
+ /* summary-only aggregate route suppress aggregated
+ route announcement. */
+ if (aggregate->summary_only)
+ {
+ ri->suppress++;
+ SET_FLAG (ri->flags, BGP_INFO_ATTR_CHANGED);
+ match++;
+ }
+ /* as-set aggregate route generate origin, as path,
+ community aggregation. */
+ if (aggregate->as_set)
+ {
+ if (origin < ri->attr->origin)
+ origin = ri->attr->origin;
+
+ if (aspath)
+ {
+ asmerge = aspath_aggregate (aspath, ri->attr->aspath);
+ aspath_free (aspath);
+ aspath = asmerge;
+ }
+ else
+ aspath = aspath_dup (ri->attr->aspath);
+
+ if (ri->attr->community)
+ {
+ if (community)
+ {
+ commerge = community_merge (community,
+ ri->attr->community);
+ community = community_uniq_sort (commerge);
+ community_free (commerge);
+ }
+ else
+ community = community_dup (ri->attr->community);
+ }
+ }
+ aggregate->count++;
+ }
+ }
+
+ /* If this node is suppressed, process the change. */
+ if (match)
+ bgp_process (bgp, rn, afi, safi);
+ }
+ bgp_unlock_node (top);
+
+ /* Add aggregate route to BGP table. */
+ if (aggregate->count)
+ {
+ rn = bgp_node_get (table, p);
+
+ new = bgp_info_new ();
+ new->type = ZEBRA_ROUTE_BGP;
+ new->sub_type = BGP_ROUTE_AGGREGATE;
+ new->peer = bgp->peer_self;
+ SET_FLAG (new->flags, BGP_INFO_VALID);
+ new->attr = bgp_attr_aggregate_intern (bgp, origin, aspath, community, aggregate->as_set);
+ new->uptime = time (NULL);
+
+ bgp_info_add (rn, new);
+
+ /* Process change. */
+ bgp_process (bgp, rn, afi, safi);
+ }
+}
+
+void
+bgp_aggregate_delete (struct bgp *bgp, struct prefix *p, afi_t afi,
+ safi_t safi, struct bgp_aggregate *aggregate)
+{
+ struct bgp_table *table;
+ struct bgp_node *top;
+ struct bgp_node *rn;
+ struct bgp_info *ri;
+ unsigned long match;
+
+ table = bgp->rib[afi][safi];
+
+ if (afi == AFI_IP && p->prefixlen == IPV4_MAX_BITLEN)
+ return;
+ if (afi == AFI_IP6 && p->prefixlen == IPV6_MAX_BITLEN)
+ return;
+
+ /* If routes exists below this node, generate aggregate routes. */
+ top = bgp_node_get (table, p);
+ for (rn = bgp_node_get (table, p); rn; rn = bgp_route_next_until (rn, top))
+ if (rn->p.prefixlen > p->prefixlen)
+ {
+ match = 0;
+
+ for (ri = rn->info; ri; ri = ri->next)
+ {
+ if (BGP_INFO_HOLDDOWN (ri))
+ continue;
+
+ if (ri->sub_type != BGP_ROUTE_AGGREGATE)
+ {
+ if (aggregate->summary_only)
+ {
+ ri->suppress--;
+
+ if (ri->suppress == 0)
+ {
+ SET_FLAG (ri->flags, BGP_INFO_ATTR_CHANGED);
+ match++;
+ }
+ }
+ aggregate->count--;
+ }
+ }
+
+ /* If this node is suppressed, process the change. */
+ if (match)
+ bgp_process (bgp, rn, afi, safi);
+ }
+ bgp_unlock_node (top);
+
+ /* Delete aggregate route from BGP table. */
+ rn = bgp_node_get (table, p);
+
+ for (ri = rn->info; ri; ri = ri->next)
+ if (ri->peer == bgp->peer_self
+ && ri->type == ZEBRA_ROUTE_BGP
+ && ri->sub_type == BGP_ROUTE_AGGREGATE)
+ break;
+
+ /* Withdraw static BGP route from routing table. */
+ if (ri)
+ {
+ UNSET_FLAG (ri->flags, BGP_INFO_VALID);
+ bgp_process (bgp, rn, afi, safi);
+ bgp_info_delete (rn, ri);
+ bgp_info_free (ri);
+ bgp_unlock_node (rn);
+ }
+
+ /* Unlock bgp_node_lookup. */
+ bgp_unlock_node (rn);
+}
+
+/* Aggregate route attribute. */
+#define AGGREGATE_SUMMARY_ONLY 1
+#define AGGREGATE_AS_SET 1
+
+int
+bgp_aggregate_set (struct vty *vty, char *prefix_str, afi_t afi, safi_t safi,
+ u_char summary_only, u_char as_set)
+{
+ int ret;
+ struct prefix p;
+ struct bgp_node *rn;
+ struct bgp *bgp;
+ struct bgp_aggregate *aggregate;
+
+ /* Convert string to prefix structure. */
+ ret = str2prefix (prefix_str, &p);
+ if (!ret)
+ {
+ vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ apply_mask (&p);
+
+ /* Get BGP structure. */
+ bgp = vty->index;
+
+ /* Old configuration check. */
+ rn = bgp_node_get (bgp->aggregate[afi][safi], &p);
+
+ if (rn->info)
+ {
+ vty_out (vty, "There is already same aggregate network.%s", VTY_NEWLINE);
+ bgp_unlock_node (rn);
+ return CMD_WARNING;
+ }
+
+ /* Make aggregate address structure. */
+ aggregate = bgp_aggregate_new ();
+ aggregate->summary_only = summary_only;
+ aggregate->as_set = as_set;
+ aggregate->safi = safi;
+ rn->info = aggregate;
+
+ /* Aggregate address insert into BGP routing table. */
+ if (safi & SAFI_UNICAST)
+ bgp_aggregate_add (bgp, &p, afi, SAFI_UNICAST, aggregate);
+ if (safi & SAFI_MULTICAST)
+ bgp_aggregate_add (bgp, &p, afi, SAFI_MULTICAST, aggregate);
+
+ return CMD_SUCCESS;
+}
+
+int
+bgp_aggregate_unset (struct vty *vty, char *prefix_str, afi_t afi, safi_t safi)
+{
+ int ret;
+ struct prefix p;
+ struct bgp_node *rn;
+ struct bgp *bgp;
+ struct bgp_aggregate *aggregate;
+
+ /* Convert string to prefix structure. */
+ ret = str2prefix (prefix_str, &p);
+ if (!ret)
+ {
+ vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ apply_mask (&p);
+
+ /* Get BGP structure. */
+ bgp = vty->index;
+
+ /* Old configuration check. */
+ rn = bgp_node_lookup (bgp->aggregate[afi][safi], &p);
+ if (! rn)
+ {
+ vty_out (vty, "%% There is no aggregate-address configuration.%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ aggregate = rn->info;
+ if (aggregate->safi & SAFI_UNICAST)
+ bgp_aggregate_delete (bgp, &p, afi, SAFI_UNICAST, aggregate);
+ if (aggregate->safi & SAFI_MULTICAST)
+ bgp_aggregate_delete (bgp, &p, afi, SAFI_MULTICAST, aggregate);
+
+ /* Unlock aggregate address configuration. */
+ rn->info = NULL;
+ bgp_aggregate_free (aggregate);
+ bgp_unlock_node (rn);
+ bgp_unlock_node (rn);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (aggregate_address,
+ aggregate_address_cmd,
+ "aggregate-address A.B.C.D/M",
+ "Configure BGP aggregate entries\n"
+ "Aggregate prefix\n")
+{
+ return bgp_aggregate_set (vty, argv[0], AFI_IP, bgp_node_safi (vty), 0, 0);
+}
+
+DEFUN (aggregate_address_mask,
+ aggregate_address_mask_cmd,
+ "aggregate-address A.B.C.D A.B.C.D",
+ "Configure BGP aggregate entries\n"
+ "Aggregate address\n"
+ "Aggregate mask\n")
+{
+ int ret;
+ char prefix_str[BUFSIZ];
+
+ ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
+
+ if (! ret)
+ {
+ vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return bgp_aggregate_set (vty, prefix_str, AFI_IP, bgp_node_safi (vty),
+ 0, 0);
+}
+
+DEFUN (aggregate_address_summary_only,
+ aggregate_address_summary_only_cmd,
+ "aggregate-address A.B.C.D/M summary-only",
+ "Configure BGP aggregate entries\n"
+ "Aggregate prefix\n"
+ "Filter more specific routes from updates\n")
+{
+ return bgp_aggregate_set (vty, argv[0], AFI_IP, bgp_node_safi (vty),
+ AGGREGATE_SUMMARY_ONLY, 0);
+}
+
+DEFUN (aggregate_address_mask_summary_only,
+ aggregate_address_mask_summary_only_cmd,
+ "aggregate-address A.B.C.D A.B.C.D summary-only",
+ "Configure BGP aggregate entries\n"
+ "Aggregate address\n"
+ "Aggregate mask\n"
+ "Filter more specific routes from updates\n")
+{
+ int ret;
+ char prefix_str[BUFSIZ];
+
+ ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
+
+ if (! ret)
+ {
+ vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return bgp_aggregate_set (vty, prefix_str, AFI_IP, bgp_node_safi (vty),
+ AGGREGATE_SUMMARY_ONLY, 0);
+}
+
+DEFUN (aggregate_address_as_set,
+ aggregate_address_as_set_cmd,
+ "aggregate-address A.B.C.D/M as-set",
+ "Configure BGP aggregate entries\n"
+ "Aggregate prefix\n"
+ "Generate AS set path information\n")
+{
+ return bgp_aggregate_set (vty, argv[0], AFI_IP, bgp_node_safi (vty),
+ 0, AGGREGATE_AS_SET);
+}
+
+DEFUN (aggregate_address_mask_as_set,
+ aggregate_address_mask_as_set_cmd,
+ "aggregate-address A.B.C.D A.B.C.D as-set",
+ "Configure BGP aggregate entries\n"
+ "Aggregate address\n"
+ "Aggregate mask\n"
+ "Generate AS set path information\n")
+{
+ int ret;
+ char prefix_str[BUFSIZ];
+
+ ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
+
+ if (! ret)
+ {
+ vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return bgp_aggregate_set (vty, prefix_str, AFI_IP, bgp_node_safi (vty),
+ 0, AGGREGATE_AS_SET);
+}
+
+
+DEFUN (aggregate_address_as_set_summary,
+ aggregate_address_as_set_summary_cmd,
+ "aggregate-address A.B.C.D/M as-set summary-only",
+ "Configure BGP aggregate entries\n"
+ "Aggregate prefix\n"
+ "Generate AS set path information\n"
+ "Filter more specific routes from updates\n")
+{
+ return bgp_aggregate_set (vty, argv[0], AFI_IP, bgp_node_safi (vty),
+ AGGREGATE_SUMMARY_ONLY, AGGREGATE_AS_SET);
+}
+
+ALIAS (aggregate_address_as_set_summary,
+ aggregate_address_summary_as_set_cmd,
+ "aggregate-address A.B.C.D/M summary-only as-set",
+ "Configure BGP aggregate entries\n"
+ "Aggregate prefix\n"
+ "Filter more specific routes from updates\n"
+ "Generate AS set path information\n")
+
+DEFUN (aggregate_address_mask_as_set_summary,
+ aggregate_address_mask_as_set_summary_cmd,
+ "aggregate-address A.B.C.D A.B.C.D as-set summary-only",
+ "Configure BGP aggregate entries\n"
+ "Aggregate address\n"
+ "Aggregate mask\n"
+ "Generate AS set path information\n"
+ "Filter more specific routes from updates\n")
+{
+ int ret;
+ char prefix_str[BUFSIZ];
+
+ ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
+
+ if (! ret)
+ {
+ vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return bgp_aggregate_set (vty, prefix_str, AFI_IP, bgp_node_safi (vty),
+ AGGREGATE_SUMMARY_ONLY, AGGREGATE_AS_SET);
+}
+
+ALIAS (aggregate_address_mask_as_set_summary,
+ aggregate_address_mask_summary_as_set_cmd,
+ "aggregate-address A.B.C.D A.B.C.D summary-only as-set",
+ "Configure BGP aggregate entries\n"
+ "Aggregate address\n"
+ "Aggregate mask\n"
+ "Filter more specific routes from updates\n"
+ "Generate AS set path information\n")
+
+DEFUN (no_aggregate_address,
+ no_aggregate_address_cmd,
+ "no aggregate-address A.B.C.D/M",
+ NO_STR
+ "Configure BGP aggregate entries\n"
+ "Aggregate prefix\n")
+{
+ return bgp_aggregate_unset (vty, argv[0], AFI_IP, bgp_node_safi (vty));
+}
+
+ALIAS (no_aggregate_address,
+ no_aggregate_address_summary_only_cmd,
+ "no aggregate-address A.B.C.D/M summary-only",
+ NO_STR
+ "Configure BGP aggregate entries\n"
+ "Aggregate prefix\n"
+ "Filter more specific routes from updates\n")
+
+ALIAS (no_aggregate_address,
+ no_aggregate_address_as_set_cmd,
+ "no aggregate-address A.B.C.D/M as-set",
+ NO_STR
+ "Configure BGP aggregate entries\n"
+ "Aggregate prefix\n"
+ "Generate AS set path information\n")
+
+ALIAS (no_aggregate_address,
+ no_aggregate_address_as_set_summary_cmd,
+ "no aggregate-address A.B.C.D/M as-set summary-only",
+ NO_STR
+ "Configure BGP aggregate entries\n"
+ "Aggregate prefix\n"
+ "Generate AS set path information\n"
+ "Filter more specific routes from updates\n")
+
+ALIAS (no_aggregate_address,
+ no_aggregate_address_summary_as_set_cmd,
+ "no aggregate-address A.B.C.D/M summary-only as-set",
+ NO_STR
+ "Configure BGP aggregate entries\n"
+ "Aggregate prefix\n"
+ "Filter more specific routes from updates\n"
+ "Generate AS set path information\n")
+
+DEFUN (no_aggregate_address_mask,
+ no_aggregate_address_mask_cmd,
+ "no aggregate-address A.B.C.D A.B.C.D",
+ NO_STR
+ "Configure BGP aggregate entries\n"
+ "Aggregate address\n"
+ "Aggregate mask\n")
+{
+ int ret;
+ char prefix_str[BUFSIZ];
+
+ ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
+
+ if (! ret)
+ {
+ vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return bgp_aggregate_unset (vty, prefix_str, AFI_IP, bgp_node_safi (vty));
+}
+
+ALIAS (no_aggregate_address_mask,
+ no_aggregate_address_mask_summary_only_cmd,
+ "no aggregate-address A.B.C.D A.B.C.D summary-only",
+ NO_STR
+ "Configure BGP aggregate entries\n"
+ "Aggregate address\n"
+ "Aggregate mask\n"
+ "Filter more specific routes from updates\n")
+
+ALIAS (no_aggregate_address_mask,
+ no_aggregate_address_mask_as_set_cmd,
+ "no aggregate-address A.B.C.D A.B.C.D as-set",
+ NO_STR
+ "Configure BGP aggregate entries\n"
+ "Aggregate address\n"
+ "Aggregate mask\n"
+ "Generate AS set path information\n")
+
+ALIAS (no_aggregate_address_mask,
+ no_aggregate_address_mask_as_set_summary_cmd,
+ "no aggregate-address A.B.C.D A.B.C.D as-set summary-only",
+ NO_STR
+ "Configure BGP aggregate entries\n"
+ "Aggregate address\n"
+ "Aggregate mask\n"
+ "Generate AS set path information\n"
+ "Filter more specific routes from updates\n")
+
+ALIAS (no_aggregate_address_mask,
+ no_aggregate_address_mask_summary_as_set_cmd,
+ "no aggregate-address A.B.C.D A.B.C.D summary-only as-set",
+ NO_STR
+ "Configure BGP aggregate entries\n"
+ "Aggregate address\n"
+ "Aggregate mask\n"
+ "Filter more specific routes from updates\n"
+ "Generate AS set path information\n")
+
+#ifdef HAVE_IPV6
+DEFUN (ipv6_aggregate_address,
+ ipv6_aggregate_address_cmd,
+ "aggregate-address X:X::X:X/M",
+ "Configure BGP aggregate entries\n"
+ "Aggregate prefix\n")
+{
+ return bgp_aggregate_set (vty, argv[0], AFI_IP6, SAFI_UNICAST, 0, 0);
+}
+
+DEFUN (ipv6_aggregate_address_summary_only,
+ ipv6_aggregate_address_summary_only_cmd,
+ "aggregate-address X:X::X:X/M summary-only",
+ "Configure BGP aggregate entries\n"
+ "Aggregate prefix\n"
+ "Filter more specific routes from updates\n")
+{
+ return bgp_aggregate_set (vty, argv[0], AFI_IP6, SAFI_UNICAST,
+ AGGREGATE_SUMMARY_ONLY, 0);
+}
+
+DEFUN (no_ipv6_aggregate_address,
+ no_ipv6_aggregate_address_cmd,
+ "no aggregate-address X:X::X:X/M",
+ NO_STR
+ "Configure BGP aggregate entries\n"
+ "Aggregate prefix\n")
+{
+ return bgp_aggregate_unset (vty, argv[0], AFI_IP6, SAFI_UNICAST);
+}
+
+DEFUN (no_ipv6_aggregate_address_summary_only,
+ no_ipv6_aggregate_address_summary_only_cmd,
+ "no aggregate-address X:X::X:X/M summary-only",
+ NO_STR
+ "Configure BGP aggregate entries\n"
+ "Aggregate prefix\n"
+ "Filter more specific routes from updates\n")
+{
+ return bgp_aggregate_unset (vty, argv[0], AFI_IP6, SAFI_UNICAST);
+}
+
+ALIAS (ipv6_aggregate_address,
+ old_ipv6_aggregate_address_cmd,
+ "ipv6 bgp aggregate-address X:X::X:X/M",
+ IPV6_STR
+ BGP_STR
+ "Configure BGP aggregate entries\n"
+ "Aggregate prefix\n")
+
+ALIAS (ipv6_aggregate_address_summary_only,
+ old_ipv6_aggregate_address_summary_only_cmd,
+ "ipv6 bgp aggregate-address X:X::X:X/M summary-only",
+ IPV6_STR
+ BGP_STR
+ "Configure BGP aggregate entries\n"
+ "Aggregate prefix\n"
+ "Filter more specific routes from updates\n")
+
+ALIAS (no_ipv6_aggregate_address,
+ old_no_ipv6_aggregate_address_cmd,
+ "no ipv6 bgp aggregate-address X:X::X:X/M",
+ NO_STR
+ IPV6_STR
+ BGP_STR
+ "Configure BGP aggregate entries\n"
+ "Aggregate prefix\n")
+
+ALIAS (no_ipv6_aggregate_address_summary_only,
+ old_no_ipv6_aggregate_address_summary_only_cmd,
+ "no ipv6 bgp aggregate-address X:X::X:X/M summary-only",
+ NO_STR
+ IPV6_STR
+ BGP_STR
+ "Configure BGP aggregate entries\n"
+ "Aggregate prefix\n"
+ "Filter more specific routes from updates\n")
+#endif /* HAVE_IPV6 */
+
+/* Redistribute route treatment. */
+void
+bgp_redistribute_add (struct prefix *p, struct in_addr *nexthop,
+ u_int32_t metric, u_char type)
+{
+ struct bgp *bgp;
+ struct listnode *nn;
+ struct bgp_info *new;
+ struct bgp_info *bi;
+ struct bgp_info info;
+ struct bgp_node *bn;
+ struct attr attr;
+ struct attr attr_new;
+ struct attr *new_attr;
+ afi_t afi;
+ int ret;
+
+ /* Make default attribute. */
+ bgp_attr_default_set (&attr, BGP_ORIGIN_INCOMPLETE);
+ if (nexthop)
+ attr.nexthop = *nexthop;
+
+ attr.med = metric;
+ attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
+
+ LIST_LOOP (bm->bgp, bgp, nn)
+ {
+ afi = family2afi (p->family);
+
+ if (bgp->redist[afi][type])
+ {
+ /* Copy attribute for modification. */
+ attr_new = attr;
+
+ if (bgp->redist_metric_flag[afi][type])
+ attr_new.med = bgp->redist_metric[afi][type];
+
+ /* Apply route-map. */
+ if (bgp->rmap[afi][type].map)
+ {
+ info.peer = bgp->peer_self;
+ info.attr = &attr_new;
+
+ ret = route_map_apply (bgp->rmap[afi][type].map, p, RMAP_BGP,
+ &info);
+ if (ret == RMAP_DENYMATCH)
+ {
+ /* Free uninterned attribute. */
+ bgp_attr_flush (&attr_new);
+
+ /* Unintern original. */
+ aspath_unintern (attr.aspath);
+ bgp_redistribute_delete (p, type);
+ return;
+ }
+ }
+
+ bn = bgp_afi_node_get (bgp, afi, SAFI_UNICAST, p, NULL);
+ new_attr = bgp_attr_intern (&attr_new);
+
+ for (bi = bn->info; bi; bi = bi->next)
+ if (bi->peer == bgp->peer_self
+ && bi->sub_type == BGP_ROUTE_REDISTRIBUTE)
+ break;
+
+ if (bi)
+ {
+ if (attrhash_cmp (bi->attr, new_attr))
+ {
+ bgp_attr_unintern (new_attr);
+ aspath_unintern (attr.aspath);
+ bgp_unlock_node (bn);
+ return;
+ }
+ else
+ {
+ /* The attribute is changed. */
+ SET_FLAG (bi->flags, BGP_INFO_ATTR_CHANGED);
+
+ /* Rewrite BGP route information. */
+ bgp_aggregate_decrement (bgp, p, bi, afi, SAFI_UNICAST);
+ bgp_attr_unintern (bi->attr);
+ bi->attr = new_attr;
+ bi->uptime = time (NULL);
+
+ /* Process change. */
+ bgp_aggregate_increment (bgp, p, bi, afi, SAFI_UNICAST);
+ bgp_process (bgp, bn, afi, SAFI_UNICAST);
+ bgp_unlock_node (bn);
+ aspath_unintern (attr.aspath);
+ return;
+ }
+ }
+
+ new = bgp_info_new ();
+ new->type = type;
+ new->sub_type = BGP_ROUTE_REDISTRIBUTE;
+ new->peer = bgp->peer_self;
+ SET_FLAG (new->flags, BGP_INFO_VALID);
+ new->attr = new_attr;
+ new->uptime = time (NULL);
+
+ bgp_aggregate_increment (bgp, p, new, afi, SAFI_UNICAST);
+ bgp_info_add (bn, new);
+ bgp_process (bgp, bn, afi, SAFI_UNICAST);
+ }
+ }
+
+ /* Unintern original. */
+ aspath_unintern (attr.aspath);
+}
+
+void
+bgp_redistribute_delete (struct prefix *p, u_char type)
+{
+ struct bgp *bgp;
+ struct listnode *nn;
+ afi_t afi;
+ struct bgp_node *rn;
+ struct bgp_info *ri;
+
+ LIST_LOOP (bm->bgp, bgp, nn)
+ {
+ afi = family2afi (p->family);
+
+ if (bgp->redist[afi][type])
+ {
+ rn = bgp_afi_node_get (bgp, afi, SAFI_UNICAST, p, NULL);
+
+ for (ri = rn->info; ri; ri = ri->next)
+ if (ri->peer == bgp->peer_self
+ && ri->type == type)
+ break;
+
+ if (ri)
+ {
+ bgp_aggregate_decrement (bgp, p, ri, afi, SAFI_UNICAST);
+ UNSET_FLAG (ri->flags, BGP_INFO_VALID);
+ bgp_process (bgp, rn, afi, SAFI_UNICAST);
+ bgp_info_delete (rn, ri);
+ bgp_info_free (ri);
+ bgp_unlock_node (rn);
+ }
+ bgp_unlock_node (rn);
+ }
+ }
+}
+
+/* Withdraw specified route type's route. */
+void
+bgp_redistribute_withdraw (struct bgp *bgp, afi_t afi, int type)
+{
+ struct bgp_node *rn;
+ struct bgp_info *ri;
+ struct bgp_table *table;
+
+ table = bgp->rib[afi][SAFI_UNICAST];
+
+ for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
+ {
+ for (ri = rn->info; ri; ri = ri->next)
+ if (ri->peer == bgp->peer_self
+ && ri->type == type)
+ break;
+
+ if (ri)
+ {
+ bgp_aggregate_decrement (bgp, &rn->p, ri, afi, SAFI_UNICAST);
+ UNSET_FLAG (ri->flags, BGP_INFO_VALID);
+ bgp_process (bgp, rn, afi, SAFI_UNICAST);
+ bgp_info_delete (rn, ri);
+ bgp_info_free (ri);
+ bgp_unlock_node (rn);
+ }
+ }
+}
+
+/* Static function to display route. */
+void
+route_vty_out_route (struct prefix *p, struct vty *vty)
+{
+ int len;
+ u_int32_t destination;
+ char buf[BUFSIZ];
+
+ if (p->family == AF_INET)
+ {
+ len = vty_out (vty, "%s", inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ));
+ destination = ntohl (p->u.prefix4.s_addr);
+
+ if ((IN_CLASSC (destination) && p->prefixlen == 24)
+ || (IN_CLASSB (destination) && p->prefixlen == 16)
+ || (IN_CLASSA (destination) && p->prefixlen == 8)
+ || p->u.prefix4.s_addr == 0)
+ {
+ /* When mask is natural, mask is not displayed. */
+ }
+ else
+ len += vty_out (vty, "/%d", p->prefixlen);
+ }
+ else
+ len = vty_out (vty, "%s/%d", inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
+ p->prefixlen);
+
+ len = 17 - len;
+ if (len < 1)
+ vty_out (vty, "%s%*s", VTY_NEWLINE, 20, " ");
+ else
+ vty_out (vty, "%*s", len, " ");
+}
+
+/* Calculate line number of output data. */
+int
+vty_calc_line (struct vty *vty, unsigned long length)
+{
+ return vty->width ? (((vty->obuf->length - length) / vty->width) + 1) : 1;
+}
+
+enum bgp_display_type
+{
+ normal_list,
+};
+
+/* called from terminal list command */
+int
+route_vty_out (struct vty *vty, struct prefix *p,
+ struct bgp_info *binfo, int display, safi_t safi)
+{
+ struct attr *attr;
+ unsigned long length = 0;
+
+ length = vty->obuf->length;
+
+ /* Route status display. */
+ if (binfo->suppress)
+ vty_out (vty, "s");
+ else if (! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
+ vty_out (vty, "*");
+ else
+ vty_out (vty, " ");
+
+ /* Selected */
+ if (CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
+ vty_out (vty, "h");
+ else if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED))
+ vty_out (vty, "d");
+ else if (CHECK_FLAG (binfo->flags, BGP_INFO_SELECTED))
+ vty_out (vty, ">");
+ else
+ vty_out (vty, " ");
+
+ /* Internal route. */
+ if ((binfo->peer->as) && (binfo->peer->as == binfo->peer->local_as))
+ vty_out (vty, "i");
+ else
+ vty_out (vty, " ");
+
+ /* print prefix and mask */
+ if (! display)
+ route_vty_out_route (p, vty);
+ else
+ vty_out (vty, "%*s", 17, " ");
+
+ /* Print attribute */
+ attr = binfo->attr;
+ if (attr)
+ {
+ if (p->family == AF_INET)
+ {
+ if (safi == SAFI_MPLS_VPN)
+ vty_out (vty, "%-16s", inet_ntoa (attr->mp_nexthop_global_in));
+ else
+ vty_out (vty, "%-16s", inet_ntoa (attr->nexthop));
+ }
+#ifdef HAVE_IPV6
+ else if (p->family == AF_INET6)
+ {
+ int len;
+ char buf[BUFSIZ];
+
+ len = vty_out (vty, "%s",
+ inet_ntop (AF_INET6, &attr->mp_nexthop_global, buf, BUFSIZ));
+ len = 16 - len;
+ if (len < 1)
+ vty_out (vty, "%s%*s", VTY_NEWLINE, 36, " ");
+ else
+ vty_out (vty, "%*s", len, " ");
+ }
+#endif /* HAVE_IPV6 */
+
+ if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
+ vty_out (vty, "%10d", attr->med);
+ else
+ vty_out (vty, " ");
+
+ if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
+ vty_out (vty, "%7d", attr->local_pref);
+ else
+ vty_out (vty, " ");
+
+ vty_out (vty, "%7u ",attr->weight);
+
+ /* Print aspath */
+ if (attr->aspath)
+ aspath_print_vty (vty, attr->aspath);
+
+ /* Print origin */
+ if (strlen (attr->aspath->str) == 0)
+ vty_out (vty, "%s", bgp_origin_str[attr->origin]);
+ else
+ vty_out (vty, " %s", bgp_origin_str[attr->origin]);
+ }
+ vty_out (vty, "%s", VTY_NEWLINE);
+
+ return vty_calc_line (vty, length);
+}
+
+/* called from terminal list command */
+void
+route_vty_out_tmp (struct vty *vty, struct prefix *p,
+ struct attr *attr, safi_t safi)
+{
+ /* Route status display. */
+ vty_out (vty, "*");
+ vty_out (vty, ">");
+ vty_out (vty, " ");
+
+ /* print prefix and mask */
+ route_vty_out_route (p, vty);
+
+ /* Print attribute */
+ if (attr)
+ {
+ if (p->family == AF_INET)
+ {
+ if (safi == SAFI_MPLS_VPN)
+ vty_out (vty, "%-16s", inet_ntoa (attr->mp_nexthop_global_in));
+ else
+ vty_out (vty, "%-16s", inet_ntoa (attr->nexthop));
+ }
+#ifdef HAVE_IPV6
+ else if (p->family == AF_INET6)
+ {
+ int len;
+ char buf[BUFSIZ];
+
+ len = vty_out (vty, "%s",
+ inet_ntop (AF_INET6, &attr->mp_nexthop_global, buf, BUFSIZ));
+ len = 16 - len;
+ if (len < 1)
+ vty_out (vty, "%s%*s", VTY_NEWLINE, 36, " ");
+ else
+ vty_out (vty, "%*s", len, " ");
+ }
+#endif /* HAVE_IPV6 */
+
+ if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
+ vty_out (vty, "%10d", attr->med);
+ else
+ vty_out (vty, " ");
+
+ if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
+ vty_out (vty, "%7d", attr->local_pref);
+ else
+ vty_out (vty, " ");
+
+ vty_out (vty, "%7d ",attr->weight);
+
+ /* Print aspath */
+ if (attr->aspath)
+ aspath_print_vty (vty, attr->aspath);
+
+ /* Print origin */
+ if (strlen (attr->aspath->str) == 0)
+ vty_out (vty, "%s", bgp_origin_str[attr->origin]);
+ else
+ vty_out (vty, " %s", bgp_origin_str[attr->origin]);
+ }
+
+ vty_out (vty, "%s", VTY_NEWLINE);
+}
+
+int
+route_vty_out_tag (struct vty *vty, struct prefix *p,
+ struct bgp_info *binfo, int display, safi_t safi)
+{
+ struct attr *attr;
+ unsigned long length = 0;
+ u_int32_t label = 0;
+
+ length = vty->obuf->length;
+
+ /* Route status display. */
+ if (binfo->suppress)
+ vty_out (vty, "s");
+ else if (! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
+ vty_out (vty, "*");
+ else
+ vty_out (vty, " ");
+
+ /* Selected */
+ if (CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
+ vty_out (vty, "h");
+ else if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED))
+ vty_out (vty, "d");
+ else if (CHECK_FLAG (binfo->flags, BGP_INFO_SELECTED))
+ vty_out (vty, ">");
+ else
+ vty_out (vty, " ");
+
+ /* Internal route. */
+ if ((binfo->peer->as) && (binfo->peer->as == binfo->peer->local_as))
+ vty_out (vty, "i");
+ else
+ vty_out (vty, " ");
+
+ /* print prefix and mask */
+ if (! display)
+ route_vty_out_route (p, vty);
+ else
+ vty_out (vty, "%*s", 17, " ");
+
+ /* Print attribute */
+ attr = binfo->attr;
+ if (attr)
+ {
+ if (p->family == AF_INET)
+ {
+ if (safi == SAFI_MPLS_VPN)
+ vty_out (vty, "%-16s", inet_ntoa (attr->mp_nexthop_global_in));
+ else
+ vty_out (vty, "%-16s", inet_ntoa (attr->nexthop));
+ }
+#ifdef HAVE_IPV6
+ else if (p->family == AF_INET6)
+ {
+ char buf[BUFSIZ];
+ char buf1[BUFSIZ];
+ if (attr->mp_nexthop_len == 16)
+ vty_out (vty, "%s",
+ inet_ntop (AF_INET6, &attr->mp_nexthop_global, buf, BUFSIZ));
+ else if (attr->mp_nexthop_len == 32)
+ vty_out (vty, "%s(%s)",
+ inet_ntop (AF_INET6, &attr->mp_nexthop_global, buf, BUFSIZ),
+ inet_ntop (AF_INET6, &attr->mp_nexthop_local, buf1, BUFSIZ));
+
+ }
+#endif /* HAVE_IPV6 */
+ }
+
+ label = decode_label (binfo->tag);
+
+ vty_out (vty, "notag/%d", label);
+
+ vty_out (vty, "%s", VTY_NEWLINE);
+
+ return vty_calc_line (vty, length);
+}
+
+/* dampening route */
+int
+damp_route_vty_out (struct vty *vty, struct prefix *p,
+ struct bgp_info *binfo, int display, safi_t safi)
+{
+ struct attr *attr;
+ unsigned long length = 0;
+ int len;
+
+ length = vty->obuf->length;
+
+ /* Route status display. */
+ if (binfo->suppress)
+ vty_out (vty, "s");
+ else if (! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
+ vty_out (vty, "*");
+ else
+ vty_out (vty, " ");
+
+ /* Selected */
+ if (CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
+ vty_out (vty, "h");
+ else if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED))
+ vty_out (vty, "d");
+ else if (CHECK_FLAG (binfo->flags, BGP_INFO_SELECTED))
+ vty_out (vty, ">");
+ else
+ vty_out (vty, " ");
+
+ vty_out (vty, " ");
+
+ /* print prefix and mask */
+ if (! display)
+ route_vty_out_route (p, vty);
+ else
+ vty_out (vty, "%*s", 17, " ");
+
+ len = vty_out (vty, "%s", binfo->peer->host);
+ len = 17 - len;
+ if (len < 1)
+ vty_out (vty, "%s%*s", VTY_NEWLINE, 34, " ");
+ else
+ vty_out (vty, "%*s", len, " ");
+
+ vty_out (vty, "%s ", bgp_damp_reuse_time_vty (vty, binfo));
+
+ /* Print attribute */
+ attr = binfo->attr;
+ if (attr)
+ {
+ /* Print aspath */
+ if (attr->aspath)
+ aspath_print_vty (vty, attr->aspath);
+
+ /* Print origin */
+ if (strlen (attr->aspath->str) == 0)
+ vty_out (vty, "%s", bgp_origin_str[attr->origin]);
+ else
+ vty_out (vty, " %s", bgp_origin_str[attr->origin]);
+ }
+ vty_out (vty, "%s", VTY_NEWLINE);
+
+ return vty_calc_line (vty, length);
+}
+
+#define BGP_UPTIME_LEN 25
+
+/* flap route */
+int
+flap_route_vty_out (struct vty *vty, struct prefix *p,
+ struct bgp_info *binfo, int display, safi_t safi)
+{
+ struct attr *attr;
+ struct bgp_damp_info *bdi;
+ unsigned long length = 0;
+ char timebuf[BGP_UPTIME_LEN];
+ int len;
+
+ length = vty->obuf->length;
+ bdi = binfo->damp_info;
+
+ /* Route status display. */
+ if (binfo->suppress)
+ vty_out (vty, "s");
+ else if (! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
+ vty_out (vty, "*");
+ else
+ vty_out (vty, " ");
+
+ /* Selected */
+ if (CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
+ vty_out (vty, "h");
+ else if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED))
+ vty_out (vty, "d");
+ else if (CHECK_FLAG (binfo->flags, BGP_INFO_SELECTED))
+ vty_out (vty, ">");
+ else
+ vty_out (vty, " ");
+
+ vty_out (vty, " ");
+
+ /* print prefix and mask */
+ if (! display)
+ route_vty_out_route (p, vty);
+ else
+ vty_out (vty, "%*s", 17, " ");
+
+ len = vty_out (vty, "%s", binfo->peer->host);
+ len = 16 - len;
+ if (len < 1)
+ vty_out (vty, "%s%*s", VTY_NEWLINE, 33, " ");
+ else
+ vty_out (vty, "%*s", len, " ");
+
+ len = vty_out (vty, "%d", bdi->flap);
+ len = 5 - len;
+ if (len < 1)
+ vty_out (vty, " ");
+ else
+ vty_out (vty, "%*s ", len, " ");
+
+ vty_out (vty, "%s ", peer_uptime (bdi->start_time,
+ timebuf, BGP_UPTIME_LEN));
+
+ if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED)
+ && ! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
+ vty_out (vty, "%s ", bgp_damp_reuse_time_vty (vty, binfo));
+ else
+ vty_out (vty, "%*s ", 8, " ");
+
+ /* Print attribute */
+ attr = binfo->attr;
+ if (attr)
+ {
+ /* Print aspath */
+ if (attr->aspath)
+ aspath_print_vty (vty, attr->aspath);
+
+ /* Print origin */
+ if (strlen (attr->aspath->str) == 0)
+ vty_out (vty, "%s", bgp_origin_str[attr->origin]);
+ else
+ vty_out (vty, " %s", bgp_origin_str[attr->origin]);
+ }
+ vty_out (vty, "%s", VTY_NEWLINE);
+
+ return vty_calc_line (vty, length);
+}
+
+void
+route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
+ struct bgp_info *binfo, afi_t afi, safi_t safi)
+{
+ char buf[INET6_ADDRSTRLEN];
+ char buf1[BUFSIZ];
+ struct attr *attr;
+ int sockunion_vty_out (struct vty *, union sockunion *);
+
+ attr = binfo->attr;
+
+ if (attr)
+ {
+ /* Line1 display AS-path, Aggregator */
+ if (attr->aspath)
+ {
+ vty_out (vty, " ");
+ if (attr->aspath->length == 0)
+ vty_out (vty, "Local");
+ else
+ aspath_print_vty (vty, attr->aspath);
+ }
+
+ if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR)
+ || CHECK_FLAG (binfo->peer->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT)
+ || CHECK_FLAG (binfo->peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
+ || CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY)
+ || CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED))
+ {
+ vty_out (vty, ",");
+
+ if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))
+ vty_out (vty, " (aggregated by %d %s)", attr->aggregator_as,
+ inet_ntoa (attr->aggregator_addr));
+ if (CHECK_FLAG (binfo->peer->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT))
+ vty_out (vty, " (Received from a RR-client)");
+ if (CHECK_FLAG (binfo->peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
+ vty_out (vty, " (Received from a RS-client)");
+ if (CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
+ vty_out (vty, " (history entry)");
+ else if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED))
+ vty_out (vty, " (suppressed due to dampening)");
+ }
+ vty_out (vty, "%s", VTY_NEWLINE);
+
+ /* Line2 display Next-hop, Neighbor, Router-id */
+ if (p->family == AF_INET)
+ {
+ vty_out (vty, " %s", safi == SAFI_MPLS_VPN ?
+ inet_ntoa (attr->mp_nexthop_global_in) :
+ inet_ntoa (attr->nexthop));
+ }
+#ifdef HAVE_IPV6
+ else
+ {
+ vty_out (vty, " %s",
+ inet_ntop (AF_INET6, &attr->mp_nexthop_global,
+ buf, INET6_ADDRSTRLEN));
+ }
+#endif /* HAVE_IPV6 */
+
+ if (binfo->peer == bgp->peer_self)
+ {
+ vty_out (vty, " from %s ",
+ p->family == AF_INET ? "0.0.0.0" : "::");
+ vty_out (vty, "(%s)", inet_ntoa(bgp->router_id));
+ }
+ else
+ {
+ if (! CHECK_FLAG (binfo->flags, BGP_INFO_VALID))
+ vty_out (vty, " (inaccessible)");
+ else if (binfo->igpmetric)
+ vty_out (vty, " (metric %d)", binfo->igpmetric);
+ vty_out (vty, " from %s", sockunion2str (&binfo->peer->su, buf, SU_ADDRSTRLEN));
+ if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
+ vty_out (vty, " (%s)", inet_ntoa (attr->originator_id));
+ else
+ vty_out (vty, " (%s)", inet_ntop (AF_INET, &binfo->peer->remote_id, buf1, BUFSIZ));
+ }
+ vty_out (vty, "%s", VTY_NEWLINE);
+
+#ifdef HAVE_IPV6
+ /* display nexthop local */
+ if (attr->mp_nexthop_len == 32)
+ {
+ vty_out (vty, " (%s)%s",
+ inet_ntop (AF_INET6, &attr->mp_nexthop_local,
+ buf, INET6_ADDRSTRLEN),
+ VTY_NEWLINE);
+ }
+#endif /* HAVE_IPV6 */
+
+ /* Line 3 display Origin, Med, Locpref, Weight, valid, Int/Ext/Local, Atomic, best */
+ vty_out (vty, " Origin %s", bgp_origin_long_str[attr->origin]);
+
+ if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
+ vty_out (vty, ", metric %d", attr->med);
+
+ if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
+ vty_out (vty, ", localpref %d", attr->local_pref);
+ else
+ vty_out (vty, ", localpref %d", bgp->default_local_pref);
+
+ if (attr->weight != 0)
+ vty_out (vty, ", weight %d", attr->weight);
+
+ if (! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
+ vty_out (vty, ", valid");
+
+ if (binfo->peer != bgp->peer_self)
+ {
+ if (binfo->peer->as == binfo->peer->local_as)
+ vty_out (vty, ", internal");
+ else
+ vty_out (vty, ", %s",
+ (bgp_confederation_peers_check(bgp, binfo->peer->as) ? "confed-external" : "external"));
+ }
+ else if (binfo->sub_type == BGP_ROUTE_AGGREGATE)
+ vty_out (vty, ", aggregated, local");
+ else if (binfo->type != ZEBRA_ROUTE_BGP)
+ vty_out (vty, ", sourced");
+ else
+ vty_out (vty, ", sourced, local");
+
+ if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
+ vty_out (vty, ", atomic-aggregate");
+
+ if (CHECK_FLAG (binfo->flags, BGP_INFO_SELECTED))
+ vty_out (vty, ", best");
+
+ vty_out (vty, "%s", VTY_NEWLINE);
+
+ /* Line 4 display Community */
+ if (attr->community)
+ vty_out (vty, " Community: %s%s", attr->community->str,
+ VTY_NEWLINE);
+
+ /* Line 5 display Extended-community */
+ if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))
+ vty_out (vty, " Extended Community: %s%s", attr->ecommunity->str,
+ VTY_NEWLINE);
+
+ /* Line 6 display Originator, Cluster-id */
+ if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) ||
+ (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)))
+ {
+ if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
+ vty_out (vty, " Originator: %s", inet_ntoa (attr->originator_id));
+
+ if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))
+ {
+ int i;
+ vty_out (vty, ", Cluster list: ");
+ for (i = 0; i < attr->cluster->length / 4; i++)
+ vty_out (vty, "%s ", inet_ntoa (attr->cluster->list[i]));
+ }
+ vty_out (vty, "%s", VTY_NEWLINE);
+ }
+
+ if (binfo->damp_info)
+ bgp_damp_info_vty (vty, binfo);
+
+ /* Line 7 display Uptime */
+ vty_out (vty, " Last update: %s", ctime (&binfo->uptime));
+ }
+ vty_out (vty, "%s", VTY_NEWLINE);
+}
+
+#define BGP_SHOW_HEADER " Network Next Hop Metric LocPrf Weight Path%s"
+#define BGP_SHOW_DAMP_HEADER " Network From Reuse Path%s"
+#define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path%s"
+
+enum bgp_show_type
+{
+ bgp_show_type_normal,
+ bgp_show_type_regexp,
+ bgp_show_type_prefix_list,
+ bgp_show_type_filter_list,
+ bgp_show_type_route_map,
+ bgp_show_type_neighbor,
+ bgp_show_type_cidr_only,
+ bgp_show_type_prefix_longer,
+ bgp_show_type_community_all,
+ bgp_show_type_community,
+ bgp_show_type_community_exact,
+ bgp_show_type_community_list,
+ bgp_show_type_community_list_exact,
+ bgp_show_type_flap_statistics,
+ bgp_show_type_flap_address,
+ bgp_show_type_flap_prefix,
+ bgp_show_type_flap_cidr_only,
+ bgp_show_type_flap_regexp,
+ bgp_show_type_flap_filter_list,
+ bgp_show_type_flap_prefix_list,
+ bgp_show_type_flap_prefix_longer,
+ bgp_show_type_flap_route_map,
+ bgp_show_type_flap_neighbor,
+ bgp_show_type_dampend_paths,
+ bgp_show_type_damp_neighbor
+};
+
+int
+bgp_show_callback (struct vty *vty, int unlock)
+{
+ struct bgp_node *rn;
+ struct bgp_info *ri;
+ int count;
+ int limit;
+ int display;
+
+ rn = vty->output_rn;
+ count = 0;
+ limit = ((vty->lines == 0)
+ ? 10 : (vty->lines > 0
+ ? vty->lines : vty->height - 2));
+ limit = limit > 0 ? limit : 2;
+
+ /* Quit of display. */
+ if (unlock && rn)
+ {
+ bgp_unlock_node (rn);
+ if (vty->output_clean)
+ (*vty->output_clean) (vty);
+ vty->output_rn = NULL;
+ vty->output_func = NULL;
+ vty->output_clean = NULL;
+ vty->output_arg = NULL;
+ return 0;
+ }
+
+ for (; rn; rn = bgp_route_next (rn))
+ if (rn->info != NULL)
+ {
+ display = 0;
+
+ for (ri = rn->info; ri; ri = ri->next)
+ {
+ if (vty->output_type == bgp_show_type_flap_statistics
+ || vty->output_type == bgp_show_type_flap_address
+ || vty->output_type == bgp_show_type_flap_prefix
+ || vty->output_type == bgp_show_type_flap_cidr_only
+ || vty->output_type == bgp_show_type_flap_regexp
+ || vty->output_type == bgp_show_type_flap_filter_list
+ || vty->output_type == bgp_show_type_flap_prefix_list
+ || vty->output_type == bgp_show_type_flap_prefix_longer
+ || vty->output_type == bgp_show_type_flap_route_map
+ || vty->output_type == bgp_show_type_flap_neighbor
+ || vty->output_type == bgp_show_type_dampend_paths
+ || vty->output_type == bgp_show_type_damp_neighbor)
+ {
+ if (! ri->damp_info)
+ continue;
+ }
+ if (vty->output_type == bgp_show_type_regexp
+ || vty->output_type == bgp_show_type_flap_regexp)
+ {
+ regex_t *regex = vty->output_arg;
+
+ if (bgp_regexec (regex, ri->attr->aspath) == REG_NOMATCH)
+ continue;
+ }
+ if (vty->output_type == bgp_show_type_prefix_list
+ || vty->output_type == bgp_show_type_flap_prefix_list)
+ {
+ struct prefix_list *plist = vty->output_arg;
+
+ if (prefix_list_apply (plist, &rn->p) != PREFIX_PERMIT)
+ continue;
+ }
+ if (vty->output_type == bgp_show_type_filter_list
+ || vty->output_type == bgp_show_type_flap_filter_list)
+ {
+ struct as_list *as_list = vty->output_arg;
+
+ if (as_list_apply (as_list, ri->attr->aspath) != AS_FILTER_PERMIT)
+ continue;
+ }
+ if (vty->output_type == bgp_show_type_route_map
+ || vty->output_type == bgp_show_type_flap_route_map)
+ {
+ struct route_map *rmap = vty->output_arg;
+ struct bgp_info binfo;
+ struct attr dummy_attr;
+ int ret;
+
+ dummy_attr = *ri->attr;
+ binfo.peer = ri->peer;
+ binfo.attr = &dummy_attr;
+
+ ret = route_map_apply (rmap, &rn->p, RMAP_BGP, &binfo);
+
+ if (ret == RMAP_DENYMATCH)
+ continue;
+ }
+ if (vty->output_type == bgp_show_type_neighbor
+ || vty->output_type == bgp_show_type_flap_neighbor
+ || vty->output_type == bgp_show_type_damp_neighbor)
+ {
+ union sockunion *su = vty->output_arg;
+
+ if (ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su))
+ continue;
+ }
+ if (vty->output_type == bgp_show_type_cidr_only
+ || vty->output_type == bgp_show_type_flap_cidr_only)
+ {
+ u_int32_t destination;
+
+ destination = ntohl (rn->p.u.prefix4.s_addr);
+ if (IN_CLASSC (destination) && rn->p.prefixlen == 24)
+ continue;
+ if (IN_CLASSB (destination) && rn->p.prefixlen == 16)
+ continue;
+ if (IN_CLASSA (destination) && rn->p.prefixlen == 8)
+ continue;
+ }
+ if (vty->output_type == bgp_show_type_prefix_longer
+ || vty->output_type == bgp_show_type_flap_prefix_longer)
+ {
+ struct prefix *p = vty->output_arg;
+
+ if (! prefix_match (p, &rn->p))
+ continue;
+ }
+ if (vty->output_type == bgp_show_type_community_all)
+ {
+ if (! ri->attr->community)
+ continue;
+ }
+ if (vty->output_type == bgp_show_type_community)
+ {
+ struct community *com = vty->output_arg;
+
+ if (! ri->attr->community ||
+ ! community_match (ri->attr->community, com))
+ continue;
+ }
+ if (vty->output_type == bgp_show_type_community_exact)
+ {
+ struct community *com = vty->output_arg;
+
+ if (! ri->attr->community ||
+ ! community_cmp (ri->attr->community, com))
+ continue;
+ }
+ if (vty->output_type == bgp_show_type_community_list)
+ {
+ struct community_list *list = vty->output_arg;
+
+ if (! community_list_match (ri->attr->community, list))
+ continue;
+ }
+ if (vty->output_type == bgp_show_type_community_list_exact)
+ {
+ struct community_list *list = vty->output_arg;
+
+ if (! community_list_exact_match (ri->attr->community, list))
+ continue;
+ }
+ if (vty->output_type == bgp_show_type_flap_address
+ || vty->output_type == bgp_show_type_flap_prefix)
+ {
+ struct prefix *p = vty->output_arg;
+
+ if (! prefix_match (&rn->p, p))
+ continue;
+
+ if (vty->output_type == bgp_show_type_flap_prefix)
+ if (p->prefixlen != rn->p.prefixlen)
+ continue;
+ }
+ if (vty->output_type == bgp_show_type_dampend_paths
+ || vty->output_type == bgp_show_type_damp_neighbor)
+ {
+ if (! CHECK_FLAG (ri->flags, BGP_INFO_DAMPED)
+ || CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
+ continue;
+ }
+
+ if (vty->output_type == bgp_show_type_dampend_paths
+ || vty->output_type == bgp_show_type_damp_neighbor)
+ count += damp_route_vty_out (vty, &rn->p, ri, display, SAFI_UNICAST);
+ else if (vty->output_type == bgp_show_type_flap_statistics
+ || vty->output_type == bgp_show_type_flap_address
+ || vty->output_type == bgp_show_type_flap_prefix
+ || vty->output_type == bgp_show_type_flap_cidr_only
+ || vty->output_type == bgp_show_type_flap_regexp
+ || vty->output_type == bgp_show_type_flap_filter_list
+ || vty->output_type == bgp_show_type_flap_prefix_list
+ || vty->output_type == bgp_show_type_flap_prefix_longer
+ || vty->output_type == bgp_show_type_flap_route_map
+ || vty->output_type == bgp_show_type_flap_neighbor)
+ count += flap_route_vty_out (vty, &rn->p, ri, display, SAFI_UNICAST);
+ else
+ count += route_vty_out (vty, &rn->p, ri, display, SAFI_UNICAST);
+ display++;
+ }
+
+ if (display)
+ vty->output_count++;
+
+ /* Remember current pointer then suspend output. */
+ if (count >= limit)
+ {
+ vty->status = VTY_CONTINUE;
+ vty->output_rn = bgp_route_next (rn);;
+ vty->output_func = bgp_show_callback;
+ return 0;
+ }
+ }
+
+ /* Total line display. */
+ if (vty->output_count)
+ vty_out (vty, "%sTotal number of prefixes %ld%s",
+ VTY_NEWLINE, vty->output_count, VTY_NEWLINE);
+
+ if (vty->output_clean)
+ (*vty->output_clean) (vty);
+
+ vty->status = VTY_CONTINUE;
+ vty->output_rn = NULL;
+ vty->output_func = NULL;
+ vty->output_clean = NULL;
+ vty->output_arg = NULL;
+
+ return 0;
+}
+
+int
+bgp_show (struct vty *vty, char *view_name, afi_t afi, safi_t safi,
+ enum bgp_show_type type)
+{
+ struct bgp *bgp;
+ struct bgp_info *ri;
+ struct bgp_node *rn;
+ struct bgp_table *table;
+ int header = 1;
+ int count;
+ int limit;
+ int display;
+
+ limit = ((vty->lines == 0)
+ ? 10 : (vty->lines > 0
+ ? vty->lines : vty->height - 2));
+ limit = limit > 0 ? limit : 2;
+
+ /* BGP structure lookup. */
+ if (view_name)
+ {
+ bgp = bgp_lookup_by_name (view_name);
+ if (bgp == NULL)
+ {
+ vty_out (vty, "Can't find BGP view %s%s", view_name, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+ else
+ {
+ bgp = bgp_get_default ();
+ if (bgp == NULL)
+ {
+ vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+
+ count = 0;
+
+ /* This is first entry point, so reset total line. */
+ vty->output_count = 0;
+ vty->output_type = type;
+
+ table = bgp->rib[afi][safi];
+
+ /* Start processing of routes. */
+ for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
+ if (rn->info != NULL)
+ {
+ display = 0;
+
+ for (ri = rn->info; ri; ri = ri->next)
+ {
+ if (vty->output_type == bgp_show_type_flap_statistics
+ || type == bgp_show_type_flap_address
+ || type == bgp_show_type_flap_prefix
+ || type == bgp_show_type_flap_cidr_only
+ || type == bgp_show_type_flap_regexp
+ || type == bgp_show_type_flap_filter_list
+ || type == bgp_show_type_flap_prefix_list
+ || type == bgp_show_type_flap_prefix_longer
+ || type == bgp_show_type_flap_route_map
+ || type == bgp_show_type_flap_neighbor
+ || type == bgp_show_type_dampend_paths
+ || type == bgp_show_type_damp_neighbor)
+ {
+ if (! ri->damp_info)
+ continue;
+ }
+ if (type == bgp_show_type_regexp
+ || type == bgp_show_type_flap_regexp)
+ {
+ regex_t *regex = vty->output_arg;
+
+ if (bgp_regexec (regex, ri->attr->aspath) == REG_NOMATCH)
+ continue;
+ }
+ if (type == bgp_show_type_prefix_list
+ || type == bgp_show_type_flap_prefix_list)
+ {
+ struct prefix_list *plist = vty->output_arg;
+
+ if (prefix_list_apply (plist, &rn->p) != PREFIX_PERMIT)
+ continue;
+ }
+ if (type == bgp_show_type_filter_list
+ || type == bgp_show_type_flap_filter_list)
+ {
+ struct as_list *as_list = vty->output_arg;
+
+ if (as_list_apply (as_list, ri->attr->aspath) != AS_FILTER_PERMIT)
+ continue;
+ }
+ if (type == bgp_show_type_route_map
+ || type == bgp_show_type_flap_route_map)
+ {
+ struct route_map *rmap = vty->output_arg;
+ struct bgp_info binfo;
+ struct attr dummy_attr;
+ int ret;
+
+ dummy_attr = *ri->attr;
+ binfo.peer = ri->peer;
+ binfo.attr = &dummy_attr;
+
+ ret = route_map_apply (rmap, &rn->p, RMAP_BGP, &binfo);
+
+ if (ret == RMAP_DENYMATCH)
+ continue;
+ }
+ if (type == bgp_show_type_neighbor
+ || type == bgp_show_type_flap_neighbor
+ || type == bgp_show_type_damp_neighbor)
+ {
+ union sockunion *su = vty->output_arg;
+
+ if (ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su))
+ continue;
+ }
+ if (type == bgp_show_type_cidr_only
+ || type == bgp_show_type_flap_cidr_only)
+ {
+ u_int32_t destination;
+
+ destination = ntohl (rn->p.u.prefix4.s_addr);
+ if (IN_CLASSC (destination) && rn->p.prefixlen == 24)
+ continue;
+ if (IN_CLASSB (destination) && rn->p.prefixlen == 16)
+ continue;
+ if (IN_CLASSA (destination) && rn->p.prefixlen == 8)
+ continue;
+ }
+ if (type == bgp_show_type_prefix_longer
+ || type == bgp_show_type_flap_prefix_longer)
+ {
+ struct prefix *p = vty->output_arg;
+
+ if (! prefix_match (p, &rn->p))
+ continue;
+ }
+ if (type == bgp_show_type_community_all)
+ {
+ if (! ri->attr->community)
+ continue;
+ }
+ if (type == bgp_show_type_community)
+ {
+ struct community *com = vty->output_arg;
+
+ if (! ri->attr->community ||
+ ! community_match (ri->attr->community, com))
+ continue;
+ }
+ if (type == bgp_show_type_community_exact)
+ {
+ struct community *com = vty->output_arg;
+
+ if (! ri->attr->community ||
+ ! community_cmp (ri->attr->community, com))
+ continue;
+ }
+ if (type == bgp_show_type_community_list)
+ {
+ struct community_list *list = vty->output_arg;
+
+ if (! community_list_match (ri->attr->community, list))
+ continue;
+ }
+ if (type == bgp_show_type_community_list_exact)
+ {
+ struct community_list *list = vty->output_arg;
+
+ if (! community_list_exact_match (ri->attr->community, list))
+ continue;
+ }
+ if (type == bgp_show_type_flap_address
+ || type == bgp_show_type_flap_prefix)
+ {
+ struct prefix *p = vty->output_arg;
+
+ if (! prefix_match (&rn->p, p))
+ continue;
+
+ if (type == bgp_show_type_flap_prefix)
+ if (p->prefixlen != rn->p.prefixlen)
+ continue;
+ }
+ if (type == bgp_show_type_dampend_paths
+ || type == bgp_show_type_damp_neighbor)
+ {
+ if (! CHECK_FLAG (ri->flags, BGP_INFO_DAMPED)
+ || CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
+ continue;
+ }
+
+ if (header)
+ {
+ vty_out (vty, "BGP table version is 0, local router ID is %s%s", inet_ntoa (bgp->router_id), VTY_NEWLINE);
+ vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s", VTY_NEWLINE);
+ vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s", VTY_NEWLINE, VTY_NEWLINE);
+ if (type == bgp_show_type_dampend_paths
+ || type == bgp_show_type_damp_neighbor)
+ vty_out (vty, BGP_SHOW_DAMP_HEADER, VTY_NEWLINE);
+ else if (type == bgp_show_type_flap_statistics
+ || type == bgp_show_type_flap_address
+ || type == bgp_show_type_flap_prefix
+ || type == bgp_show_type_flap_cidr_only
+ || type == bgp_show_type_flap_regexp
+ || type == bgp_show_type_flap_filter_list
+ || type == bgp_show_type_flap_prefix_list
+ || type == bgp_show_type_flap_prefix_longer
+ || type == bgp_show_type_flap_route_map
+ || type == bgp_show_type_flap_neighbor)
+ vty_out (vty, BGP_SHOW_FLAP_HEADER, VTY_NEWLINE);
+ else
+ vty_out (vty, BGP_SHOW_HEADER, VTY_NEWLINE);
+ count += 5;
+ header = 0;
+ }
+
+ if (type == bgp_show_type_dampend_paths
+ || type == bgp_show_type_damp_neighbor)
+ count += damp_route_vty_out (vty, &rn->p, ri, display, SAFI_UNICAST);
+ else if (type == bgp_show_type_flap_statistics
+ || type == bgp_show_type_flap_address
+ || type == bgp_show_type_flap_prefix
+ || type == bgp_show_type_flap_cidr_only
+ || type == bgp_show_type_flap_regexp
+ || type == bgp_show_type_flap_filter_list
+ || type == bgp_show_type_flap_prefix_list
+ || type == bgp_show_type_flap_prefix_longer
+ || type == bgp_show_type_flap_route_map
+ || type == bgp_show_type_flap_neighbor)
+ count += flap_route_vty_out (vty, &rn->p, ri, display, SAFI_UNICAST);
+ else
+ count += route_vty_out (vty, &rn->p, ri, display, SAFI_UNICAST);
+ display++;
+ }
+ if (display)
+ vty->output_count++;
+
+ /* Remember current pointer then suspend output. */
+ if (count >= limit && vty->type != VTY_SHELL_SERV)
+ {
+ vty->status = VTY_START;
+ vty->output_rn = bgp_route_next (rn);
+ vty->output_func = bgp_show_callback;
+ vty->output_type = type;
+
+ return CMD_SUCCESS;
+ }
+ }
+
+ /* No route is displayed */
+ if (vty->output_count == 0)
+ {
+ if (type == bgp_show_type_normal)
+ vty_out (vty, "No BGP network exists%s", VTY_NEWLINE);
+ }
+ else
+ vty_out (vty, "%sTotal number of prefixes %ld%s",
+ VTY_NEWLINE, vty->output_count, VTY_NEWLINE);
+
+ /* Clean up allocated resources. */
+ if (vty->output_clean)
+ (*vty->output_clean) (vty);
+
+ vty->status = VTY_START;
+ vty->output_rn = NULL;
+ vty->output_func = NULL;
+ vty->output_clean = NULL;
+ vty->output_arg = NULL;
+
+ return CMD_SUCCESS;
+}
+
+/* Header of detailed BGP route information */
+void
+route_vty_out_detail_header (struct vty *vty, struct bgp *bgp,
+ struct bgp_node *rn,
+ struct prefix_rd *prd, afi_t afi, safi_t safi)
+{
+ struct bgp_info *ri;
+ struct prefix *p;
+ struct peer *peer;
+ struct listnode *nn;
+ char buf1[INET6_ADDRSTRLEN];
+ char buf2[INET6_ADDRSTRLEN];
+ int count = 0;
+ int best = 0;
+ int suppress = 0;
+ int no_export = 0;
+ int no_advertise = 0;
+ int local_as = 0;
+ int first = 0;
+
+ p = &rn->p;
+ vty_out (vty, "BGP routing table entry for %s%s%s/%d%s",
+ (safi == SAFI_MPLS_VPN ?
+ prefix_rd2str (prd, buf1, RD_ADDRSTRLEN) : ""),
+ safi == SAFI_MPLS_VPN ? ":" : "",
+ inet_ntop (p->family, &p->u.prefix, buf2, INET6_ADDRSTRLEN),
+ p->prefixlen, VTY_NEWLINE);
+
+ for (ri = rn->info; ri; ri = ri->next)
+ {
+ count++;
+ if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED))
+ {
+ best = count;
+ if (ri->suppress)
+ suppress = 1;
+ if (ri->attr->community != NULL)
+ {
+ if (community_include (ri->attr->community, COMMUNITY_NO_ADVERTISE))
+ no_advertise = 1;
+ if (community_include (ri->attr->community, COMMUNITY_NO_EXPORT))
+ no_export = 1;
+ if (community_include (ri->attr->community, COMMUNITY_LOCAL_AS))
+ local_as = 1;
+ }
+ }
+ }
+
+ vty_out (vty, "Paths: (%d available", count);
+ if (best)
+ {
+ vty_out (vty, ", best #%d", best);
+ if (safi == SAFI_UNICAST)
+ vty_out (vty, ", table Default-IP-Routing-Table");
+ }
+ else
+ vty_out (vty, ", no best path");
+ if (no_advertise)
+ vty_out (vty, ", not advertised to any peer");
+ else if (no_export)
+ vty_out (vty, ", not advertised to EBGP peer");
+ else if (local_as)
+ vty_out (vty, ", not advertised outside local AS");
+ if (suppress)
+ vty_out (vty, ", Advertisements suppressed by an aggregate.");
+ vty_out (vty, ")%s", VTY_NEWLINE);
+
+ /* advertised peer */
+ LIST_LOOP (bgp->peer, peer, nn)
+ {
+ if (bgp_adj_out_lookup (peer, p, afi, safi, rn))
+ {
+ if (! first)
+ vty_out (vty, " Advertised to non peer-group peers:%s ", VTY_NEWLINE);
+ vty_out (vty, " %s", sockunion2str (&peer->su, buf1, SU_ADDRSTRLEN));
+ first = 1;
+ }
+ }
+ if (! first)
+ vty_out (vty, " Not advertised to any peer");
+ vty_out (vty, "%s", VTY_NEWLINE);
+}
+
+/* Display specified route of BGP table. */
+int
+bgp_show_route (struct vty *vty, char *view_name, char *ip_str,
+ afi_t afi, safi_t safi, struct prefix_rd *prd,
+ int prefix_check)
+{
+ int ret;
+ int header;
+ int display = 0;
+ struct prefix match;
+ struct bgp_node *rn;
+ struct bgp_node *rm;
+ struct bgp_info *ri;
+ struct bgp *bgp;
+ struct bgp_table *table;
+
+ /* BGP structure lookup. */
+ if (view_name)
+ {
+ bgp = bgp_lookup_by_name (view_name);
+ if (bgp == NULL)
+ {
+ vty_out (vty, "Can't find BGP view %s%s", view_name, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+ else
+ {
+ bgp = bgp_get_default ();
+ if (bgp == NULL)
+ {
+ vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+
+ /* Check IP address argument. */
+ ret = str2prefix (ip_str, &match);
+ if (! ret)
+ {
+ vty_out (vty, "address is malformed%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ match.family = afi2family (afi);
+
+ if (safi == SAFI_MPLS_VPN)
+ {
+ for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn; rn = bgp_route_next (rn))
+ {
+ if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
+ continue;
+
+ if ((table = rn->info) != NULL)
+ {
+ header = 1;
+
+ if ((rm = bgp_node_match (table, &match)) != NULL)
+ {
+ if (prefix_check && rm->p.prefixlen != match.prefixlen)
+ continue;
+
+ for (ri = rm->info; ri; ri = ri->next)
+ {
+ if (header)
+ {
+ route_vty_out_detail_header (vty, bgp, rm, (struct prefix_rd *)&rn->p,
+ AFI_IP, SAFI_MPLS_VPN);
+
+ header = 0;
+ }
+ display++;
+ route_vty_out_detail (vty, bgp, &rm->p, ri, AFI_IP, SAFI_MPLS_VPN);
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ header = 1;
+
+ if ((rn = bgp_node_match (bgp->rib[afi][safi], &match)) != NULL)
+ {
+ if (! prefix_check || rn->p.prefixlen == match.prefixlen)
+ {
+ for (ri = rn->info; ri; ri = ri->next)
+ {
+ if (header)
+ {
+ route_vty_out_detail_header (vty, bgp, rn, NULL, afi, safi);
+ header = 0;
+ }
+ display++;
+ route_vty_out_detail (vty, bgp, &rn->p, ri, afi, safi);
+ }
+ }
+ }
+ }
+
+ if (! display)
+ {
+ vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return CMD_SUCCESS;
+}
+
+/* BGP route print out function. */
+DEFUN (show_ip_bgp,
+ show_ip_bgp_cmd,
+ "show ip bgp",
+ SHOW_STR
+ IP_STR
+ BGP_STR)
+{
+ return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST, bgp_show_type_normal);
+}
+
+DEFUN (show_ip_bgp_ipv4,
+ show_ip_bgp_ipv4_cmd,
+ "show ip bgp ipv4 (unicast|multicast)",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n")
+{
+ if (strncmp (argv[0], "m", 1) == 0)
+ return bgp_show (vty, NULL, AFI_IP, SAFI_MULTICAST, bgp_show_type_normal);
+
+ return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST, bgp_show_type_normal);
+}
+
+DEFUN (show_ip_bgp_route,
+ show_ip_bgp_route_cmd,
+ "show ip bgp A.B.C.D",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Network in the BGP routing table to display\n")
+{
+ return bgp_show_route (vty, NULL, argv[0], AFI_IP, SAFI_UNICAST, NULL, 0);
+}
+
+DEFUN (show_ip_bgp_ipv4_route,
+ show_ip_bgp_ipv4_route_cmd,
+ "show ip bgp ipv4 (unicast|multicast) A.B.C.D",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Network in the BGP routing table to display\n")
+{
+ if (strncmp (argv[0], "m", 1) == 0)
+ return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_MULTICAST, NULL, 0);
+
+ return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_UNICAST, NULL, 0);
+}
+
+DEFUN (show_ip_bgp_vpnv4_all_route,
+ show_ip_bgp_vpnv4_all_route_cmd,
+ "show ip bgp vpnv4 all A.B.C.D",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display VPNv4 NLRI specific information\n"
+ "Display information about all VPNv4 NLRIs\n"
+ "Network in the BGP routing table to display\n")
+{
+ return bgp_show_route (vty, NULL, argv[0], AFI_IP, SAFI_MPLS_VPN, NULL, 0);
+}
+
+DEFUN (show_ip_bgp_vpnv4_rd_route,
+ show_ip_bgp_vpnv4_rd_route_cmd,
+ "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn A.B.C.D",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display VPNv4 NLRI specific information\n"
+ "Display information for a route distinguisher\n"
+ "VPN Route Distinguisher\n"
+ "Network in the BGP routing table to display\n")
+{
+ int ret;
+ struct prefix_rd prd;
+
+ ret = str2prefix_rd (argv[0], &prd);
+ if (! ret)
+ {
+ vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_MPLS_VPN, &prd, 0);
+}
+
+DEFUN (show_ip_bgp_prefix,
+ show_ip_bgp_prefix_cmd,
+ "show ip bgp A.B.C.D/M",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
+{
+ return bgp_show_route (vty, NULL, argv[0], AFI_IP, SAFI_UNICAST, NULL, 1);
+}
+
+DEFUN (show_ip_bgp_ipv4_prefix,
+ show_ip_bgp_ipv4_prefix_cmd,
+ "show ip bgp ipv4 (unicast|multicast) A.B.C.D/M",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
+{
+ if (strncmp (argv[0], "m", 1) == 0)
+ return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_MULTICAST, NULL, 1);
+
+ return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_UNICAST, NULL, 1);
+}
+
+DEFUN (show_ip_bgp_vpnv4_all_prefix,
+ show_ip_bgp_vpnv4_all_prefix_cmd,
+ "show ip bgp vpnv4 all A.B.C.D/M",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display VPNv4 NLRI specific information\n"
+ "Display information about all VPNv4 NLRIs\n"
+ "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
+{
+ return bgp_show_route (vty, NULL, argv[0], AFI_IP, SAFI_MPLS_VPN, NULL, 1);
+}
+
+DEFUN (show_ip_bgp_vpnv4_rd_prefix,
+ show_ip_bgp_vpnv4_rd_prefix_cmd,
+ "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn A.B.C.D/M",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display VPNv4 NLRI specific information\n"
+ "Display information for a route distinguisher\n"
+ "VPN Route Distinguisher\n"
+ "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
+{
+ int ret;
+ struct prefix_rd prd;
+
+ ret = str2prefix_rd (argv[0], &prd);
+ if (! ret)
+ {
+ vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_MPLS_VPN, &prd, 1);
+}
+
+DEFUN (show_ip_bgp_view,
+ show_ip_bgp_view_cmd,
+ "show ip bgp view WORD",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "BGP view\n"
+ "BGP view name\n")
+{
+ return bgp_show (vty, argv[0], AFI_IP, SAFI_UNICAST, bgp_show_type_normal);
+}
+
+DEFUN (show_ip_bgp_view_route,
+ show_ip_bgp_view_route_cmd,
+ "show ip bgp view WORD A.B.C.D",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "BGP view\n"
+ "BGP view name\n"
+ "Network in the BGP routing table to display\n")
+{
+ return bgp_show_route (vty, argv[0], argv[1], AFI_IP, SAFI_UNICAST, NULL, 0);
+}
+
+DEFUN (show_ip_bgp_view_prefix,
+ show_ip_bgp_view_prefix_cmd,
+ "show ip bgp view WORD A.B.C.D/M",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "BGP view\n"
+ "BGP view name\n"
+ "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
+{
+ return bgp_show_route (vty, argv[0], argv[1], AFI_IP, SAFI_UNICAST, NULL, 1);
+}
+
+#ifdef HAVE_IPV6
+DEFUN (show_bgp,
+ show_bgp_cmd,
+ "show bgp",
+ SHOW_STR
+ BGP_STR)
+{
+ return bgp_show (vty, NULL, AFI_IP6, SAFI_UNICAST, bgp_show_type_normal);
+}
+
+ALIAS (show_bgp,
+ show_bgp_ipv6_cmd,
+ "show bgp ipv6",
+ SHOW_STR
+ BGP_STR
+ "Address family\n")
+
+/* old command */
+DEFUN (show_ipv6_bgp,
+ show_ipv6_bgp_cmd,
+ "show ipv6 bgp",
+ SHOW_STR
+ IP_STR
+ BGP_STR)
+{
+ return bgp_show (vty, NULL, AFI_IP6, SAFI_UNICAST, bgp_show_type_normal);
+}
+
+DEFUN (show_bgp_route,
+ show_bgp_route_cmd,
+ "show bgp X:X::X:X",
+ SHOW_STR
+ BGP_STR
+ "Network in the BGP routing table to display\n")
+{
+ return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST, NULL, 0);
+}
+
+ALIAS (show_bgp_route,
+ show_bgp_ipv6_route_cmd,
+ "show bgp ipv6 X:X::X:X",
+ SHOW_STR
+ BGP_STR
+ "Address family\n"
+ "Network in the BGP routing table to display\n")
+
+/* old command */
+DEFUN (show_ipv6_bgp_route,
+ show_ipv6_bgp_route_cmd,
+ "show ipv6 bgp X:X::X:X",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Network in the BGP routing table to display\n")
+{
+ return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST, NULL, 0);
+}
+
+DEFUN (show_bgp_prefix,
+ show_bgp_prefix_cmd,
+ "show bgp X:X::X:X/M",
+ SHOW_STR
+ BGP_STR
+ "IPv6 prefix <network>/<length>\n")
+{
+ return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST, NULL, 1);
+}
+
+ALIAS (show_bgp_prefix,
+ show_bgp_ipv6_prefix_cmd,
+ "show bgp ipv6 X:X::X:X/M",
+ SHOW_STR
+ BGP_STR
+ "Address family\n"
+ "IPv6 prefix <network>/<length>\n")
+
+/* old command */
+DEFUN (show_ipv6_bgp_prefix,
+ show_ipv6_bgp_prefix_cmd,
+ "show ipv6 bgp X:X::X:X/M",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n")
+{
+ return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST, NULL, 1);
+}
+
+/* old command */
+DEFUN (show_ipv6_mbgp,
+ show_ipv6_mbgp_cmd,
+ "show ipv6 mbgp",
+ SHOW_STR
+ IP_STR
+ MBGP_STR)
+{
+ return bgp_show (vty, NULL, AFI_IP6, SAFI_MULTICAST, bgp_show_type_normal);
+}
+
+/* old command */
+DEFUN (show_ipv6_mbgp_route,
+ show_ipv6_mbgp_route_cmd,
+ "show ipv6 mbgp X:X::X:X",
+ SHOW_STR
+ IP_STR
+ MBGP_STR
+ "Network in the MBGP routing table to display\n")
+{
+ return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_MULTICAST, NULL, 0);
+}
+
+/* old command */
+DEFUN (show_ipv6_mbgp_prefix,
+ show_ipv6_mbgp_prefix_cmd,
+ "show ipv6 mbgp X:X::X:X/M",
+ SHOW_STR
+ IP_STR
+ MBGP_STR
+ "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n")
+{
+ return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_MULTICAST, NULL, 1);
+}
+#endif
+
+void
+bgp_show_regexp_clean (struct vty *vty)
+{
+ bgp_regex_free (vty->output_arg);
+}
+
+int
+bgp_show_regexp (struct vty *vty, int argc, char **argv, afi_t afi,
+ safi_t safi, enum bgp_show_type type)
+{
+ int i;
+ struct buffer *b;
+ char *regstr;
+ int first;
+ regex_t *regex;
+
+ first = 0;
+ b = buffer_new (1024);
+ for (i = 0; i < argc; i++)
+ {
+ if (first)
+ buffer_putc (b, ' ');
+ else
+ {
+ if ((strcmp (argv[i], "unicast") == 0) || (strcmp (argv[i], "multicast") == 0))
+ continue;
+ first = 1;
+ }
+
+ buffer_putstr (b, argv[i]);
+ }
+ buffer_putc (b, '\0');
+
+ regstr = buffer_getstr (b);
+ buffer_free (b);
+
+ regex = bgp_regcomp (regstr);
+ if (! regex)
+ {
+ vty_out (vty, "Can't compile regexp %s%s", argv[0],
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ vty->output_arg = regex;
+ vty->output_clean = bgp_show_regexp_clean;
+
+ return bgp_show (vty, NULL, afi, safi, type);
+}
+
+DEFUN (show_ip_bgp_regexp,
+ show_ip_bgp_regexp_cmd,
+ "show ip bgp regexp .LINE",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display routes matching the AS path regular expression\n"
+ "A regular-expression to match the BGP AS paths\n")
+{
+ return bgp_show_regexp (vty, argc, argv, AFI_IP, SAFI_UNICAST,
+ bgp_show_type_regexp);
+}
+
+DEFUN (show_ip_bgp_flap_regexp,
+ show_ip_bgp_flap_regexp_cmd,
+ "show ip bgp flap-statistics regexp .LINE",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display flap statistics of routes\n"
+ "Display routes matching the AS path regular expression\n"
+ "A regular-expression to match the BGP AS paths\n")
+{
+ return bgp_show_regexp (vty, argc, argv, AFI_IP, SAFI_UNICAST,
+ bgp_show_type_flap_regexp);
+}
+
+DEFUN (show_ip_bgp_ipv4_regexp,
+ show_ip_bgp_ipv4_regexp_cmd,
+ "show ip bgp ipv4 (unicast|multicast) regexp .LINE",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Display routes matching the AS path regular expression\n"
+ "A regular-expression to match the BGP AS paths\n")
+{
+ if (strncmp (argv[0], "m", 1) == 0)
+ return bgp_show_regexp (vty, argc, argv, AFI_IP, SAFI_MULTICAST,
+ bgp_show_type_regexp);
+
+ return bgp_show_regexp (vty, argc, argv, AFI_IP, SAFI_UNICAST,
+ bgp_show_type_regexp);
+}
+
+#ifdef HAVE_IPV6
+DEFUN (show_bgp_regexp,
+ show_bgp_regexp_cmd,
+ "show bgp regexp .LINE",
+ SHOW_STR
+ BGP_STR
+ "Display routes matching the AS path regular expression\n"
+ "A regular-expression to match the BGP AS paths\n")
+{
+ return bgp_show_regexp (vty, argc, argv, AFI_IP6, SAFI_UNICAST,
+ bgp_show_type_regexp);
+}
+
+ALIAS (show_bgp_regexp,
+ show_bgp_ipv6_regexp_cmd,
+ "show bgp ipv6 regexp .LINE",
+ SHOW_STR
+ BGP_STR
+ "Address family\n"
+ "Display routes matching the AS path regular expression\n"
+ "A regular-expression to match the BGP AS paths\n")
+
+/* old command */
+DEFUN (show_ipv6_bgp_regexp,
+ show_ipv6_bgp_regexp_cmd,
+ "show ipv6 bgp regexp .LINE",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display routes matching the AS path regular expression\n"
+ "A regular-expression to match the BGP AS paths\n")
+{
+ return bgp_show_regexp (vty, argc, argv, AFI_IP6, SAFI_UNICAST,
+ bgp_show_type_regexp);
+}
+
+/* old command */
+DEFUN (show_ipv6_mbgp_regexp,
+ show_ipv6_mbgp_regexp_cmd,
+ "show ipv6 mbgp regexp .LINE",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display routes matching the AS path regular expression\n"
+ "A regular-expression to match the MBGP AS paths\n")
+{
+ return bgp_show_regexp (vty, argc, argv, AFI_IP6, SAFI_MULTICAST,
+ bgp_show_type_regexp);
+}
+#endif /* HAVE_IPV6 */
+
+int
+bgp_show_prefix_list (struct vty *vty, char *prefix_list_str, afi_t afi,
+ safi_t safi, enum bgp_show_type type)
+{
+ struct prefix_list *plist;
+
+ plist = prefix_list_lookup (afi, prefix_list_str);
+ if (plist == NULL)
+ {
+ vty_out (vty, "%% %s is not a valid prefix-list name%s",
+ prefix_list_str, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ vty->output_arg = plist;
+
+ return bgp_show (vty, NULL, afi, safi, type);
+}
+
+DEFUN (show_ip_bgp_prefix_list,
+ show_ip_bgp_prefix_list_cmd,
+ "show ip bgp prefix-list WORD",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display routes conforming to the prefix-list\n"
+ "IP prefix-list name\n")
+{
+ return bgp_show_prefix_list (vty, argv[0], AFI_IP, SAFI_UNICAST,
+ bgp_show_type_prefix_list);
+}
+
+DEFUN (show_ip_bgp_flap_prefix_list,
+ show_ip_bgp_flap_prefix_list_cmd,
+ "show ip bgp flap-statistics prefix-list WORD",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display flap statistics of routes\n"
+ "Display routes conforming to the prefix-list\n"
+ "IP prefix-list name\n")
+{
+ return bgp_show_prefix_list (vty, argv[0], AFI_IP, SAFI_UNICAST,
+ bgp_show_type_flap_prefix_list);
+}
+
+DEFUN (show_ip_bgp_ipv4_prefix_list,
+ show_ip_bgp_ipv4_prefix_list_cmd,
+ "show ip bgp ipv4 (unicast|multicast) prefix-list WORD",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Display routes conforming to the prefix-list\n"
+ "IP prefix-list name\n")
+{
+ if (strncmp (argv[0], "m", 1) == 0)
+ return bgp_show_prefix_list (vty, argv[1], AFI_IP, SAFI_MULTICAST,
+ bgp_show_type_prefix_list);
+
+ return bgp_show_prefix_list (vty, argv[1], AFI_IP, SAFI_UNICAST,
+ bgp_show_type_prefix_list);
+}
+
+#ifdef HAVE_IPV6
+DEFUN (show_bgp_prefix_list,
+ show_bgp_prefix_list_cmd,
+ "show bgp prefix-list WORD",
+ SHOW_STR
+ BGP_STR
+ "Display routes conforming to the prefix-list\n"
+ "IPv6 prefix-list name\n")
+{
+ return bgp_show_prefix_list (vty, argv[0], AFI_IP6, SAFI_UNICAST,
+ bgp_show_type_prefix_list);
+}
+
+ALIAS (show_bgp_prefix_list,
+ show_bgp_ipv6_prefix_list_cmd,
+ "show bgp ipv6 prefix-list WORD",
+ SHOW_STR
+ BGP_STR
+ "Address family\n"
+ "Display routes conforming to the prefix-list\n"
+ "IPv6 prefix-list name\n")
+
+/* old command */
+DEFUN (show_ipv6_bgp_prefix_list,
+ show_ipv6_bgp_prefix_list_cmd,
+ "show ipv6 bgp prefix-list WORD",
+ SHOW_STR
+ IPV6_STR
+ BGP_STR
+ "Display routes matching the prefix-list\n"
+ "IPv6 prefix-list name\n")
+{
+ return bgp_show_prefix_list (vty, argv[0], AFI_IP6, SAFI_UNICAST,
+ bgp_show_type_prefix_list);
+}
+
+/* old command */
+DEFUN (show_ipv6_mbgp_prefix_list,
+ show_ipv6_mbgp_prefix_list_cmd,
+ "show ipv6 mbgp prefix-list WORD",
+ SHOW_STR
+ IPV6_STR
+ MBGP_STR
+ "Display routes matching the prefix-list\n"
+ "IPv6 prefix-list name\n")
+{
+ return bgp_show_prefix_list (vty, argv[0], AFI_IP6, SAFI_MULTICAST,
+ bgp_show_type_prefix_list);
+}
+#endif /* HAVE_IPV6 */
+
+int
+bgp_show_filter_list (struct vty *vty, char *filter, afi_t afi,
+ safi_t safi, enum bgp_show_type type)
+{
+ struct as_list *as_list;
+
+ as_list = as_list_lookup (filter);
+ if (as_list == NULL)
+ {
+ vty_out (vty, "%% %s is not a valid AS-path access-list name%s", filter, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ vty->output_arg = as_list;
+
+ return bgp_show (vty, NULL, afi, safi, type);
+}
+
+DEFUN (show_ip_bgp_filter_list,
+ show_ip_bgp_filter_list_cmd,
+ "show ip bgp filter-list WORD",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display routes conforming to the filter-list\n"
+ "Regular expression access list name\n")
+{
+ return bgp_show_filter_list (vty, argv[0], AFI_IP, SAFI_UNICAST,
+ bgp_show_type_filter_list);
+}
+
+DEFUN (show_ip_bgp_flap_filter_list,
+ show_ip_bgp_flap_filter_list_cmd,
+ "show ip bgp flap-statistics filter-list WORD",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display flap statistics of routes\n"
+ "Display routes conforming to the filter-list\n"
+ "Regular expression access list name\n")
+{
+ return bgp_show_filter_list (vty, argv[0], AFI_IP, SAFI_UNICAST,
+ bgp_show_type_flap_filter_list);
+}
+
+DEFUN (show_ip_bgp_ipv4_filter_list,
+ show_ip_bgp_ipv4_filter_list_cmd,
+ "show ip bgp ipv4 (unicast|multicast) filter-list WORD",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Display routes conforming to the filter-list\n"
+ "Regular expression access list name\n")
+{
+ if (strncmp (argv[0], "m", 1) == 0)
+ return bgp_show_filter_list (vty, argv[1], AFI_IP, SAFI_MULTICAST,
+ bgp_show_type_filter_list);
+
+ return bgp_show_filter_list (vty, argv[1], AFI_IP, SAFI_UNICAST,
+ bgp_show_type_filter_list);
+}
+
+#ifdef HAVE_IPV6
+DEFUN (show_bgp_filter_list,
+ show_bgp_filter_list_cmd,
+ "show bgp filter-list WORD",
+ SHOW_STR
+ BGP_STR
+ "Display routes conforming to the filter-list\n"
+ "Regular expression access list name\n")
+{
+ return bgp_show_filter_list (vty, argv[0], AFI_IP6, SAFI_UNICAST,
+ bgp_show_type_filter_list);
+}
+
+ALIAS (show_bgp_filter_list,
+ show_bgp_ipv6_filter_list_cmd,
+ "show bgp ipv6 filter-list WORD",
+ SHOW_STR
+ BGP_STR
+ "Address family\n"
+ "Display routes conforming to the filter-list\n"
+ "Regular expression access list name\n")
+
+/* old command */
+DEFUN (show_ipv6_bgp_filter_list,
+ show_ipv6_bgp_filter_list_cmd,
+ "show ipv6 bgp filter-list WORD",
+ SHOW_STR
+ IPV6_STR
+ BGP_STR
+ "Display routes conforming to the filter-list\n"
+ "Regular expression access list name\n")
+{
+ return bgp_show_filter_list (vty, argv[0], AFI_IP6, SAFI_UNICAST,
+ bgp_show_type_filter_list);
+}
+
+/* old command */
+DEFUN (show_ipv6_mbgp_filter_list,
+ show_ipv6_mbgp_filter_list_cmd,
+ "show ipv6 mbgp filter-list WORD",
+ SHOW_STR
+ IPV6_STR
+ MBGP_STR
+ "Display routes conforming to the filter-list\n"
+ "Regular expression access list name\n")
+{
+ return bgp_show_filter_list (vty, argv[0], AFI_IP6, SAFI_MULTICAST,
+ bgp_show_type_filter_list);
+}
+#endif /* HAVE_IPV6 */
+
+int
+bgp_show_route_map (struct vty *vty, char *rmap_str, afi_t afi,
+ safi_t safi, enum bgp_show_type type)
+{
+ struct route_map *rmap;
+
+ rmap = route_map_lookup_by_name (rmap_str);
+ if (! rmap)
+ {
+ vty_out (vty, "%% %s is not a valid route-map name%s",
+ rmap_str, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ vty->output_arg = rmap;
+
+ return bgp_show (vty, NULL, afi, safi, type);
+}
+
+DEFUN (show_ip_bgp_route_map,
+ show_ip_bgp_route_map_cmd,
+ "show ip bgp route-map WORD",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display routes matching the route-map\n"
+ "A route-map to match on\n")
+{
+ return bgp_show_route_map (vty, argv[0], AFI_IP, SAFI_UNICAST,
+ bgp_show_type_route_map);
+}
+
+DEFUN (show_ip_bgp_flap_route_map,
+ show_ip_bgp_flap_route_map_cmd,
+ "show ip bgp flap-statistics route-map WORD",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display flap statistics of routes\n"
+ "Display routes matching the route-map\n"
+ "A route-map to match on\n")
+{
+ return bgp_show_route_map (vty, argv[0], AFI_IP, SAFI_UNICAST,
+ bgp_show_type_flap_route_map);
+}
+
+DEFUN (show_ip_bgp_ipv4_route_map,
+ show_ip_bgp_ipv4_route_map_cmd,
+ "show ip bgp ipv4 (unicast|multicast) route-map WORD",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Display routes matching the route-map\n"
+ "A route-map to match on\n")
+{
+ if (strncmp (argv[0], "m", 1) == 0)
+ return bgp_show_route_map (vty, argv[1], AFI_IP, SAFI_MULTICAST,
+ bgp_show_type_route_map);
+
+ return bgp_show_route_map (vty, argv[1], AFI_IP, SAFI_UNICAST,
+ bgp_show_type_route_map);
+}
+
+DEFUN (show_bgp_route_map,
+ show_bgp_route_map_cmd,
+ "show bgp route-map WORD",
+ SHOW_STR
+ BGP_STR
+ "Display routes matching the route-map\n"
+ "A route-map to match on\n")
+{
+ return bgp_show_route_map (vty, argv[0], AFI_IP6, SAFI_UNICAST,
+ bgp_show_type_route_map);
+}
+
+ALIAS (show_bgp_route_map,
+ show_bgp_ipv6_route_map_cmd,
+ "show bgp ipv6 route-map WORD",
+ SHOW_STR
+ BGP_STR
+ "Address family\n"
+ "Display routes matching the route-map\n"
+ "A route-map to match on\n")
+
+DEFUN (show_ip_bgp_cidr_only,
+ show_ip_bgp_cidr_only_cmd,
+ "show ip bgp cidr-only",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display only routes with non-natural netmasks\n")
+{
+ return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST,
+ bgp_show_type_cidr_only);
+}
+
+DEFUN (show_ip_bgp_flap_cidr_only,
+ show_ip_bgp_flap_cidr_only_cmd,
+ "show ip bgp flap-statistics cidr-only",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display flap statistics of routes\n"
+ "Display only routes with non-natural netmasks\n")
+{
+ return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST,
+ bgp_show_type_flap_cidr_only);
+}
+
+DEFUN (show_ip_bgp_ipv4_cidr_only,
+ show_ip_bgp_ipv4_cidr_only_cmd,
+ "show ip bgp ipv4 (unicast|multicast) cidr-only",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Display only routes with non-natural netmasks\n")
+{
+ if (strncmp (argv[0], "m", 1) == 0)
+ return bgp_show (vty, NULL, AFI_IP, SAFI_MULTICAST,
+ bgp_show_type_cidr_only);
+
+ return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST,
+ bgp_show_type_cidr_only);
+}
+
+DEFUN (show_ip_bgp_community_all,
+ show_ip_bgp_community_all_cmd,
+ "show ip bgp community",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display routes matching the communities\n")
+{
+ return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST,
+ bgp_show_type_community_all);
+}
+
+DEFUN (show_ip_bgp_ipv4_community_all,
+ show_ip_bgp_ipv4_community_all_cmd,
+ "show ip bgp ipv4 (unicast|multicast) community",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Display routes matching the communities\n")
+{
+ if (strncmp (argv[0], "m", 1) == 0)
+ return bgp_show (vty, NULL, AFI_IP, SAFI_MULTICAST,
+ bgp_show_type_community_all);
+
+ return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST,
+ bgp_show_type_community_all);
+}
+
+#ifdef HAVE_IPV6
+DEFUN (show_bgp_community_all,
+ show_bgp_community_all_cmd,
+ "show bgp community",
+ SHOW_STR
+ BGP_STR
+ "Display routes matching the communities\n")
+{
+ return bgp_show (vty, NULL, AFI_IP6, SAFI_UNICAST,
+ bgp_show_type_community_all);
+}
+
+ALIAS (show_bgp_community_all,
+ show_bgp_ipv6_community_all_cmd,
+ "show bgp ipv6 community",
+ SHOW_STR
+ BGP_STR
+ "Address family\n"
+ "Display routes matching the communities\n")
+
+/* old command */
+DEFUN (show_ipv6_bgp_community_all,
+ show_ipv6_bgp_community_all_cmd,
+ "show ipv6 bgp community",
+ SHOW_STR
+ IPV6_STR
+ BGP_STR
+ "Display routes matching the communities\n")
+{
+ return bgp_show (vty, NULL, AFI_IP6, SAFI_UNICAST,
+ bgp_show_type_community_all);
+}
+
+/* old command */
+DEFUN (show_ipv6_mbgp_community_all,
+ show_ipv6_mbgp_community_all_cmd,
+ "show ipv6 mbgp community",
+ SHOW_STR
+ IPV6_STR
+ MBGP_STR
+ "Display routes matching the communities\n")
+{
+ return bgp_show (vty, NULL, AFI_IP6, SAFI_MULTICAST,
+ bgp_show_type_community_all);
+}
+#endif /* HAVE_IPV6 */
+
+int
+bgp_show_community (struct vty *vty, int argc, char **argv, int exact,
+ u_int16_t afi, u_char safi)
+{
+ struct community *com;
+ struct buffer *b;
+ int i;
+ char *str;
+ int first = 0;
+
+ b = buffer_new (1024);
+ for (i = 0; i < argc; i++)
+ {
+ if (first)
+ buffer_putc (b, ' ');
+ else
+ {
+ if ((strcmp (argv[i], "unicast") == 0) || (strcmp (argv[i], "multicast") == 0))
+ continue;
+ first = 1;
+ }
+
+ buffer_putstr (b, argv[i]);
+ }
+ buffer_putc (b, '\0');
+
+ str = buffer_getstr (b);
+ buffer_free (b);
+
+ com = community_str2com (str);
+ free (str);
+ if (! com)
+ {
+ vty_out (vty, "%% Community malformed: %s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ vty->output_arg = com;
+
+ if (exact)
+ return bgp_show (vty, NULL, afi, safi, bgp_show_type_community_exact);
+
+ return bgp_show (vty, NULL, afi, safi, bgp_show_type_community);
+}
+
+DEFUN (show_ip_bgp_community,
+ show_ip_bgp_community_cmd,
+ "show ip bgp community (AA:NN|local-AS|no-advertise|no-export)",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n")
+{
+ return bgp_show_community (vty, argc, argv, 0, AFI_IP, SAFI_UNICAST);
+}
+
+ALIAS (show_ip_bgp_community,
+ show_ip_bgp_community2_cmd,
+ "show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n")
+
+ALIAS (show_ip_bgp_community,
+ show_ip_bgp_community3_cmd,
+ "show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n")
+
+ALIAS (show_ip_bgp_community,
+ show_ip_bgp_community4_cmd,
+ "show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n")
+
+DEFUN (show_ip_bgp_ipv4_community,
+ show_ip_bgp_ipv4_community_cmd,
+ "show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export)",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n")
+{
+ if (strncmp (argv[0], "m", 1) == 0)
+ return bgp_show_community (vty, argc, argv, 0, AFI_IP, SAFI_MULTICAST);
+
+ return bgp_show_community (vty, argc, argv, 0, AFI_IP, SAFI_UNICAST);
+}
+
+ALIAS (show_ip_bgp_ipv4_community,
+ show_ip_bgp_ipv4_community2_cmd,
+ "show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n")
+
+ALIAS (show_ip_bgp_ipv4_community,
+ show_ip_bgp_ipv4_community3_cmd,
+ "show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n")
+
+ALIAS (show_ip_bgp_ipv4_community,
+ show_ip_bgp_ipv4_community4_cmd,
+ "show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n")
+
+DEFUN (show_ip_bgp_community_exact,
+ show_ip_bgp_community_exact_cmd,
+ "show ip bgp community (AA:NN|local-AS|no-advertise|no-export) exact-match",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "Exact match of the communities")
+{
+ return bgp_show_community (vty, argc, argv, 1, AFI_IP, SAFI_UNICAST);
+}
+
+ALIAS (show_ip_bgp_community_exact,
+ show_ip_bgp_community2_exact_cmd,
+ "show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "Exact match of the communities")
+
+ALIAS (show_ip_bgp_community_exact,
+ show_ip_bgp_community3_exact_cmd,
+ "show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "Exact match of the communities")
+
+ALIAS (show_ip_bgp_community_exact,
+ show_ip_bgp_community4_exact_cmd,
+ "show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "Exact match of the communities")
+
+DEFUN (show_ip_bgp_ipv4_community_exact,
+ show_ip_bgp_ipv4_community_exact_cmd,
+ "show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) exact-match",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "Exact match of the communities")
+{
+ if (strncmp (argv[0], "m", 1) == 0)
+ return bgp_show_community (vty, argc, argv, 1, AFI_IP, SAFI_MULTICAST);
+
+ return bgp_show_community (vty, argc, argv, 1, AFI_IP, SAFI_UNICAST);
+}
+
+ALIAS (show_ip_bgp_ipv4_community_exact,
+ show_ip_bgp_ipv4_community2_exact_cmd,
+ "show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "Exact match of the communities")
+
+ALIAS (show_ip_bgp_ipv4_community_exact,
+ show_ip_bgp_ipv4_community3_exact_cmd,
+ "show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "Exact match of the communities")
+
+ALIAS (show_ip_bgp_ipv4_community_exact,
+ show_ip_bgp_ipv4_community4_exact_cmd,
+ "show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "Exact match of the communities")
+
+#ifdef HAVE_IPV6
+DEFUN (show_bgp_community,
+ show_bgp_community_cmd,
+ "show bgp community (AA:NN|local-AS|no-advertise|no-export)",
+ SHOW_STR
+ BGP_STR
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n")
+{
+ return bgp_show_community (vty, argc, argv, 0, AFI_IP6, SAFI_UNICAST);
+}
+
+ALIAS (show_bgp_community,
+ show_bgp_ipv6_community_cmd,
+ "show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export)",
+ SHOW_STR
+ BGP_STR
+ "Address family\n"
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n")
+
+ALIAS (show_bgp_community,
+ show_bgp_community2_cmd,
+ "show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
+ SHOW_STR
+ BGP_STR
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n")
+
+ALIAS (show_bgp_community,
+ show_bgp_ipv6_community2_cmd,
+ "show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
+ SHOW_STR
+ BGP_STR
+ "Address family\n"
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n")
+
+ALIAS (show_bgp_community,
+ show_bgp_community3_cmd,
+ "show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
+ SHOW_STR
+ BGP_STR
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n")
+
+ALIAS (show_bgp_community,
+ show_bgp_ipv6_community3_cmd,
+ "show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
+ SHOW_STR
+ BGP_STR
+ "Address family\n"
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n")
+
+ALIAS (show_bgp_community,
+ show_bgp_community4_cmd,
+ "show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
+ SHOW_STR
+ BGP_STR
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n")
+
+ALIAS (show_bgp_community,
+ show_bgp_ipv6_community4_cmd,
+ "show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
+ SHOW_STR
+ BGP_STR
+ "Address family\n"
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n")
+
+/* old command */
+DEFUN (show_ipv6_bgp_community,
+ show_ipv6_bgp_community_cmd,
+ "show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export)",
+ SHOW_STR
+ IPV6_STR
+ BGP_STR
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n")
+{
+ return bgp_show_community (vty, argc, argv, 0, AFI_IP6, SAFI_UNICAST);
+}
+
+/* old command */
+ALIAS (show_ipv6_bgp_community,
+ show_ipv6_bgp_community2_cmd,
+ "show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
+ SHOW_STR
+ IPV6_STR
+ BGP_STR
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n")
+
+/* old command */
+ALIAS (show_ipv6_bgp_community,
+ show_ipv6_bgp_community3_cmd,
+ "show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
+ SHOW_STR
+ IPV6_STR
+ BGP_STR
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n")
+
+/* old command */
+ALIAS (show_ipv6_bgp_community,
+ show_ipv6_bgp_community4_cmd,
+ "show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
+ SHOW_STR
+ IPV6_STR
+ BGP_STR
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n")
+
+DEFUN (show_bgp_community_exact,
+ show_bgp_community_exact_cmd,
+ "show bgp community (AA:NN|local-AS|no-advertise|no-export) exact-match",
+ SHOW_STR
+ BGP_STR
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "Exact match of the communities")
+{
+ return bgp_show_community (vty, argc, argv, 1, AFI_IP6, SAFI_UNICAST);
+}
+
+ALIAS (show_bgp_community_exact,
+ show_bgp_ipv6_community_exact_cmd,
+ "show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) exact-match",
+ SHOW_STR
+ BGP_STR
+ "Address family\n"
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "Exact match of the communities")
+
+ALIAS (show_bgp_community_exact,
+ show_bgp_community2_exact_cmd,
+ "show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
+ SHOW_STR
+ BGP_STR
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "Exact match of the communities")
+
+ALIAS (show_bgp_community_exact,
+ show_bgp_ipv6_community2_exact_cmd,
+ "show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
+ SHOW_STR
+ BGP_STR
+ "Address family\n"
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "Exact match of the communities")
+
+ALIAS (show_bgp_community_exact,
+ show_bgp_community3_exact_cmd,
+ "show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
+ SHOW_STR
+ BGP_STR
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "Exact match of the communities")
+
+ALIAS (show_bgp_community_exact,
+ show_bgp_ipv6_community3_exact_cmd,
+ "show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
+ SHOW_STR
+ BGP_STR
+ "Address family\n"
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "Exact match of the communities")
+
+ALIAS (show_bgp_community_exact,
+ show_bgp_community4_exact_cmd,
+ "show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
+ SHOW_STR
+ BGP_STR
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "Exact match of the communities")
+
+ALIAS (show_bgp_community_exact,
+ show_bgp_ipv6_community4_exact_cmd,
+ "show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
+ SHOW_STR
+ BGP_STR
+ "Address family\n"
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "Exact match of the communities")
+
+/* old command */
+DEFUN (show_ipv6_bgp_community_exact,
+ show_ipv6_bgp_community_exact_cmd,
+ "show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) exact-match",
+ SHOW_STR
+ IPV6_STR
+ BGP_STR
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "Exact match of the communities")
+{
+ return bgp_show_community (vty, argc, argv, 1, AFI_IP6, SAFI_UNICAST);
+}
+
+/* old command */
+ALIAS (show_ipv6_bgp_community_exact,
+ show_ipv6_bgp_community2_exact_cmd,
+ "show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
+ SHOW_STR
+ IPV6_STR
+ BGP_STR
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "Exact match of the communities")
+
+/* old command */
+ALIAS (show_ipv6_bgp_community_exact,
+ show_ipv6_bgp_community3_exact_cmd,
+ "show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
+ SHOW_STR
+ IPV6_STR
+ BGP_STR
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "Exact match of the communities")
+
+/* old command */
+ALIAS (show_ipv6_bgp_community_exact,
+ show_ipv6_bgp_community4_exact_cmd,
+ "show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
+ SHOW_STR
+ IPV6_STR
+ BGP_STR
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "Exact match of the communities")
+
+/* old command */
+DEFUN (show_ipv6_mbgp_community,
+ show_ipv6_mbgp_community_cmd,
+ "show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export)",
+ SHOW_STR
+ IPV6_STR
+ MBGP_STR
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n")
+{
+ return bgp_show_community (vty, argc, argv, 0, AFI_IP6, SAFI_MULTICAST);
+}
+
+/* old command */
+ALIAS (show_ipv6_mbgp_community,
+ show_ipv6_mbgp_community2_cmd,
+ "show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
+ SHOW_STR
+ IPV6_STR
+ MBGP_STR
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n")
+
+/* old command */
+ALIAS (show_ipv6_mbgp_community,
+ show_ipv6_mbgp_community3_cmd,
+ "show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
+ SHOW_STR
+ IPV6_STR
+ MBGP_STR
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n")
+
+/* old command */
+ALIAS (show_ipv6_mbgp_community,
+ show_ipv6_mbgp_community4_cmd,
+ "show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
+ SHOW_STR
+ IPV6_STR
+ MBGP_STR
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n")
+
+/* old command */
+DEFUN (show_ipv6_mbgp_community_exact,
+ show_ipv6_mbgp_community_exact_cmd,
+ "show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) exact-match",
+ SHOW_STR
+ IPV6_STR
+ MBGP_STR
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "Exact match of the communities")
+{
+ return bgp_show_community (vty, argc, argv, 1, AFI_IP6, SAFI_MULTICAST);
+}
+
+/* old command */
+ALIAS (show_ipv6_mbgp_community_exact,
+ show_ipv6_mbgp_community2_exact_cmd,
+ "show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
+ SHOW_STR
+ IPV6_STR
+ MBGP_STR
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "Exact match of the communities")
+
+/* old command */
+ALIAS (show_ipv6_mbgp_community_exact,
+ show_ipv6_mbgp_community3_exact_cmd,
+ "show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
+ SHOW_STR
+ IPV6_STR
+ MBGP_STR
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "Exact match of the communities")
+
+/* old command */
+ALIAS (show_ipv6_mbgp_community_exact,
+ show_ipv6_mbgp_community4_exact_cmd,
+ "show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
+ SHOW_STR
+ IPV6_STR
+ MBGP_STR
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "Exact match of the communities")
+#endif /* HAVE_IPV6 */
+
+int
+bgp_show_community_list (struct vty *vty, char *com, int exact,
+ u_int16_t afi, u_char safi)
+{
+ struct community_list *list;
+
+ list = community_list_lookup (bgp_clist, com, COMMUNITY_LIST_AUTO);
+ if (list == NULL)
+ {
+ vty_out (vty, "%% %s is not a valid community-list name%s", com,
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ vty->output_arg = list;
+
+ if (exact)
+ return bgp_show (vty, NULL, afi, safi, bgp_show_type_community_list_exact);
+
+ return bgp_show (vty, NULL, afi, safi, bgp_show_type_community_list);
+}
+
+DEFUN (show_ip_bgp_community_list,
+ show_ip_bgp_community_list_cmd,
+ "show ip bgp community-list WORD",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display routes matching the community-list\n"
+ "community-list name\n")
+{
+ return bgp_show_community_list (vty, argv[0], 0, AFI_IP, SAFI_UNICAST);
+}
+
+DEFUN (show_ip_bgp_ipv4_community_list,
+ show_ip_bgp_ipv4_community_list_cmd,
+ "show ip bgp ipv4 (unicast|multicast) community-list WORD",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Display routes matching the community-list\n"
+ "community-list name\n")
+{
+ if (strncmp (argv[0], "m", 1) == 0)
+ return bgp_show_community_list (vty, argv[1], 0, AFI_IP, SAFI_MULTICAST);
+
+ return bgp_show_community_list (vty, argv[1], 0, AFI_IP, SAFI_UNICAST);
+}
+
+DEFUN (show_ip_bgp_community_list_exact,
+ show_ip_bgp_community_list_exact_cmd,
+ "show ip bgp community-list WORD exact-match",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display routes matching the community-list\n"
+ "community-list name\n"
+ "Exact match of the communities\n")
+{
+ return bgp_show_community_list (vty, argv[0], 1, AFI_IP, SAFI_UNICAST);
+}
+
+DEFUN (show_ip_bgp_ipv4_community_list_exact,
+ show_ip_bgp_ipv4_community_list_exact_cmd,
+ "show ip bgp ipv4 (unicast|multicast) community-list WORD exact-match",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Display routes matching the community-list\n"
+ "community-list name\n"
+ "Exact match of the communities\n")
+{
+ if (strncmp (argv[0], "m", 1) == 0)
+ return bgp_show_community_list (vty, argv[1], 1, AFI_IP, SAFI_MULTICAST);
+
+ return bgp_show_community_list (vty, argv[1], 1, AFI_IP, SAFI_UNICAST);
+}
+
+#ifdef HAVE_IPV6
+DEFUN (show_bgp_community_list,
+ show_bgp_community_list_cmd,
+ "show bgp community-list WORD",
+ SHOW_STR
+ BGP_STR
+ "Display routes matching the community-list\n"
+ "community-list name\n")
+{
+ return bgp_show_community_list (vty, argv[0], 0, AFI_IP6, SAFI_UNICAST);
+}
+
+ALIAS (show_bgp_community_list,
+ show_bgp_ipv6_community_list_cmd,
+ "show bgp ipv6 community-list WORD",
+ SHOW_STR
+ BGP_STR
+ "Address family\n"
+ "Display routes matching the community-list\n"
+ "community-list name\n")
+
+/* old command */
+DEFUN (show_ipv6_bgp_community_list,
+ show_ipv6_bgp_community_list_cmd,
+ "show ipv6 bgp community-list WORD",
+ SHOW_STR
+ IPV6_STR
+ BGP_STR
+ "Display routes matching the community-list\n"
+ "community-list name\n")
+{
+ return bgp_show_community_list (vty, argv[0], 0, AFI_IP6, SAFI_UNICAST);
+}
+
+/* old command */
+DEFUN (show_ipv6_mbgp_community_list,
+ show_ipv6_mbgp_community_list_cmd,
+ "show ipv6 mbgp community-list WORD",
+ SHOW_STR
+ IPV6_STR
+ MBGP_STR
+ "Display routes matching the community-list\n"
+ "community-list name\n")
+{
+ return bgp_show_community_list (vty, argv[0], 0, AFI_IP6, SAFI_MULTICAST);
+}
+
+DEFUN (show_bgp_community_list_exact,
+ show_bgp_community_list_exact_cmd,
+ "show bgp community-list WORD exact-match",
+ SHOW_STR
+ BGP_STR
+ "Display routes matching the community-list\n"
+ "community-list name\n"
+ "Exact match of the communities\n")
+{
+ return bgp_show_community_list (vty, argv[0], 1, AFI_IP6, SAFI_UNICAST);
+}
+
+ALIAS (show_bgp_community_list_exact,
+ show_bgp_ipv6_community_list_exact_cmd,
+ "show bgp ipv6 community-list WORD exact-match",
+ SHOW_STR
+ BGP_STR
+ "Address family\n"
+ "Display routes matching the community-list\n"
+ "community-list name\n"
+ "Exact match of the communities\n")
+
+/* old command */
+DEFUN (show_ipv6_bgp_community_list_exact,
+ show_ipv6_bgp_community_list_exact_cmd,
+ "show ipv6 bgp community-list WORD exact-match",
+ SHOW_STR
+ IPV6_STR
+ BGP_STR
+ "Display routes matching the community-list\n"
+ "community-list name\n"
+ "Exact match of the communities\n")
+{
+ return bgp_show_community_list (vty, argv[0], 1, AFI_IP6, SAFI_UNICAST);
+}
+
+/* old command */
+DEFUN (show_ipv6_mbgp_community_list_exact,
+ show_ipv6_mbgp_community_list_exact_cmd,
+ "show ipv6 mbgp community-list WORD exact-match",
+ SHOW_STR
+ IPV6_STR
+ MBGP_STR
+ "Display routes matching the community-list\n"
+ "community-list name\n"
+ "Exact match of the communities\n")
+{
+ return bgp_show_community_list (vty, argv[0], 1, AFI_IP6, SAFI_MULTICAST);
+}
+#endif /* HAVE_IPV6 */
+
+void
+bgp_show_prefix_longer_clean (struct vty *vty)
+{
+ struct prefix *p;
+
+ p = vty->output_arg;
+ prefix_free (p);
+}
+
+int
+bgp_show_prefix_longer (struct vty *vty, char *prefix, afi_t afi,
+ safi_t safi, enum bgp_show_type type)
+{
+ int ret;
+ struct prefix *p;
+
+ p = prefix_new();
+
+ ret = str2prefix (prefix, p);
+ if (! ret)
+ {
+ vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ vty->output_arg = p;
+ vty->output_clean = bgp_show_prefix_longer_clean;
+
+ return bgp_show (vty, NULL, afi, safi, type);
+}
+
+DEFUN (show_ip_bgp_prefix_longer,
+ show_ip_bgp_prefix_longer_cmd,
+ "show ip bgp A.B.C.D/M longer-prefixes",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
+ "Display route and more specific routes\n")
+{
+ return bgp_show_prefix_longer (vty, argv[0], AFI_IP, SAFI_UNICAST,
+ bgp_show_type_prefix_longer);
+}
+
+DEFUN (show_ip_bgp_flap_prefix_longer,
+ show_ip_bgp_flap_prefix_longer_cmd,
+ "show ip bgp flap-statistics A.B.C.D/M longer-prefixes",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display flap statistics of routes\n"
+ "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
+ "Display route and more specific routes\n")
+{
+ return bgp_show_prefix_longer (vty, argv[0], AFI_IP, SAFI_UNICAST,
+ bgp_show_type_flap_prefix_longer);
+}
+
+DEFUN (show_ip_bgp_ipv4_prefix_longer,
+ show_ip_bgp_ipv4_prefix_longer_cmd,
+ "show ip bgp ipv4 (unicast|multicast) A.B.C.D/M longer-prefixes",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
+ "Display route and more specific routes\n")
+{
+ if (strncmp (argv[0], "m", 1) == 0)
+ return bgp_show_prefix_longer (vty, argv[1], AFI_IP, SAFI_MULTICAST,
+ bgp_show_type_prefix_longer);
+
+ return bgp_show_prefix_longer (vty, argv[1], AFI_IP, SAFI_UNICAST,
+ bgp_show_type_prefix_longer);
+}
+
+DEFUN (show_ip_bgp_flap_address,
+ show_ip_bgp_flap_address_cmd,
+ "show ip bgp flap-statistics A.B.C.D",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display flap statistics of routes\n"
+ "Network in the BGP routing table to display\n")
+{
+ return bgp_show_prefix_longer (vty, argv[0], AFI_IP, SAFI_UNICAST,
+ bgp_show_type_flap_address);
+}
+
+DEFUN (show_ip_bgp_flap_prefix,
+ show_ip_bgp_flap_prefix_cmd,
+ "show ip bgp flap-statistics A.B.C.D/M",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display flap statistics of routes\n"
+ "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
+{
+ return bgp_show_prefix_longer (vty, argv[0], AFI_IP, SAFI_UNICAST,
+ bgp_show_type_flap_prefix);
+}
+#ifdef HAVE_IPV6
+DEFUN (show_bgp_prefix_longer,
+ show_bgp_prefix_longer_cmd,
+ "show bgp X:X::X:X/M longer-prefixes",
+ SHOW_STR
+ BGP_STR
+ "IPv6 prefix <network>/<length>\n"
+ "Display route and more specific routes\n")
+{
+ return bgp_show_prefix_longer (vty, argv[0], AFI_IP6, SAFI_UNICAST,
+ bgp_show_type_prefix_longer);
+}
+
+ALIAS (show_bgp_prefix_longer,
+ show_bgp_ipv6_prefix_longer_cmd,
+ "show bgp ipv6 X:X::X:X/M longer-prefixes",
+ SHOW_STR
+ BGP_STR
+ "Address family\n"
+ "IPv6 prefix <network>/<length>\n"
+ "Display route and more specific routes\n")
+
+/* old command */
+DEFUN (show_ipv6_bgp_prefix_longer,
+ show_ipv6_bgp_prefix_longer_cmd,
+ "show ipv6 bgp X:X::X:X/M longer-prefixes",
+ SHOW_STR
+ IPV6_STR
+ BGP_STR
+ "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
+ "Display route and more specific routes\n")
+{
+ return bgp_show_prefix_longer (vty, argv[0], AFI_IP6, SAFI_UNICAST,
+ bgp_show_type_prefix_longer);
+}
+
+/* old command */
+DEFUN (show_ipv6_mbgp_prefix_longer,
+ show_ipv6_mbgp_prefix_longer_cmd,
+ "show ipv6 mbgp X:X::X:X/M longer-prefixes",
+ SHOW_STR
+ IPV6_STR
+ MBGP_STR
+ "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
+ "Display route and more specific routes\n")
+{
+ return bgp_show_prefix_longer (vty, argv[0], AFI_IP6, SAFI_MULTICAST,
+ bgp_show_type_prefix_longer);
+}
+#endif /* HAVE_IPV6 */
+
+void
+show_adj_route (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi,
+ int in)
+{
+ struct bgp_table *table;
+ struct bgp_adj_in *ain;
+ struct bgp_adj_out *adj;
+ unsigned long output_count;
+ struct bgp_node *rn;
+ int header1 = 1;
+ struct bgp *bgp;
+ int header2 = 1;
+
+ bgp = bgp_get_default ();
+
+ if (! bgp)
+ return;
+
+ table = bgp->rib[afi][safi];
+
+ output_count = 0;
+
+ if (! in && CHECK_FLAG (peer->af_sflags[afi][safi],
+ PEER_STATUS_DEFAULT_ORIGINATE))
+ {
+ vty_out (vty, "BGP table version is 0, local router ID is %s%s", inet_ntoa (bgp->router_id), VTY_NEWLINE);
+ vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s", VTY_NEWLINE);
+ vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s", VTY_NEWLINE, VTY_NEWLINE);
+
+ vty_out (vty, "Originating default network 0.0.0.0%s%s",
+ VTY_NEWLINE, VTY_NEWLINE);
+ header1 = 0;
+ }
+
+ for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
+ if (in)
+ {
+ for (ain = rn->adj_in; ain; ain = ain->next)
+ if (ain->peer == peer)
+ {
+ if (header1)
+ {
+ vty_out (vty, "BGP table version is 0, local router ID is %s%s", inet_ntoa (bgp->router_id), VTY_NEWLINE);
+ vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s", VTY_NEWLINE);
+ vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s", VTY_NEWLINE, VTY_NEWLINE);
+ header1 = 0;
+ }
+ if (header2)
+ {
+ vty_out (vty, BGP_SHOW_HEADER, VTY_NEWLINE);
+ header2 = 0;
+ }
+ if (ain->attr)
+ {
+ route_vty_out_tmp (vty, &rn->p, ain->attr, safi);
+ output_count++;
+ }
+ }
+ }
+ else
+ {
+ for (adj = rn->adj_out; adj; adj = adj->next)
+ if (adj->peer == peer)
+ {
+ if (header1)
+ {
+ vty_out (vty, "BGP table version is 0, local router ID is %s%s", inet_ntoa (bgp->router_id), VTY_NEWLINE);
+ vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s", VTY_NEWLINE);
+ vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s", VTY_NEWLINE, VTY_NEWLINE);
+ header1 = 0;
+ }
+ if (header2)
+ {
+ vty_out (vty, BGP_SHOW_HEADER, VTY_NEWLINE);
+ header2 = 0;
+ }
+ if (adj->attr)
+ {
+ route_vty_out_tmp (vty, &rn->p, adj->attr, safi);
+ output_count++;
+ }
+ }
+ }
+
+ if (output_count != 0)
+ vty_out (vty, "%sTotal number of prefixes %ld%s",
+ VTY_NEWLINE, output_count, VTY_NEWLINE);
+}
+
+int
+peer_adj_routes (struct vty *vty, char *ip_str, afi_t afi, safi_t safi, int in)
+{
+ int ret;
+ struct peer *peer;
+ union sockunion su;
+
+ ret = str2sockunion (ip_str, &su);
+ if (ret < 0)
+ {
+ vty_out (vty, "Malformed address: %s%s", ip_str, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ peer = peer_lookup (NULL, &su);
+ if (! peer || ! peer->afc[afi][safi])
+ {
+ vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if (in && ! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
+ {
+ vty_out (vty, "%% Inbound soft reconfiguration not enabled%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ show_adj_route (vty, peer, afi, safi, in);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (show_ip_bgp_neighbor_advertised_route,
+ show_ip_bgp_neighbor_advertised_route_cmd,
+ "show ip bgp neighbors (A.B.C.D|X:X::X:X) advertised-routes",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Detailed information on TCP and BGP neighbor connections\n"
+ "Neighbor to display information about\n"
+ "Neighbor to display information about\n"
+ "Display the routes advertised to a BGP neighbor\n")
+{
+ return peer_adj_routes (vty, argv[0], AFI_IP, SAFI_UNICAST, 0);
+}
+
+DEFUN (show_ip_bgp_ipv4_neighbor_advertised_route,
+ show_ip_bgp_ipv4_neighbor_advertised_route_cmd,
+ "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X) advertised-routes",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Detailed information on TCP and BGP neighbor connections\n"
+ "Neighbor to display information about\n"
+ "Neighbor to display information about\n"
+ "Display the routes advertised to a BGP neighbor\n")
+{
+ if (strncmp (argv[0], "m", 1) == 0)
+ return peer_adj_routes (vty, argv[1], AFI_IP, SAFI_MULTICAST, 0);
+
+ return peer_adj_routes (vty, argv[1], AFI_IP, SAFI_UNICAST, 0);
+}
+
+#ifdef HAVE_IPV6
+DEFUN (show_bgp_neighbor_advertised_route,
+ show_bgp_neighbor_advertised_route_cmd,
+ "show bgp neighbors (A.B.C.D|X:X::X:X) advertised-routes",
+ SHOW_STR
+ BGP_STR
+ "Detailed information on TCP and BGP neighbor connections\n"
+ "Neighbor to display information about\n"
+ "Neighbor to display information about\n"
+ "Display the routes advertised to a BGP neighbor\n")
+{
+ return peer_adj_routes (vty, argv[0], AFI_IP6, SAFI_UNICAST, 0);
+}
+
+ALIAS (show_bgp_neighbor_advertised_route,
+ show_bgp_ipv6_neighbor_advertised_route_cmd,
+ "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X) advertised-routes",
+ SHOW_STR
+ BGP_STR
+ "Address family\n"
+ "Detailed information on TCP and BGP neighbor connections\n"
+ "Neighbor to display information about\n"
+ "Neighbor to display information about\n"
+ "Display the routes advertised to a BGP neighbor\n")
+
+/* old command */
+DEFUN (ipv6_bgp_neighbor_advertised_route,
+ ipv6_bgp_neighbor_advertised_route_cmd,
+ "show ipv6 bgp neighbors (A.B.C.D|X:X::X:X) advertised-routes",
+ SHOW_STR
+ IPV6_STR
+ BGP_STR
+ "Detailed information on TCP and BGP neighbor connections\n"
+ "Neighbor to display information about\n"
+ "Neighbor to display information about\n"
+ "Display the routes advertised to a BGP neighbor\n")
+{
+ return peer_adj_routes (vty, argv[0], AFI_IP6, SAFI_UNICAST, 0);
+}
+
+/* old command */
+DEFUN (ipv6_mbgp_neighbor_advertised_route,
+ ipv6_mbgp_neighbor_advertised_route_cmd,
+ "show ipv6 mbgp neighbors (A.B.C.D|X:X::X:X) advertised-routes",
+ SHOW_STR
+ IPV6_STR
+ MBGP_STR
+ "Detailed information on TCP and BGP neighbor connections\n"
+ "Neighbor to display information about\n"
+ "Neighbor to display information about\n"
+ "Display the routes advertised to a BGP neighbor\n")
+{
+ return peer_adj_routes (vty, argv[0], AFI_IP6, SAFI_MULTICAST, 0);
+}
+#endif /* HAVE_IPV6 */
+
+DEFUN (show_ip_bgp_neighbor_received_routes,
+ show_ip_bgp_neighbor_received_routes_cmd,
+ "show ip bgp neighbors (A.B.C.D|X:X::X:X) received-routes",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Detailed information on TCP and BGP neighbor connections\n"
+ "Neighbor to display information about\n"
+ "Neighbor to display information about\n"
+ "Display the received routes from neighbor\n")
+{
+ return peer_adj_routes (vty, argv[0], AFI_IP, SAFI_UNICAST, 1);
+}
+
+DEFUN (show_ip_bgp_ipv4_neighbor_received_routes,
+ show_ip_bgp_ipv4_neighbor_received_routes_cmd,
+ "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X) received-routes",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Detailed information on TCP and BGP neighbor connections\n"
+ "Neighbor to display information about\n"
+ "Neighbor to display information about\n"
+ "Display the received routes from neighbor\n")
+{
+ if (strncmp (argv[0], "m", 1) == 0)
+ return peer_adj_routes (vty, argv[1], AFI_IP, SAFI_MULTICAST, 1);
+
+ return peer_adj_routes (vty, argv[1], AFI_IP, SAFI_UNICAST, 1);
+}
+
+DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
+ show_ip_bgp_neighbor_received_prefix_filter_cmd,
+ "show ip bgp neighbors (A.B.C.D|X:X::X:X) received prefix-filter",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Detailed information on TCP and BGP neighbor connections\n"
+ "Neighbor to display information about\n"
+ "Neighbor to display information about\n"
+ "Display information received from a BGP neighbor\n"
+ "Display the prefixlist filter\n")
+{
+ char name[BUFSIZ];
+ union sockunion *su;
+ struct peer *peer;
+ int count;
+
+ su = sockunion_str2su (argv[0]);
+ if (su == NULL)
+ return CMD_WARNING;
+
+ peer = peer_lookup (NULL, su);
+ if (! peer)
+ return CMD_WARNING;
+
+ sprintf (name, "%s.%d.%d", peer->host, AFI_IP, SAFI_UNICAST);
+ count = prefix_bgp_show_prefix_list (NULL, AFI_IP, name);
+ if (count)
+ {
+ vty_out (vty, "Address family: IPv4 Unicast%s", VTY_NEWLINE);
+ prefix_bgp_show_prefix_list (vty, AFI_IP, name);
+ }
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (show_ip_bgp_ipv4_neighbor_received_prefix_filter,
+ show_ip_bgp_ipv4_neighbor_received_prefix_filter_cmd,
+ "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X) received prefix-filter",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Detailed information on TCP and BGP neighbor connections\n"
+ "Neighbor to display information about\n"
+ "Neighbor to display information about\n"
+ "Display information received from a BGP neighbor\n"
+ "Display the prefixlist filter\n")
+{
+ char name[BUFSIZ];
+ union sockunion *su;
+ struct peer *peer;
+ int count;
+
+ su = sockunion_str2su (argv[1]);
+ if (su == NULL)
+ return CMD_WARNING;
+
+ peer = peer_lookup (NULL, su);
+ if (! peer)
+ return CMD_WARNING;
+
+ if (strncmp (argv[0], "m", 1) == 0)
+ {
+ sprintf (name, "%s.%d.%d", peer->host, AFI_IP, SAFI_MULTICAST);
+ count = prefix_bgp_show_prefix_list (NULL, AFI_IP, name);
+ if (count)
+ {
+ vty_out (vty, "Address family: IPv4 Multicast%s", VTY_NEWLINE);
+ prefix_bgp_show_prefix_list (vty, AFI_IP, name);
+ }
+ }
+ else
+ {
+ sprintf (name, "%s.%d.%d", peer->host, AFI_IP, SAFI_UNICAST);
+ count = prefix_bgp_show_prefix_list (NULL, AFI_IP, name);
+ if (count)
+ {
+ vty_out (vty, "Address family: IPv4 Unicast%s", VTY_NEWLINE);
+ prefix_bgp_show_prefix_list (vty, AFI_IP, name);
+ }
+ }
+
+ return CMD_SUCCESS;
+}
+
+
+#ifdef HAVE_IPV6
+DEFUN (show_bgp_neighbor_received_routes,
+ show_bgp_neighbor_received_routes_cmd,
+ "show bgp neighbors (A.B.C.D|X:X::X:X) received-routes",
+ SHOW_STR
+ BGP_STR
+ "Detailed information on TCP and BGP neighbor connections\n"
+ "Neighbor to display information about\n"
+ "Neighbor to display information about\n"
+ "Display the received routes from neighbor\n")
+{
+ return peer_adj_routes (vty, argv[0], AFI_IP6, SAFI_UNICAST, 1);
+}
+
+ALIAS (show_bgp_neighbor_received_routes,
+ show_bgp_ipv6_neighbor_received_routes_cmd,
+ "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X) received-routes",
+ SHOW_STR
+ BGP_STR
+ "Address family\n"
+ "Detailed information on TCP and BGP neighbor connections\n"
+ "Neighbor to display information about\n"
+ "Neighbor to display information about\n"
+ "Display the received routes from neighbor\n")
+
+DEFUN (show_bgp_neighbor_received_prefix_filter,
+ show_bgp_neighbor_received_prefix_filter_cmd,
+ "show bgp neighbors (A.B.C.D|X:X::X:X) received prefix-filter",
+ SHOW_STR
+ BGP_STR
+ "Detailed information on TCP and BGP neighbor connections\n"
+ "Neighbor to display information about\n"
+ "Neighbor to display information about\n"
+ "Display information received from a BGP neighbor\n"
+ "Display the prefixlist filter\n")
+{
+ char name[BUFSIZ];
+ union sockunion *su;
+ struct peer *peer;
+ int count;
+
+ su = sockunion_str2su (argv[0]);
+ if (su == NULL)
+ return CMD_WARNING;
+
+ peer = peer_lookup (NULL, su);
+ if (! peer)
+ return CMD_WARNING;
+
+ sprintf (name, "%s.%d.%d", peer->host, AFI_IP6, SAFI_UNICAST);
+ count = prefix_bgp_show_prefix_list (NULL, AFI_IP6, name);
+ if (count)
+ {
+ vty_out (vty, "Address family: IPv6 Unicast%s", VTY_NEWLINE);
+ prefix_bgp_show_prefix_list (vty, AFI_IP6, name);
+ }
+
+ return CMD_SUCCESS;
+}
+
+ALIAS (show_bgp_neighbor_received_prefix_filter,
+ show_bgp_ipv6_neighbor_received_prefix_filter_cmd,
+ "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X) received prefix-filter",
+ SHOW_STR
+ BGP_STR
+ "Address family\n"
+ "Detailed information on TCP and BGP neighbor connections\n"
+ "Neighbor to display information about\n"
+ "Neighbor to display information about\n"
+ "Display information received from a BGP neighbor\n"
+ "Display the prefixlist filter\n")
+
+/* old command */
+DEFUN (ipv6_bgp_neighbor_received_routes,
+ ipv6_bgp_neighbor_received_routes_cmd,
+ "show ipv6 bgp neighbors (A.B.C.D|X:X::X:X) received-routes",
+ SHOW_STR
+ IPV6_STR
+ BGP_STR
+ "Detailed information on TCP and BGP neighbor connections\n"
+ "Neighbor to display information about\n"
+ "Neighbor to display information about\n"
+ "Display the received routes from neighbor\n")
+{
+ return peer_adj_routes (vty, argv[0], AFI_IP6, SAFI_UNICAST, 1);
+}
+
+/* old command */
+DEFUN (ipv6_mbgp_neighbor_received_routes,
+ ipv6_mbgp_neighbor_received_routes_cmd,
+ "show ipv6 mbgp neighbors (A.B.C.D|X:X::X:X) received-routes",
+ SHOW_STR
+ IPV6_STR
+ MBGP_STR
+ "Detailed information on TCP and BGP neighbor connections\n"
+ "Neighbor to display information about\n"
+ "Neighbor to display information about\n"
+ "Display the received routes from neighbor\n")
+{
+ return peer_adj_routes (vty, argv[0], AFI_IP6, SAFI_MULTICAST, 1);
+}
+#endif /* HAVE_IPV6 */
+
+void
+bgp_show_neighbor_route_clean (struct vty *vty)
+{
+ union sockunion *su;
+
+ su = vty->output_arg;
+ XFREE (MTYPE_SOCKUNION, su);
+}
+
+int
+bgp_show_neighbor_route (struct vty *vty, char *ip_str, afi_t afi,
+ safi_t safi, enum bgp_show_type type)
+{
+ union sockunion *su;
+ struct peer *peer;
+
+ su = sockunion_str2su (ip_str);
+ if (su == NULL)
+ {
+ vty_out (vty, "Malformed address: %s%s", ip_str, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ peer = peer_lookup (NULL, su);
+ if (! peer || ! peer->afc[afi][safi])
+ {
+ vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
+ XFREE (MTYPE_SOCKUNION, su);
+ return CMD_WARNING;
+ }
+
+ vty->output_arg = su;
+ vty->output_clean = bgp_show_neighbor_route_clean;
+
+ return bgp_show (vty, NULL, afi, safi, type);
+}
+
+DEFUN (show_ip_bgp_neighbor_routes,
+ show_ip_bgp_neighbor_routes_cmd,
+ "show ip bgp neighbors (A.B.C.D|X:X::X:X) routes",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Detailed information on TCP and BGP neighbor connections\n"
+ "Neighbor to display information about\n"
+ "Neighbor to display information about\n"
+ "Display routes learned from neighbor\n")
+{
+ return bgp_show_neighbor_route (vty, argv[0], AFI_IP, SAFI_UNICAST,
+ bgp_show_type_neighbor);
+}
+
+DEFUN (show_ip_bgp_neighbor_flap,
+ show_ip_bgp_neighbor_flap_cmd,
+ "show ip bgp neighbors (A.B.C.D|X:X::X:X) flap-statistics",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Detailed information on TCP and BGP neighbor connections\n"
+ "Neighbor to display information about\n"
+ "Neighbor to display information about\n"
+ "Display flap statistics of the routes learned from neighbor\n")
+{
+ return bgp_show_neighbor_route (vty, argv[0], AFI_IP, SAFI_UNICAST,
+ bgp_show_type_flap_neighbor);
+}
+
+DEFUN (show_ip_bgp_neighbor_damp,
+ show_ip_bgp_neighbor_damp_cmd,
+ "show ip bgp neighbors (A.B.C.D|X:X::X:X) dampened-routes",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Detailed information on TCP and BGP neighbor connections\n"
+ "Neighbor to display information about\n"
+ "Neighbor to display information about\n"
+ "Display the dampened routes received from neighbor\n")
+{
+ return bgp_show_neighbor_route (vty, argv[0], AFI_IP, SAFI_UNICAST,
+ bgp_show_type_damp_neighbor);
+}
+
+DEFUN (show_ip_bgp_ipv4_neighbor_routes,
+ show_ip_bgp_ipv4_neighbor_routes_cmd,
+ "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X) routes",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Detailed information on TCP and BGP neighbor connections\n"
+ "Neighbor to display information about\n"
+ "Neighbor to display information about\n"
+ "Display routes learned from neighbor\n")
+{
+ if (strncmp (argv[0], "m", 1) == 0)
+ return bgp_show_neighbor_route (vty, argv[1], AFI_IP, SAFI_MULTICAST,
+ bgp_show_type_neighbor);
+
+ return bgp_show_neighbor_route (vty, argv[1], AFI_IP, SAFI_UNICAST,
+ bgp_show_type_neighbor);
+}
+#ifdef HAVE_IPV6
+DEFUN (show_bgp_neighbor_routes,
+ show_bgp_neighbor_routes_cmd,
+ "show bgp neighbors (A.B.C.D|X:X::X:X) routes",
+ SHOW_STR
+ BGP_STR
+ "Detailed information on TCP and BGP neighbor connections\n"
+ "Neighbor to display information about\n"
+ "Neighbor to display information about\n"
+ "Display routes learned from neighbor\n")
+{
+ return bgp_show_neighbor_route (vty, argv[0], AFI_IP6, SAFI_UNICAST,
+ bgp_show_type_neighbor);
+}
+
+ALIAS (show_bgp_neighbor_routes,
+ show_bgp_ipv6_neighbor_routes_cmd,
+ "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X) routes",
+ SHOW_STR
+ BGP_STR
+ "Address family\n"
+ "Detailed information on TCP and BGP neighbor connections\n"
+ "Neighbor to display information about\n"
+ "Neighbor to display information about\n"
+ "Display routes learned from neighbor\n")
+
+/* old command */
+DEFUN (ipv6_bgp_neighbor_routes,
+ ipv6_bgp_neighbor_routes_cmd,
+ "show ipv6 bgp neighbors (A.B.C.D|X:X::X:X) routes",
+ SHOW_STR
+ IPV6_STR
+ BGP_STR
+ "Detailed information on TCP and BGP neighbor connections\n"
+ "Neighbor to display information about\n"
+ "Neighbor to display information about\n"
+ "Display routes learned from neighbor\n")
+{
+ return bgp_show_neighbor_route (vty, argv[0], AFI_IP6, SAFI_UNICAST,
+ bgp_show_type_neighbor);
+}
+
+/* old command */
+DEFUN (ipv6_mbgp_neighbor_routes,
+ ipv6_mbgp_neighbor_routes_cmd,
+ "show ipv6 mbgp neighbors (A.B.C.D|X:X::X:X) routes",
+ SHOW_STR
+ IPV6_STR
+ MBGP_STR
+ "Detailed information on TCP and BGP neighbor connections\n"
+ "Neighbor to display information about\n"
+ "Neighbor to display information about\n"
+ "Display routes learned from neighbor\n")
+{
+ return bgp_show_neighbor_route (vty, argv[0], AFI_IP6, SAFI_MULTICAST,
+ bgp_show_type_neighbor);
+}
+#endif /* HAVE_IPV6 */
+
+struct bgp_table *bgp_distance_table;
+
+struct bgp_distance
+{
+ /* Distance value for the IP source prefix. */
+ u_char distance;
+
+ /* Name of the access-list to be matched. */
+ char *access_list;
+};
+
+struct bgp_distance *
+bgp_distance_new ()
+{
+ struct bgp_distance *new;
+ new = XMALLOC (MTYPE_BGP_DISTANCE, sizeof (struct bgp_distance));
+ memset (new, 0, sizeof (struct bgp_distance));
+ return new;
+}
+
+void
+bgp_distance_free (struct bgp_distance *bdistance)
+{
+ XFREE (MTYPE_BGP_DISTANCE, bdistance);
+}
+
+int
+bgp_distance_set (struct vty *vty, char *distance_str, char *ip_str,
+ char *access_list_str)
+{
+ int ret;
+ struct prefix_ipv4 p;
+ u_char distance;
+ struct bgp_node *rn;
+ struct bgp_distance *bdistance;
+
+ ret = str2prefix_ipv4 (ip_str, &p);
+ if (ret == 0)
+ {
+ vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ distance = atoi (distance_str);
+
+ /* Get BGP distance node. */
+ rn = bgp_node_get (bgp_distance_table, (struct prefix *) &p);
+ if (rn->info)
+ {
+ bdistance = rn->info;
+ bgp_unlock_node (rn);
+ }
+ else
+ {
+ bdistance = bgp_distance_new ();
+ rn->info = bdistance;
+ }
+
+ /* Set distance value. */
+ bdistance->distance = distance;
+
+ /* Reset access-list configuration. */
+ if (bdistance->access_list)
+ {
+ free (bdistance->access_list);
+ bdistance->access_list = NULL;
+ }
+ if (access_list_str)
+ bdistance->access_list = strdup (access_list_str);
+
+ return CMD_SUCCESS;
+}
+
+int
+bgp_distance_unset (struct vty *vty, char *distance_str, char *ip_str,
+ char *access_list_str)
+{
+ int ret;
+ struct prefix_ipv4 p;
+ u_char distance;
+ struct bgp_node *rn;
+ struct bgp_distance *bdistance;
+
+ ret = str2prefix_ipv4 (ip_str, &p);
+ if (ret == 0)
+ {
+ vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ distance = atoi (distance_str);
+
+ rn = bgp_node_lookup (bgp_distance_table, (struct prefix *)&p);
+ if (! rn)
+ {
+ vty_out (vty, "Can't find specified prefix%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ bdistance = rn->info;
+
+ if (bdistance->access_list)
+ free (bdistance->access_list);
+ bgp_distance_free (bdistance);
+
+ rn->info = NULL;
+ bgp_unlock_node (rn);
+ bgp_unlock_node (rn);
+
+ return CMD_SUCCESS;
+}
+
+void
+bgp_distance_reset ()
+{
+ struct bgp_node *rn;
+ struct bgp_distance *bdistance;
+
+ for (rn = bgp_table_top (bgp_distance_table); rn; rn = bgp_route_next (rn))
+ if ((bdistance = rn->info) != NULL)
+ {
+ if (bdistance->access_list)
+ free (bdistance->access_list);
+ bgp_distance_free (bdistance);
+ rn->info = NULL;
+ bgp_unlock_node (rn);
+ }
+}
+
+/* Apply BGP information to distance method. */
+u_char
+bgp_distance_apply (struct prefix *p, struct bgp_info *rinfo, struct bgp *bgp)
+{
+ struct bgp_node *rn;
+ struct prefix_ipv4 q;
+ struct peer *peer;
+ struct bgp_distance *bdistance;
+ struct access_list *alist;
+ struct bgp_static *bgp_static;
+
+ if (! bgp)
+ return 0;
+
+ if (p->family != AF_INET)
+ return 0;
+
+ peer = rinfo->peer;
+
+ if (peer->su.sa.sa_family != AF_INET)
+ return 0;
+
+ memset (&q, 0, sizeof (struct prefix_ipv4));
+ q.family = AF_INET;
+ q.prefix = peer->su.sin.sin_addr;
+ q.prefixlen = IPV4_MAX_BITLEN;
+
+ /* Check source address. */
+ rn = bgp_node_match (bgp_distance_table, (struct prefix *) &q);
+ if (rn)
+ {
+ bdistance = rn->info;
+ bgp_unlock_node (rn);
+
+ if (bdistance->access_list)
+ {
+ alist = access_list_lookup (AFI_IP, bdistance->access_list);
+ if (alist && access_list_apply (alist, p) == FILTER_PERMIT)
+ return bdistance->distance;
+ }
+ else
+ return bdistance->distance;
+ }
+
+ /* Backdoor check. */
+ rn = bgp_node_lookup (bgp->route[AFI_IP][SAFI_UNICAST], p);
+ if (rn)
+ {
+ bgp_static = rn->info;
+ bgp_unlock_node (rn);
+
+ if (bgp_static->backdoor)
+ {
+ if (bgp->distance_local)
+ return bgp->distance_local;
+ else
+ return ZEBRA_IBGP_DISTANCE_DEFAULT;
+ }
+ }
+
+ if (peer_sort (peer) == BGP_PEER_EBGP)
+ {
+ if (bgp->distance_ebgp)
+ return bgp->distance_ebgp;
+ return ZEBRA_EBGP_DISTANCE_DEFAULT;
+ }
+ else
+ {
+ if (bgp->distance_ibgp)
+ return bgp->distance_ibgp;
+ return ZEBRA_IBGP_DISTANCE_DEFAULT;
+ }
+}
+
+DEFUN (bgp_distance,
+ bgp_distance_cmd,
+ "distance bgp <1-255> <1-255> <1-255>",
+ "Define an administrative distance\n"
+ "BGP distance\n"
+ "Distance for routes external to the AS\n"
+ "Distance for routes internal to the AS\n"
+ "Distance for local routes\n")
+{
+ struct bgp *bgp;
+
+ bgp = vty->index;
+
+ bgp->distance_ebgp = atoi (argv[0]);
+ bgp->distance_ibgp = atoi (argv[1]);
+ bgp->distance_local = atoi (argv[2]);
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_bgp_distance,
+ no_bgp_distance_cmd,
+ "no distance bgp <1-255> <1-255> <1-255>",
+ NO_STR
+ "Define an administrative distance\n"
+ "BGP distance\n"
+ "Distance for routes external to the AS\n"
+ "Distance for routes internal to the AS\n"
+ "Distance for local routes\n")
+{
+ struct bgp *bgp;
+
+ bgp = vty->index;
+
+ bgp->distance_ebgp= 0;
+ bgp->distance_ibgp = 0;
+ bgp->distance_local = 0;
+ return CMD_SUCCESS;
+}
+
+ALIAS (no_bgp_distance,
+ no_bgp_distance2_cmd,
+ "no distance bgp",
+ NO_STR
+ "Define an administrative distance\n"
+ "BGP distance\n")
+
+DEFUN (bgp_distance_source,
+ bgp_distance_source_cmd,
+ "distance <1-255> A.B.C.D/M",
+ "Define an administrative distance\n"
+ "Administrative distance\n"
+ "IP source prefix\n")
+{
+ bgp_distance_set (vty, argv[0], argv[1], NULL);
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_bgp_distance_source,
+ no_bgp_distance_source_cmd,
+ "no distance <1-255> A.B.C.D/M",
+ NO_STR
+ "Define an administrative distance\n"
+ "Administrative distance\n"
+ "IP source prefix\n")
+{
+ bgp_distance_unset (vty, argv[0], argv[1], NULL);
+ return CMD_SUCCESS;
+}
+
+DEFUN (bgp_distance_source_access_list,
+ bgp_distance_source_access_list_cmd,
+ "distance <1-255> A.B.C.D/M WORD",
+ "Define an administrative distance\n"
+ "Administrative distance\n"
+ "IP source prefix\n"
+ "Access list name\n")
+{
+ bgp_distance_set (vty, argv[0], argv[1], argv[2]);
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_bgp_distance_source_access_list,
+ no_bgp_distance_source_access_list_cmd,
+ "no distance <1-255> A.B.C.D/M WORD",
+ NO_STR
+ "Define an administrative distance\n"
+ "Administrative distance\n"
+ "IP source prefix\n"
+ "Access list name\n")
+{
+ bgp_distance_unset (vty, argv[0], argv[1], argv[2]);
+ return CMD_SUCCESS;
+}
+
+DEFUN (bgp_damp_set,
+ bgp_damp_set_cmd,
+ "bgp dampening <1-45> <1-20000> <1-20000> <1-255>",
+ "BGP Specific commands\n"
+ "Enable route-flap dampening\n"
+ "Half-life time for the penalty\n"
+ "Value to start reusing a route\n"
+ "Value to start suppressing a route\n"
+ "Maximum duration to suppress a stable route\n")
+{
+ struct bgp *bgp;
+ int half = DEFAULT_HALF_LIFE * 60;
+ int reuse = DEFAULT_REUSE;
+ int suppress = DEFAULT_SUPPRESS;
+ int max = 4 * half;
+
+ if (argc == 4)
+ {
+ half = atoi (argv[0]) * 60;
+ reuse = atoi (argv[1]);
+ suppress = atoi (argv[2]);
+ max = atoi (argv[3]) * 60;
+ }
+ else if (argc == 1)
+ {
+ half = atoi (argv[0]) * 60;
+ max = 4 * half;
+ }
+
+ bgp = vty->index;
+ return bgp_damp_enable (bgp, bgp_node_afi (vty), bgp_node_safi (vty),
+ half, reuse, suppress, max);
+}
+
+ALIAS (bgp_damp_set,
+ bgp_damp_set2_cmd,
+ "bgp dampening <1-45>",
+ "BGP Specific commands\n"
+ "Enable route-flap dampening\n"
+ "Half-life time for the penalty\n")
+
+ALIAS (bgp_damp_set,
+ bgp_damp_set3_cmd,
+ "bgp dampening",
+ "BGP Specific commands\n"
+ "Enable route-flap dampening\n")
+
+DEFUN (bgp_damp_unset,
+ bgp_damp_unset_cmd,
+ "no bgp dampening",
+ NO_STR
+ "BGP Specific commands\n"
+ "Enable route-flap dampening\n")
+{
+ struct bgp *bgp;
+
+ bgp = vty->index;
+ return bgp_damp_disable (bgp, bgp_node_afi (vty), bgp_node_safi (vty));
+}
+
+ALIAS (bgp_damp_unset,
+ bgp_damp_unset2_cmd,
+ "no bgp dampening <1-45> <1-20000> <1-20000> <1-255>",
+ NO_STR
+ "BGP Specific commands\n"
+ "Enable route-flap dampening\n"
+ "Half-life time for the penalty\n"
+ "Value to start reusing a route\n"
+ "Value to start suppressing a route\n"
+ "Maximum duration to suppress a stable route\n")
+
+DEFUN (show_ip_bgp_dampened_paths,
+ show_ip_bgp_dampened_paths_cmd,
+ "show ip bgp dampened-paths",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display paths suppressed due to dampening\n")
+{
+ return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST, bgp_show_type_dampend_paths);
+}
+
+DEFUN (show_ip_bgp_flap_statistics,
+ show_ip_bgp_flap_statistics_cmd,
+ "show ip bgp flap-statistics",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display flap statistics of routes\n")
+{
+ return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST, bgp_show_type_flap_statistics);
+}
+
+/* Display specified route of BGP table. */
+int
+bgp_clear_damp_route (struct vty *vty, char *view_name, char *ip_str,
+ afi_t afi, safi_t safi, struct prefix_rd *prd,
+ int prefix_check)
+{
+ int ret;
+ struct prefix match;
+ struct bgp_node *rn;
+ struct bgp_node *rm;
+ struct bgp_info *ri;
+ struct bgp_info *ri_temp;
+ struct bgp *bgp;
+ struct bgp_table *table;
+
+ /* BGP structure lookup. */
+ if (view_name)
+ {
+ bgp = bgp_lookup_by_name (view_name);
+ if (bgp == NULL)
+ {
+ vty_out (vty, "%% Can't find BGP view %s%s", view_name, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+ else
+ {
+ bgp = bgp_get_default ();
+ if (bgp == NULL)
+ {
+ vty_out (vty, "%% No BGP process is configured%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+
+ /* Check IP address argument. */
+ ret = str2prefix (ip_str, &match);
+ if (! ret)
+ {
+ vty_out (vty, "%% address is malformed%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ match.family = afi2family (afi);
+
+ if (safi == SAFI_MPLS_VPN)
+ {
+ for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn; rn = bgp_route_next (rn))
+ {
+ if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
+ continue;
+
+ if ((table = rn->info) != NULL)
+ if ((rm = bgp_node_match (table, &match)) != NULL)
+ if (! prefix_check || rm->p.prefixlen == match.prefixlen)
+ {
+ ri = rm->info;
+ while (ri)
+ {
+ if (ri->damp_info)
+ {
+ ri_temp = ri->next;
+ bgp_damp_info_free (ri->damp_info, 1);
+ ri = ri_temp;
+ }
+ else
+ ri = ri->next;
+ }
+ }
+ }
+ }
+ else
+ {
+ if ((rn = bgp_node_match (bgp->rib[afi][safi], &match)) != NULL)
+ if (! prefix_check || rn->p.prefixlen == match.prefixlen)
+ {
+ ri = rn->info;
+ while (ri)
+ {
+ if (ri->damp_info)
+ {
+ ri_temp = ri->next;
+ bgp_damp_info_free (ri->damp_info, 1);
+ ri = ri_temp;
+ }
+ else
+ ri = ri->next;
+ }
+ }
+ }
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (clear_ip_bgp_dampening,
+ clear_ip_bgp_dampening_cmd,
+ "clear ip bgp dampening",
+ CLEAR_STR
+ IP_STR
+ BGP_STR
+ "Clear route flap dampening information\n")
+{
+ bgp_damp_info_clean ();
+ return CMD_SUCCESS;
+}
+
+DEFUN (clear_ip_bgp_dampening_prefix,
+ clear_ip_bgp_dampening_prefix_cmd,
+ "clear ip bgp dampening A.B.C.D/M",
+ CLEAR_STR
+ IP_STR
+ BGP_STR
+ "Clear route flap dampening information\n"
+ "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
+{
+ return bgp_clear_damp_route (vty, NULL, argv[0], AFI_IP,
+ SAFI_UNICAST, NULL, 1);
+}
+
+DEFUN (clear_ip_bgp_dampening_address,
+ clear_ip_bgp_dampening_address_cmd,
+ "clear ip bgp dampening A.B.C.D",
+ CLEAR_STR
+ IP_STR
+ BGP_STR
+ "Clear route flap dampening information\n"
+ "Network to clear damping information\n")
+{
+ return bgp_clear_damp_route (vty, NULL, argv[0], AFI_IP,
+ SAFI_UNICAST, NULL, 0);
+}
+
+DEFUN (clear_ip_bgp_dampening_address_mask,
+ clear_ip_bgp_dampening_address_mask_cmd,
+ "clear ip bgp dampening A.B.C.D A.B.C.D",
+ CLEAR_STR
+ IP_STR
+ BGP_STR
+ "Clear route flap dampening information\n"
+ "Network to clear damping information\n"
+ "Network mask\n")
+{
+ int ret;
+ char prefix_str[BUFSIZ];
+
+ ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
+ if (! ret)
+ {
+ vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return bgp_clear_damp_route (vty, NULL, prefix_str, AFI_IP,
+ SAFI_UNICAST, NULL, 0);
+}
+
+int
+bgp_config_write_network_vpnv4 (struct vty *vty, struct bgp *bgp,
+ afi_t afi, safi_t safi, int *write)
+{
+ struct bgp_node *prn;
+ struct bgp_node *rn;
+ struct bgp_table *table;
+ struct prefix *p;
+ struct prefix_rd *prd;
+ struct bgp_static *bgp_static;
+ u_int32_t label;
+ char buf[SU_ADDRSTRLEN];
+ char rdbuf[RD_ADDRSTRLEN];
+
+ /* Network configuration. */
+ for (prn = bgp_table_top (bgp->route[afi][safi]); prn; prn = bgp_route_next (prn))
+ if ((table = prn->info) != NULL)
+ for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
+ if ((bgp_static = rn->info) != NULL)
+ {
+ p = &rn->p;
+ prd = (struct prefix_rd *) &prn->p;
+
+ /* "address-family" display. */
+ bgp_config_write_family_header (vty, afi, safi, write);
+
+ /* "network" configuration display. */
+ prefix_rd2str (prd, rdbuf, RD_ADDRSTRLEN);
+ label = decode_label (bgp_static->tag);
+
+ vty_out (vty, " network %s/%d rd %s tag %d",
+ inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
+ p->prefixlen,
+ rdbuf, label);
+ vty_out (vty, "%s", VTY_NEWLINE);
+ }
+ return 0;
+}
+
+/* Configuration of static route announcement and aggregate
+ information. */
+int
+bgp_config_write_network (struct vty *vty, struct bgp *bgp,
+ afi_t afi, safi_t safi, int *write)
+{
+ struct bgp_node *rn;
+ struct prefix *p;
+ struct bgp_static *bgp_static;
+ struct bgp_aggregate *bgp_aggregate;
+ char buf[SU_ADDRSTRLEN];
+
+ if (afi == AFI_IP && safi == SAFI_MPLS_VPN)
+ return bgp_config_write_network_vpnv4 (vty, bgp, afi, safi, write);
+
+ /* Network configuration. */
+ for (rn = bgp_table_top (bgp->route[afi][safi]); rn; rn = bgp_route_next (rn))
+ if ((bgp_static = rn->info) != NULL)
+ {
+ p = &rn->p;
+
+ /* "address-family" display. */
+ bgp_config_write_family_header (vty, afi, safi, write);
+
+ /* "network" configuration display. */
+ if (bgp_option_check (BGP_OPT_CONFIG_CISCO) && afi == AFI_IP)
+ {
+ u_int32_t destination;
+ struct in_addr netmask;
+
+ destination = ntohl (p->u.prefix4.s_addr);
+ masklen2ip (p->prefixlen, &netmask);
+ vty_out (vty, " network %s",
+ inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN));
+
+ if ((IN_CLASSC (destination) && p->prefixlen == 24)
+ || (IN_CLASSB (destination) && p->prefixlen == 16)
+ || (IN_CLASSA (destination) && p->prefixlen == 8)
+ || p->u.prefix4.s_addr == 0)
+ {
+ /* Natural mask is not display. */
+ }
+ else
+ vty_out (vty, " mask %s", inet_ntoa (netmask));
+ }
+ else
+ {
+ vty_out (vty, " network %s/%d",
+ inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
+ p->prefixlen);
+ }
+
+ if (bgp_static->rmap.name)
+ vty_out (vty, " route-map %s", bgp_static->rmap.name);
+ else if (bgp_static->backdoor)
+ vty_out (vty, " backdoor");
+
+ vty_out (vty, "%s", VTY_NEWLINE);
+ }
+
+ /* Aggregate-address configuration. */
+ for (rn = bgp_table_top (bgp->aggregate[afi][safi]); rn; rn = bgp_route_next (rn))
+ if ((bgp_aggregate = rn->info) != NULL)
+ {
+ p = &rn->p;
+
+ /* "address-family" display. */
+ bgp_config_write_family_header (vty, afi, safi, write);
+
+ if (bgp_option_check (BGP_OPT_CONFIG_CISCO) && afi == AFI_IP)
+ {
+ struct in_addr netmask;
+
+ masklen2ip (p->prefixlen, &netmask);
+ vty_out (vty, " aggregate-address %s %s",
+ inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
+ inet_ntoa (netmask));
+ }
+ else
+ {
+ vty_out (vty, " aggregate-address %s/%d",
+ inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
+ p->prefixlen);
+ }
+
+ if (bgp_aggregate->as_set)
+ vty_out (vty, " as-set");
+
+ if (bgp_aggregate->summary_only)
+ vty_out (vty, " summary-only");
+
+ vty_out (vty, "%s", VTY_NEWLINE);
+ }
+
+ return 0;
+}
+
+int
+bgp_config_write_distance (struct vty *vty, struct bgp *bgp)
+{
+ struct bgp_node *rn;
+ struct bgp_distance *bdistance;
+
+ /* Distance configuration. */
+ if (bgp->distance_ebgp
+ && bgp->distance_ibgp
+ && bgp->distance_local
+ && (bgp->distance_ebgp != ZEBRA_EBGP_DISTANCE_DEFAULT
+ || bgp->distance_ibgp != ZEBRA_IBGP_DISTANCE_DEFAULT
+ || bgp->distance_local != ZEBRA_IBGP_DISTANCE_DEFAULT))
+ vty_out (vty, " distance bgp %d %d %d%s",
+ bgp->distance_ebgp, bgp->distance_ibgp, bgp->distance_local,
+ VTY_NEWLINE);
+
+ for (rn = bgp_table_top (bgp_distance_table); rn; rn = bgp_route_next (rn))
+ if ((bdistance = rn->info) != NULL)
+ {
+ vty_out (vty, " distance %d %s/%d %s%s", bdistance->distance,
+ inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen,
+ bdistance->access_list ? bdistance->access_list : "",
+ VTY_NEWLINE);
+ }
+
+ return 0;
+}
+
+/* Allocate routing table structure and install commands. */
+void
+bgp_route_init ()
+{
+ /* Init BGP distance table. */
+ bgp_distance_table = bgp_table_init ();
+
+ /* IPv4 BGP commands. */
+ install_element (BGP_NODE, &bgp_network_cmd);
+ install_element (BGP_NODE, &bgp_network_mask_cmd);
+ install_element (BGP_NODE, &bgp_network_mask_natural_cmd);
+ install_element (BGP_NODE, &bgp_network_route_map_cmd);
+ install_element (BGP_NODE, &bgp_network_mask_route_map_cmd);
+ install_element (BGP_NODE, &bgp_network_mask_natural_route_map_cmd);
+ install_element (BGP_NODE, &bgp_network_backdoor_cmd);
+ install_element (BGP_NODE, &bgp_network_mask_backdoor_cmd);
+ install_element (BGP_NODE, &bgp_network_mask_natural_backdoor_cmd);
+ install_element (BGP_NODE, &no_bgp_network_cmd);
+ install_element (BGP_NODE, &no_bgp_network_mask_cmd);
+ install_element (BGP_NODE, &no_bgp_network_mask_natural_cmd);
+ install_element (BGP_NODE, &no_bgp_network_route_map_cmd);
+ install_element (BGP_NODE, &no_bgp_network_mask_route_map_cmd);
+ install_element (BGP_NODE, &no_bgp_network_mask_natural_route_map_cmd);
+ install_element (BGP_NODE, &no_bgp_network_backdoor_cmd);
+ install_element (BGP_NODE, &no_bgp_network_mask_backdoor_cmd);
+ install_element (BGP_NODE, &no_bgp_network_mask_natural_backdoor_cmd);
+
+ install_element (BGP_NODE, &aggregate_address_cmd);
+ install_element (BGP_NODE, &aggregate_address_mask_cmd);
+ install_element (BGP_NODE, &aggregate_address_summary_only_cmd);
+ install_element (BGP_NODE, &aggregate_address_mask_summary_only_cmd);
+ install_element (BGP_NODE, &aggregate_address_as_set_cmd);
+ install_element (BGP_NODE, &aggregate_address_mask_as_set_cmd);
+ install_element (BGP_NODE, &aggregate_address_as_set_summary_cmd);
+ install_element (BGP_NODE, &aggregate_address_mask_as_set_summary_cmd);
+ install_element (BGP_NODE, &aggregate_address_summary_as_set_cmd);
+ install_element (BGP_NODE, &aggregate_address_mask_summary_as_set_cmd);
+ install_element (BGP_NODE, &no_aggregate_address_cmd);
+ install_element (BGP_NODE, &no_aggregate_address_summary_only_cmd);
+ install_element (BGP_NODE, &no_aggregate_address_as_set_cmd);
+ install_element (BGP_NODE, &no_aggregate_address_as_set_summary_cmd);
+ install_element (BGP_NODE, &no_aggregate_address_summary_as_set_cmd);
+ install_element (BGP_NODE, &no_aggregate_address_mask_cmd);
+ install_element (BGP_NODE, &no_aggregate_address_mask_summary_only_cmd);
+ install_element (BGP_NODE, &no_aggregate_address_mask_as_set_cmd);
+ install_element (BGP_NODE, &no_aggregate_address_mask_as_set_summary_cmd);
+ install_element (BGP_NODE, &no_aggregate_address_mask_summary_as_set_cmd);
+
+ /* IPv4 unicast configuration. */
+ install_element (BGP_IPV4_NODE, &bgp_network_cmd);
+ install_element (BGP_IPV4_NODE, &bgp_network_mask_cmd);
+ install_element (BGP_IPV4_NODE, &bgp_network_mask_natural_cmd);
+ install_element (BGP_IPV4_NODE, &bgp_network_route_map_cmd);
+ install_element (BGP_IPV4_NODE, &bgp_network_mask_route_map_cmd);
+ install_element (BGP_IPV4_NODE, &bgp_network_mask_natural_route_map_cmd);
+ install_element (BGP_IPV4_NODE, &no_bgp_network_cmd);
+ install_element (BGP_IPV4_NODE, &no_bgp_network_mask_cmd);
+ install_element (BGP_IPV4_NODE, &no_bgp_network_mask_natural_cmd);
+ install_element (BGP_IPV4_NODE, &no_bgp_network_route_map_cmd);
+ install_element (BGP_IPV4_NODE, &no_bgp_network_mask_route_map_cmd);
+ install_element (BGP_IPV4_NODE, &no_bgp_network_mask_natural_route_map_cmd);
+ install_element (BGP_IPV4_NODE, &aggregate_address_cmd);
+ install_element (BGP_IPV4_NODE, &aggregate_address_mask_cmd);
+ install_element (BGP_IPV4_NODE, &aggregate_address_summary_only_cmd);
+ install_element (BGP_IPV4_NODE, &aggregate_address_mask_summary_only_cmd);
+ install_element (BGP_IPV4_NODE, &aggregate_address_as_set_cmd);
+ install_element (BGP_IPV4_NODE, &aggregate_address_mask_as_set_cmd);
+ install_element (BGP_IPV4_NODE, &aggregate_address_as_set_summary_cmd);
+ install_element (BGP_IPV4_NODE, &aggregate_address_mask_as_set_summary_cmd);
+ install_element (BGP_IPV4_NODE, &aggregate_address_summary_as_set_cmd);
+ install_element (BGP_IPV4_NODE, &aggregate_address_mask_summary_as_set_cmd);
+ install_element (BGP_IPV4_NODE, &no_aggregate_address_cmd);
+ install_element (BGP_IPV4_NODE, &no_aggregate_address_summary_only_cmd);
+ install_element (BGP_IPV4_NODE, &no_aggregate_address_as_set_cmd);
+ install_element (BGP_IPV4_NODE, &no_aggregate_address_as_set_summary_cmd);
+ install_element (BGP_IPV4_NODE, &no_aggregate_address_summary_as_set_cmd);
+ install_element (BGP_IPV4_NODE, &no_aggregate_address_mask_cmd);
+ install_element (BGP_IPV4_NODE, &no_aggregate_address_mask_summary_only_cmd);
+ install_element (BGP_IPV4_NODE, &no_aggregate_address_mask_as_set_cmd);
+ install_element (BGP_IPV4_NODE, &no_aggregate_address_mask_as_set_summary_cmd);
+ install_element (BGP_IPV4_NODE, &no_aggregate_address_mask_summary_as_set_cmd);
+
+ /* IPv4 multicast configuration. */
+ install_element (BGP_IPV4M_NODE, &bgp_network_cmd);
+ install_element (BGP_IPV4M_NODE, &bgp_network_mask_cmd);
+ install_element (BGP_IPV4M_NODE, &bgp_network_mask_natural_cmd);
+ install_element (BGP_IPV4M_NODE, &bgp_network_route_map_cmd);
+ install_element (BGP_IPV4M_NODE, &bgp_network_mask_route_map_cmd);
+ install_element (BGP_IPV4M_NODE, &bgp_network_mask_natural_route_map_cmd);
+ install_element (BGP_IPV4M_NODE, &no_bgp_network_cmd);
+ install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_cmd);
+ install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_natural_cmd);
+ install_element (BGP_IPV4M_NODE, &no_bgp_network_route_map_cmd);
+ install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_route_map_cmd);
+ install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_natural_route_map_cmd);
+ install_element (BGP_IPV4M_NODE, &aggregate_address_cmd);
+ install_element (BGP_IPV4M_NODE, &aggregate_address_mask_cmd);
+ install_element (BGP_IPV4M_NODE, &aggregate_address_summary_only_cmd);
+ install_element (BGP_IPV4M_NODE, &aggregate_address_mask_summary_only_cmd);
+ install_element (BGP_IPV4M_NODE, &aggregate_address_as_set_cmd);
+ install_element (BGP_IPV4M_NODE, &aggregate_address_mask_as_set_cmd);
+ install_element (BGP_IPV4M_NODE, &aggregate_address_as_set_summary_cmd);
+ install_element (BGP_IPV4M_NODE, &aggregate_address_mask_as_set_summary_cmd);
+ install_element (BGP_IPV4M_NODE, &aggregate_address_summary_as_set_cmd);
+ install_element (BGP_IPV4M_NODE, &aggregate_address_mask_summary_as_set_cmd);
+ install_element (BGP_IPV4M_NODE, &no_aggregate_address_cmd);
+ install_element (BGP_IPV4M_NODE, &no_aggregate_address_summary_only_cmd);
+ install_element (BGP_IPV4M_NODE, &no_aggregate_address_as_set_cmd);
+ install_element (BGP_IPV4M_NODE, &no_aggregate_address_as_set_summary_cmd);
+ install_element (BGP_IPV4M_NODE, &no_aggregate_address_summary_as_set_cmd);
+ install_element (BGP_IPV4M_NODE, &no_aggregate_address_mask_cmd);
+ install_element (BGP_IPV4M_NODE, &no_aggregate_address_mask_summary_only_cmd);
+ install_element (BGP_IPV4M_NODE, &no_aggregate_address_mask_as_set_cmd);
+ install_element (BGP_IPV4M_NODE, &no_aggregate_address_mask_as_set_summary_cmd);
+ install_element (BGP_IPV4M_NODE, &no_aggregate_address_mask_summary_as_set_cmd);
+
+ install_element (VIEW_NODE, &show_ip_bgp_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_ipv4_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_route_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_ipv4_route_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_route_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_route_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_prefix_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_ipv4_prefix_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_prefix_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_prefix_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_view_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_view_route_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_view_prefix_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_regexp_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_ipv4_regexp_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_prefix_list_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_ipv4_prefix_list_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_filter_list_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_ipv4_filter_list_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_route_map_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_ipv4_route_map_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_cidr_only_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_ipv4_cidr_only_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_community_all_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_ipv4_community_all_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_community_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_community2_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_community3_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_community4_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_ipv4_community_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_ipv4_community2_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_ipv4_community3_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_ipv4_community4_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_community_exact_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_community2_exact_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_community3_exact_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_community4_exact_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_ipv4_community_exact_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_ipv4_community2_exact_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_ipv4_community3_exact_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_ipv4_community4_exact_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_community_list_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_ipv4_community_list_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_community_list_exact_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_ipv4_community_list_exact_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_prefix_longer_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_ipv4_prefix_longer_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_neighbor_advertised_route_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_ipv4_neighbor_advertised_route_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_neighbor_received_routes_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_ipv4_neighbor_received_routes_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_ipv4_neighbor_routes_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_neighbor_received_prefix_filter_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_ipv4_neighbor_received_prefix_filter_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_dampened_paths_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_flap_statistics_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_flap_address_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_flap_prefix_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_flap_cidr_only_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_flap_regexp_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_flap_filter_list_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_flap_prefix_list_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_flap_prefix_longer_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_flap_route_map_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_neighbor_flap_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_neighbor_damp_cmd);
+
+ install_element (ENABLE_NODE, &show_ip_bgp_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_ipv4_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_route_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_ipv4_route_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_route_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_route_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_prefix_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_ipv4_prefix_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_prefix_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_prefix_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_view_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_view_route_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_view_prefix_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_regexp_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_ipv4_regexp_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_prefix_list_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_ipv4_prefix_list_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_filter_list_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_ipv4_filter_list_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_route_map_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_ipv4_route_map_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_cidr_only_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_ipv4_cidr_only_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_community_all_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_ipv4_community_all_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_community_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_community2_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_community3_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_community4_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_ipv4_community_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_ipv4_community2_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_ipv4_community3_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_ipv4_community4_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_community_exact_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_community2_exact_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_community3_exact_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_community4_exact_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_ipv4_community_exact_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_ipv4_community2_exact_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_ipv4_community3_exact_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_ipv4_community4_exact_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_community_list_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_ipv4_community_list_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_community_list_exact_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_ipv4_community_list_exact_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_prefix_longer_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_ipv4_prefix_longer_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_neighbor_advertised_route_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_ipv4_neighbor_advertised_route_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_neighbor_received_routes_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_ipv4_neighbor_received_routes_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_neighbor_routes_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_ipv4_neighbor_routes_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_neighbor_received_prefix_filter_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_ipv4_neighbor_received_prefix_filter_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_dampened_paths_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_flap_statistics_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_flap_address_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_flap_prefix_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_flap_cidr_only_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_flap_regexp_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_flap_filter_list_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_flap_prefix_list_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_flap_prefix_longer_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_flap_route_map_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_neighbor_flap_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_neighbor_damp_cmd);
+
+ /* BGP dampening clear commands */
+ install_element (ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
+ install_element (ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
+ install_element (ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
+ install_element (ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
+
+#ifdef HAVE_IPV6
+ /* New config IPv6 BGP commands. */
+ install_element (BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
+ install_element (BGP_IPV6_NODE, &ipv6_bgp_network_route_map_cmd);
+ install_element (BGP_IPV6_NODE, &no_ipv6_bgp_network_cmd);
+ install_element (BGP_IPV6_NODE, &no_ipv6_bgp_network_route_map_cmd);
+
+ install_element (BGP_IPV6_NODE, &ipv6_aggregate_address_cmd);
+ install_element (BGP_IPV6_NODE, &ipv6_aggregate_address_summary_only_cmd);
+ install_element (BGP_IPV6_NODE, &no_ipv6_aggregate_address_cmd);
+ install_element (BGP_IPV6_NODE, &no_ipv6_aggregate_address_summary_only_cmd);
+
+ /* Old config IPv6 BGP commands. */
+ install_element (BGP_NODE, &old_ipv6_bgp_network_cmd);
+ install_element (BGP_NODE, &old_no_ipv6_bgp_network_cmd);
+
+ install_element (BGP_NODE, &old_ipv6_aggregate_address_cmd);
+ install_element (BGP_NODE, &old_ipv6_aggregate_address_summary_only_cmd);
+ install_element (BGP_NODE, &old_no_ipv6_aggregate_address_cmd);
+ install_element (BGP_NODE, &old_no_ipv6_aggregate_address_summary_only_cmd);
+
+ install_element (VIEW_NODE, &show_bgp_cmd);
+ install_element (VIEW_NODE, &show_bgp_ipv6_cmd);
+ install_element (VIEW_NODE, &show_bgp_route_cmd);
+ install_element (VIEW_NODE, &show_bgp_ipv6_route_cmd);
+ install_element (VIEW_NODE, &show_bgp_prefix_cmd);
+ install_element (VIEW_NODE, &show_bgp_ipv6_prefix_cmd);
+ install_element (VIEW_NODE, &show_bgp_regexp_cmd);
+ install_element (VIEW_NODE, &show_bgp_ipv6_regexp_cmd);
+ install_element (VIEW_NODE, &show_bgp_prefix_list_cmd);
+ install_element (VIEW_NODE, &show_bgp_ipv6_prefix_list_cmd);
+ install_element (VIEW_NODE, &show_bgp_filter_list_cmd);
+ install_element (VIEW_NODE, &show_bgp_ipv6_filter_list_cmd);
+ install_element (VIEW_NODE, &show_bgp_route_map_cmd);
+ install_element (VIEW_NODE, &show_bgp_ipv6_route_map_cmd);
+ install_element (VIEW_NODE, &show_bgp_community_all_cmd);
+ install_element (VIEW_NODE, &show_bgp_ipv6_community_all_cmd);
+ install_element (VIEW_NODE, &show_bgp_community_cmd);
+ install_element (VIEW_NODE, &show_bgp_ipv6_community_cmd);
+ install_element (VIEW_NODE, &show_bgp_community2_cmd);
+ install_element (VIEW_NODE, &show_bgp_ipv6_community2_cmd);
+ install_element (VIEW_NODE, &show_bgp_community3_cmd);
+ install_element (VIEW_NODE, &show_bgp_ipv6_community3_cmd);
+ install_element (VIEW_NODE, &show_bgp_community4_cmd);
+ install_element (VIEW_NODE, &show_bgp_ipv6_community4_cmd);
+ install_element (VIEW_NODE, &show_bgp_community_exact_cmd);
+ install_element (VIEW_NODE, &show_bgp_ipv6_community_exact_cmd);
+ install_element (VIEW_NODE, &show_bgp_community2_exact_cmd);
+ install_element (VIEW_NODE, &show_bgp_ipv6_community2_exact_cmd);
+ install_element (VIEW_NODE, &show_bgp_community3_exact_cmd);
+ install_element (VIEW_NODE, &show_bgp_ipv6_community3_exact_cmd);
+ install_element (VIEW_NODE, &show_bgp_community4_exact_cmd);
+ install_element (VIEW_NODE, &show_bgp_ipv6_community4_exact_cmd);
+ install_element (VIEW_NODE, &show_bgp_community_list_cmd);
+ install_element (VIEW_NODE, &show_bgp_ipv6_community_list_cmd);
+ install_element (VIEW_NODE, &show_bgp_community_list_exact_cmd);
+ install_element (VIEW_NODE, &show_bgp_ipv6_community_list_exact_cmd);
+ install_element (VIEW_NODE, &show_bgp_prefix_longer_cmd);
+ install_element (VIEW_NODE, &show_bgp_ipv6_prefix_longer_cmd);
+ install_element (VIEW_NODE, &show_bgp_neighbor_advertised_route_cmd);
+ install_element (VIEW_NODE, &show_bgp_ipv6_neighbor_advertised_route_cmd);
+ install_element (VIEW_NODE, &show_bgp_neighbor_received_routes_cmd);
+ install_element (VIEW_NODE, &show_bgp_ipv6_neighbor_received_routes_cmd);
+ install_element (VIEW_NODE, &show_bgp_neighbor_routes_cmd);
+ install_element (VIEW_NODE, &show_bgp_ipv6_neighbor_routes_cmd);
+ install_element (VIEW_NODE, &show_bgp_neighbor_received_prefix_filter_cmd);
+ install_element (VIEW_NODE, &show_bgp_ipv6_neighbor_received_prefix_filter_cmd);
+
+ install_element (ENABLE_NODE, &show_bgp_cmd);
+ install_element (ENABLE_NODE, &show_bgp_ipv6_cmd);
+ install_element (ENABLE_NODE, &show_bgp_route_cmd);
+ install_element (ENABLE_NODE, &show_bgp_ipv6_route_cmd);
+ install_element (ENABLE_NODE, &show_bgp_prefix_cmd);
+ install_element (ENABLE_NODE, &show_bgp_ipv6_prefix_cmd);
+ install_element (ENABLE_NODE, &show_bgp_regexp_cmd);
+ install_element (ENABLE_NODE, &show_bgp_ipv6_regexp_cmd);
+ install_element (ENABLE_NODE, &show_bgp_prefix_list_cmd);
+ install_element (ENABLE_NODE, &show_bgp_ipv6_prefix_list_cmd);
+ install_element (ENABLE_NODE, &show_bgp_filter_list_cmd);
+ install_element (ENABLE_NODE, &show_bgp_ipv6_filter_list_cmd);
+ install_element (ENABLE_NODE, &show_bgp_route_map_cmd);
+ install_element (ENABLE_NODE, &show_bgp_ipv6_route_map_cmd);
+ install_element (ENABLE_NODE, &show_bgp_community_all_cmd);
+ install_element (ENABLE_NODE, &show_bgp_ipv6_community_all_cmd);
+ install_element (ENABLE_NODE, &show_bgp_community_cmd);
+ install_element (ENABLE_NODE, &show_bgp_ipv6_community_cmd);
+ install_element (ENABLE_NODE, &show_bgp_community2_cmd);
+ install_element (ENABLE_NODE, &show_bgp_ipv6_community2_cmd);
+ install_element (ENABLE_NODE, &show_bgp_community3_cmd);
+ install_element (ENABLE_NODE, &show_bgp_ipv6_community3_cmd);
+ install_element (ENABLE_NODE, &show_bgp_community4_cmd);
+ install_element (ENABLE_NODE, &show_bgp_ipv6_community4_cmd);
+ install_element (ENABLE_NODE, &show_bgp_community_exact_cmd);
+ install_element (ENABLE_NODE, &show_bgp_ipv6_community_exact_cmd);
+ install_element (ENABLE_NODE, &show_bgp_community2_exact_cmd);
+ install_element (ENABLE_NODE, &show_bgp_ipv6_community2_exact_cmd);
+ install_element (ENABLE_NODE, &show_bgp_community3_exact_cmd);
+ install_element (ENABLE_NODE, &show_bgp_ipv6_community3_exact_cmd);
+ install_element (ENABLE_NODE, &show_bgp_community4_exact_cmd);
+ install_element (ENABLE_NODE, &show_bgp_ipv6_community4_exact_cmd);
+ install_element (ENABLE_NODE, &show_bgp_community_list_cmd);
+ install_element (ENABLE_NODE, &show_bgp_ipv6_community_list_cmd);
+ install_element (ENABLE_NODE, &show_bgp_community_list_exact_cmd);
+ install_element (ENABLE_NODE, &show_bgp_ipv6_community_list_exact_cmd);
+ install_element (ENABLE_NODE, &show_bgp_prefix_longer_cmd);
+ install_element (ENABLE_NODE, &show_bgp_ipv6_prefix_longer_cmd);
+ install_element (ENABLE_NODE, &show_bgp_neighbor_advertised_route_cmd);
+ install_element (ENABLE_NODE, &show_bgp_ipv6_neighbor_advertised_route_cmd);
+ install_element (ENABLE_NODE, &show_bgp_neighbor_received_routes_cmd);
+ install_element (ENABLE_NODE, &show_bgp_ipv6_neighbor_received_routes_cmd);
+ install_element (ENABLE_NODE, &show_bgp_neighbor_routes_cmd);
+ install_element (ENABLE_NODE, &show_bgp_ipv6_neighbor_routes_cmd);
+ install_element (ENABLE_NODE, &show_bgp_neighbor_received_prefix_filter_cmd);
+ install_element (ENABLE_NODE, &show_bgp_ipv6_neighbor_received_prefix_filter_cmd);
+
+ /* old command */
+ install_element (VIEW_NODE, &show_ipv6_bgp_cmd);
+ install_element (VIEW_NODE, &show_ipv6_bgp_route_cmd);
+ install_element (VIEW_NODE, &show_ipv6_bgp_prefix_cmd);
+ install_element (VIEW_NODE, &show_ipv6_bgp_regexp_cmd);
+ install_element (VIEW_NODE, &show_ipv6_bgp_prefix_list_cmd);
+ install_element (VIEW_NODE, &show_ipv6_bgp_filter_list_cmd);
+ install_element (VIEW_NODE, &show_ipv6_bgp_community_all_cmd);
+ install_element (VIEW_NODE, &show_ipv6_bgp_community_cmd);
+ install_element (VIEW_NODE, &show_ipv6_bgp_community2_cmd);
+ install_element (VIEW_NODE, &show_ipv6_bgp_community3_cmd);
+ install_element (VIEW_NODE, &show_ipv6_bgp_community4_cmd);
+ install_element (VIEW_NODE, &show_ipv6_bgp_community_exact_cmd);
+ install_element (VIEW_NODE, &show_ipv6_bgp_community2_exact_cmd);
+ install_element (VIEW_NODE, &show_ipv6_bgp_community3_exact_cmd);
+ install_element (VIEW_NODE, &show_ipv6_bgp_community4_exact_cmd);
+ install_element (VIEW_NODE, &show_ipv6_bgp_community_list_cmd);
+ install_element (VIEW_NODE, &show_ipv6_bgp_community_list_exact_cmd);
+ install_element (VIEW_NODE, &show_ipv6_bgp_prefix_longer_cmd);
+ install_element (VIEW_NODE, &show_ipv6_mbgp_cmd);
+ install_element (VIEW_NODE, &show_ipv6_mbgp_route_cmd);
+ install_element (VIEW_NODE, &show_ipv6_mbgp_prefix_cmd);
+ install_element (VIEW_NODE, &show_ipv6_mbgp_regexp_cmd);
+ install_element (VIEW_NODE, &show_ipv6_mbgp_prefix_list_cmd);
+ install_element (VIEW_NODE, &show_ipv6_mbgp_filter_list_cmd);
+ install_element (VIEW_NODE, &show_ipv6_mbgp_community_all_cmd);
+ install_element (VIEW_NODE, &show_ipv6_mbgp_community_cmd);
+ install_element (VIEW_NODE, &show_ipv6_mbgp_community2_cmd);
+ install_element (VIEW_NODE, &show_ipv6_mbgp_community3_cmd);
+ install_element (VIEW_NODE, &show_ipv6_mbgp_community4_cmd);
+ install_element (VIEW_NODE, &show_ipv6_mbgp_community_exact_cmd);
+ install_element (VIEW_NODE, &show_ipv6_mbgp_community2_exact_cmd);
+ install_element (VIEW_NODE, &show_ipv6_mbgp_community3_exact_cmd);
+ install_element (VIEW_NODE, &show_ipv6_mbgp_community4_exact_cmd);
+ install_element (VIEW_NODE, &show_ipv6_mbgp_community_list_cmd);
+ install_element (VIEW_NODE, &show_ipv6_mbgp_community_list_exact_cmd);
+ install_element (VIEW_NODE, &show_ipv6_mbgp_prefix_longer_cmd);
+
+ /* old command */
+ install_element (ENABLE_NODE, &show_ipv6_bgp_cmd);
+ install_element (ENABLE_NODE, &show_ipv6_bgp_route_cmd);
+ install_element (ENABLE_NODE, &show_ipv6_bgp_prefix_cmd);
+ install_element (ENABLE_NODE, &show_ipv6_bgp_regexp_cmd);
+ install_element (ENABLE_NODE, &show_ipv6_bgp_prefix_list_cmd);
+ install_element (ENABLE_NODE, &show_ipv6_bgp_filter_list_cmd);
+ install_element (ENABLE_NODE, &show_ipv6_bgp_community_all_cmd);
+ install_element (ENABLE_NODE, &show_ipv6_bgp_community_cmd);
+ install_element (ENABLE_NODE, &show_ipv6_bgp_community2_cmd);
+ install_element (ENABLE_NODE, &show_ipv6_bgp_community3_cmd);
+ install_element (ENABLE_NODE, &show_ipv6_bgp_community4_cmd);
+ install_element (ENABLE_NODE, &show_ipv6_bgp_community_exact_cmd);
+ install_element (ENABLE_NODE, &show_ipv6_bgp_community2_exact_cmd);
+ install_element (ENABLE_NODE, &show_ipv6_bgp_community3_exact_cmd);
+ install_element (ENABLE_NODE, &show_ipv6_bgp_community4_exact_cmd);
+ install_element (ENABLE_NODE, &show_ipv6_bgp_community_list_cmd);
+ install_element (ENABLE_NODE, &show_ipv6_bgp_community_list_exact_cmd);
+ install_element (ENABLE_NODE, &show_ipv6_bgp_prefix_longer_cmd);
+ install_element (ENABLE_NODE, &show_ipv6_mbgp_cmd);
+ install_element (ENABLE_NODE, &show_ipv6_mbgp_route_cmd);
+ install_element (ENABLE_NODE, &show_ipv6_mbgp_prefix_cmd);
+ install_element (ENABLE_NODE, &show_ipv6_mbgp_regexp_cmd);
+ install_element (ENABLE_NODE, &show_ipv6_mbgp_prefix_list_cmd);
+ install_element (ENABLE_NODE, &show_ipv6_mbgp_filter_list_cmd);
+ install_element (ENABLE_NODE, &show_ipv6_mbgp_community_all_cmd);
+ install_element (ENABLE_NODE, &show_ipv6_mbgp_community_cmd);
+ install_element (ENABLE_NODE, &show_ipv6_mbgp_community2_cmd);
+ install_element (ENABLE_NODE, &show_ipv6_mbgp_community3_cmd);
+ install_element (ENABLE_NODE, &show_ipv6_mbgp_community4_cmd);
+ install_element (ENABLE_NODE, &show_ipv6_mbgp_community_exact_cmd);
+ install_element (ENABLE_NODE, &show_ipv6_mbgp_community2_exact_cmd);
+ install_element (ENABLE_NODE, &show_ipv6_mbgp_community3_exact_cmd);
+ install_element (ENABLE_NODE, &show_ipv6_mbgp_community4_exact_cmd);
+ install_element (ENABLE_NODE, &show_ipv6_mbgp_community_list_cmd);
+ install_element (ENABLE_NODE, &show_ipv6_mbgp_community_list_exact_cmd);
+ install_element (ENABLE_NODE, &show_ipv6_mbgp_prefix_longer_cmd);
+
+ /* old command */
+ install_element (VIEW_NODE, &ipv6_bgp_neighbor_advertised_route_cmd);
+ install_element (ENABLE_NODE, &ipv6_bgp_neighbor_advertised_route_cmd);
+ install_element (VIEW_NODE, &ipv6_mbgp_neighbor_advertised_route_cmd);
+ install_element (ENABLE_NODE, &ipv6_mbgp_neighbor_advertised_route_cmd);
+
+ /* old command */
+ install_element (VIEW_NODE, &ipv6_bgp_neighbor_received_routes_cmd);
+ install_element (ENABLE_NODE, &ipv6_bgp_neighbor_received_routes_cmd);
+ install_element (VIEW_NODE, &ipv6_mbgp_neighbor_received_routes_cmd);
+ install_element (ENABLE_NODE, &ipv6_mbgp_neighbor_received_routes_cmd);
+
+ /* old command */
+ install_element (VIEW_NODE, &ipv6_bgp_neighbor_routes_cmd);
+ install_element (ENABLE_NODE, &ipv6_bgp_neighbor_routes_cmd);
+ install_element (VIEW_NODE, &ipv6_mbgp_neighbor_routes_cmd);
+ install_element (ENABLE_NODE, &ipv6_mbgp_neighbor_routes_cmd);
+#endif /* HAVE_IPV6 */
+
+ install_element (BGP_NODE, &bgp_distance_cmd);
+ install_element (BGP_NODE, &no_bgp_distance_cmd);
+ install_element (BGP_NODE, &no_bgp_distance2_cmd);
+ install_element (BGP_NODE, &bgp_distance_source_cmd);
+ install_element (BGP_NODE, &no_bgp_distance_source_cmd);
+ install_element (BGP_NODE, &bgp_distance_source_access_list_cmd);
+ install_element (BGP_NODE, &no_bgp_distance_source_access_list_cmd);
+
+ install_element (BGP_NODE, &bgp_damp_set_cmd);
+ install_element (BGP_NODE, &bgp_damp_set2_cmd);
+ install_element (BGP_NODE, &bgp_damp_set3_cmd);
+ install_element (BGP_NODE, &bgp_damp_unset_cmd);
+ install_element (BGP_NODE, &bgp_damp_unset2_cmd);
+ install_element (BGP_IPV4_NODE, &bgp_damp_set_cmd);
+ install_element (BGP_IPV4_NODE, &bgp_damp_set2_cmd);
+ install_element (BGP_IPV4_NODE, &bgp_damp_set3_cmd);
+ install_element (BGP_IPV4_NODE, &bgp_damp_unset_cmd);
+ install_element (BGP_IPV4_NODE, &bgp_damp_unset2_cmd);
+}