#include "bgpd/bgp_addpath.h"
#include "bgpd/bgp_mac.h"
#include "bgpd/bgp_network.h"
+#include "bgpd/bgp_trace.h"
#ifdef ENABLE_BGP_VNC
#include "bgpd/rfapi/rfapi_backend.h"
#include "bgpd/bgp_flowspec.h"
#include "bgpd/bgp_flowspec_util.h"
#include "bgpd/bgp_pbr.h"
+#include "northbound.h"
+#include "northbound_cli.h"
+#include "bgpd/bgp_nb.h"
#ifndef VTYSH_EXTRACT_PL
#include "bgpd/bgp_route_clippy.c"
struct peer *peer, bool withdraw),
(bgp, afi, safi, bn, peer, withdraw))
+/** Test if path is suppressed. */
+static bool bgp_path_suppressed(struct bgp_path_info *pi)
+{
+ if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
+ return false;
+
+ return listcount(pi->extra->aggr_suppressors) > 0;
+}
struct bgp_dest *bgp_afi_node_get(struct bgp_table *table, afi_t afi,
safi_t safi, const struct prefix *p,
unsigned refcount;
bpi = bgp_path_info_lock(bpi);
- refcount = bpi->net->lock - 1;
+ refcount = bgp_dest_get_lock_count(bpi->net) - 1;
bgp_dest_unlock_node((struct bgp_dest *)bpi->net);
if (!refcount)
bpi->net = NULL;
if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED)) {
if (BGP_DEBUG(update, UPDATE_OUT))
zlog_debug(
- "Route %pRN is in workqueue and being processed, not deferred.",
- bgp_dest_to_rnode(dest));
+ "Route %pBD is in workqueue and being processed, not deferred.",
+ dest);
return 0;
}
bgp->gr_info[afi][safi].route_list,
dest);
if (BGP_DEBUG(update, UPDATE_OUT))
- zlog_debug("DEFER route %pRN, dest %p, node %p",
+ zlog_debug("DEFER route %pBD, dest %p, node %p",
dest, dest, dest->rt_node);
return 0;
}
*reason = bgp_path_selection_evpn_lower_ip;
if (debug)
zlog_debug(
- "%s: %s wins over %s due to same MM seq %u and lower IP %s",
+ "%s: %s wins over %s due to same MM seq %u and lower IP %pI4",
pfx_buf, new_buf, exist_buf, new_mm_seq,
- inet_ntoa(new->attr->nexthop));
+ &new->attr->nexthop);
return 1;
}
if (nh_cmp > 0) {
*reason = bgp_path_selection_evpn_lower_ip;
if (debug)
zlog_debug(
- "%s: %s loses to %s due to same MM seq %u and higher IP %s",
+ "%s: %s loses to %s due to same MM seq %u and higher IP %pI4",
pfx_buf, new_buf, exist_buf, new_mm_seq,
- inet_ntoa(new->attr->nexthop));
+ &new->attr->nexthop);
return 0;
}
}
safi_t safi)
{
struct bgp_filter *filter;
+ enum filter_type ret = FILTER_PERMIT;
filter = &peer->filter[afi][safi];
if (DISTRIBUTE_IN_NAME(filter)) {
FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
- if (access_list_apply(DISTRIBUTE_IN(filter), p) == FILTER_DENY)
- return FILTER_DENY;
+ if (access_list_apply(DISTRIBUTE_IN(filter), p)
+ == FILTER_DENY) {
+ ret = FILTER_DENY;
+ goto done;
+ }
}
if (PREFIX_LIST_IN_NAME(filter)) {
FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
- if (prefix_list_apply(PREFIX_LIST_IN(filter), p) == PREFIX_DENY)
- return FILTER_DENY;
+ if (prefix_list_apply(PREFIX_LIST_IN(filter), p)
+ == PREFIX_DENY) {
+ ret = FILTER_DENY;
+ goto done;
+ }
}
if (FILTER_LIST_IN_NAME(filter)) {
FILTER_EXIST_WARN(FILTER_LIST, as, filter);
if (as_list_apply(FILTER_LIST_IN(filter), attr->aspath)
- == AS_FILTER_DENY)
- return FILTER_DENY;
+ == AS_FILTER_DENY) {
+ ret = FILTER_DENY;
+ goto done;
+ }
}
- return FILTER_PERMIT;
+done:
+ if (frrtrace_enabled(frr_bgp, input_filter)) {
+ char pfxprint[PREFIX2STR_BUFFER];
+
+ prefix2str(p, pfxprint, sizeof(pfxprint));
+ frrtrace(5, frr_bgp, input_filter, peer, pfxprint, afi, safi,
+ ret == FILTER_PERMIT ? "permit" : "deny");
+ }
+
+ return ret;
#undef FILTER_EXIST_WARN
}
safi_t safi)
{
struct bgp_filter *filter;
+ enum filter_type ret = FILTER_PERMIT;
filter = &peer->filter[afi][safi];
if (DISTRIBUTE_OUT_NAME(filter)) {
FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
- if (access_list_apply(DISTRIBUTE_OUT(filter), p) == FILTER_DENY)
- return FILTER_DENY;
+ if (access_list_apply(DISTRIBUTE_OUT(filter), p)
+ == FILTER_DENY) {
+ ret = FILTER_DENY;
+ goto done;
+ }
}
if (PREFIX_LIST_OUT_NAME(filter)) {
FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
if (prefix_list_apply(PREFIX_LIST_OUT(filter), p)
- == PREFIX_DENY)
- return FILTER_DENY;
+ == PREFIX_DENY) {
+ ret = FILTER_DENY;
+ goto done;
+ }
}
if (FILTER_LIST_OUT_NAME(filter)) {
FILTER_EXIST_WARN(FILTER_LIST, as, filter);
if (as_list_apply(FILTER_LIST_OUT(filter), attr->aspath)
- == AS_FILTER_DENY)
- return FILTER_DENY;
+ == AS_FILTER_DENY) {
+ ret = FILTER_DENY;
+ goto done;
+ }
+ }
+
+ if (frrtrace_enabled(frr_bgp, output_filter)) {
+ char pfxprint[PREFIX2STR_BUFFER];
+
+ prefix2str(p, pfxprint, sizeof(pfxprint));
+ frrtrace(5, frr_bgp, output_filter, peer, pfxprint, afi, safi,
+ ret == FILTER_PERMIT ? "permit" : "deny");
}
- return FILTER_PERMIT;
+done:
+ return ret;
#undef FILTER_EXIST_WARN
}
}
-static void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr)
+/* Notify BGP Conditional advertisement scanner process. */
+void bgp_notify_conditional_adv_scanner(struct update_subgroup *subgrp)
+{
+ struct peer *temp_peer;
+ struct peer *peer = SUBGRP_PEER(subgrp);
+ struct listnode *temp_node, *temp_nnode = NULL;
+ afi_t afi = SUBGRP_AFI(subgrp);
+ safi_t safi = SUBGRP_SAFI(subgrp);
+ struct bgp *bgp = SUBGRP_INST(subgrp);
+ struct bgp_filter *filter = &peer->filter[afi][safi];
+
+ if (!ADVERTISE_MAP_NAME(filter))
+ return;
+
+ for (ALL_LIST_ELEMENTS(bgp->peer, temp_node, temp_nnode, temp_peer)) {
+ if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
+ continue;
+
+ if (peer != temp_peer)
+ continue;
+
+ temp_peer->advmap_table_change = true;
+ break;
+ }
+}
+
+
+void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr)
{
if (family == AF_INET) {
attr->nexthop.s_addr = INADDR_ANY;
bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
struct update_subgroup *subgrp,
- const struct prefix *p, struct attr *attr)
+ const struct prefix *p, struct attr *attr,
+ bool skip_rmap_check)
{
struct bgp_filter *filter;
struct peer *from;
struct peer *onlypeer;
struct bgp *bgp;
struct attr *piattr;
- char buf[PREFIX_STRLEN];
route_map_result_t ret;
int transparent;
int reflect;
* though they can have peer pointers that reference other
* systems
*/
- prefix2str(p, buf, PREFIX_STRLEN);
- zlog_debug("%s: pfx %s bgp_direct->vpn route peer safe",
- __func__, buf);
+ zlog_debug("%s: pfx %pFX bgp_direct->vpn route peer safe",
+ __func__, p);
samepeer_safe = 1;
}
#endif
}
/* Aggregate-address suppress check. */
- if (pi->extra && pi->extra->suppress)
- if (!UNSUPPRESS_MAP_NAME(filter)) {
- return false;
- }
+ if (bgp_path_suppressed(pi) && !UNSUPPRESS_MAP_NAME(filter))
+ return false;
/*
* If we are doing VRF 2 VRF leaking via the import
mpls_label_t label = bgp_adv_label(dest, pi, peer, afi, safi);
if (!bgp_is_valid_label(&label)) {
if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
- zlog_debug("u%" PRIu64 ":s%" PRIu64" %s/%d is filtered - no label (%p)",
+ zlog_debug("u%" PRIu64 ":s%" PRIu64
+ " %pFX is filtered - no label (%p)",
subgrp->update_group->id, subgrp->id,
- inet_ntop(p->family, &p->u.prefix,
- buf, SU_ADDRSTRLEN),
- p->prefixlen, &label);
+ p, &label);
return false;
}
}
&& (IPV4_ADDR_SAME(&onlypeer->remote_id, &piattr->originator_id))) {
if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
zlog_debug(
- "%s [Update:SEND] %s originator-id is same as remote router-id",
- onlypeer->host,
- prefix2str(p, buf, sizeof(buf)));
+ "%s [Update:SEND] %pFX originator-id is same as remote router-id",
+ onlypeer->host, p);
return false;
}
if (bgp_debug_update(NULL, p,
subgrp->update_group, 0))
zlog_debug(
- "%s [Update:SEND] %s is filtered via ORF",
- peer->host,
- prefix2str(p, buf,
- sizeof(buf)));
+ "%s [Update:SEND] %pFX is filtered via ORF",
+ peer->host, p);
return false;
}
}
/* Output filter check. */
if (bgp_output_filter(peer, p, piattr, afi, safi) == FILTER_DENY) {
if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
- zlog_debug("%s [Update:SEND] %s is filtered",
- peer->host, prefix2str(p, buf, sizeof(buf)));
+ zlog_debug("%s [Update:SEND] %pFX is filtered",
+ peer->host, p);
return false;
}
bgp_peer_as_override(bgp, afi, safi, peer, attr);
/* Route map & unsuppress-map apply. */
- if (ROUTE_MAP_OUT_NAME(filter) || (pi->extra && pi->extra->suppress)) {
+ if (!skip_rmap_check
+ && (ROUTE_MAP_OUT_NAME(filter) || bgp_path_suppressed(pi))) {
struct bgp_path_info rmap_path = {0};
struct bgp_path_info_extra dummy_rmap_path_extra = {0};
struct attr dummy_attr = {0};
SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
- if (pi->extra && pi->extra->suppress)
+ if (bgp_path_suppressed(pi))
ret = route_map_apply(UNSUPPRESS_MAP(filter), p,
RMAP_BGP, &rmap_path);
else
if (ret == RMAP_DENYMATCH) {
if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
- zlog_debug("%s [Update:SEND] %s is filtered by route-map",
- peer->host, prefix2str(p, buf, sizeof(buf)));
+ zlog_debug(
+ "%s [Update:SEND] %pFX is filtered by route-map",
+ peer->host, p);
bgp_attr_flush(attr);
return false;
if (debug) {
bgp_path_info_path_with_addpath_rx_str(
new_select, path_buf);
- zlog_debug("%s: %s is the bestpath from AS %u",
- pfx_buf, path_buf,
- aspath_get_first_as(
- new_select->attr->aspath));
+ zlog_debug(
+ "%pBD: %s is the bestpath from AS %u",
+ dest, path_buf,
+ aspath_get_first_as(
+ new_select->attr->aspath));
}
}
}
else
snprintf(path_buf, sizeof(path_buf), "NONE");
zlog_debug(
- "%s: After path selection, newbest is %s oldbest was %s",
- pfx_buf, path_buf,
+ "%pBD: After path selection, newbest is %s oldbest was %s",
+ dest, path_buf,
old_select ? old_select->peer->host : "NONE");
}
if (pi == new_select) {
if (debug)
zlog_debug(
- "%s: %s is the bestpath, add to the multipath list",
- pfx_buf, path_buf);
+ "%pBD: %s is the bestpath, add to the multipath list",
+ dest, path_buf);
bgp_mp_list_add(&mp_list, pi);
continue;
}
if (!bgp_path_info_nexthop_cmp(pi, new_select)) {
if (debug)
zlog_debug(
- "%s: %s has the same nexthop as the bestpath, skip it",
- pfx_buf, path_buf);
+ "%pBD: %s has the same nexthop as the bestpath, skip it",
+ dest, path_buf);
continue;
}
if (paths_eq) {
if (debug)
zlog_debug(
- "%s: %s is equivalent to the bestpath, add to the multipath list",
- pfx_buf, path_buf);
+ "%pBD: %s is equivalent to the bestpath, add to the multipath list",
+ dest, path_buf);
bgp_mp_list_add(&mp_list, pi);
}
}
onlypeer = ((SUBGRP_PCOUNT(subgrp) == 1) ? (SUBGRP_PFIRST(subgrp))->peer
: NULL);
- if (BGP_DEBUG(update, UPDATE_OUT)) {
- char buf_prefix[PREFIX_STRLEN];
- prefix2str(p, buf_prefix, sizeof(buf_prefix));
- zlog_debug("%s: p=%s, selected=%p", __func__, buf_prefix,
- selected);
- }
+ if (BGP_DEBUG(update, UPDATE_OUT))
+ zlog_debug("%s: p=%pFX, selected=%p", __func__, p, selected);
/* First update is deferred until ORF or ROUTE-REFRESH is received */
if (onlypeer && CHECK_FLAG(onlypeer->af_sflags[afi][safi],
/* Announcement to the subgroup. If the route is filtered withdraw it.
*/
if (selected) {
- if (subgroup_announce_check(dest, selected, subgrp, p, &attr))
+ if (subgroup_announce_check(dest, selected, subgrp, p, &attr,
+ false))
bgp_adj_out_set_subgroup(dest, subgrp, &attr, selected);
else
bgp_adj_out_unset_subgroup(dest, subgrp, 1,
debug = bgp_debug_bestpath(dest);
if (debug)
zlog_debug(
- "%s: bgp delete in progress, ignoring event, p=%pRN",
+ "%s: bgp delete in progress, ignoring event, p=%pBD",
__func__, dest);
return;
}
debug = bgp_debug_bestpath(dest);
if (debug)
- zlog_debug("%s: p=%pRN afi=%s, safi=%s start", __func__, dest,
+ zlog_debug("%s: p=%pBD afi=%s, safi=%s start", __func__, dest,
afi2str(afi), safi2str(safi));
/* The best path calculation for the route is deferred if
*/
if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
if (BGP_DEBUG(update, UPDATE_OUT))
- zlog_debug("SELECT_DEFER falg set for route %p", dest);
+ zlog_debug("SELECT_DEFER flag set for route %p", dest);
return;
}
if (debug)
zlog_debug(
- "%s: p=%pRN afi=%s, safi=%s, old_select=%p, new_select=%p",
+ "%s: p=%pBD afi=%s, safi=%s, old_select=%p, new_select=%p",
__func__, dest, afi2str(afi), safi2str(safi),
old_select, new_select);
XFREE(MTYPE_BGP_PROCESS_QUEUE, pqnode);
}
-void bgp_process_queue_init(void)
+void bgp_process_queue_init(struct bgp *bgp)
{
- if (!bm->process_main_queue)
- bm->process_main_queue =
- work_queue_new(bm->master, "process_main_queue");
+ if (!bgp->process_queue) {
+ char name[BUFSIZ];
+
+ snprintf(name, BUFSIZ, "process_queue %s", bgp->name_pretty);
+ bgp->process_queue = work_queue_new(bm->master, name);
+ }
- bm->process_main_queue->spec.workfunc = &bgp_process_wq;
- bm->process_main_queue->spec.del_item_data = &bgp_processq_del;
- bm->process_main_queue->spec.max_retries = 0;
- bm->process_main_queue->spec.hold = 50;
+ bgp->process_queue->spec.workfunc = &bgp_process_wq;
+ bgp->process_queue->spec.del_item_data = &bgp_processq_del;
+ bgp->process_queue->spec.max_retries = 0;
+ bgp->process_queue->spec.hold = 50;
/* Use a higher yield value of 50ms for main queue processing */
- bm->process_main_queue->spec.yield = 50 * 1000L;
+ bgp->process_queue->spec.yield = 50 * 1000L;
}
static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp)
void bgp_process(struct bgp *bgp, struct bgp_dest *dest, afi_t afi, safi_t safi)
{
#define ARBITRARY_PROCESS_QLEN 10000
- struct work_queue *wq = bm->process_main_queue;
+ struct work_queue *wq = bgp->process_queue;
struct bgp_process_queue *pqnode;
int pqnode_reuse = 0;
{
struct bgp_process_queue *pqnode;
- if (bm->process_main_queue == NULL)
+ if (bgp->process_queue == NULL)
return;
pqnode = bgp_processq_alloc(bgp);
SET_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER);
- work_queue_add(bm->process_main_queue, pqnode);
+ work_queue_add(bgp->process_queue, pqnode);
}
static int bgp_maximum_prefix_restart_timer(struct thread *thread)
UNSET_FLAG(peer->af_sflags[afi][safi],
PEER_STATUS_PREFIX_LIMIT);
- if (pcount > (pcount * peer->pmax_threshold[afi][safi] / 100)) {
+ if (pcount
+ > (peer->pmax[afi][safi] * peer->pmax_threshold[afi][safi] / 100)) {
if (CHECK_FLAG(peer->af_sflags[afi][safi],
PEER_STATUS_PREFIX_THRESHOLD)
&& !always)
uint8_t pi_type = 0;
uint8_t pi_sub_type = 0;
+ if (frrtrace_enabled(frr_bgp, process_update)) {
+ char pfxprint[PREFIX2STR_BUFFER];
+
+ prefix2str(p, pfxprint, sizeof(pfxprint));
+ frrtrace(6, frr_bgp, process_update, peer, pfxprint, addpath_id,
+ afi, safi, attr);
+ }
+
#ifdef ENABLE_BGP_VNC
int vnc_implicit_withdraw = 0;
#endif
if (!paf->t_announce_route)
return;
- THREAD_TIMER_OFF(paf->t_announce_route);
+ thread_cancel(&paf->t_announce_route);
}
/*
return 0;
peer_af_announce_route(paf, 1);
+
+ /* Notify BGP conditional advertisement scanner percess */
+ peer->advmap_config_change[paf->afi][paf->safi] = true;
+
return 0;
}
struct bgp_table *table)
{
struct bgp_dest *dest;
- int force = bm->process_main_queue ? 0 : 1;
+ int force = peer->bgp->process_queue ? 0 : 1;
if (!table)
table = peer->bgp->rib[afi][safi];
*/
flog_err(
EC_BGP_UPDATE_RCV,
- "%s: IPv4 unicast NLRI is multicast address %s, ignoring",
- peer->host, inet_ntoa(p.u.prefix4));
+ "%s: IPv4 unicast NLRI is multicast address %pI4, ignoring",
+ peer->host, &p.u.prefix4);
continue;
}
}
/* Configure static BGP network. When user don't run zebra, static
route should be installed as valid. */
-static int bgp_static_set(struct vty *vty, const char *negate,
- const char *ip_str, afi_t afi, safi_t safi,
- const char *rmap, int backdoor, uint32_t label_index)
+int bgp_static_set(struct bgp *bgp, const char *negate, struct prefix *pfx,
+ afi_t afi, safi_t safi, const char *rmap, int backdoor,
+ uint32_t label_index, char *errmsg, size_t errmsg_len)
{
- VTY_DECLVAR_CONTEXT(bgp, bgp);
- int ret;
struct prefix p;
struct bgp_static *bgp_static;
struct bgp_dest *dest;
uint8_t need_update = 0;
- /* Convert IP prefix string to struct prefix. */
- ret = str2prefix(ip_str, &p);
- if (!ret) {
- vty_out(vty, "%% Malformed prefix\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
- vty_out(vty, "%% Malformed prefix (link-local address)\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
+ prefix_copy(&p, pfx);
apply_mask(&p);
if (negate) {
dest = bgp_node_lookup(bgp->route[afi][safi], &p);
if (!dest) {
- vty_out(vty, "%% Can't find static route specified\n");
- return CMD_WARNING_CONFIG_FAILED;
+ snprintf(errmsg, errmsg_len,
+ "Can't find static route specified\n");
+ return -1;
}
bgp_static = bgp_dest_get_bgp_static_info(dest);
if ((label_index != BGP_INVALID_LABEL_INDEX)
&& (label_index != bgp_static->label_index)) {
- vty_out(vty,
- "%% label-index doesn't match static route\n");
- return CMD_WARNING_CONFIG_FAILED;
+ snprintf(errmsg, errmsg_len,
+ "label-index doesn't match static route\n");
+ return -1;
}
if ((rmap && bgp_static->rmap.name)
&& strcmp(rmap, bgp_static->rmap.name)) {
- vty_out(vty,
- "%% route-map name doesn't match static route\n");
- return CMD_WARNING_CONFIG_FAILED;
+ snprintf(errmsg, errmsg_len,
+ "route-map name doesn't match static route\n");
+ return -1;
}
/* Update BGP RIB. */
/* Configuration change. */
/* Label index cannot be changed. */
if (bgp_static->label_index != label_index) {
- vty_out(vty, "%% cannot change label-index\n");
- return CMD_WARNING_CONFIG_FAILED;
+ snprintf(errmsg, errmsg_len,
+ "cannot change label-index\n");
+ return -1;
}
/* Check previous routes are installed into BGP. */
bgp_static_update(bgp, &p, bgp_static, afi, safi);
}
- return CMD_SUCCESS;
+ return 0;
}
void bgp_static_add(struct bgp *bgp)
bgp_dest_get_prefix(
dest));
bgp_static_free(bgp_static);
- bgp_dest_set_bgp_static_info(dest,
+ bgp_dest_set_bgp_static_info(rm,
NULL);
- bgp_dest_unlock_node(dest);
+ bgp_dest_unlock_node(rm);
}
} else {
bgp_static = bgp_dest_get_bgp_static_info(dest);
argv[idx_word]->arg);
}
-DEFPY(bgp_network,
- bgp_network_cmd,
- "[no] network \
- <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
- [{route-map WORD$map_name|label-index (0-1048560)$label_index| \
- backdoor$backdoor}]",
- NO_STR
- "Specify a network to announce via BGP\n"
- "IPv4 prefix\n"
- "Network number\n"
- "Network mask\n"
- "Network mask\n"
- "Route-map to modify the attributes\n"
- "Name of the route map\n"
- "Label index to associate with the prefix\n"
- "Label index value\n"
- "Specify a BGP backdoor route\n")
-{
- char addr_prefix_str[BUFSIZ];
+DEFPY_YANG (bgp_network, bgp_network_cmd,
+ "[no] network \
+ <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
+ [{route-map WORD$map_name|label-index (0-1048560)$label_index| \
+ backdoor$backdoor}]",
+ NO_STR
+ "Specify a network to announce via BGP\n"
+ "IPv4 prefix\n"
+ "Network number\n"
+ "Network mask\n"
+ "Network mask\n"
+ "Route-map to modify the attributes\n"
+ "Name of the route map\n"
+ "Label index to associate with the prefix\n"
+ "Label index value\n"
+ "Specify a BGP backdoor route\n")
+{
+ char addr_prefix_str[PREFIX_STRLEN];
+ char base_xpath[XPATH_MAXLEN];
+ afi_t afi;
+ safi_t safi;
if (address_str) {
int ret;
}
}
- return bgp_static_set(
- vty, no, address_str ? addr_prefix_str : prefix_str, AFI_IP,
- bgp_node_safi(vty), map_name, backdoor ? 1 : 0,
- label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
+ afi = bgp_node_afi(vty);
+ safi = bgp_node_safi(vty);
+
+ if (no) {
+ nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
+ } else {
+ nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
+
+ if (map_name)
+ nb_cli_enqueue_change(vty, "./rmap-policy-export",
+ NB_OP_CREATE, map_name);
+ else
+ nb_cli_enqueue_change(vty, "./rmap-policy-export",
+ NB_OP_DESTROY, NULL);
+
+ if (label_index_str)
+ nb_cli_enqueue_change(vty, "./label-index",
+ NB_OP_MODIFY, label_index_str);
+
+ nb_cli_enqueue_change(vty, "./backdoor", NB_OP_MODIFY,
+ backdoor ? "true" : "false");
+ }
+
+ snprintf(
+ base_xpath, sizeof(base_xpath),
+ "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/network-config[prefix='%s']",
+ yang_afi_safi_value2identity(afi, safi),
+ bgp_afi_safi_get_container_str(afi, safi),
+ address_str ? addr_prefix_str : prefix_str);
+
+ return nb_cli_apply_changes(vty, base_xpath);
}
-DEFPY(ipv6_bgp_network,
- ipv6_bgp_network_cmd,
- "[no] network X:X::X:X/M$prefix \
- [{route-map WORD$map_name|label-index (0-1048560)$label_index}]",
- NO_STR
- "Specify a network to announce via BGP\n"
- "IPv6 prefix\n"
- "Route-map to modify the attributes\n"
- "Name of the route map\n"
- "Label index to associate with the prefix\n"
- "Label index value\n")
+DEFPY_YANG (ipv6_bgp_network,
+ ipv6_bgp_network_cmd,
+ "[no] network X:X::X:X/M$prefix \
+ [{route-map WORD$map_name|label-index (0-1048560)$label_index}]",
+ NO_STR
+ "Specify a network to announce via BGP\n"
+ "IPv6 prefix\n"
+ "Route-map to modify the attributes\n"
+ "Name of the route map\n"
+ "Label index to associate with the prefix\n"
+ "Label index value\n")
{
- return bgp_static_set(
- vty, no, prefix_str, AFI_IP6, bgp_node_safi(vty), map_name, 0,
- label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
+ char base_xpath[XPATH_MAXLEN];
+ afi_t afi;
+ safi_t safi;
+
+ afi = bgp_node_afi(vty);
+ safi = bgp_node_safi(vty);
+
+ if (no) {
+ nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
+ } else {
+ nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
+
+ if (map_name)
+ nb_cli_enqueue_change(vty, "./rmap-policy-export",
+ NB_OP_MODIFY, map_name);
+ else
+ nb_cli_enqueue_change(vty, "./rmap-policy-export",
+ NB_OP_DESTROY, NULL);
+
+ if (label_index_str)
+ nb_cli_enqueue_change(vty, "./label-index",
+ NB_OP_MODIFY, label_index_str);
+ }
+
+ snprintf(
+ base_xpath, sizeof(base_xpath),
+ "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/network-config[prefix='%s']",
+ yang_afi_safi_value2identity(afi, safi),
+ bgp_afi_safi_get_container_str(afi, safi), prefix_str);
+
+ return nb_cli_apply_changes(vty, base_xpath);
+}
+
+void cli_show_bgp_global_afi_safi_network_config(struct vty *vty,
+ struct lyd_node *dnode,
+ bool show_defaults)
+{
+ vty_out(vty, " network %s", yang_dnode_get_string(dnode, "./prefix"));
+
+ if (yang_dnode_exists(dnode, "./label-index"))
+ vty_out(vty, " label-index %s",
+ yang_dnode_get_string(dnode, "./label-index"));
+
+ if (yang_dnode_exists(dnode, "./rmap-policy-export"))
+ vty_out(vty, " route-map %s",
+ yang_dnode_get_string(dnode, "./rmap-policy-export"));
+
+ if (yang_dnode_get_bool(dnode, "./backdoor"))
+ vty_out(vty, " backdoor");
+
+ vty_out(vty, "\n");
}
static struct bgp_aggregate *bgp_aggregate_new(void)
static void bgp_aggregate_free(struct bgp_aggregate *aggregate)
{
+ XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
+ route_map_counter_decrement(aggregate->suppress_map);
XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
route_map_counter_decrement(aggregate->rmap.map);
XFREE(MTYPE_BGP_AGGREGATE, aggregate);
}
+/**
+ * Helper function to avoid repeated code: prepare variables for a
+ * `route_map_apply` call.
+ *
+ * \returns `true` on route map match, otherwise `false`.
+ */
+static bool aggr_suppress_map_test(struct bgp *bgp,
+ struct bgp_aggregate *aggregate,
+ struct bgp_path_info *pi)
+{
+ const struct prefix *p = bgp_dest_get_prefix(pi->net);
+ route_map_result_t rmr = RMAP_DENYMATCH;
+ struct bgp_path_info rmap_path = {};
+ struct attr attr = {};
+
+ /* No route map entries created, just don't match. */
+ if (aggregate->suppress_map == NULL)
+ return false;
+
+ /* Call route map matching and return result. */
+ attr.aspath = aspath_empty();
+ rmap_path.peer = bgp->peer_self;
+ rmap_path.attr = &attr;
+
+ SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_AGGREGATE);
+ rmr = route_map_apply(aggregate->suppress_map, p, RMAP_BGP, &rmap_path);
+ bgp->peer_self->rmap_type = 0;
+
+ bgp_attr_flush(&attr);
+
+ return rmr == RMAP_PERMITMATCH;
+}
+
+/** Test whether the aggregation has suppressed this path or not. */
+static bool aggr_suppress_exists(struct bgp_aggregate *aggregate,
+ struct bgp_path_info *pi)
+{
+ if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
+ return false;
+
+ return listnode_lookup(pi->extra->aggr_suppressors, aggregate) != NULL;
+}
+
+/**
+ * Suppress this path and keep the reference.
+ *
+ * \returns `true` if needs processing otherwise `false`.
+ */
+static bool aggr_suppress_path(struct bgp_aggregate *aggregate,
+ struct bgp_path_info *pi)
+{
+ struct bgp_path_info_extra *pie;
+
+ /* Path is already suppressed by this aggregation. */
+ if (aggr_suppress_exists(aggregate, pi))
+ return false;
+
+ pie = bgp_path_info_extra_get(pi);
+
+ /* This is the first suppression, allocate memory and list it. */
+ if (pie->aggr_suppressors == NULL)
+ pie->aggr_suppressors = list_new();
+
+ listnode_add(pie->aggr_suppressors, aggregate);
+
+ /* Only mark for processing if suppressed. */
+ if (listcount(pie->aggr_suppressors) == 1) {
+ if (BGP_DEBUG(update, UPDATE_OUT))
+ zlog_debug("aggregate-address suppressing: %pFX",
+ bgp_dest_get_prefix(pi->net));
+
+ bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * Unsuppress this path and remove the reference.
+ *
+ * \returns `true` if needs processing otherwise `false`.
+ */
+static bool aggr_unsuppress_path(struct bgp_aggregate *aggregate,
+ struct bgp_path_info *pi)
+{
+ /* Path wasn't suppressed. */
+ if (!aggr_suppress_exists(aggregate, pi))
+ return false;
+
+ listnode_delete(pi->extra->aggr_suppressors, aggregate);
+
+ /* Unsuppress and free extra memory if last item. */
+ if (listcount(pi->extra->aggr_suppressors) == 0) {
+ if (BGP_DEBUG(update, UPDATE_OUT))
+ zlog_debug("aggregate-address unsuppressing: %pFX",
+ bgp_dest_get_prefix(pi->net));
+
+ list_delete(&pi->extra->aggr_suppressors);
+ bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
+ return true;
+ }
+
+ return false;
+}
+
static bool bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
struct aspath *aspath,
struct community *comm,
* Toggles the route suppression status for this aggregate address
* configuration.
*/
-static void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate,
- struct bgp *bgp,
- const struct prefix *p, afi_t afi,
- safi_t safi, bool suppress)
+void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate,
+ struct bgp *bgp, const struct prefix *p,
+ afi_t afi, safi_t safi, bool suppress)
{
struct bgp_table *table = bgp->rib[afi][safi];
- struct bgp_path_info_extra *pie;
const struct prefix *dest_p;
struct bgp_dest *dest, *top;
struct bgp_path_info *pi;
if (pi->sub_type == BGP_ROUTE_AGGREGATE)
continue;
- /*
- * On installation it is possible that pi->extra is
- * set to NULL, otherwise it must exists.
- */
- assert(!suppress && pi->extra != NULL);
-
/* We are toggling suppression back. */
if (suppress) {
- pie = bgp_path_info_extra_get(pi);
/* Suppress route if not suppressed already. */
- pie->suppress++;
- bgp_path_info_set_flag(dest, pi,
- BGP_PATH_ATTR_CHANGED);
- toggle_suppression = true;
+ if (aggr_suppress_path(aggregate, pi))
+ toggle_suppression = true;
continue;
}
- pie = pi->extra;
- assert(pie->suppress > 0);
- pie->suppress--;
/* Install route if there is no more suppression. */
- if (pie->suppress == 0) {
- bgp_path_info_set_flag(dest, pi,
- BGP_PATH_ATTR_CHANGED);
+ if (aggr_unsuppress_path(aggregate, pi))
toggle_suppression = true;
- }
}
if (toggle_suppression)
if (aggregate->match_med)
bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi);
+ /*
+ * Reset aggregate count: we might've been called from route map
+ * update so in that case we must retest all more specific routes.
+ *
+ * \see `bgp_route_map_process_update`.
+ */
+ aggregate->count = 0;
+ aggregate->incomplete_origin_count = 0;
+ aggregate->incomplete_origin_count = 0;
+ aggregate->egp_origin_count = 0;
+
/* 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
*/
if (aggregate->summary_only
&& AGGREGATE_MED_VALID(aggregate)) {
- (bgp_path_info_extra_get(pi))->suppress++;
- bgp_path_info_set_flag(dest, pi,
- BGP_PATH_ATTR_CHANGED);
- match++;
+ if (aggr_suppress_path(aggregate, pi))
+ match++;
+ }
+
+ /*
+ * Suppress more specific routes that match the route
+ * map results.
+ *
+ * MED matching:
+ * Don't suppress routes if MED matching is enabled and
+ * it mismatched otherwise we might end up with no
+ * routes for this path.
+ */
+ if (aggregate->suppress_map_name
+ && AGGREGATE_MED_VALID(aggregate)
+ && aggr_suppress_map_test(bgp, aggregate, pi)) {
+ if (aggr_suppress_path(aggregate, pi))
+ match++;
}
aggregate->count++;
if (aggregate->summary_only && pi->extra
&& AGGREGATE_MED_VALID(aggregate)) {
- pi->extra->suppress--;
+ if (aggr_unsuppress_path(aggregate, pi))
+ match++;
+ }
- if (pi->extra->suppress == 0) {
- bgp_path_info_set_flag(
- dest, pi,
- BGP_PATH_ATTR_CHANGED);
+ if (aggregate->suppress_map_name
+ && AGGREGATE_MED_VALID(aggregate)
+ && aggr_suppress_map_test(bgp, aggregate, pi)) {
+ if (aggr_unsuppress_path(aggregate, pi))
match++;
- }
}
+
aggregate->count--;
if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
pinew, true);
if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
- (bgp_path_info_extra_get(pinew))->suppress++;
+ aggr_suppress_path(aggregate, pinew);
+
+ if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
+ && aggr_suppress_map_test(bgp, aggregate, pinew))
+ aggr_suppress_path(aggregate, pinew);
switch (pinew->attr->origin) {
case BGP_ORIGIN_INCOMPLETE:
if (pi->sub_type == BGP_ROUTE_AGGREGATE)
return;
- if (aggregate->summary_only && pi->extra && pi->extra->suppress > 0
- && AGGREGATE_MED_VALID(aggregate)) {
- pi->extra->suppress--;
+ if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
+ if (aggr_unsuppress_path(aggregate, pi))
+ match++;
- if (pi->extra->suppress == 0) {
- bgp_path_info_set_flag(pi->net, pi,
- BGP_PATH_ATTR_CHANGED);
+ if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
+ && aggr_suppress_map_test(bgp, aggregate, pi))
+ if (aggr_unsuppress_path(aggregate, pi))
match++;
- }
- }
/*
- * This must be called after `summary` check to avoid
+ * This must be called after `summary`, `suppress-map` check to avoid
* "unsuppressing" twice.
*/
if (aggregate->match_med)
return "n/a";
}
-static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
- afi_t afi, safi_t safi)
+int bgp_aggregate_unset(struct bgp *bgp, struct prefix *prefix, afi_t afi,
+ safi_t safi, char *errmsg, size_t errmsg_len)
{
- VTY_DECLVAR_CONTEXT(bgp, bgp);
- int ret;
- struct prefix p;
struct bgp_dest *dest;
struct bgp_aggregate *aggregate;
- /* Convert string to prefix structure. */
- ret = str2prefix(prefix_str, &p);
- if (!ret) {
- vty_out(vty, "Malformed prefix\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- apply_mask(&p);
-
+ apply_mask(prefix);
/* Old configuration check. */
- dest = bgp_node_lookup(bgp->aggregate[afi][safi], &p);
+ dest = bgp_node_lookup(bgp->aggregate[afi][safi], prefix);
if (!dest) {
- vty_out(vty,
- "%% There is no aggregate-address configuration.\n");
- return CMD_WARNING_CONFIG_FAILED;
+ snprintf(errmsg, errmsg_len,
+ "There is no aggregate-address configuration.\n");
+ return -1;
}
aggregate = bgp_dest_get_bgp_aggregate_info(dest);
- bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
- bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL,
- NULL, NULL, 0, aggregate);
+ bgp_aggregate_delete(bgp, prefix, afi, safi, aggregate);
+ bgp_aggregate_install(bgp, afi, safi, prefix, 0, NULL, NULL, NULL, NULL,
+ 0, aggregate);
/* Unlock aggregate address configuration. */
bgp_dest_set_bgp_aggregate_info(dest, NULL);
bgp_dest_unlock_node(dest);
bgp_dest_unlock_node(dest);
- return CMD_SUCCESS;
+ return 0;
}
-static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
- safi_t safi, const char *rmap,
- uint8_t summary_only, uint8_t as_set,
- uint8_t origin, bool match_med)
+int bgp_aggregate_set(struct bgp *bgp, struct prefix *prefix, afi_t afi,
+ safi_t safi, const char *rmap, uint8_t summary_only,
+ uint8_t as_set, uint8_t origin, bool match_med,
+ const char *suppress_map,
+ char *errmsg, size_t errmsg_len)
{
- VTY_DECLVAR_CONTEXT(bgp, bgp);
int ret;
- struct prefix p;
struct bgp_dest *dest;
struct bgp_aggregate *aggregate;
uint8_t as_set_new = as_set;
+ char buf[PREFIX2STR_BUFFER];
- /* Convert string to prefix structure. */
- ret = str2prefix(prefix_str, &p);
- if (!ret) {
- vty_out(vty, "Malformed prefix\n");
- return CMD_WARNING_CONFIG_FAILED;
+ if (suppress_map && summary_only) {
+ snprintf(errmsg, errmsg_len,
+ "'summary-only' and 'suppress-map' can't be used at the same time\n");
+ return -1;
}
- apply_mask(&p);
- if ((afi == AFI_IP && p.prefixlen == IPV4_MAX_BITLEN) ||
- (afi == AFI_IP6 && p.prefixlen == IPV6_MAX_BITLEN)) {
- vty_out(vty, "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
- prefix_str);
- return CMD_WARNING_CONFIG_FAILED;
+ apply_mask(prefix);
+
+ if ((afi == AFI_IP && prefix->prefixlen == IPV4_MAX_BITLEN)
+ || (afi == AFI_IP6 && prefix->prefixlen == IPV6_MAX_BITLEN)) {
+ snprintf(
+ errmsg, errmsg_len,
+ "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
+ prefix2str(prefix, buf, PREFIX_STRLEN));
+ return -1;
}
/* Old configuration check. */
- dest = bgp_node_get(bgp->aggregate[afi][safi], &p);
+ dest = bgp_node_get(bgp->aggregate[afi][safi], prefix);
aggregate = bgp_dest_get_bgp_aggregate_info(dest);
if (aggregate) {
- vty_out(vty, "There is already same aggregate network.\n");
+ snprintf(errmsg, errmsg_len,
+ "There is already same aggregate network.\n");
/* try to remove the old entry */
- ret = bgp_aggregate_unset(vty, prefix_str, afi, safi);
+ ret = bgp_aggregate_unset(bgp, prefix, afi, safi, errmsg,
+ errmsg_len);
if (ret) {
- vty_out(vty, "Error deleting aggregate.\n");
+ snprintf(errmsg, errmsg_len,
+ "Error deleting aggregate.\n");
bgp_dest_unlock_node(dest);
- return CMD_WARNING_CONFIG_FAILED;
+ return -1;
}
}
zlog_warn(
"%s: Ignoring as-set because `bgp reject-as-sets` is enabled.",
__func__);
- vty_out(vty,
+ snprintf(
+ errmsg, errmsg_len,
"Ignoring as-set because `bgp reject-as-sets` is enabled.\n");
}
}
aggregate->rmap.map = route_map_lookup_by_name(rmap);
route_map_counter_increment(aggregate->rmap.map);
}
+
+ if (suppress_map) {
+ XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
+ route_map_counter_decrement(aggregate->suppress_map);
+
+ aggregate->suppress_map_name =
+ XSTRDUP(MTYPE_ROUTE_MAP_NAME, suppress_map);
+ aggregate->suppress_map =
+ route_map_lookup_by_name(aggregate->suppress_map_name);
+ route_map_counter_increment(aggregate->suppress_map);
+ }
+
bgp_dest_set_bgp_aggregate_info(dest, aggregate);
/* Aggregate address insert into BGP routing table. */
- bgp_aggregate_route(bgp, &p, afi, safi, aggregate);
+ bgp_aggregate_route(bgp, prefix, afi, safi, aggregate);
- return CMD_SUCCESS;
+ return 0;
}
-DEFPY(aggregate_addressv4, aggregate_addressv4_cmd,
- "[no] aggregate-address <A.B.C.D/M$prefix|A.B.C.D$addr A.B.C.D$mask> {"
- "as-set$as_set_s"
- "|summary-only$summary_only"
- "|route-map WORD$rmap_name"
- "|origin <egp|igp|incomplete>$origin_s"
- "|matching-MED-only$match_med"
- "}",
- NO_STR
- "Configure BGP aggregate entries\n"
- "Aggregate prefix\n" "Aggregate address\n" "Aggregate mask\n"
- "Generate AS set path information\n"
- "Filter more specific routes from updates\n"
- "Apply route map to aggregate network\n"
- "Route map name\n"
- "BGP origin code\n"
- "Remote EGP\n"
- "Local IGP\n"
- "Unknown heritage\n"
- "Only aggregate routes with matching MED\n")
-{
- const char *prefix_s = NULL;
+DEFPY_YANG(
+ aggregate_addressv4, aggregate_addressv4_cmd,
+ "[no] aggregate-address <A.B.C.D/M$prefix|A.B.C.D$addr A.B.C.D$mask> {"
+ "as-set$as_set_s"
+ "|summary-only$summary_only"
+ "|route-map WORD$rmap_name"
+ "|origin <egp|igp|incomplete>$origin_s"
+ "|matching-MED-only$match_med"
+ "|suppress-map WORD$suppress_map"
+ "}",
+ NO_STR
+ "Configure BGP aggregate entries\n"
+ "Aggregate prefix\n"
+ "Aggregate address\n"
+ "Aggregate mask\n"
+ "Generate AS set path information\n"
+ "Filter more specific routes from updates\n"
+ "Apply route map to aggregate network\n"
+ "Route map name\n"
+ "BGP origin code\n"
+ "Remote EGP\n"
+ "Local IGP\n"
+ "Unknown heritage\n"
+ "Only aggregate routes with matching MED\n"
+ "Suppress the selected more specific routes\n"
+ "Route map with the route selectors\n")
+{
+ char base_xpath[XPATH_MAXLEN];
safi_t safi = bgp_node_safi(vty);
- uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
- int as_set = AGGREGATE_AS_UNSET;
char prefix_buf[PREFIX2STR_BUFFER];
if (addr_str) {
vty_out(vty, "%% Inconsistent address and mask\n");
return CMD_WARNING_CONFIG_FAILED;
}
- prefix_s = prefix_buf;
- } else
- prefix_s = prefix_str;
-
- if (origin_s) {
- if (strcmp(origin_s, "egp") == 0)
- origin = BGP_ORIGIN_EGP;
- else if (strcmp(origin_s, "igp") == 0)
- origin = BGP_ORIGIN_IGP;
- else if (strcmp(origin_s, "incomplete") == 0)
- origin = BGP_ORIGIN_INCOMPLETE;
+ } else {
+ strlcpy(prefix_buf, prefix_str, sizeof(prefix_buf));
}
- if (as_set_s)
- as_set = AGGREGATE_AS_SET;
+ if (!no && origin_s)
+ nb_cli_enqueue_change(vty, "./origin", NB_OP_MODIFY, origin_s);
+
+ if (!no && as_set_s)
+ nb_cli_enqueue_change(vty, "./as-set", NB_OP_MODIFY, "true");
+ else
+ nb_cli_enqueue_change(vty, "./as-set", NB_OP_MODIFY, "false");
+
+ if (!no && summary_only)
+ nb_cli_enqueue_change(vty, "./summary-only", NB_OP_MODIFY,
+ "true");
+ else
+ nb_cli_enqueue_change(vty, "./summary-only", NB_OP_MODIFY,
+ "false");
+
+ if (!no && match_med)
+ nb_cli_enqueue_change(vty, "./match-med", NB_OP_MODIFY, "true");
+ else
+ nb_cli_enqueue_change(vty, "./match-med", NB_OP_MODIFY,
+ "false");
+
+ if (rmap_name)
+ nb_cli_enqueue_change(vty, "./rmap-policy-export", NB_OP_MODIFY,
+ rmap_name);
+ else
+ nb_cli_enqueue_change(vty, "./rmap-policy-export",
+ NB_OP_DESTROY, NULL);
+
+ if (suppress_map)
+ nb_cli_enqueue_change(vty, "./suppress-map", NB_OP_MODIFY,
+ suppress_map);
+ else
+ nb_cli_enqueue_change(vty, "./suppress-map", NB_OP_DESTROY,
+ NULL);
+
+ snprintf(
+ base_xpath, sizeof(base_xpath),
+ "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/aggregate-route[prefix='%s']",
+ yang_afi_safi_value2identity(AFI_IP, safi),
+ bgp_afi_safi_get_container_str(AFI_IP, safi), prefix_buf);
- /* Handle configuration removal, otherwise installation. */
if (no)
- return bgp_aggregate_unset(vty, prefix_s, AFI_IP, safi);
-
- return bgp_aggregate_set(vty, prefix_s, AFI_IP, safi, rmap_name,
- summary_only != NULL, as_set, origin,
- match_med != NULL);
-}
-
-DEFPY(aggregate_addressv6, aggregate_addressv6_cmd,
- "[no] aggregate-address X:X::X:X/M$prefix {"
- "as-set$as_set_s"
- "|summary-only$summary_only"
- "|route-map WORD$rmap_name"
- "|origin <egp|igp|incomplete>$origin_s"
- "|matching-MED-only$match_med"
- "}",
- NO_STR
- "Configure BGP aggregate entries\n"
- "Aggregate prefix\n"
- "Generate AS set path information\n"
- "Filter more specific routes from updates\n"
- "Apply route map to aggregate network\n"
- "Route map name\n"
- "BGP origin code\n"
- "Remote EGP\n"
- "Local IGP\n"
- "Unknown heritage\n"
- "Only aggregate routes with matching MED\n")
-{
- uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
- int as_set = AGGREGATE_AS_UNSET;
-
- if (origin_s) {
- if (strcmp(origin_s, "egp") == 0)
- origin = BGP_ORIGIN_EGP;
- else if (strcmp(origin_s, "igp") == 0)
- origin = BGP_ORIGIN_IGP;
- else if (strcmp(origin_s, "incomplete") == 0)
- origin = BGP_ORIGIN_INCOMPLETE;
- }
-
- if (as_set_s)
- as_set = AGGREGATE_AS_SET;
-
- /* Handle configuration removal, otherwise installation. */
+ nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
+ else
+ nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
+
+ return nb_cli_apply_changes(vty, base_xpath);
+}
+
+DEFPY_YANG(aggregate_addressv6, aggregate_addressv6_cmd,
+ "[no] aggregate-address X:X::X:X/M$prefix {"
+ "as-set$as_set_s"
+ "|summary-only$summary_only"
+ "|route-map WORD$rmap_name"
+ "|origin <egp|igp|incomplete>$origin_s"
+ "|matching-MED-only$match_med"
+ "|suppress-map WORD$suppress_map"
+ "}",
+ NO_STR
+ "Configure BGP aggregate entries\n"
+ "Aggregate prefix\n"
+ "Generate AS set path information\n"
+ "Filter more specific routes from updates\n"
+ "Apply route map to aggregate network\n"
+ "Route map name\n"
+ "BGP origin code\n"
+ "Remote EGP\n"
+ "Local IGP\n"
+ "Unknown heritage\n"
+ "Only aggregate routes with matching MED\n"
+ "Suppress the selected more specific routes\n"
+ "Route map with the route selectors\n")
+{
+ char base_xpath[XPATH_MAXLEN];
+ safi_t safi = bgp_node_safi(vty);
+
+ if (!no && origin_s)
+ nb_cli_enqueue_change(vty, "./origin", NB_OP_MODIFY, origin_s);
+
+ if (!no && as_set_s)
+ nb_cli_enqueue_change(vty, "./as-set", NB_OP_MODIFY, "true");
+ else
+ nb_cli_enqueue_change(vty, "./as-set", NB_OP_MODIFY, "false");
+
+ if (!no && summary_only)
+ nb_cli_enqueue_change(vty, "./summary-only", NB_OP_MODIFY,
+ "true");
+ else
+ nb_cli_enqueue_change(vty, "./summary-only", NB_OP_MODIFY,
+ "false");
+
+ if (!no && match_med)
+ nb_cli_enqueue_change(vty, "./match-med", NB_OP_MODIFY, "true");
+ else
+ nb_cli_enqueue_change(vty, "./match-med", NB_OP_MODIFY,
+ "false");
+
+ if (rmap_name)
+ nb_cli_enqueue_change(vty, "./rmap-policy-export", NB_OP_MODIFY,
+ rmap_name);
+
+ if (suppress_map)
+ nb_cli_enqueue_change(vty, "./suppress-map", NB_OP_MODIFY,
+ suppress_map);
+ else
+ nb_cli_enqueue_change(vty, "./suppress-map", NB_OP_DESTROY,
+ NULL);
+
+ snprintf(
+ base_xpath, sizeof(base_xpath),
+ "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/aggregate-route[prefix='%s']",
+ yang_afi_safi_value2identity(AFI_IP6, safi),
+ bgp_afi_safi_get_container_str(AFI_IP6, safi), prefix_str);
+
if (no)
- return bgp_aggregate_unset(vty, prefix_str, AFI_IP6,
- SAFI_UNICAST);
+ nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
+ else
+ nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
+
+ return nb_cli_apply_changes(vty, base_xpath);
+}
+
+void cli_show_bgp_global_afi_safi_unicast_aggregate_route(
+ struct vty *vty, struct lyd_node *dnode, bool show_defaults)
+{
+ uint8_t origin;
+
+ vty_out(vty, " aggregate-address %s",
+ yang_dnode_get_string(dnode, "./prefix"));
- return bgp_aggregate_set(vty, prefix_str, AFI_IP6, SAFI_UNICAST,
- rmap_name, summary_only != NULL, as_set,
- origin, match_med != NULL);
+ if (yang_dnode_get_bool(dnode, "./as-set"))
+ vty_out(vty, " as-set");
+
+ if (yang_dnode_get_bool(dnode, "./summary-only"))
+ vty_out(vty, " summary-only");
+
+ if (yang_dnode_exists(dnode, "./rmap-policy-export"))
+ vty_out(vty, " route-map %s",
+ yang_dnode_get_string(dnode, "./rmap-policy-export"));
+
+ origin = yang_dnode_get_enum(dnode, "./origin");
+ if (origin != BGP_ORIGIN_UNSPECIFIED)
+ vty_out(vty, " origin %s", bgp_origin2str(origin));
+
+ if (yang_dnode_get_bool(dnode, "./match-med"))
+ vty_out(vty, " matching-MED-only");
+
+ vty_out(vty, "\n");
}
/* Redistribute route treatment. */
if (p->family == AF_INET) {
if (!json) {
- len = vty_out(
- vty, "%s/%d",
- inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ),
- p->prefixlen);
+ len = vty_out(vty, "%pFX", p);
} else {
json_object_string_add(json, "prefix",
inet_ntop(p->family,
json_object_string_add(json, "network", buf2);
}
} else if (p->family == AF_ETHERNET) {
- prefix2str(p, buf, PREFIX_STRLEN);
- len = vty_out(vty, "%s", buf);
+ len = vty_out(vty, "%pFX", p);
} else if (p->family == AF_EVPN) {
if (!json)
- len = vty_out(
- vty, "%s",
- bgp_evpn_route2str((struct prefix_evpn *)p, buf,
- BUFSIZ));
+ len = vty_out(vty, "%pFX", (struct prefix_evpn *)p);
else
bgp_evpn_route2json((struct prefix_evpn *)p, json);
} else if (p->family == AF_FLOWSPEC) {
NLRI_STRING_FORMAT_MIN, json);
} else {
if (!json)
- len = vty_out(
- vty, "%s/%d",
- inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ),
- p->prefixlen);
+ len = vty_out(vty, "%pFX", p);
else {
json_object_string_add(json, "prefix",
inet_ntop(p->family,
if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
json_object_boolean_true_add(json_path, "stale");
- if (path->extra && path->extra->suppress)
+ if (path->extra && bgp_path_suppressed(path))
json_object_boolean_true_add(json_path, "suppressed");
if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
vty_out(vty, "R");
else if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
vty_out(vty, "S");
- else if (path->extra && path->extra->suppress)
+ else if (bgp_path_suppressed(path))
vty_out(vty, "s");
else if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
&& !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
}
} else if (safi == SAFI_EVPN) {
if (json_paths) {
+ char buf[BUFSIZ] = {0};
+
json_nexthop_global = json_object_new_object();
json_object_string_add(json_nexthop_global, "ip",
- inet_ntoa(attr->nexthop));
+ inet_ntop(AF_INET,
+ &attr->nexthop, buf,
+ sizeof(buf)));
if (path->peer->hostname)
json_object_string_add(json_nexthop_global,
} else if (safi == SAFI_FLOWSPEC) {
if (attr->nexthop.s_addr != INADDR_ANY) {
if (json_paths) {
+ char buf[BUFSIZ] = {0};
+
json_nexthop_global = json_object_new_object();
json_object_string_add(json_nexthop_global,
"afi", "ipv4");
json_object_string_add(
json_nexthop_global, "ip",
- inet_ntoa(attr->nexthop));
+ inet_ntop(AF_INET, &attr->nexthop, buf,
+ sizeof(buf)));
if (path->peer->hostname)
json_object_string_add(
}
} else if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
if (json_paths) {
+ char buf[BUFSIZ] = {0};
+
json_nexthop_global = json_object_new_object();
json_object_string_add(json_nexthop_global, "ip",
- inet_ntoa(attr->nexthop));
+ inet_ntop(AF_INET,
+ &attr->nexthop, buf,
+ sizeof(buf)));
if (path->peer->hostname)
json_object_string_add(json_nexthop_global,
/* Print attribute */
if (attr) {
if (use_json) {
+ char buf[BUFSIZ] = {0};
+
if (p->family == AF_INET
&& (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
|| !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
json_object_string_add(
json_net, "nextHop",
- inet_ntoa(
- attr->mp_nexthop_global_in));
+ inet_ntop(
+ AF_INET,
+ &attr->mp_nexthop_global_in,
+ buf, sizeof(buf)));
else
json_object_string_add(
json_net, "nextHop",
- inet_ntoa(attr->nexthop));
+ inet_ntop(AF_INET,
+ &attr->nexthop, buf,
+ sizeof(buf)));
} else if (p->family == AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
char buf[BUFSIZ];
inet_ntop(AF_INET6,
&attr->mp_nexthop_global, buf,
BUFSIZ));
- } else if (p->family == AF_EVPN &&
- !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
- json_object_string_add(json_net,
- "nextHop", inet_ntoa(
- attr->mp_nexthop_global_in));
+ } else if (p->family == AF_EVPN
+ && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
+ char buf[BUFSIZ] = {0};
+
+ json_object_string_add(
+ json_net, "nextHop",
+ inet_ntop(AF_INET,
+ &attr->mp_nexthop_global_in,
+ buf, sizeof(buf)));
+ }
if (attr->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
|| !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
|| safi == SAFI_EVPN)
- vty_out(vty, "%-16s",
- inet_ntoa(
- attr->mp_nexthop_global_in));
+ vty_out(vty, "%-16pI4",
+ &attr->mp_nexthop_global_in);
else if (wide)
- vty_out(vty, "%-41s",
- inet_ntoa(attr->nexthop));
+ vty_out(vty, "%-41pI4", &attr->nexthop);
else
- vty_out(vty, "%-16s",
- inet_ntoa(attr->nexthop));
+ vty_out(vty, "%-16pI4", &attr->nexthop);
} else if (p->family == AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
char buf[BUFSIZ];
&& ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
|| (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
|| (!BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
+ char buf[BUFSIZ] = {0};
+
if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
|| safi == SAFI_EVPN) {
if (json)
json_object_string_add(
json_out, "mpNexthopGlobalIn",
- inet_ntoa(attr->mp_nexthop_global_in));
+ inet_ntop(AF_INET,
+ &attr->mp_nexthop_global_in,
+ buf, sizeof(buf)));
else
- vty_out(vty, "%-16s",
- inet_ntoa(attr->mp_nexthop_global_in));
+ vty_out(vty, "%-16pI4",
+ &attr->mp_nexthop_global_in);
} else {
if (json)
json_object_string_add(
json_out, "nexthop",
- inet_ntoa(attr->nexthop));
+ inet_ntop(AF_INET, &attr->nexthop, buf,
+ sizeof(buf)));
else
- vty_out(vty, "%-16s", inet_ntoa(attr->nexthop));
+ vty_out(vty, "%-16pI4", &attr->nexthop);
}
} else if (((p->family == AF_INET6)
&& ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
{
char buf[INET6_ADDRSTRLEN];
char buf1[BUFSIZ];
- char buf2[EVPN_ROUTE_STRLEN];
struct attr *attr = path->attr;
int sockunion_vty_out(struct vty *, union sockunion *);
time_t tbuf;
if (path->extra) {
char tag_buf[30];
- buf2[0] = '\0';
tag_buf[0] = '\0';
if (path->extra && path->extra->num_labels) {
bgp_evpn_label2str(path->extra->label,
}
if (safi == SAFI_EVPN) {
if (!json_paths) {
- bgp_evpn_route2str(
+ vty_out(vty, " Route %pFX",
(struct prefix_evpn *)
- bgp_dest_get_prefix(bn),
- buf2, sizeof(buf2));
- vty_out(vty, " Route %s", buf2);
+ bgp_dest_get_prefix(bn));
if (tag_buf[0] != '\0')
vty_out(vty, " VNI %s", tag_buf);
vty_out(vty, "\n");
pdest),
buf1, sizeof(buf1));
if (is_pi_family_evpn(parent_ri)) {
- bgp_evpn_route2str(
+ vty_out(vty,
+ " Imported from %s:%pFX, VNI %s\n",
+ buf1,
(struct prefix_evpn *)
bgp_dest_get_prefix(
dest),
- buf2, sizeof(buf2));
- vty_out(vty, " Imported from %s:%s, VNI %s\n", buf1, buf2, tag_buf);
+ tag_buf);
} else
- vty_out(vty, " Imported from %s:%s\n", buf1, buf2);
+ vty_out(vty,
+ " Imported from %s:%pFX\n",
+ buf1,
+ (struct prefix_evpn *)
+ bgp_dest_get_prefix(
+ dest));
}
}
}
if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
if (json_paths) {
+ char buf[BUFSIZ] = {0};
+
json_object_int_add(json_path, "aggregatorAs",
attr->aggregator_as);
- json_object_string_add(
- json_path, "aggregatorId",
- inet_ntoa(attr->aggregator_addr));
+ json_object_string_add(json_path, "aggregatorId",
+ inet_ntop(AF_INET,
+ &attr->aggregator_addr,
+ buf, sizeof(buf)));
if (attr->aggregator_as == BGP_AS_ZERO)
json_object_boolean_true_add(
json_path, "aggregatorAsMalformed");
} else {
if (attr->aggregator_as == BGP_AS_ZERO)
vty_out(vty,
- ", (aggregated by %u(malformed) %s)",
+ ", (aggregated by %u(malformed) %pI4)",
attr->aggregator_as,
- inet_ntoa(attr->aggregator_addr));
+ &attr->aggregator_addr);
else
- vty_out(vty, ", (aggregated by %u %s)",
+ vty_out(vty, ", (aggregated by %u %pI4)",
attr->aggregator_as,
- inet_ntoa(attr->aggregator_addr));
+ &attr->aggregator_addr);
}
}
|| bn_p->family == AF_EVPN)
&& (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN
|| !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
+ char buf[BUFSIZ] = {0};
+
if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
|| safi == SAFI_EVPN) {
if (json_paths) {
json_object_string_add(
json_nexthop_global, "ip",
- inet_ntoa(attr->mp_nexthop_global_in));
+ inet_ntop(AF_INET,
+ &attr->mp_nexthop_global_in,
+ buf, sizeof(buf)));
if (path->peer->hostname)
json_object_string_add(
if (json_paths) {
json_object_string_add(
json_nexthop_global, "ip",
- inet_ntoa(attr->nexthop));
+ inet_ntop(AF_INET, &attr->nexthop, buf,
+ sizeof(buf)));
if (path->peer->hostname)
json_object_string_add(
vty_out(vty, " from :: ");
}
- if (json_paths)
+ if (json_paths) {
+ char buf[BUFSIZ] = {0};
+
json_object_string_add(json_peer, "routerId",
- inet_ntoa(bgp->router_id));
- else
- vty_out(vty, "(%s)", inet_ntoa(bgp->router_id));
+ inet_ntop(AF_INET,
+ &bgp->router_id, buf,
+ sizeof(buf)));
+ } else {
+ vty_out(vty, "(%pI4)", &bgp->router_id);
+ }
}
/* We RXed this path from one of our peers */
}
if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
- vty_out(vty, " (%s)",
- inet_ntoa(attr->originator_id));
+ vty_out(vty, " (%pI4)", &attr->originator_id);
else
vty_out(vty, " (%s)",
inet_ntop(AF_INET,
/* Line 7 display Originator, Cluster-id */
if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
|| (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
+ char buf[BUFSIZ] = {0};
+
if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
if (json_paths)
json_object_string_add(
json_path, "originatorId",
- inet_ntoa(attr->originator_id));
+ inet_ntop(AF_INET, &attr->originator_id,
+ buf, sizeof(buf)));
else
- vty_out(vty, " Originator: %s",
- inet_ntoa(attr->originator_id));
+ vty_out(vty, " Originator: %pI4",
+ &attr->originator_id);
}
if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
for (i = 0; i < attr->cluster->length / 4;
i++) {
json_string = json_object_new_string(
- inet_ntoa(attr->cluster
- ->list[i]));
+ inet_ntop(
+ AF_INET,
+ &attr->cluster->list[i],
+ buf, sizeof(buf)));
json_object_array_add(
json_cluster_list_list,
json_string);
for (i = 0; i < attr->cluster->length / 4;
i++) {
- vty_out(vty, "%s ",
- inet_ntoa(attr->cluster
- ->list[i]));
+ vty_out(vty, "%pI4 ",
+ &attr->cluster->list[i]);
}
}
}
}
vty_out(vty,
- " \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64",\n \"routerId\": \"%s\",\n \"defaultLocPrf\": %u,\n"
+ " \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
+ ",\n \"routerId\": \"%pI4\",\n \"defaultLocPrf\": %u,\n"
" \"localAS\": %u,\n \"routes\": { ",
bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
- ? VRF_DEFAULT_NAME
- : bgp->name,
- table->version, inet_ntoa(bgp->router_id),
+ ? VRF_DEFAULT_NAME
+ : bgp->name,
+ table->version, &bgp->router_id,
bgp->default_local_pref, bgp->as);
if (rd) {
vty_out(vty, " \"routeDistinguishers\" : {");
}
if (!use_json && header) {
- vty_out(vty, "BGP table version is %" PRIu64", local router ID is %s, vrf id ",
- table->version,
- inet_ntoa(bgp->router_id));
+ vty_out(vty,
+ "BGP table version is %" PRIu64
+ ", local router ID is %pI4, vrf id ",
+ table->version, &bgp->router_id);
if (bgp->vrf_id == VRF_UNKNOWN)
vty_out(vty, "%s", VRFID_NONE_STR);
else
struct peer *peer;
struct listnode *node, *nnode;
char buf1[RD_ADDRSTRLEN];
- char buf2[INET6_ADDRSTRLEN];
- char buf3[EVPN_ROUTE_STRLEN];
char prefix_str[BUFSIZ];
int count = 0;
int best = 0;
if (safi == SAFI_EVPN) {
if (!json) {
- vty_out(vty, "BGP routing table entry for %s%s%s\n",
+ vty_out(vty, "BGP routing table entry for %s%s%pFX\n",
prd ? prefix_rd2str(prd, buf1, sizeof(buf1))
- : "", prd ? ":" : "",
- bgp_evpn_route2str((struct prefix_evpn *)p,
- buf3, sizeof(buf3)));
+ : "",
+ prd ? ":" : "", (struct prefix_evpn *)p);
} else {
json_object_string_add(json, "rd",
prd ? prefix_rd2str(prd, buf1, sizeof(buf1)) :
}
} else {
if (!json) {
- vty_out(vty, "BGP routing table entry for %s%s%s/%d\n",
+ vty_out(vty, "BGP routing table entry for %s%s%pFX\n",
((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
- ? prefix_rd2str(prd, buf1,
- sizeof(buf1))
- : ""),
- safi == SAFI_MPLS_VPN ? ":" : "",
- inet_ntop(p->family, &p->u.prefix, buf2,
- INET6_ADDRSTRLEN),
- p->prefixlen);
+ ? prefix_rd2str(prd, buf1,
+ sizeof(buf1))
+ : ""),
+ safi == SAFI_MPLS_VPN ? ":" : "", p);
} else
json_object_string_add(json, "prefix",
count++;
if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
best = count;
- if (pi->extra && pi->extra->suppress)
+ if (bgp_path_suppressed(pi))
suppress = 1;
if (pi->attr->community == NULL)
json_object *json_ocode, bool wide)
{
uint64_t version = table ? table->version : 0;
+ char buf[BUFSIZ] = {0};
if (*header1) {
if (json) {
json_object_int_add(json, "bgpTableVersion", version);
json_object_string_add(json, "bgpLocalRouterId",
- inet_ntoa(bgp->router_id));
+ inet_ntop(AF_INET,
+ &bgp->router_id, buf,
+ sizeof(buf)));
json_object_int_add(json, "defaultLocPrf",
bgp->default_local_pref);
json_object_int_add(json, "localAS", bgp->as);
json_ocode);
} else {
vty_out(vty,
- "BGP table version is %" PRIu64 ", local router ID is %s, vrf id ",
- version, inet_ntoa(bgp->router_id));
+ "BGP table version is %" PRIu64
+ ", local router ID is %pI4, vrf id ",
+ version, &bgp->router_id);
if (bgp->vrf_id == VRF_UNKNOWN)
vty_out(vty, "%s", VRFID_NONE_STR);
else
if (type == bgp_show_adj_route_advertised && subgrp
&& CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
+ char buf[BUFSIZ] = {0};
+
if (use_json) {
json_object_int_add(json, "bgpTableVersion",
table->version);
json_object_string_add(json, "bgpLocalRouterId",
- inet_ntoa(bgp->router_id));
+ inet_ntop(AF_INET,
+ &bgp->router_id, buf,
+ sizeof(buf)));
json_object_int_add(json, "defaultLocPrf",
bgp->default_local_pref);
json_object_int_add(json, "localAS", bgp->as);
json, "bgpOriginatingDefaultNetwork",
(afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
} else {
- vty_out(vty, "BGP table version is %" PRIu64", local router ID is %s, vrf id ",
- table->version, inet_ntoa(bgp->router_id));
+ vty_out(vty,
+ "BGP table version is %" PRIu64
+ ", local router ID is %pI4, vrf id ",
+ table->version, &bgp->router_id);
if (bgp->vrf_id == VRF_UNKNOWN)
vty_out(vty, "%s", VRFID_NONE_STR);
else
if (use_json)
SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
- /* labeled-unicast routes live in the unicast table */
- if (safi == SAFI_LABELED_UNICAST)
- safi = SAFI_UNICAST;
-
if (!peer || !peer->afc[afi][safi]) {
if (use_json) {
json_object *json_no = NULL;
return CMD_WARNING;
}
+ /* labeled-unicast routes live in the unicast table */
+ if (safi == SAFI_LABELED_UNICAST)
+ safi = SAFI_UNICAST;
+
return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, show_flags);
}
XFREE(MTYPE_BGP_DISTANCE, bdistance);
}
-static int bgp_distance_set(struct vty *vty, const char *distance_str,
- const char *ip_str, const char *access_list_str)
+int bgp_distance_set(uint8_t distance, const char *ip_str,
+ const char *access_list_str, afi_t afi, safi_t safi,
+ char *errmsg, size_t errmsg_len)
{
int ret;
- afi_t afi;
- safi_t safi;
struct prefix p;
- uint8_t distance;
struct bgp_dest *dest;
struct bgp_distance *bdistance;
- afi = bgp_node_afi(vty);
- safi = bgp_node_safi(vty);
-
ret = str2prefix(ip_str, &p);
if (ret == 0) {
- vty_out(vty, "Malformed prefix\n");
+ snprintf(errmsg, errmsg_len, "Malformed prefix\n");
return CMD_WARNING_CONFIG_FAILED;
}
- distance = atoi(distance_str);
-
/* Get BGP distance node. */
dest = bgp_node_get(bgp_distance_table[afi][safi], &p);
bdistance = bgp_dest_get_bgp_distance_info(dest);
return CMD_SUCCESS;
}
-static int bgp_distance_unset(struct vty *vty, const char *distance_str,
- const char *ip_str, const char *access_list_str)
+int bgp_distance_unset(uint8_t distance, const char *ip_str,
+ const char *access_list_str, afi_t afi, safi_t safi,
+ char *errmsg, size_t errmsg_len)
{
int ret;
- afi_t afi;
- safi_t safi;
struct prefix p;
- int distance;
struct bgp_dest *dest;
struct bgp_distance *bdistance;
- afi = bgp_node_afi(vty);
- safi = bgp_node_safi(vty);
-
ret = str2prefix(ip_str, &p);
if (ret == 0) {
- vty_out(vty, "Malformed prefix\n");
+ snprintf(errmsg, errmsg_len, "Malformed prefix\n");
return CMD_WARNING_CONFIG_FAILED;
}
dest = bgp_node_lookup(bgp_distance_table[afi][safi], &p);
if (!dest) {
- vty_out(vty, "Can't find specified prefix\n");
+ snprintf(errmsg, errmsg_len, "Can't find specified prefix\n");
return CMD_WARNING_CONFIG_FAILED;
}
bdistance = bgp_dest_get_bgp_distance_info(dest);
- distance = atoi(distance_str);
if (bdistance->distance != distance) {
- vty_out(vty, "Distance does not match configured\n");
+ snprintf(errmsg, errmsg_len,
+ "Distance does not match configured\n");
return CMD_WARNING_CONFIG_FAILED;
}
* we should tell ZEBRA update the routes for a specific
* AFI/SAFI to reflect changes in RIB.
*/
-static void bgp_announce_routes_distance_update(struct bgp *bgp,
- afi_t update_afi,
- safi_t update_safi)
+void bgp_announce_routes_distance_update(struct bgp *bgp, afi_t update_afi,
+ safi_t update_safi)
{
afi_t afi;
safi_t safi;
}
}
-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")
+DEFUN_YANG(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")
{
- VTY_DECLVAR_CONTEXT(bgp, bgp);
int idx_number = 2;
int idx_number_2 = 3;
int idx_number_3 = 4;
- int distance_ebgp = atoi(argv[idx_number]->arg);
- int distance_ibgp = atoi(argv[idx_number_2]->arg);
- int distance_local = atoi(argv[idx_number_3]->arg);
afi_t afi;
safi_t safi;
+ char xpath[XPATH_MAXLEN];
afi = bgp_node_afi(vty);
safi = bgp_node_safi(vty);
- if (bgp->distance_ebgp[afi][safi] != distance_ebgp
- || bgp->distance_ibgp[afi][safi] != distance_ibgp
- || bgp->distance_local[afi][safi] != distance_local) {
- bgp->distance_ebgp[afi][safi] = distance_ebgp;
- bgp->distance_ibgp[afi][safi] = distance_ibgp;
- bgp->distance_local[afi][safi] = distance_local;
- bgp_announce_routes_distance_update(bgp, afi, safi);
- }
- return CMD_SUCCESS;
-}
+ snprintf(
+ xpath, sizeof(xpath),
+ "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/external",
+ yang_afi_safi_value2identity(afi, safi),
+ bgp_afi_safi_get_container_str(afi, safi));
+ nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, argv[idx_number]->arg);
+ snprintf(
+ xpath, sizeof(xpath),
+ "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/internal",
+ yang_afi_safi_value2identity(afi, safi),
+ bgp_afi_safi_get_container_str(afi, safi));
+ nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY,
+ argv[idx_number_2]->arg);
+ snprintf(
+ xpath, sizeof(xpath),
+ "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/local",
+ yang_afi_safi_value2identity(afi, safi),
+ bgp_afi_safi_get_container_str(afi, safi));
+
+ nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY,
+ argv[idx_number_3]->arg);
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFUN_YANG(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")
+{
+ afi_t afi;
+ safi_t safi;
+ char xpath[XPATH_MAXLEN];
-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")
+ afi = bgp_node_afi(vty);
+ safi = bgp_node_safi(vty);
+
+ snprintf(
+ xpath, sizeof(xpath),
+ "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/external",
+ yang_afi_safi_value2identity(afi, safi),
+ bgp_afi_safi_get_container_str(afi, safi));
+ nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, NULL);
+ snprintf(
+ xpath, sizeof(xpath),
+ "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/internal",
+ yang_afi_safi_value2identity(afi, safi),
+ bgp_afi_safi_get_container_str(afi, safi));
+ nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, NULL);
+ snprintf(
+ xpath, sizeof(xpath),
+ "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/local",
+ yang_afi_safi_value2identity(afi, safi),
+ bgp_afi_safi_get_container_str(afi, safi));
+
+ nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, NULL);
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_bgp_global_afi_safi_admin_distance_config(struct vty *vty,
+ struct lyd_node *dnode,
+ bool show_defaults)
+{
+ uint8_t distance_ebgp, distance_ibgp, distance_local;
+
+ distance_ebgp = yang_dnode_get_uint8(dnode, "./external");
+ distance_ibgp = yang_dnode_get_uint8(dnode, "./internal");
+ distance_local = yang_dnode_get_uint8(dnode, "./local");
+
+ vty_out(vty, " distance bgp %d %d %d\n", distance_ebgp, distance_ibgp,
+ distance_local);
+}
+
+DEFPY_YANG(bgp_distance_source,
+ bgp_distance_source_cmd,
+ "[no] distance (1-255) <A.B.C.D/M | X:X::X:X/M>$prefix [WORD$acl]",
+ NO_STR
+ "Define an administrative distance\n"
+ "Distance value\n"
+ "IPv4 source prefix\n"
+ "IPv6 source prefix\n"
+ "Access list name\n")
{
- VTY_DECLVAR_CONTEXT(bgp, bgp);
afi_t afi;
safi_t safi;
+ char xpath[XPATH_MAXLEN];
afi = bgp_node_afi(vty);
safi = bgp_node_safi(vty);
- if (bgp->distance_ebgp[afi][safi] != 0
- || bgp->distance_ibgp[afi][safi] != 0
- || bgp->distance_local[afi][safi] != 0) {
- bgp->distance_ebgp[afi][safi] = 0;
- bgp->distance_ibgp[afi][safi] = 0;
- bgp->distance_local[afi][safi] = 0;
- bgp_announce_routes_distance_update(bgp, afi, safi);
+ if (!no) {
+ nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
+ nb_cli_enqueue_change(vty, "./distance", NB_OP_MODIFY,
+ distance_str);
+ if (acl)
+ nb_cli_enqueue_change(vty,
+ "./access-list-policy-export",
+ NB_OP_CREATE, acl);
+ else
+ nb_cli_enqueue_change(vty,
+ "./access-list-policy-export",
+ NB_OP_DESTROY, NULL);
+ } else {
+ nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
}
- return CMD_SUCCESS;
-}
+ snprintf(
+ xpath, sizeof(xpath),
+ "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance-route[prefix='%s']",
+ yang_afi_safi_value2identity(afi, safi),
+ bgp_afi_safi_get_container_str(afi, safi), prefix_str);
-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")
-{
- int idx_number = 1;
- int idx_ipv4_prefixlen = 2;
- bgp_distance_set(vty, argv[idx_number]->arg,
- argv[idx_ipv4_prefixlen]->arg, NULL);
- return CMD_SUCCESS;
+ return nb_cli_apply_changes(vty, xpath);
}
-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")
+void cli_show_bgp_global_afi_safi_unicast_admin_distance_route(
+ struct vty *vty, struct lyd_node *dnode, bool show_defaults)
{
- int idx_number = 2;
- int idx_ipv4_prefixlen = 3;
- bgp_distance_unset(vty, argv[idx_number]->arg,
- argv[idx_ipv4_prefixlen]->arg, NULL);
- return CMD_SUCCESS;
+ vty_out(vty, " distance %d %s %s\n",
+ yang_dnode_get_uint8(dnode, "./distance"),
+ yang_dnode_get_string(dnode, "./prefix"),
+ (yang_dnode_exists(dnode, "./access-list-policy-export"))
+ ? yang_dnode_get_string(dnode,
+ "./access-list-policy-export")
+ : "");
}
-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")
+DEFPY_YANG(bgp_dampening,
+ bgp_dampening_cmd,
+ "[no] bgp dampening [(1-45)$halflife [(1-20000)$reuse (1-20000)$suppress (1-255)$max_supress]]",
+ 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")
{
- int idx_number = 1;
- int idx_ipv4_prefixlen = 2;
- int idx_word = 3;
- bgp_distance_set(vty, argv[idx_number]->arg,
- argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
- return CMD_SUCCESS;
-}
+ afi_t afi;
+ safi_t safi;
+ char xpath[XPATH_MAXLEN];
-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")
-{
- int idx_number = 2;
- int idx_ipv4_prefixlen = 3;
- int idx_word = 4;
- bgp_distance_unset(vty, argv[idx_number]->arg,
- argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
- return CMD_SUCCESS;
-}
+ afi = bgp_node_afi(vty);
+ safi = bgp_node_safi(vty);
-DEFUN (ipv6_bgp_distance_source,
- ipv6_bgp_distance_source_cmd,
- "distance (1-255) X:X::X:X/M",
- "Define an administrative distance\n"
- "Administrative distance\n"
- "IP source prefix\n")
-{
- bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
- return CMD_SUCCESS;
-}
+ if (!no) {
+ nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY, "true");
+ if (argc == 6) {
+ nb_cli_enqueue_change(vty, "./reach-decay",
+ NB_OP_MODIFY, halflife_str);
+ nb_cli_enqueue_change(vty, "./reuse-above",
+ NB_OP_MODIFY, reuse_str);
+ nb_cli_enqueue_change(vty, "./suppress-above",
+ NB_OP_MODIFY, suppress_str);
+ nb_cli_enqueue_change(vty, "./unreach-decay",
+ NB_OP_MODIFY, max_supress_str);
+ } if (argc == 3) {
+ nb_cli_enqueue_change(vty, "./reach-decay",
+ NB_OP_MODIFY, halflife_str);
+ }
+ } else {
+ nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY, "false");
+ }
-DEFUN (no_ipv6_bgp_distance_source,
- no_ipv6_bgp_distance_source_cmd,
- "no distance (1-255) X:X::X:X/M",
- NO_STR
- "Define an administrative distance\n"
- "Administrative distance\n"
- "IP source prefix\n")
-{
- bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
- return CMD_SUCCESS;
-}
+ snprintf(
+ xpath, sizeof(xpath),
+ "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/route-flap-dampening",
+ yang_afi_safi_value2identity(afi, safi),
+ bgp_afi_safi_get_container_str(afi, safi));
-DEFUN (ipv6_bgp_distance_source_access_list,
- ipv6_bgp_distance_source_access_list_cmd,
- "distance (1-255) X:X::X:X/M WORD",
- "Define an administrative distance\n"
- "Administrative distance\n"
- "IP source prefix\n"
- "Access list name\n")
-{
- bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
- return CMD_SUCCESS;
+ return nb_cli_apply_changes(vty, xpath);
}
-DEFUN (no_ipv6_bgp_distance_source_access_list,
- no_ipv6_bgp_distance_source_access_list_cmd,
- "no distance (1-255) X:X::X:X/M WORD",
- NO_STR
- "Define an administrative distance\n"
- "Administrative distance\n"
- "IP source prefix\n"
- "Access list name\n")
+void cli_show_bgp_global_afi_safi_route_flap_dampening(struct vty *vty,
+ struct lyd_node *dnode,
+ bool show_defaults)
{
- bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
- return CMD_SUCCESS;
-}
+ if (!yang_dnode_get_bool(dnode, "./enable"))
+ return;
-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")
-{
- VTY_DECLVAR_CONTEXT(bgp, bgp);
- int idx_half_life = 2;
- int idx_reuse = 3;
- int idx_suppress = 4;
- int idx_max_suppress = 5;
int half = DEFAULT_HALF_LIFE * 60;
int reuse = DEFAULT_REUSE;
int suppress = DEFAULT_SUPPRESS;
- int max = 4 * half;
-
- if (argc == 6) {
- half = atoi(argv[idx_half_life]->arg) * 60;
- reuse = atoi(argv[idx_reuse]->arg);
- suppress = atoi(argv[idx_suppress]->arg);
- max = atoi(argv[idx_max_suppress]->arg) * 60;
- } else if (argc == 3) {
- half = atoi(argv[idx_half_life]->arg) * 60;
- max = 4 * half;
- }
-
- /*
- * These can't be 0 but our SA doesn't understand the
- * way our cli is constructed
- */
- assert(reuse);
- assert(half);
- if (suppress < reuse) {
- vty_out(vty,
- "Suppress value cannot be less than reuse value \n");
- return 0;
- }
-
- return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
- reuse, suppress, max);
-}
-
-DEFUN (bgp_damp_unset,
- bgp_damp_unset_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")
-{
- VTY_DECLVAR_CONTEXT(bgp, bgp);
- return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
+ int max;
+
+ half = yang_dnode_get_uint8(dnode, "../reach-decay");
+ reuse = yang_dnode_get_uint16(dnode, "../reuse-above");
+ suppress = yang_dnode_get_uint16(dnode, "../suppress-above");
+ max = yang_dnode_get_uint8(dnode, "../unreach-decay");
+
+ if (half == DEFAULT_HALF_LIFE * 60 && reuse == DEFAULT_REUSE
+ && suppress == DEFAULT_SUPPRESS && max == half * 4)
+ vty_out(vty, " bgp dampening\n");
+ else if (half != DEFAULT_HALF_LIFE * 60 && reuse == DEFAULT_REUSE
+ && suppress == DEFAULT_SUPPRESS && max == half * 4)
+ vty_out(vty, " bgp dampening %u\n", half);
+ else
+ vty_out(vty, " bgp dampening %u %d %d %d\n", half, reuse,
+ suppress, max);
}
/* Display specified route of BGP table. */
const struct prefix_rd *prd;
struct bgp_static *bgp_static;
mpls_label_t label;
- char buf[SU_ADDRSTRLEN];
char rdbuf[RD_ADDRSTRLEN];
/* Network configuration. */
prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
label = decode_label(&bgp_static->label);
- vty_out(vty, " network %s/%d rd %s",
- inet_ntop(p->family, &p->u.prefix, buf,
- SU_ADDRSTRLEN),
- p->prefixlen, rdbuf);
+ vty_out(vty, " network %pFX rd %s", p, rdbuf);
if (safi == SAFI_MPLS_VPN)
vty_out(vty, " label %u", label);
const struct prefix *p;
struct bgp_static *bgp_static;
struct bgp_aggregate *bgp_aggregate;
- char buf[SU_ADDRSTRLEN];
if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
bgp_config_write_network_vpn(vty, bgp, afi, safi);
p = bgp_dest_get_prefix(dest);
- vty_out(vty, " network %s/%d",
- inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
- p->prefixlen);
+ vty_out(vty, " network %pFX", p);
if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
vty_out(vty, " label-index %u",
p = bgp_dest_get_prefix(dest);
- vty_out(vty, " aggregate-address %s/%d",
- inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
- p->prefixlen);
+ vty_out(vty, " aggregate-address %pFX", p);
if (bgp_aggregate->as_set)
vty_out(vty, " as-set");
if (bgp_aggregate->match_med)
vty_out(vty, " matching-MED-only");
+ if (bgp_aggregate->suppress_map_name)
+ vty_out(vty, " suppress-map %s",
+ bgp_aggregate->suppress_map_name);
+
vty_out(vty, "\n");
}
}
dest = bgp_route_next(dest)) {
bdistance = bgp_dest_get_bgp_distance_info(dest);
if (bdistance != NULL)
- vty_out(vty, " distance %d %pRN %s\n",
+ vty_out(vty, " distance %d %pBD %s\n",
bdistance->distance, dest,
bdistance->access_list ? bdistance->access_list
: "");
install_element(BGP_NODE, &bgp_distance_cmd);
install_element(BGP_NODE, &no_bgp_distance_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_IPV4_NODE, &bgp_distance_cmd);
install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
- install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
- install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
- install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
- install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
- install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
- install_element(BGP_IPV4M_NODE,
- &no_bgp_distance_source_access_list_cmd);
install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
- install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
- install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
- install_element(BGP_IPV6_NODE,
- &ipv6_bgp_distance_source_access_list_cmd);
- install_element(BGP_IPV6_NODE,
- &no_ipv6_bgp_distance_source_access_list_cmd);
+ install_element(BGP_IPV6_NODE, &bgp_distance_source_cmd);
install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
- install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
- install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
- install_element(BGP_IPV6M_NODE,
- &ipv6_bgp_distance_source_access_list_cmd);
- install_element(BGP_IPV6M_NODE,
- &no_ipv6_bgp_distance_source_access_list_cmd);
+ install_element(BGP_IPV6M_NODE, &bgp_distance_source_cmd);
/* BGP dampening */
- install_element(BGP_NODE, &bgp_damp_set_cmd);
- install_element(BGP_NODE, &bgp_damp_unset_cmd);
- install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
- install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
- install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
- install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
- install_element(BGP_IPV4L_NODE, &bgp_damp_set_cmd);
- install_element(BGP_IPV4L_NODE, &bgp_damp_unset_cmd);
- install_element(BGP_IPV6_NODE, &bgp_damp_set_cmd);
- install_element(BGP_IPV6_NODE, &bgp_damp_unset_cmd);
- install_element(BGP_IPV6M_NODE, &bgp_damp_set_cmd);
- install_element(BGP_IPV6M_NODE, &bgp_damp_unset_cmd);
- install_element(BGP_IPV6L_NODE, &bgp_damp_set_cmd);
- install_element(BGP_IPV6L_NODE, &bgp_damp_unset_cmd);
+ install_element(BGP_NODE, &bgp_dampening_cmd);
+ install_element(BGP_IPV4_NODE, &bgp_dampening_cmd);
+ install_element(BGP_IPV4M_NODE, &bgp_dampening_cmd);
+ install_element(BGP_IPV4L_NODE, &bgp_dampening_cmd);
+ install_element(BGP_IPV6_NODE, &bgp_dampening_cmd);
+ install_element(BGP_IPV6M_NODE, &bgp_dampening_cmd);
+ install_element(BGP_IPV6L_NODE, &bgp_dampening_cmd);
/* Large Communities */
install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);