mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-28 11:50:21 +00:00
9054 lines
271 KiB
C
9054 lines
271 KiB
C
/* 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);
|
||
}
|