extern char *bgp_origin_long_str[];
\f
struct bgp_node *
-bgp_afi_node_get (struct bgp *bgp, afi_t afi, safi_t safi, struct prefix *p,
+bgp_afi_node_get (struct bgp_table *table, 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);
+ prn = bgp_node_get (table, (struct prefix *) prd);
if (prn->info == NULL)
prn->info = bgp_table_init ();
bgp_unlock_node (prn);
table = prn->info;
}
- else
- table = bgp->rib[afi][safi];
rn = bgp_node_get (table, p);
}
\f
int
+bgp_export_modifier (struct peer *rsclient, 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];
+
+ /* Route map apply. */
+ if (ROUTE_MAP_EXPORT_NAME (filter))
+ {
+ /* Duplicate current value to new strucutre for modification. */
+ info.peer = rsclient;
+ info.attr = attr;
+
+ SET_FLAG (rsclient->rmap_type, PEER_RMAP_TYPE_EXPORT);
+
+ /* Apply BGP route map to the attribute. */
+ ret = route_map_apply (ROUTE_MAP_EXPORT (filter), p, RMAP_BGP, &info);
+
+ rsclient->rmap_type = 0;
+
+ 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_import_modifier (struct peer *rsclient, 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 = &rsclient->filter[afi][safi];
+
+ /* Apply default weight value. */
+ attr->weight = peer->weight;
+
+ /* Route map apply. */
+ if (ROUTE_MAP_IMPORT_NAME (filter))
+ {
+ /* Duplicate current value to new strucutre for modification. */
+ info.peer = peer;
+ info.attr = attr;
+
+ SET_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT);
+
+ /* Apply BGP route map to the attribute. */
+ ret = route_map_apply (ROUTE_MAP_IMPORT (filter), p, RMAP_BGP, &info);
+
+ peer->rmap_type = 0;
+
+ if (ret == RMAP_DENYMATCH)
+ {
+ /* Free newly generated AS path and community by route-map. */
+ bgp_attr_flush (attr);
+ return RMAP_DENY;
+ }
+ }
+ return RMAP_PERMIT;
+}
+\f
+int
bgp_announce_check (struct bgp_info *ri, struct peer *peer, struct prefix *p,
struct attr *attr, afi_t afi, safi_t safi)
{
return 0;
#endif
+ /* Do not send announces to RS-clients from the 'normal' bgp_table. */
+ if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
+ return 0;
+
/* Do not send back route to sender. */
if (from == peer)
return 0;
|| (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED)
&& ((p->family == AF_INET && attr->nexthop.s_addr)
#ifdef HAVE_IPV6
- || (p->family == AF_INET6 && ri->peer != bgp->peer_self)
+ || (p->family == AF_INET6 &&
+ ! IN6_IS_ADDR_UNSPECIFIED(&attr->mp_nexthop_global))
#endif /* HAVE_IPV6 */
)))
{
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)
+ || (p->family == AF_INET6 &&
+ IN6_IS_ADDR_UNSPECIFIED(&attr->mp_nexthop_global))
#endif /* HAVE_IPV6 */
|| (peer_sort (peer) == BGP_PEER_EBGP
&& bgp_multiaccess_check_v4 (attr->nexthop, peer->host) == 0))
#ifdef HAVE_IPV6
if (p->family == AF_INET6)
{
+ /* Left nexthop_local unchanged if so configured. */
+ if ( CHECK_FLAG (peer->af_flags[afi][safi],
+ PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED) )
+ {
+ if ( IN6_IS_ADDR_LINKLOCAL (&attr->mp_nexthop_local) )
+ attr->mp_nexthop_len=32;
+ else
+ attr->mp_nexthop_len=16;
+ }
+
+ /* Default nexthop_local treatment for non-RS-Clients */
+ else
+ {
/* Link-local address should not be transit to different peer. */
attr->mp_nexthop_len = 16;
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. */
}
int
-bgp_process (struct bgp *bgp, struct bgp_node *rn, afi_t afi, safi_t safi)
+bgp_announce_check_rsclient (struct bgp_info *ri, struct peer *rsclient,
+ 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;
+
+ from = ri->peer;
+ filter = &rsclient->filter[afi][safi];
+ bgp = rsclient->bgp;
+
+#ifdef DISABLE_BGP_ANNOUNCE
+ return 0;
+#endif
+
+ /* Do not send back route to sender. */
+ if (from == rsclient)
+ return 0;
+
+ /* Aggregate-address suppress check. */
+ if (ri->suppress)
+ if (! UNSUPPRESS_MAP_NAME (filter))
+ return 0;
+
+ /* Default route check. */
+ if (CHECK_FLAG (rsclient->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 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 (&rsclient->remote_id, &ri->attr->originator_id))
+ {
+ if (BGP_DEBUG (filter, FILTER))
+ zlog (rsclient->log, LOG_INFO,
+ "%s [Update:SEND] %s/%d originator-id is same as remote router-id",
+ rsclient->host,
+ inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
+ p->prefixlen);
+ return 0;
+ }
+ }
+
+ /* ORF prefix-list filter check */
+ if (CHECK_FLAG (rsclient->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV)
+ && (CHECK_FLAG (rsclient->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
+ || CHECK_FLAG (rsclient->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_OLD_RCV)))
+ if (rsclient->orf_plist[afi][safi])
+ {
+ if (prefix_list_apply (rsclient->orf_plist[afi][safi], p) == PREFIX_DENY)
+ return 0;
+ }
+
+ /* Output filter check. */
+ if (bgp_output_filter (rsclient, p, ri->attr, afi, safi) == FILTER_DENY)
+ {
+ if (BGP_DEBUG (filter, FILTER))
+ zlog (rsclient->log, LOG_INFO,
+ "%s [Update:SEND] %s/%d is filtered",
+ rsclient->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, rsclient->as))
+ {
+ if (BGP_DEBUG (filter, FILTER))
+ zlog (rsclient->log, LOG_INFO,
+ "%s [Update:SEND] suppress announcement to peer AS %d is AS path.",
+ rsclient->host, rsclient->as);
+ return 0;
+ }
+#endif /* BGP_SEND_ASPATH_CHECK */
+
+ /* For modify attribute, copy it to temporary structure. */
+ *attr = *ri->attr;
+
+ /* next-hop-set */
+ if ((p->family == AF_INET && attr->nexthop.s_addr == 0)
+#ifdef HAVE_IPV6
+ || (p->family == AF_INET6 &&
+ IN6_IS_ADDR_UNSPECIFIED(&attr->mp_nexthop_global))
+#endif /* HAVE_IPV6 */
+ )
+ {
+ /* Set IPv4 nexthop. */
+ if (p->family == AF_INET)
+ {
+ if (safi == SAFI_MPLS_VPN)
+ memcpy (&attr->mp_nexthop_global_in, &rsclient->nexthop.v4,
+ IPV4_MAX_BYTELEN);
+ else
+ memcpy (&attr->nexthop, &rsclient->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, &rsclient->nexthop.v6_global,
+
+ IPV6_MAX_BYTELEN);
+ attr->mp_nexthop_len = 16;
+ }
+#endif /* HAVE_IPV6 */
+ }
+
+#ifdef HAVE_IPV6
+ if (p->family == AF_INET6)
+ {
+ /* Left nexthop_local unchanged if so configured. */
+ if ( CHECK_FLAG (rsclient->af_flags[afi][safi],
+ PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED) )
+ {
+ if ( IN6_IS_ADDR_LINKLOCAL (&attr->mp_nexthop_local) )
+ attr->mp_nexthop_len=32;
+ else
+ attr->mp_nexthop_len=16;
+ }
+
+ /* Default nexthop_local treatment for RS-Clients */
+ else
+ {
+ /* Announcer and RS-Client are both in the same network */
+ if (rsclient->shared_network && from->shared_network &&
+ (rsclient->ifindex == from->ifindex))
+ {
+ if ( IN6_IS_ADDR_LINKLOCAL (&attr->mp_nexthop_local) )
+ attr->mp_nexthop_len=32;
+ else
+ attr->mp_nexthop_len=16;
+ }
+
+ /* Set link-local address for shared network peer. */
+ else if (rsclient->shared_network
+ && IN6_IS_ADDR_LINKLOCAL (&rsclient->nexthop.v6_local))
+ {
+ memcpy (&attr->mp_nexthop_local, &rsclient->nexthop.v6_local,
+ IPV6_MAX_BYTELEN);
+ attr->mp_nexthop_len = 32;
+ }
+
+ else
+ attr->mp_nexthop_len = 16;
+ }
+
+ }
+#endif /* HAVE_IPV6 */
+
+
+ /* If this is EBGP peer and remove-private-AS is set. */
+ if (peer_sort (rsclient) == BGP_PEER_EBGP
+ && peer_af_flag_check (rsclient, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS)
+ && aspath_private_as_check (attr->aspath))
+ attr->aspath = aspath_empty_get ();
+
+ /* Route map & unsuppress-map apply. */
+ if (ROUTE_MAP_OUT_NAME (filter) || ri->suppress)
+ {
+ info.peer = rsclient;
+ info.attr = attr;
+
+ SET_FLAG (rsclient->rmap_type, PEER_RMAP_TYPE_OUT);
+
+ 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);
+
+ rsclient->rmap_type = 0;
+
+ if (ret == RMAP_DENYMATCH)
+ {
+ bgp_attr_flush (attr);
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+struct bgp_info_pair
+{
+ struct bgp_info *old;
+ struct bgp_info *new;
+};
+
+void
+bgp_best_selection (struct bgp *bgp, struct bgp_node *rn, struct bgp_info_pair *result)
{
- 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 *ri;
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))
new_select = ri;
}
- /* Nothing to do. */
- if (old_select && old_select == new_select)
- {
- if (! CHECK_FLAG (old_select->flags, BGP_INFO_ATTR_CHANGED))
+ if ( (! old_select) || old_select != new_select)
{
- 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)
+ result->old = old_select;
+ result->new = new_select;
+
+ return;
+}
+
+int
+bgp_process_announce_selected (struct peer *peer, struct bgp_info *selected,
+ struct bgp_node *rn, struct attr *attr, afi_t afi, safi_t safi)
{
+ struct prefix *p;
+
+ p = &rn->p;
+
/* Announce route to Established peer. */
if (peer->status != Established)
- continue;
+ return 0;
/* Address family configuration check. */
if (! peer->afc_nego[afi][safi])
- continue;
+ return 0;
/* 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;
+ if (CHECK_FLAG (peer->af_sflags[afi][safi],
+ PEER_STATUS_ORF_WAIT_REFRESH))
+ return 0;
+ switch (rn->table->type)
+ {
+ case BGP_TABLE_MAIN:
/* 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);
+ if (selected && bgp_announce_check (selected, peer, p, attr, afi, safi))
+ bgp_adj_out_set (rn, peer, p, attr, afi, safi, selected);
+ else
+ bgp_adj_out_unset (rn, peer, p, afi, safi);
+ break;
+ case BGP_TABLE_RSCLIENT:
+ /* Announcement to peer->conf. If the route is filtered,
+ withdraw it. */
+ if (selected && bgp_announce_check_rsclient
+ (selected, peer, p, attr, afi, safi))
+ bgp_adj_out_set (rn, peer, p, attr, afi, safi, selected);
else
bgp_adj_out_unset (rn, peer, p, afi, safi);
+ break;
+ }
+ return 0;
+ }
+
+int
+bgp_process_rsclient (struct bgp *bgp, struct peer *rsclient,
+ struct bgp_node *rn, afi_t afi, safi_t safi)
+{
+ struct prefix *p;
+ struct bgp_info *new_select;
+ struct bgp_info *old_select;
+ struct bgp_info_pair old_and_new;
+ struct attr attr;
+ struct peer_group *group;
+ struct listnode *nn;
+
+ p = &rn->p;
+
+ /* Best path selection. */
+ bgp_best_selection (bgp, rn, &old_and_new);
+ new_select = old_and_new.new;
+ old_select = old_and_new.old;
+
+ if (CHECK_FLAG(rsclient->sflags, PEER_STATUS_GROUP))
+ {
+ group = rsclient->group;
+ LIST_LOOP(group->peer, rsclient, nn)
+ {
+ /* Nothing to do. */
+ if (old_select && old_select == new_select)
+ if (! CHECK_FLAG (old_select->flags, BGP_INFO_ATTR_CHANGED))
+ continue;
+
+ bgp_process_announce_selected (rsclient, new_select, rn, &attr,
+ afi, safi);
+ }
+ return 0;
+ }
+
+ bgp_process_announce_selected (rsclient, new_select, rn, &attr, afi, safi);
+
+ return 0;
+}
+
+int
+bgp_process_main (struct bgp *bgp, struct bgp_node *rn, afi_t afi, safi_t safi)
+ {
+ struct prefix *p;
+ struct bgp_info *new_select;
+ struct bgp_info *old_select;
+ struct bgp_info_pair old_and_new;
+ struct listnode *nn;
+ struct peer *peer;
+ struct attr attr;
+
+ p = &rn->p;
+
+ /* Best path selection. */
+ bgp_best_selection (bgp, rn, &old_and_new);
+ old_select = old_and_new.old;
+ new_select = old_and_new.new;
+
+ /* 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;
+ }
+ }
+
+ /* Check each BGP peer. */
+ LIST_LOOP (bgp->peer, peer, nn)
+ {
+ bgp_process_announce_selected (peer, new_select, rn, &attr, afi, safi);
}
/* FIB update. */
return 0;
}
+int
+bgp_process (struct bgp *bgp, struct bgp_node *rn, afi_t afi, safi_t safi)
+{
+ switch (rn->table->type)
+ {
+ case BGP_TABLE_MAIN:
+ return bgp_process_main (bgp, rn, afi, safi);
+ case BGP_TABLE_RSCLIENT:
+ return bgp_process_rsclient (bgp, (struct peer *) rn->table->owner,
+ rn, afi, safi);
+ }
+ return 0;
+}
+
int
bgp_maximum_prefix_overflow (struct peer *peer, afi_t afi,
safi_t safi, int always)
{
if (! CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
{
+ /* Ignore 'pcount' for RS-client tables */
+ if ( rn->table->type == BGP_TABLE_MAIN)
+ {
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);
}
int valid;
int status = BGP_DAMP_NONE;
- if (! CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
+ /* Ignore 'pcount' for RS-client tables */
+ if (! CHECK_FLAG (ri->flags, BGP_INFO_HISTORY) &&
+ rn->table->type == BGP_TABLE_MAIN)
{
peer->pcount[afi][safi]--;
bgp_aggregate_decrement (peer->bgp, &rn->p, ri, afi, safi);
}
}
+void
+bgp_update_rsclient (struct peer *rsclient, afi_t afi, safi_t safi,
+ struct attr *attr, struct peer *peer, struct prefix *p, int type,
+ int sub_type, struct prefix_rd *prd, u_char *tag)
+{
+ struct bgp_node *rn;
+ struct bgp *bgp;
+ struct attr new_attr;
+ struct attr *attr_new;
+ struct attr *attr_new2;
+ struct bgp_info *ri;
+ struct bgp_info *new;
+ char *reason;
+ char buf[SU_ADDRSTRLEN];
+
+ /* Do not insert announces from a rsclient into its own 'bgp_table'. */
+ if (peer == rsclient)
+ return;
+
+ bgp = peer->bgp;
+ rn = bgp_afi_node_get (rsclient->rib[afi][safi], afi, safi, p, prd);
+
+ /* 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 loop check. */
+ if (aspath_loop_check (attr->aspath, rsclient->as) > 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 (&rsclient->remote_id, &attr->originator_id))
+ {
+ reason = "originator is us;";
+ goto filtered;
+ }
+
+ new_attr = *attr;
+
+ /* Apply export policy. */
+ if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT) &&
+ bgp_export_modifier (rsclient, peer, p, &new_attr, afi, safi) == RMAP_DENY)
+ {
+ reason = "export-policy;";
+ goto filtered;
+ }
+
+ attr_new2 = bgp_attr_intern (&new_attr);
+
+ /* Apply import policy. */
+ if (bgp_import_modifier (rsclient, peer, p, &new_attr, afi, safi) == RMAP_DENY)
+ {
+ bgp_attr_unintern (attr_new2);
+
+ reason = "import-policy;";
+ goto filtered;
+ }
+
+ attr_new = bgp_attr_intern (&new_attr);
+ bgp_attr_unintern (attr_new2);
+
+ /* IPv4 unicast next hop check. */
+ if (afi == AFI_IP && safi == SAFI_UNICAST)
+ {
+ /* Next hop must not be 0.0.0.0 nor Class E address. */
+ if (new_attr.nexthop.s_addr == 0
+ || ntohl (new_attr.nexthop.s_addr) >= 0xe0000000)
+ {
+ bgp_attr_unintern (attr_new);
+
+ reason = "martian next-hop;";
+ goto filtered;
+ }
+ }
+
+ /* 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 (BGP_DEBUG (update, UPDATE_IN))
+ zlog (peer->log, LOG_INFO,
+ "%s rcvd %s/%d for RS-client %s...duplicate ignored",
+ peer->host,
+ inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
+ p->prefixlen, rsclient->host);
+
+ bgp_unlock_node (rn);
+ bgp_attr_unintern (attr_new);
+
+ return;
+ }
+
+ /* Received Logging. */
+ if (BGP_DEBUG (update, UPDATE_IN))
+ zlog (peer->log, LOG_INFO, "%s rcvd %s/%d for RS-client %s",
+ peer->host,
+ inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
+ p->prefixlen, rsclient->host);
+
+ /* The attribute is changed. */
+ SET_FLAG (ri->flags, BGP_INFO_ATTR_CHANGED);
+
+ /* 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);
+
+ SET_FLAG (ri->flags, BGP_INFO_VALID);
+
+ /* Process change. */
+ bgp_process (bgp, rn, afi, safi);
+ bgp_unlock_node (rn);
+
+ return;
+ }
+
+ /* Received Logging. */
+ if (BGP_DEBUG (update, UPDATE_IN))
+ {
+ zlog (peer->log, LOG_INFO, "%s rcvd %s/%d for RS-client %s",
+ peer->host,
+ inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
+ p->prefixlen, rsclient->host);
+ }
+
+ /* 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);
+
+ SET_FLAG (new->flags, BGP_INFO_VALID);
+
+ /* Register new BGP information. */
+ bgp_info_add (rn, new);
+
+ /* Process change. */
+ bgp_process (bgp, rn, afi, safi);
+
+ return;
+
+ filtered:
+
+ /* This BGP update is filtered. Log the reason then update BGP entry. */
+ if (BGP_DEBUG (update, UPDATE_IN))
+ zlog (peer->log, LOG_INFO,
+ "%s rcvd UPDATE about %s/%d -- DENIED for RS-client %s due to: %s",
+ peer->host,
+ inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
+ p->prefixlen, rsclient->host, reason);
+
+ if (ri)
+ bgp_rib_withdraw (rn, ri, peer, afi, safi, 1);
+
+ bgp_unlock_node (rn);
+
+ return;
+}
+
+void
+bgp_withdraw_rsclient (struct peer *rsclient, afi_t afi, safi_t safi,
+ struct peer *peer, struct prefix *p, int type, int sub_type,
+ struct prefix_rd *prd, u_char *tag)
+ {
+ struct bgp_node *rn;
+ struct bgp_info *ri;
+ char buf[SU_ADDRSTRLEN];
+
+ if (rsclient == peer)
+ return;
+
+ rn = bgp_afi_node_get (rsclient->rib[afi][safi], afi, safi, p, prd);
+
+ /* 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);
+ }
+
int
-bgp_update (struct peer *peer, struct prefix *p, struct attr *attr,
+bgp_update_main (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)
{
char buf[SU_ADDRSTRLEN];
bgp = peer->bgp;
- rn = bgp_afi_node_get (bgp, afi, safi, p, prd);
+ rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd);
/* When peer's soft reconfiguration enabled. Record input packet in
Adj-RIBs-In. */
return 0;
}
+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)
+{
+ struct peer *rsclient;
+ struct listnode *nn;
+ struct bgp *bgp;
+ int ret;
+
+ ret = bgp_update_main (peer, p, attr, afi, safi, type, sub_type, prd, tag,
+ soft_reconfig);
+
+ bgp = peer->bgp;
+
+ /* Process the update for each RS-client. */
+ LIST_LOOP(bgp->rsclient, rsclient, nn)
+ {
+ if (CHECK_FLAG (rsclient->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
+ bgp_update_rsclient (rsclient, afi, safi, attr, peer, p, type,
+ sub_type, prd, tag);
+ }
+
+ return ret;
+}
+
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,
char buf[SU_ADDRSTRLEN];
struct bgp_node *rn;
struct bgp_info *ri;
+ struct peer *rsclient;
+ struct listnode *nn;
bgp = peer->bgp;
+ /* Process the withdraw for each RS-client. */
+ LIST_LOOP (bgp->rsclient, rsclient, nn)
+ {
+ if (CHECK_FLAG (rsclient->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
+ bgp_withdraw_rsclient (rsclient, afi, safi, peer, p, type, sub_type, prd, tag);
+ }
+
/* Logging. */
if (BGP_DEBUG (update, UPDATE_IN))
zlog (peer->log, LOG_INFO, "%s rcvd UPDATE about %s/%d -- withdrawn",
p->prefixlen);
/* Lookup node. */
- rn = bgp_afi_node_get (bgp, afi, safi, p, prd);
+ rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd);
/* If peer is soft reconfiguration enabled. Record input packet for
further calculation. */
binfo.peer = bgp->peer_self;
binfo.attr = &attr;
+ SET_FLAG (bgp->peer_self->rmap_type, PEER_RMAP_TYPE_DEFAULT);
+
ret = route_map_apply (peer->default_rmap[afi][safi].map, &p,
RMAP_BGP, &binfo);
+ bgp->peer_self->rmap_type = 0;
+
if (ret == RMAP_DENYMATCH)
{
bgp_attr_flush (&attr);
\f
static void
bgp_announce_table (struct peer *peer, afi_t afi, safi_t safi,
- struct bgp_table *table)
+ struct bgp_table *table, int rsclient)
{
struct bgp_node *rn;
struct bgp_info *ri;
struct attr attr;
if (! table)
- table = peer->bgp->rib[afi][safi];
+ table = (rsclient) ? peer->rib[afi][safi] : peer->bgp->rib[afi][safi];
if (safi != SAFI_MPLS_VPN
&& CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE))
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))
+ if ( (rsclient) ?
+ (bgp_announce_check_rsclient (ri, peer, &rn->p, &attr, afi, safi))
+ : (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);
return;
if (safi != SAFI_MPLS_VPN)
- bgp_announce_table (peer, afi, safi, NULL);
+ bgp_announce_table (peer, afi, safi, NULL, 0);
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);
+ bgp_announce_table (peer, afi, safi, table, 0);
+
+ if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
+ bgp_announce_table (peer, afi, safi, NULL, 1);
}
void
}
\f
static void
+bgp_soft_reconfig_table_rsclient (struct peer *rsclient, afi_t afi,
+ safi_t safi, struct bgp_table *table)
+{
+ struct bgp_node *rn;
+ struct bgp_adj_in *ain;
+
+ if (! table)
+ table = rsclient->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)
+ {
+ bgp_update_rsclient (rsclient, afi, safi, ain->attr, ain->peer,
+ &rn->p, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, NULL);
+ }
+}
+
+void
+bgp_soft_reconfig_rsclient (struct peer *rsclient, afi_t afi, safi_t safi)
+{
+ struct bgp_table *table;
+ struct bgp_node *rn;
+
+ if (safi != SAFI_MPLS_VPN)
+ bgp_soft_reconfig_table_rsclient (rsclient, afi, safi, NULL);
+
+ else
+ for (rn = bgp_table_top (rsclient->bgp->rib[afi][safi]); rn;
+ rn = bgp_route_next (rn))
+ if ((table = rn->info) != NULL)
+ bgp_soft_reconfig_table_rsclient (rsclient, afi, safi, table);
+}
+\f
+static void
bgp_soft_reconfig_table (struct peer *peer, afi_t afi, safi_t safi,
struct bgp_table *table)
{
\f
static void
bgp_clear_route_table (struct peer *peer, afi_t afi, safi_t safi,
- struct bgp_table *table)
+ struct bgp_table *table, struct peer *rsclient)
{
struct bgp_node *rn;
struct bgp_adj_in *ain;
struct bgp_info *ri;
if (! table)
- table = peer->bgp->rib[afi][safi];
+ table = (rsclient) ? rsclient->rib[afi][safi] : peer->bgp->rib[afi][safi];
for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
{
{
struct bgp_node *rn;
struct bgp_table *table;
+ struct peer *rsclient;
+ struct listnode *nn;
if (! peer->afc[afi][safi])
return;
if (safi != SAFI_MPLS_VPN)
- bgp_clear_route_table (peer, afi, safi, NULL);
+ bgp_clear_route_table (peer, afi, safi, NULL, 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);
+ bgp_clear_route_table (peer, afi, safi, table, NULL);
+
+ LIST_LOOP (peer->bgp->rsclient, rsclient, nn)
+ {
+ if (CHECK_FLAG(rsclient->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
+ bgp_clear_route_table (peer, afi, safi, NULL, rsclient);
+ }
}
void
}
void
-bgp_static_update (struct bgp *bgp, struct prefix *p,
+bgp_static_withdraw_rsclient (struct bgp *bgp, struct peer *rsclient,
+ struct prefix *p, afi_t afi, safi_t safi)
+{
+ struct bgp_node *rn;
+ struct bgp_info *ri;
+
+ rn = bgp_afi_node_get (rsclient->rib[afi][safi], 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)
+ {
+ 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_update_rsclient (struct peer *rsclient, 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 new_attr;
+ struct attr *attr_new;
+ struct attr attr;
+ struct bgp *bgp;
+ int ret;
+ char buf[SU_ADDRSTRLEN];
+
+ bgp = rsclient->bgp;
+
+ rn = bgp_afi_node_get (rsclient->rib[afi][safi], 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);
+ }
+
+ new_attr = attr;
+
+ /* Apply network route-map for export to this rsclient. */
+ if (bgp_static->rmap.name)
+ {
+ info.peer = rsclient;
+ info.attr = &new_attr;
+
+ SET_FLAG (rsclient->rmap_type, PEER_RMAP_TYPE_EXPORT);
+ SET_FLAG (rsclient->rmap_type, PEER_RMAP_TYPE_NETWORK);
+
+ ret = route_map_apply (bgp_static->rmap.map, p, RMAP_BGP, &info);
+
+ rsclient->rmap_type = 0;
+
+ if (ret == RMAP_DENYMATCH)
+ {
+ /* Free uninterned attribute. */
+ bgp_attr_flush (&new_attr);
+
+ /* Unintern original. */
+ aspath_unintern (attr.aspath);
+ bgp_static_withdraw_rsclient (bgp, rsclient, p, afi, safi);
+
+ return;
+ }
+ attr_new = bgp_attr_intern (&new_attr);
+ }
+ else
+ attr_new = bgp_attr_intern (&attr);
+
+ new_attr = *attr_new;
+
+ SET_FLAG (bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
+
+ if (bgp_import_modifier (rsclient, bgp->peer_self, p, &new_attr, afi, safi) == RMAP_DENY)
+{
+ /* This BGP update is filtered. Log the reason then update BGP entry. */
+ if (BGP_DEBUG (update, UPDATE_IN))
+ zlog (rsclient->log, LOG_INFO,
+ "Static UPDATE about %s/%d -- DENIED for RS-client %s due to: import-policy",
+ inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
+ p->prefixlen, rsclient->host);
+
+ bgp->peer_self->rmap_type = 0;
+
+ bgp_attr_unintern (attr_new);
+ aspath_unintern (attr.aspath);
+
+ bgp_static_withdraw_rsclient (bgp, rsclient, p, afi, safi);
+
+ return;
+ }
+
+ bgp->peer_self->rmap_type = 0;
+
+ bgp_attr_unintern (attr_new);
+ attr_new = bgp_attr_intern (&new_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_attr_unintern (ri->attr);
+ ri->attr = attr_new;
+ ri->uptime = time (NULL);
+
+ /* Process change. */
+ bgp_process (bgp, rn, afi, safi);
+ bgp_unlock_node (rn);
+ aspath_unintern (attr.aspath);
+ return;
+ }
+}
+\f
+ /* 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);
+
+ /* 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_main (struct bgp *bgp, struct prefix *p,
struct bgp_static *bgp_static, afi_t afi, safi_t safi)
{
struct bgp_node *rn;
struct attr *attr_new;
int ret;
- rn = bgp_afi_node_get (bgp, afi, safi, p, NULL);
+ rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, NULL);
bgp_attr_default_set (&attr, BGP_ORIGIN_IGP);
if (bgp_static)
info.peer = bgp->peer_self;
info.attr = &attr_tmp;
+ SET_FLAG (bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
+
ret = route_map_apply (bgp_static->rmap.map, p, RMAP_BGP, &info);
+ bgp->peer_self->rmap_type = 0;
+
if (ret == RMAP_DENYMATCH)
{
/* Free uninterned attribute. */
aspath_unintern (attr.aspath);
}
+void
+bgp_static_update (struct bgp *bgp, struct prefix *p,
+ struct bgp_static *bgp_static, afi_t afi, safi_t safi)
+{
+ struct peer *rsclient;
+ struct listnode *nn;
+
+ bgp_static_update_main (bgp, p, bgp_static, afi, safi);
+
+ LIST_LOOP(bgp->rsclient, rsclient, nn)
+ {
+ bgp_static_update_rsclient (rsclient, p, bgp_static, afi, safi);
+ }
+}
+
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);
+ rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd);
/* Make new BGP info. */
new = bgp_info_new ();
struct bgp_node *rn;
struct bgp_info *ri;
- rn = bgp_afi_node_get (bgp, afi, safi, p, NULL);
+ rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, NULL);
/* Check selected route and self inserted route. */
for (ri = rn->info; ri; ri = ri->next)
bgp_unlock_node (rn);
}
+void
+bgp_check_local_routes_rsclient (struct peer *rsclient, afi_t afi, safi_t safi)
+{
+ struct bgp_static *bgp_static;
+ struct bgp *bgp;
+ struct bgp_node *rn;
+ struct prefix *p;
+
+ bgp = rsclient->bgp;
+
+ for (rn = bgp_table_top (bgp->route[afi][safi]); rn; rn = bgp_route_next (rn))
+ if ((bgp_static = rn->info) != NULL)
+ {
+ p = &rn->p;
+
+ bgp_static_update_rsclient (rsclient, p, bgp_static,
+ afi, safi);
+ }
+}
+
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);
+ rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd);
/* Check selected route and self inserted route. */
for (ri = rn->info; ri; ri = ri->next)
info.peer = bgp->peer_self;
info.attr = &attr_new;
+ SET_FLAG (bgp->peer_self->rmap_type, PEER_RMAP_TYPE_REDISTRIBUTE);
+
ret = route_map_apply (bgp->rmap[afi][type].map, p, RMAP_BGP,
&info);
+
+ bgp->peer_self->rmap_type = 0;
+
if (ret == RMAP_DENYMATCH)
{
/* Free uninterned attribute. */
}
}
- bn = bgp_afi_node_get (bgp, afi, SAFI_UNICAST, p, NULL);
+ bn = bgp_afi_node_get (bgp->rib[afi][SAFI_UNICAST], afi, SAFI_UNICAST, p, NULL);
new_attr = bgp_attr_intern (&attr_new);
for (bi = bn->info; bi; bi = bi->next)
if (bgp->redist[afi][type])
{
- rn = bgp_afi_node_get (bgp, afi, SAFI_UNICAST, p, NULL);
+ rn = bgp_afi_node_get (bgp->rib[afi][SAFI_UNICAST], afi, SAFI_UNICAST, p, NULL);
for (ri = rn->info; ri; ri = ri->next)
if (ri->peer == bgp->peer_self
}
int
-bgp_show (struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
+bgp_show_table (struct vty *vty, struct bgp_table *table, struct in_addr *router_id,
enum bgp_show_type type)
{
struct bgp_info *ri;
struct bgp_node *rn;
- struct bgp_table *table;
int header = 1;
int count;
int limit;
? vty->lines : vty->height - 2));
limit = limit > 0 ? limit : 2;
- if (bgp == NULL) {
- 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)
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, "BGP table version is 0, local router ID is %s%s", inet_ntoa (*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
return CMD_SUCCESS;
}
+int
+bgp_show (struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
+ enum bgp_show_type type)
+{
+ struct bgp_table *table;
+
+ if (bgp == NULL) {
+ bgp = bgp_get_default ();
+ }
+
+ if (bgp == NULL)
+ {
+ vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+
+ table = bgp->rib[afi][safi];
+
+ return bgp_show_table (vty, table, &bgp->router_id, type);
+}
+
/* Header of detailed BGP route information */
void
route_vty_out_detail_header (struct vty *vty, struct bgp *bgp,
/* Display specified route of BGP table. */
int
-bgp_show_route (struct vty *vty, char *view_name, char *ip_str,
+bgp_show_route_in_table (struct vty *vty, struct bgp *bgp,
+ struct bgp_table *rib, char *ip_str,
afi_t afi, safi_t safi, struct prefix_rd *prd,
int prefix_check)
{
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)
if (safi == SAFI_MPLS_VPN)
{
- for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn; rn = bgp_route_next (rn))
+ for (rn = bgp_table_top (rib); rn; rn = bgp_route_next (rn))
{
if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
continue;
{
header = 1;
- if ((rn = bgp_node_match (bgp->rib[afi][safi], &match)) != NULL)
+ if ((rn = bgp_node_match (rib, &match)) != NULL)
{
if (! prefix_check || rn->p.prefixlen == match.prefixlen)
{
return CMD_SUCCESS;
}
+/* Display specified route of Main RIB */
+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)
+{
+ struct bgp *bgp;
+
+ /* 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;
+ }
+ }
+
+ return bgp_show_route_in_table (vty, bgp, bgp->rib[afi][safi], ip_str,
+ afi, safi, prd, prefix_check);
+}
+
/* BGP route print out function. */
DEFUN (show_ip_bgp,
show_ip_bgp_cmd,
bgp_show_type_neighbor);
}
+DEFUN (show_ip_bgp_view_rsclient,
+ show_ip_bgp_view_rsclient_cmd,
+ "show ip bgp view WORD rsclient (A.B.C.D|X:X::X:X)",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "BGP view\n"
+ "BGP view name\n"
+ "Information about Route Server Client\n"
+ NEIGHBOR_ADDR_STR)
+{
+ struct bgp_table *table;
+ struct peer *peer;
+
+ if (argc == 2)
+ peer = peer_lookup_in_view (vty, argv[0], argv[1]);
+ else
+ peer = peer_lookup_in_view (vty, NULL, argv[0]);
+
+ if (! peer)
+ return CMD_WARNING;
+
+ if (! peer->afc[AFI_IP][SAFI_UNICAST])
+ {
+ vty_out (vty, "%% Activate the neighbor for the address family first%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if ( ! CHECK_FLAG (peer->af_flags[AFI_IP][SAFI_UNICAST],
+ PEER_FLAG_RSERVER_CLIENT))
+ {
+ vty_out (vty, "%% Neighbor is not a Route-Server client%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ table = peer->rib[AFI_IP][SAFI_UNICAST];
+
+ return bgp_show_table (vty, table, &peer->remote_id, bgp_show_type_normal);
+}
+
+ALIAS (show_ip_bgp_view_rsclient,
+ show_ip_bgp_rsclient_cmd,
+ "show ip bgp rsclient (A.B.C.D|X:X::X:X)",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Information about Route Server Client\n"
+ NEIGHBOR_ADDR_STR)
+
+DEFUN (show_ip_bgp_view_rsclient_route,
+ show_ip_bgp_view_rsclient_route_cmd,
+ "show bgp view WORD rsclient (A.B.C.D|X:X::X:X) A.B.C.D",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "BGP view\n"
+ "BGP view name\n"
+ "Information about Route Server Client\n"
+ NEIGHBOR_ADDR_STR
+ "Network in the BGP routing table to display\n")
+{
+ struct bgp *bgp;
+ struct peer *peer;
+
+ /* BGP structure lookup. */
+ if (argc == 3)
+ {
+ bgp = bgp_lookup_by_name (argv[0]);
+ if (bgp == NULL)
+ {
+ vty_out (vty, "Can't find BGP view %s%s", argv[0], 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;
+ }
+ }
+
+ if (argc == 3)
+ peer = peer_lookup_in_view (vty, argv[0], argv[1]);
+ else
+ peer = peer_lookup_in_view (vty, NULL, argv[0]);
+
+ if (! peer)
+ return CMD_WARNING;
+
+ if (! peer->afc[AFI_IP][SAFI_UNICAST])
+ {
+ vty_out (vty, "%% Activate the neighbor for the address family first%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+}
+
+ if ( ! CHECK_FLAG (peer->af_flags[AFI_IP][SAFI_UNICAST],
+ PEER_FLAG_RSERVER_CLIENT))
+ {
+ vty_out (vty, "%% Neighbor is not a Route-Server client%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return bgp_show_route_in_table (vty, bgp, peer->rib[AFI_IP][SAFI_UNICAST],
+ (argc == 3) ? argv[2] : argv[1],
+ AFI_IP, SAFI_UNICAST, NULL, 0);
+}
+
+ALIAS (show_ip_bgp_view_rsclient_route,
+ show_ip_bgp_rsclient_route_cmd,
+ "show ip bgp rsclient (A.B.C.D|X:X::X:X) A.B.C.D",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Information about Route Server Client\n"
+ NEIGHBOR_ADDR_STR
+ "Network in the BGP routing table to display\n")
+
+DEFUN (show_ip_bgp_view_rsclient_prefix,
+ show_ip_bgp_view_rsclient_prefix_cmd,
+ "show ip bgp view WORD rsclient (A.B.C.D|X:X::X:X) A.B.C.D/M",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "BGP view\n"
+ "BGP view name\n"
+ "Information about Route Server Client\n"
+ NEIGHBOR_ADDR_STR
+ "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
+{
+ struct bgp *bgp;
+ struct peer *peer;
+
+ /* BGP structure lookup. */
+ if (argc == 3)
+ {
+ bgp = bgp_lookup_by_name (argv[0]);
+ if (bgp == NULL)
+ {
+ vty_out (vty, "Can't find BGP view %s%s", argv[0], 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;
+ }
+ }
+
+ if (argc == 3)
+ peer = peer_lookup_in_view (vty, argv[0], argv[1]);
+ else
+ peer = peer_lookup_in_view (vty, NULL, argv[0]);
+
+ if (! peer)
+ return CMD_WARNING;
+
+ if (! peer->afc[AFI_IP][SAFI_UNICAST])
+ {
+ vty_out (vty, "%% Activate the neighbor for the address family first%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+}
+
+ if ( ! CHECK_FLAG (peer->af_flags[AFI_IP][SAFI_UNICAST],
+ PEER_FLAG_RSERVER_CLIENT))
+{
+ vty_out (vty, "%% Neighbor is not a Route-Server client%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return bgp_show_route_in_table (vty, bgp, peer->rib[AFI_IP][SAFI_UNICAST],
+ (argc == 3) ? argv[2] : argv[1],
+ AFI_IP, SAFI_UNICAST, NULL, 1);
+}
+
+ALIAS (show_ip_bgp_view_rsclient_prefix,
+ show_ip_bgp_rsclient_prefix_cmd,
+ "show ip bgp rsclient (A.B.C.D|X:X::X:X) A.B.C.D/M",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Information about Route Server Client\n"
+ NEIGHBOR_ADDR_STR
+ "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
+
+
#ifdef HAVE_IPV6
DEFUN (show_bgp_view_neighbor_routes,
show_bgp_view_neighbor_routes_cmd,
"Neighbor to display information about\n"
"Neighbor to display information about\n"
"Display the dampened routes received from neighbor\n")
+
+DEFUN (show_bgp_view_rsclient,
+ show_bgp_view_rsclient_cmd,
+ "show bgp view WORD rsclient (A.B.C.D|X:X::X:X)",
+ SHOW_STR
+ BGP_STR
+ "BGP view\n"
+ "BGP view name\n"
+ "Information about Route Server Client\n"
+ NEIGHBOR_ADDR_STR)
+{
+ struct bgp_table *table;
+ struct peer *peer;
+
+ if (argc == 2)
+ peer = peer_lookup_in_view (vty, argv[0], argv[1]);
+ else
+ peer = peer_lookup_in_view (vty, NULL, argv[0]);
+
+ if (! peer)
+ return CMD_WARNING;
+
+ if (! peer->afc[AFI_IP6][SAFI_UNICAST])
+ {
+ vty_out (vty, "%% Activate the neighbor for the address family first%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if ( ! CHECK_FLAG (peer->af_flags[AFI_IP6][SAFI_UNICAST],
+ PEER_FLAG_RSERVER_CLIENT))
+ {
+ vty_out (vty, "%% Neighbor is not a Route-Server client%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ table = peer->rib[AFI_IP6][SAFI_UNICAST];
+
+ return bgp_show_table (vty, table, &peer->remote_id, bgp_show_type_normal);
+}
+
+ALIAS (show_bgp_view_rsclient,
+ show_bgp_rsclient_cmd,
+ "show bgp rsclient (A.B.C.D|X:X::X:X)",
+ SHOW_STR
+ BGP_STR
+ "Information about Route Server Client\n"
+ NEIGHBOR_ADDR_STR)
+
+DEFUN (show_bgp_view_rsclient_route,
+ show_bgp_view_rsclient_route_cmd,
+ "show bgp view WORD rsclient (A.B.C.D|X:X::X:X) X:X::X:X",
+ SHOW_STR
+ BGP_STR
+ "BGP view\n"
+ "BGP view name\n"
+ "Information about Route Server Client\n"
+ NEIGHBOR_ADDR_STR
+ "Network in the BGP routing table to display\n")
+{
+ struct bgp *bgp;
+ struct peer *peer;
+
+ /* BGP structure lookup. */
+ if (argc == 3)
+ {
+ bgp = bgp_lookup_by_name (argv[0]);
+ if (bgp == NULL)
+ {
+ vty_out (vty, "Can't find BGP view %s%s", argv[0], 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;
+ }
+ }
+
+ if (argc == 3)
+ peer = peer_lookup_in_view (vty, argv[0], argv[1]);
+ else
+ peer = peer_lookup_in_view (vty, NULL, argv[0]);
+
+ if (! peer)
+ return CMD_WARNING;
+
+ if (! peer->afc[AFI_IP6][SAFI_UNICAST])
+ {
+ vty_out (vty, "%% Activate the neighbor for the address family first%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if ( ! CHECK_FLAG (peer->af_flags[AFI_IP6][SAFI_UNICAST],
+ PEER_FLAG_RSERVER_CLIENT))
+ {
+ vty_out (vty, "%% Neighbor is not a Route-Server client%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return bgp_show_route_in_table (vty, bgp, peer->rib[AFI_IP6][SAFI_UNICAST],
+ (argc == 3) ? argv[2] : argv[1],
+ AFI_IP6, SAFI_UNICAST, NULL, 0);
+}
+
+ALIAS (show_bgp_view_rsclient_route,
+ show_bgp_rsclient_route_cmd,
+ "show bgp rsclient (A.B.C.D|X:X::X:X) X:X::X:X",
+ SHOW_STR
+ BGP_STR
+ "Information about Route Server Client\n"
+ NEIGHBOR_ADDR_STR
+ "Network in the BGP routing table to display\n")
+
+DEFUN (show_bgp_view_rsclient_prefix,
+ show_bgp_view_rsclient_prefix_cmd,
+ "show bgp view WORD rsclient (A.B.C.D|X:X::X:X) X:X::X:X/M",
+ SHOW_STR
+ BGP_STR
+ "BGP view\n"
+ "BGP view name\n"
+ "Information about Route Server Client\n"
+ NEIGHBOR_ADDR_STR
+ "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n")
+{
+ struct bgp *bgp;
+ struct peer *peer;
+
+ /* BGP structure lookup. */
+ if (argc == 3)
+ {
+ bgp = bgp_lookup_by_name (argv[0]);
+ if (bgp == NULL)
+ {
+ vty_out (vty, "Can't find BGP view %s%s", argv[0], 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;
+ }
+ }
+
+ if (argc == 3)
+ peer = peer_lookup_in_view (vty, argv[0], argv[1]);
+ else
+ peer = peer_lookup_in_view (vty, NULL, argv[0]);
+
+ if (! peer)
+ return CMD_WARNING;
+
+ if (! peer->afc[AFI_IP6][SAFI_UNICAST])
+ {
+ vty_out (vty, "%% Activate the neighbor for the address family first%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if ( ! CHECK_FLAG (peer->af_flags[AFI_IP6][SAFI_UNICAST],
+ PEER_FLAG_RSERVER_CLIENT))
+ {
+ vty_out (vty, "%% Neighbor is not a Route-Server client%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return bgp_show_route_in_table (vty, bgp, peer->rib[AFI_IP6][SAFI_UNICAST],
+ (argc == 3) ? argv[2] : argv[1],
+ AFI_IP6, SAFI_UNICAST, NULL, 1);
+}
+
+ALIAS (show_bgp_view_rsclient_prefix,
+ show_bgp_rsclient_prefix_cmd,
+ "show bgp rsclient (A.B.C.D|X:X::X:X) X:X::X:X/M",
+ SHOW_STR
+ BGP_STR
+ "Information about Route Server Client\n"
+ NEIGHBOR_ADDR_STR
+ "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n")
+
#endif /* HAVE_IPV6 */
\f
struct bgp_table *bgp_distance_table;
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 (VIEW_NODE, &show_ip_bgp_rsclient_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_rsclient_route_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_rsclient_prefix_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_view_rsclient_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_view_rsclient_route_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_view_rsclient_prefix_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_flap_route_map_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_neighbor_flap_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_neighbor_damp_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_rsclient_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_rsclient_route_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_rsclient_prefix_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_view_rsclient_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_view_rsclient_route_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_view_rsclient_prefix_cmd);
/* BGP dampening clear commands */
install_element (ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
install_element (VIEW_NODE, &show_bgp_ipv6_neighbor_flap_cmd);
install_element (VIEW_NODE, &show_bgp_neighbor_damp_cmd);
install_element (VIEW_NODE, &show_bgp_ipv6_neighbor_damp_cmd);
+ install_element (VIEW_NODE, &show_bgp_rsclient_cmd);
+ install_element (VIEW_NODE, &show_bgp_rsclient_route_cmd);
+ install_element (VIEW_NODE, &show_bgp_rsclient_prefix_cmd);
install_element (VIEW_NODE, &show_bgp_view_cmd);
install_element (VIEW_NODE, &show_bgp_view_ipv6_cmd);
install_element (VIEW_NODE, &show_bgp_view_route_cmd);
install_element (VIEW_NODE, &show_bgp_view_ipv6_neighbor_flap_cmd);
install_element (VIEW_NODE, &show_bgp_view_neighbor_damp_cmd);
install_element (VIEW_NODE, &show_bgp_view_ipv6_neighbor_damp_cmd);
+ install_element (VIEW_NODE, &show_bgp_view_rsclient_cmd);
+ install_element (VIEW_NODE, &show_bgp_view_rsclient_route_cmd);
+ install_element (VIEW_NODE, &show_bgp_view_rsclient_prefix_cmd);
install_element (ENABLE_NODE, &show_bgp_cmd);
install_element (ENABLE_NODE, &show_bgp_ipv6_cmd);
install_element (ENABLE_NODE, &show_bgp_ipv6_neighbor_flap_cmd);
install_element (ENABLE_NODE, &show_bgp_neighbor_damp_cmd);
install_element (ENABLE_NODE, &show_bgp_ipv6_neighbor_damp_cmd);
+ install_element (ENABLE_NODE, &show_bgp_rsclient_cmd);
+ install_element (ENABLE_NODE, &show_bgp_rsclient_route_cmd);
+ install_element (ENABLE_NODE, &show_bgp_rsclient_prefix_cmd);
install_element (ENABLE_NODE, &show_bgp_view_cmd);
install_element (ENABLE_NODE, &show_bgp_view_ipv6_cmd);
install_element (ENABLE_NODE, &show_bgp_view_route_cmd);
install_element (ENABLE_NODE, &show_bgp_view_ipv6_neighbor_flap_cmd);
install_element (ENABLE_NODE, &show_bgp_view_neighbor_damp_cmd);
install_element (ENABLE_NODE, &show_bgp_view_ipv6_neighbor_damp_cmd);
+ install_element (ENABLE_NODE, &show_bgp_view_rsclient_cmd);
+ install_element (ENABLE_NODE, &show_bgp_view_rsclient_route_cmd);
+ install_element (ENABLE_NODE, &show_bgp_view_rsclient_prefix_cmd);
/* old command */
install_element (VIEW_NODE, &show_ipv6_bgp_cmd);
#include "bgpd/bgp_open.h"
#include "bgpd/bgp_route.h"
#include "bgpd/bgp_zebra.h"
+#include "bgpd/bgp_table.h"
/* Utility function to get address family from current node. */
afi_t
\f
int
peer_af_flag_modify_vty (struct vty *vty, char *peer_str, afi_t afi,
- safi_t safi, u_int16_t flag, int set)
+ safi_t safi, u_int32_t flag, int set)
{
int ret;
struct peer *peer;
int
peer_af_flag_set_vty (struct vty *vty, char *peer_str, afi_t afi,
- safi_t safi, u_int16_t flag)
+ safi_t safi, u_int32_t flag)
{
return peer_af_flag_modify_vty (vty, peer_str, afi, safi, flag, 1);
}
int
peer_af_flag_unset_vty (struct vty *vty, char *peer_str, afi_t afi,
- safi_t safi, u_int16_t flag)
+ safi_t safi, u_int32_t flag)
{
return peer_af_flag_modify_vty (vty, peer_str, afi, safi, flag, 0);
}
PEER_FLAG_REFLECTOR_CLIENT);
}
\f
+int
+peer_rsclient_set_vty (struct vty *vty, char *peer_str, int afi, int safi)
+{
+ int ret;
+ struct bgp *bgp;
+ struct peer *peer;
+ struct peer_group *group;
+ struct listnode *nn;
+ struct bgp_filter *pfilter;
+ struct bgp_filter *gfilter;
+
+ bgp = vty->index;
+
+ peer = peer_and_group_lookup_vty (vty, peer_str);
+ if ( ! peer )
+ return CMD_WARNING;
+
+ /* If it is already a RS-Client, don't do anything. */
+ if ( CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT) )
+ return CMD_SUCCESS;
+
+ if ( ! peer_rsclient_active (peer) )
+ listnode_add_sort (bgp->rsclient, peer);
+
+ ret = peer_af_flag_set (peer, afi, safi, PEER_FLAG_RSERVER_CLIENT);
+ if (ret < 0)
+ return bgp_vty_return (vty, ret);
+
+ peer->rib[afi][safi] = bgp_table_init ();
+ peer->rib[afi][safi]->type = BGP_TABLE_RSCLIENT;
+ peer->rib[afi][safi]->owner = peer;
+
+ /* Check for existing 'network' and 'redistribute' routes. */
+ bgp_check_local_routes_rsclient (peer, afi, safi);
+
+ /* Check for routes for peers configured with 'soft-reconfiguration'. */
+ bgp_soft_reconfig_rsclient (peer, afi, safi);
+
+ if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
+ {
+ group = peer->group;
+ gfilter = &peer->filter[afi][safi];
+
+ LIST_LOOP(group->peer, peer, nn)
+ {
+ pfilter = &peer->filter[afi][safi];
+
+ /* Members of a non-RS-Client group should not be RS-Clients, as that
+ is checked when the become part of the peer-group */
+ ret = peer_af_flag_set (peer, afi, safi, PEER_FLAG_RSERVER_CLIENT);
+ if (ret < 0)
+ return bgp_vty_return (vty, ret);
+
+ /* Make peer's RIB point to group's RIB. */
+ peer->rib[afi][safi] = group->conf->rib[afi][safi];
+
+ /* Import policy. */
+ if (pfilter->map[RMAP_IMPORT].name)
+ free (pfilter->map[RMAP_IMPORT].name);
+ if (gfilter->map[RMAP_IMPORT].name)
+ {
+ pfilter->map[RMAP_IMPORT].name = strdup (gfilter->map[RMAP_IMPORT].name);
+ pfilter->map[RMAP_IMPORT].map = gfilter->map[RMAP_IMPORT].map;
+ }
+ else
+ {
+ pfilter->map[RMAP_IMPORT].name = NULL;
+ pfilter->map[RMAP_IMPORT].map =NULL;
+ }
+
+ /* Export policy. */
+ if (gfilter->map[RMAP_EXPORT].name && ! pfilter->map[RMAP_EXPORT].name)
+ {
+ pfilter->map[RMAP_EXPORT].name = strdup (gfilter->map[RMAP_EXPORT].name);
+ pfilter->map[RMAP_EXPORT].map = gfilter->map[RMAP_EXPORT].map;
+ }
+ }
+ }
+ return CMD_SUCCESS;
+}
+
+int
+peer_rsclient_unset_vty (struct vty *vty, char *peer_str, int afi, int safi)
+{
+ int ret;
+ struct bgp *bgp;
+ struct peer *peer;
+ struct peer_group *group;
+ struct listnode *nn;
+
+ bgp = vty->index;
+
+ peer = peer_and_group_lookup_vty (vty, peer_str);
+ if ( ! peer )
+ return CMD_WARNING;
+
+ /* If it is not a RS-Client, don't do anything. */
+ if ( ! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT) )
+ return CMD_SUCCESS;
+
+ if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
+ {
+ group = peer->group;
+
+ LIST_LOOP (group->peer, peer, nn)
+ {
+ ret = peer_af_flag_unset (peer, afi, safi, PEER_FLAG_RSERVER_CLIENT);
+ if (ret < 0)
+ return bgp_vty_return (vty, ret);
+
+ peer->rib[afi][safi] = NULL;
+ }
+
+ peer = group->conf;
+ }
+
+ ret = peer_af_flag_unset (peer, afi, safi, PEER_FLAG_RSERVER_CLIENT);
+ if (ret < 0)
+ return bgp_vty_return (vty, ret);
+
+ if ( ! peer_rsclient_active (peer) )
+ listnode_delete (bgp->rsclient, peer);
+
+ bgp_table_finish (peer->rib[bgp_node_afi(vty)][bgp_node_safi(vty)]);
+
+ return CMD_SUCCESS;
+}
+\f
/* neighbor route-server-client. */
DEFUN (neighbor_route_server_client,
neighbor_route_server_client_cmd,
NEIGHBOR_ADDR_STR2
"Configure a neighbor as Route Server client\n")
{
- return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
- bgp_node_safi (vty),
- PEER_FLAG_RSERVER_CLIENT);
+ return peer_rsclient_set_vty (vty, argv[0], bgp_node_afi(vty),
+ bgp_node_safi(vty));
}
DEFUN (no_neighbor_route_server_client,
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Configure a neighbor as Route Server client\n")
+{
+ return peer_rsclient_unset_vty (vty, argv[0], bgp_node_afi(vty),
+ bgp_node_safi(vty));
+}
+\f
+DEFUN (neighbor_nexthop_local_unchanged,
+ neighbor_nexthop_local_unchanged_cmd,
+ NEIGHBOR_CMD2 "nexthop-local unchanged",
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Configure treatment of outgoing link-local nexthop attribute\n"
+ "Leave link-local nexthop unchanged for this peer\n")
+{
+ return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
+ bgp_node_safi (vty),
+ PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED );
+}
+\f
+DEFUN (no_neighbor_nexthop_local_unchanged,
+ no_neighbor_nexthop_local_unchanged_cmd,
+ NO_NEIGHBOR_CMD2 "nexthop-local unchanged",
+ NO_STR
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Configure treatment of outgoing link-local-nexthop attribute\n"
+ "Leave link-local nexthop unchanged for this peer\n")
{
return peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
bgp_node_safi (vty),
- PEER_FLAG_RSERVER_CLIENT);
+ PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED );
}
\f
DEFUN (neighbor_attr_unchanged,
{
int ret;
struct peer *peer;
- int direct = FILTER_IN;
+ int direct = RMAP_IN;
peer = peer_and_group_lookup_vty (vty, ip_str);
if (! peer)
return CMD_WARNING;
/* Check filter direction. */
- if (strncmp (direct_str, "i", 1) == 0)
- direct = FILTER_IN;
+ if (strncmp (direct_str, "in", 2) == 0)
+ direct = RMAP_IN;
else if (strncmp (direct_str, "o", 1) == 0)
- direct = FILTER_OUT;
+ direct = RMAP_OUT;
+ else if (strncmp (direct_str, "im", 2) == 0)
+ direct = RMAP_IMPORT;
+ else if (strncmp (direct_str, "e", 1) == 0)
+ direct = RMAP_EXPORT;
ret = peer_route_map_set (peer, afi, safi, direct, name_str);
{
int ret;
struct peer *peer;
- int direct = FILTER_IN;
+ int direct = RMAP_IN;
peer = peer_and_group_lookup_vty (vty, ip_str);
if (! peer)
return CMD_WARNING;
/* Check filter direction. */
- if (strncmp (direct_str, "i", 1) == 0)
- direct = FILTER_IN;
+ if (strncmp (direct_str, "in", 2) == 0)
+ direct = RMAP_IN;
else if (strncmp (direct_str, "o", 1) == 0)
-
- direct = FILTER_OUT;
+ direct = RMAP_OUT;
+ else if (strncmp (direct_str, "im", 2) == 0)
+ direct = RMAP_IMPORT;
+ else if (strncmp (direct_str, "e", 1) == 0)
+ direct = RMAP_EXPORT;
ret = peer_route_map_unset (peer, afi, safi, direct);
DEFUN (neighbor_route_map,
neighbor_route_map_cmd,
- NEIGHBOR_CMD2 "route-map WORD (in|out)",
+ NEIGHBOR_CMD2 "route-map WORD (in|out|import|export)",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Apply route map to neighbor\n"
"Name of route map\n"
"Apply map to incoming routes\n"
- "Apply map to outbound routes\n")
+ "Apply map to outbound routes\n"
+ "Apply map to routes going into a Route-Server client's table\n"
+ "Apply map to routes coming from a Route-Server client")
{
return peer_route_map_set_vty (vty, argv[0], bgp_node_afi (vty),
bgp_node_safi (vty), argv[1], argv[2]);
DEFUN (no_neighbor_route_map,
no_neighbor_route_map_cmd,
- NO_NEIGHBOR_CMD2 "route-map WORD (in|out)",
+ NO_NEIGHBOR_CMD2 "route-map WORD (in|out|import|export)",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Apply route map to neighbor\n"
"Name of route map\n"
"Apply map to incoming routes\n"
- "Apply map to outbound routes\n")
+ "Apply map to outbound routes\n"
+ "Apply map to routes going into a Route-Server client's table\n"
+ "Apply map to routes coming from a Route-Server client")
{
return peer_route_map_unset_vty (vty, argv[0], bgp_node_afi (vty),
bgp_node_safi (vty), argv[2]);
"Clear peers with the AS number\n"
"Soft reconfig\n")
\f
+/* RS-client soft reconfiguration. */
+#ifdef HAVE_IPV6
+DEFUN (clear_bgp_all_rsclient,
+ clear_bgp_all_rsclient_cmd,
+ "clear bgp * rsclient",
+ CLEAR_STR
+ BGP_STR
+ "Clear all peers\n"
+ "Soft reconfig for rsclient RIB\n")
+{
+ if (argc == 1)
+ return bgp_clear_vty (vty, argv[0], AFI_IP6, SAFI_UNICAST, clear_all,
+ BGP_CLEAR_SOFT_RSCLIENT, NULL);
+
+ return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_all,
+ BGP_CLEAR_SOFT_RSCLIENT, NULL);
+}
+
+ALIAS (clear_bgp_all_rsclient,
+ clear_bgp_ipv6_all_rsclient_cmd,
+ "clear bgp ipv6 * rsclient",
+ CLEAR_STR
+ BGP_STR
+ "Address family\n"
+ "Clear all peers\n"
+ "Soft reconfig for rsclient RIB\n")
+
+ALIAS (clear_bgp_all_rsclient,
+ clear_bgp_instance_all_rsclient_cmd,
+ "clear bgp view WORD * rsclient",
+ CLEAR_STR
+ BGP_STR
+ "BGP view\n"
+ "view name\n"
+ "Clear all peers\n"
+ "Soft reconfig for rsclient RIB\n")
+
+ALIAS (clear_bgp_all_rsclient,
+ clear_bgp_ipv6_instance_all_rsclient_cmd,
+ "clear bgp ipv6 view WORD * rsclient",
+ CLEAR_STR
+ BGP_STR
+ "Address family\n"
+ "BGP view\n"
+ "view name\n"
+ "Clear all peers\n"
+ "Soft reconfig for rsclient RIB\n")
+#endif /* HAVE_IPV6 */
+
+DEFUN (clear_ip_bgp_all_rsclient,
+ clear_ip_bgp_all_rsclient_cmd,
+ "clear ip bgp * rsclient",
+ CLEAR_STR
+ IP_STR
+ BGP_STR
+ "Clear all peers\n"
+ "Soft reconfig for rsclient RIB\n")
+{
+ if (argc == 1)
+ return bgp_clear_vty (vty, argv[0], AFI_IP, SAFI_UNICAST, clear_all,
+ BGP_CLEAR_SOFT_RSCLIENT, NULL);
+
+ return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_all,
+ BGP_CLEAR_SOFT_RSCLIENT, NULL);
+}
+
+ALIAS (clear_ip_bgp_all_rsclient,
+ clear_ip_bgp_instance_all_rsclient_cmd,
+ "clear ip bgp view WORD * rsclient",
+ CLEAR_STR
+ IP_STR
+ BGP_STR
+ "BGP view\n"
+ "view name\n"
+ "Clear all peers\n"
+ "Soft reconfig for rsclient RIB\n")
+
+#ifdef HAVE_IPV6
+DEFUN (clear_bgp_peer_rsclient,
+ clear_bgp_peer_rsclient_cmd,
+ "clear bgp (A.B.C.D|X:X::X:X) rsclient",
+ CLEAR_STR
+ BGP_STR
+ "BGP neighbor IP address to clear\n"
+ "BGP IPv6 neighbor to clear\n"
+ "Soft reconfig for rsclient RIB\n")
+{
+ if (argc == 2)
+ return bgp_clear_vty (vty, argv[0], AFI_IP6, SAFI_UNICAST, clear_peer,
+ BGP_CLEAR_SOFT_RSCLIENT, argv[1]);
+
+ return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_peer,
+ BGP_CLEAR_SOFT_RSCLIENT, argv[0]);
+}
+
+ALIAS (clear_bgp_peer_rsclient,
+ clear_bgp_ipv6_peer_rsclient_cmd,
+ "clear bgp ipv6 (A.B.C.D|X:X::X:X) rsclient",
+ CLEAR_STR
+ BGP_STR
+ "Address family\n"
+ "BGP neighbor IP address to clear\n"
+ "BGP IPv6 neighbor to clear\n"
+ "Soft reconfig for rsclient RIB\n")
+
+ALIAS (clear_bgp_peer_rsclient,
+ clear_bgp_instance_peer_rsclient_cmd,
+ "clear bgp view WORD (A.B.C.D|X:X::X:X) rsclient",
+ CLEAR_STR
+ BGP_STR
+ "BGP view\n"
+ "view name\n"
+ "BGP neighbor IP address to clear\n"
+ "BGP IPv6 neighbor to clear\n"
+ "Soft reconfig for rsclient RIB\n")
+
+ALIAS (clear_bgp_peer_rsclient,
+ clear_bgp_ipv6_instance_peer_rsclient_cmd,
+ "clear bgp ipv6 view WORD (A.B.C.D|X:X::X:X) rsclient",
+ CLEAR_STR
+ BGP_STR
+ "Address family\n"
+ "BGP view\n"
+ "view name\n"
+ "BGP neighbor IP address to clear\n"
+ "BGP IPv6 neighbor to clear\n"
+ "Soft reconfig for rsclient RIB\n")
+#endif /* HAVE_IPV6 */
+
+DEFUN (clear_ip_bgp_peer_rsclient,
+ clear_ip_bgp_peer_rsclient_cmd,
+ "clear ip bgp (A.B.C.D|X:X::X:X) rsclient",
+ CLEAR_STR
+ IP_STR
+ BGP_STR
+ "BGP neighbor IP address to clear\n"
+ "BGP IPv6 neighbor to clear\n"
+ "Soft reconfig for rsclient RIB\n")
+{
+ if (argc == 2)
+ return bgp_clear_vty (vty, argv[0], AFI_IP, SAFI_UNICAST, clear_peer,
+ BGP_CLEAR_SOFT_RSCLIENT, argv[1]);
+
+ return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_peer,
+ BGP_CLEAR_SOFT_RSCLIENT, argv[0]);
+}
+
+ALIAS (clear_ip_bgp_peer_rsclient,
+ clear_ip_bgp_instance_peer_rsclient_cmd,
+ "clear ip bgp view WORD (A.B.C.D|X:X::X:X) rsclient",
+ CLEAR_STR
+ IP_STR
+ BGP_STR
+ "BGP view\n"
+ "view name\n"
+ "BGP neighbor IP address to clear\n"
+ "BGP IPv6 neighbor to clear\n"
+ "Soft reconfig for rsclient RIB\n")
+
+
/* Show BGP peer's summary information. */
int
bgp_show_summary (struct vty *vty, struct bgp *bgp, int afi, int safi)
if (filter->plist[FILTER_IN].name
|| filter->dlist[FILTER_IN].name
|| filter->aslist[FILTER_IN].name
- || filter->map[FILTER_IN].name)
+ || filter->map[RMAP_IN].name)
vty_out (vty, " Inbound path policy configured%s", VTY_NEWLINE);
if (filter->plist[FILTER_OUT].name
|| filter->dlist[FILTER_OUT].name
|| filter->aslist[FILTER_OUT].name
- || filter->map[FILTER_OUT].name
+ || filter->map[RMAP_OUT].name
|| filter->usmap.name)
vty_out (vty, " Outbound path policy configured%s", VTY_NEWLINE);
+ if (filter->map[RMAP_IMPORT].name)
+ vty_out (vty, " Import policy for this RS-client configured%s", VTY_NEWLINE);
+ if (filter->map[RMAP_EXPORT].name)
+ vty_out (vty, " Export policy for this RS-client configured%s", VTY_NEWLINE);
/* prefix-list */
if (filter->plist[FILTER_IN].name)
VTY_NEWLINE);
/* route-map. */
- if (filter->map[FILTER_IN].name)
+ if (filter->map[RMAP_IN].name)
vty_out (vty, " Route map for incoming advertisements is %s%s%s",
- filter->map[FILTER_IN].map ? "*" : "",
- filter->map[FILTER_IN].name,
+ filter->map[RMAP_IN].map ? "*" : "",
+ filter->map[RMAP_IN].name,
VTY_NEWLINE);
- if (filter->map[FILTER_OUT].name)
+ if (filter->map[RMAP_OUT].name)
vty_out (vty, " Route map for outgoing advertisements is %s%s%s",
- filter->map[FILTER_OUT].map ? "*" : "",
- filter->map[FILTER_OUT].name,
+ filter->map[RMAP_OUT].map ? "*" : "",
+ filter->map[RMAP_OUT].name,
+ VTY_NEWLINE);
+ if (filter->map[RMAP_IMPORT].name)
+ vty_out (vty, " Route map for advertisements going into this RS-client's table is %s%s%s",
+ filter->map[RMAP_IMPORT].map ? "*" : "",
+ filter->map[RMAP_IMPORT].name,
+ VTY_NEWLINE);
+ if (filter->map[RMAP_EXPORT].name)
+ vty_out (vty, " Route map for advertisements coming from this RS-client is %s%s%s",
+ filter->map[RMAP_EXPORT].map ? "*" : "",
+ filter->map[RMAP_EXPORT].name,
VTY_NEWLINE);
/* unsuppress-map */
return CMD_SUCCESS;
}
\f
+int
+bgp_write_rsclient_summary (struct vty *vty, struct peer *rsclient,
+ afi_t afi, safi_t safi)
+{
+ char timebuf[BGP_UPTIME_LEN];
+ char rmbuf[14];
+ char *rmname;
+ struct peer *peer;
+ struct listnode *nn;
+ int len;
+ int count = 0;
+
+ if (CHECK_FLAG (rsclient->sflags, PEER_STATUS_GROUP))
+ {
+ LIST_LOOP (rsclient->group->peer, peer, nn)
+ {
+ count++;
+ bgp_write_rsclient_summary (vty, peer, afi, safi);
+ }
+ return count;
+ }
+
+ len = vty_out (vty, "%s", rsclient->host);
+ len = 16 - len;
+
+ if (len < 1)
+ vty_out (vty, "%s%*s", VTY_NEWLINE, 16, " ");
+ else
+ vty_out (vty, "%*s", len, " ");
+
+ switch (rsclient->version)
+ {
+ case BGP_VERSION_4:
+ vty_out (vty, "4 ");
+ break;
+ case BGP_VERSION_MP_4_DRAFT_00:
+ vty_out (vty, "4-");
+ break;
+ }
+
+ vty_out (vty, "%5d ", rsclient->as);
+
+ rmname = ROUTE_MAP_EXPORT_NAME(&rsclient->filter[afi][safi]);
+ if ( rmname && strlen (rmname) > 13 )
+ {
+ sprintf (rmbuf, "%13s", "...");
+ rmname = strncpy (rmbuf, rmname, 10);
+ }
+ else if (! rmname)
+ rmname = "<none>";
+ vty_out (vty, " %13s ", rmname);
+
+ rmname = ROUTE_MAP_IMPORT_NAME(&rsclient->filter[afi][safi]);
+ if ( rmname && strlen (rmname) > 13 )
+ {
+ sprintf (rmbuf, "%13s", "...");
+ rmname = strncpy (rmbuf, rmname, 10);
+ }
+ else if (! rmname)
+ rmname = "<none>";
+ vty_out (vty, " %13s ", rmname);
+
+ vty_out (vty, "%8s", peer_uptime (rsclient->uptime, timebuf, BGP_UPTIME_LEN));
+
+ if (CHECK_FLAG (rsclient->flags, PEER_FLAG_SHUTDOWN))
+ vty_out (vty, " Idle (Admin)");
+ else if (CHECK_FLAG (rsclient->sflags, PEER_STATUS_PREFIX_OVERFLOW))
+ vty_out (vty, " Idle (PfxCt)");
+ else
+ vty_out (vty, " %-11s", LOOKUP(bgp_status_msg, rsclient->status));
+
+ vty_out (vty, "%s", VTY_NEWLINE);
+
+ return 1;
+}
+
+int
+bgp_show_rsclient_summary (struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi)
+{
+ struct peer *peer;
+ struct listnode *nn;
+ int count = 0;
+
+ /* Header string for each address family. */
+ static char header[] = "Neighbor V AS Export-Policy Import-Policy Up/Down State";
+
+ LIST_LOOP (bgp->rsclient, peer, nn)
+ {
+ if (peer->afc[afi][safi] &&
+ CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
+ {
+ if (! count)
+ {
+ vty_out (vty,
+ "Route Server's BGP router identifier %s%s",
+ inet_ntoa (bgp->router_id), VTY_NEWLINE);
+ vty_out (vty,
+ "Route Server's local AS number %d%s", bgp->as,
+ VTY_NEWLINE);
+
+ vty_out (vty, "%s", VTY_NEWLINE);
+ vty_out (vty, "%s%s", header, VTY_NEWLINE);
+ }
+
+ count += bgp_write_rsclient_summary (vty, peer, afi, safi);
+ }
+ }
+
+ if (count)
+ vty_out (vty, "%sTotal number of Route Server Clients %d%s", VTY_NEWLINE,
+ count, VTY_NEWLINE);
+ else
+ vty_out (vty, "No %s Route Server Client is configured%s",
+ afi == AFI_IP ? "IPv4" : "IPv6", VTY_NEWLINE);
+
+ return CMD_SUCCESS;
+}
+
+int
+bgp_show_rsclient_summary_vty (struct vty *vty, char *name, afi_t afi, safi_t safi)
+{
+ struct bgp *bgp;
+
+ if (name)
+ {
+ bgp = bgp_lookup_by_name (name);
+
+ if (! bgp)
+ {
+ vty_out (vty, "%% No such BGP instance exist%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ bgp_show_rsclient_summary (vty, bgp, afi, safi);
+ return CMD_SUCCESS;
+ }
+
+ bgp = bgp_get_default ();
+
+ if (bgp)
+ bgp_show_rsclient_summary (vty, bgp, afi, safi);
+
+ return CMD_SUCCESS;
+}
+
+/* 'show bgp rsclient' commands. */
+DEFUN (show_ip_bgp_rsclient_summary,
+ show_ip_bgp_rsclient_summary_cmd,
+ "show ip bgp rsclient summary",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Information about Route Server Clients\n"
+ "Summary of all Route Server Clients\n")
+{
+ return bgp_show_rsclient_summary_vty (vty, NULL, AFI_IP, SAFI_UNICAST);
+}
+
+DEFUN (show_ip_bgp_instance_rsclient_summary,
+ show_ip_bgp_instance_rsclient_summary_cmd,
+ "show ip bgp view WORD rsclient summary",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "BGP view\n"
+ "View name\n"
+ "Information about Route Server Clients\n"
+ "Summary of all Route Server Clients\n")
+{
+ return bgp_show_rsclient_summary_vty (vty, argv[0], AFI_IP, SAFI_UNICAST);
+}
+
+DEFUN (show_ip_bgp_ipv4_rsclient_summary,
+ show_ip_bgp_ipv4_rsclient_summary_cmd,
+ "show ip bgp ipv4 (unicast|multicast) rsclient summary",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Information about Route Server Clients\n"
+ "Summary of all Route Server Clients\n")
+{
+ if (strncmp (argv[0], "m", 1) == 0)
+ return bgp_show_rsclient_summary_vty (vty, NULL, AFI_IP, SAFI_MULTICAST);
+
+ return bgp_show_rsclient_summary_vty (vty, NULL, AFI_IP, SAFI_UNICAST);
+}
+
+DEFUN (show_ip_bgp_instance_ipv4_rsclient_summary,
+ show_ip_bgp_instance_ipv4_rsclient_summary_cmd,
+ "show ip bgp view WORD ipv4 (unicast|multicast) rsclient summary",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "BGP view\n"
+ "View name\n"
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Information about Route Server Clients\n"
+ "Summary of all Route Server Clients\n")
+{
+ if (strncmp (argv[1], "m", 1) == 0)
+ return bgp_show_rsclient_summary_vty (vty, argv[0], AFI_IP, SAFI_MULTICAST);
+
+ return bgp_show_rsclient_summary_vty (vty, argv[0], AFI_IP, SAFI_UNICAST);
+}
+
+#ifdef HAVE_IPV6
+DEFUN (show_bgp_rsclient_summary,
+ show_bgp_rsclient_summary_cmd,
+ "show bgp rsclient summary",
+ SHOW_STR
+ BGP_STR
+ "Information about Route Server Clients\n"
+ "Summary of all Route Server Clients\n")
+{
+ return bgp_show_rsclient_summary_vty (vty, NULL, AFI_IP6, SAFI_UNICAST);
+}
+
+DEFUN (show_bgp_instance_rsclient_summary,
+ show_bgp_instance_rsclient_summary_cmd,
+ "show bgp view WORD rsclient summary",
+ SHOW_STR
+ BGP_STR
+ "BGP view\n"
+ "View name\n"
+ "Information about Route Server Clients\n"
+ "Summary of all Route Server Clients\n")
+{
+ return bgp_show_rsclient_summary_vty (vty, argv[0], AFI_IP6, SAFI_UNICAST);
+}
+
+ALIAS (show_bgp_rsclient_summary,
+ show_bgp_ipv6_rsclient_summary_cmd,
+ "show bgp ipv6 rsclient summary",
+ SHOW_STR
+ BGP_STR
+ "Address family\n"
+ "Information about Route Server Clients\n"
+ "Summary of all Route Server Clients\n")
+
+ALIAS (show_bgp_instance_rsclient_summary,
+ show_bgp_instance_ipv6_rsclient_summary_cmd,
+ "show bgp view WORD ipv6 rsclient summary",
+ SHOW_STR
+ BGP_STR
+ "BGP view\n"
+ "View name\n"
+ "Address family\n"
+ "Information about Route Server Clients\n"
+ "Summary of all Route Server Clients\n")
+#endif /* HAVE IPV6 */
+\f
/* Redistribute VTY commands. */
/* Utility function to convert user input route type string to route
install_element (BGP_VPNV4_NODE, &no_neighbor_attr_unchanged9_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_attr_unchanged10_cmd);
+ /* "nexthop-local unchanged" commands */
+ install_element (BGP_IPV6_NODE, &neighbor_nexthop_local_unchanged_cmd);
+ install_element (BGP_IPV6_NODE, &no_neighbor_nexthop_local_unchanged_cmd);
+
/* "transparent-as" and "transparent-nexthop" for old version
compatibility. */
install_element (BGP_NODE, &neighbor_transparent_as_cmd);
install_element (ENABLE_NODE, &clear_bgp_ipv6_as_soft_cmd);
#endif /* HAVE_IPV6 */
+ /* "clear ip bgp neighbor rsclient" */
+ install_element (ENABLE_NODE, &clear_ip_bgp_all_rsclient_cmd);
+ install_element (ENABLE_NODE, &clear_ip_bgp_instance_all_rsclient_cmd);
+ install_element (ENABLE_NODE, &clear_ip_bgp_peer_rsclient_cmd);
+ install_element (ENABLE_NODE, &clear_ip_bgp_instance_peer_rsclient_cmd);
+#ifdef HAVE_IPV6
+ install_element (ENABLE_NODE, &clear_bgp_all_rsclient_cmd);
+ install_element (ENABLE_NODE, &clear_bgp_instance_all_rsclient_cmd);
+ install_element (ENABLE_NODE, &clear_bgp_ipv6_all_rsclient_cmd);
+ install_element (ENABLE_NODE, &clear_bgp_ipv6_instance_all_rsclient_cmd);
+ install_element (ENABLE_NODE, &clear_bgp_peer_rsclient_cmd);
+ install_element (ENABLE_NODE, &clear_bgp_instance_peer_rsclient_cmd);
+ install_element (ENABLE_NODE, &clear_bgp_ipv6_peer_rsclient_cmd);
+ install_element (ENABLE_NODE, &clear_bgp_ipv6_instance_peer_rsclient_cmd);
+#endif /* HAVE_IPV6 */
+
/* "show ip bgp summary" commands. */
install_element (VIEW_NODE, &show_ip_bgp_summary_cmd);
install_element (VIEW_NODE, &show_ip_bgp_instance_summary_cmd);
install_element (ENABLE_NODE, &show_ipv6_mbgp_summary_cmd);
#endif /* HAVE_IPV6 */
+ /* "show ip bgp rsclient" commands. */
+ install_element (VIEW_NODE, &show_ip_bgp_rsclient_summary_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_instance_rsclient_summary_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_ipv4_rsclient_summary_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_instance_ipv4_rsclient_summary_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_rsclient_summary_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_instance_rsclient_summary_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_ipv4_rsclient_summary_cmd);
+ install_element (ENABLE_NODE, &show_ip_bgp_instance_ipv4_rsclient_summary_cmd);
+
+#ifdef HAVE_IPV6
+ install_element (VIEW_NODE, &show_bgp_rsclient_summary_cmd);
+ install_element (VIEW_NODE, &show_bgp_ipv6_rsclient_summary_cmd);
+ install_element (VIEW_NODE, &show_bgp_instance_rsclient_summary_cmd);
+ install_element (VIEW_NODE, &show_bgp_instance_ipv6_rsclient_summary_cmd);
+ install_element (ENABLE_NODE, &show_bgp_rsclient_summary_cmd);
+ install_element (ENABLE_NODE, &show_bgp_ipv6_rsclient_summary_cmd);
+ install_element (ENABLE_NODE, &show_bgp_instance_rsclient_summary_cmd);
+ install_element (ENABLE_NODE, &show_bgp_instance_ipv6_rsclient_summary_cmd);
+#endif /* HAVE_IPV6 */
+
/* "show ip bgp paths" commands. */
install_element (VIEW_NODE, &show_ip_bgp_paths_cmd);
install_element (VIEW_NODE, &show_ip_bgp_ipv4_paths_cmd);