summaryrefslogtreecommitdiff
path: root/bgpd/bgp_route.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_route.c')
-rw-r--r--bgpd/bgp_route.c1279
1 files changed, 581 insertions, 698 deletions
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 4637cef3eb..716ba26305 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -88,9 +88,6 @@
#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"
@@ -221,6 +218,9 @@ void bgp_path_info_extra_free(struct bgp_path_info_extra **extra)
return;
e = *extra;
+ if (e->damp_info)
+ bgp_damp_info_free(e->damp_info, 0, e->damp_info->afi,
+ e->damp_info->safi);
e->damp_info = NULL;
if (e->parent) {
@@ -3391,16 +3391,14 @@ static void bgp_rib_withdraw(struct bgp_dest *dest, struct bgp_path_info *pi,
/* apply dampening, if result is suppressed, we'll be retaining
* the bgp_path_info in the RIB for historical reference.
*/
- if (peer->sort == BGP_PEER_EBGP) {
- if (get_active_bdc_from_pi(pi, afi, safi)) {
- if (bgp_damp_withdraw(pi, dest, afi, safi, 0)
- == BGP_DAMP_SUPPRESSED) {
- bgp_aggregate_decrement(peer->bgp, p, pi, afi,
- safi);
- return;
- }
+ if (CHECK_FLAG(peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
+ && peer->sort == BGP_PEER_EBGP)
+ if ((bgp_damp_withdraw(pi, dest, afi, safi, 0))
+ == BGP_DAMP_SUPPRESSED) {
+ bgp_aggregate_decrement(peer->bgp, p, pi, afi,
+ safi);
+ return;
}
- }
#ifdef ENABLE_BGP_VNC
if (safi == SAFI_MPLS_VPN) {
@@ -3604,6 +3602,7 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
afi_t nh_afi;
uint8_t pi_type = 0;
uint8_t pi_sub_type = 0;
+ bool force_evpn_import = false;
if (frrtrace_enabled(frr_bgp, process_update)) {
char pfxprint[PREFIX2STR_BUFFER];
@@ -3663,7 +3662,7 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
if (aspath_loop_check(attr->aspath, peer->change_local_as)
> aspath_loop_count) {
peer->stat_pfx_aspath_loop++;
- reason = "as-path contains our own AS A;";
+ reason = "as-path contains our own AS;";
goto filtered;
}
}
@@ -3848,7 +3847,8 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
|| memcmp(&(bgp_path_info_extra_get(pi))->label, label,
num_labels * sizeof(mpls_label_t))
== 0)) {
- if (get_active_bdc_from_pi(pi, afi, safi)
+ if (CHECK_FLAG(bgp->af_flags[afi][safi],
+ BGP_CONFIG_DAMPENING)
&& peer->sort == BGP_PEER_EBGP
&& CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
if (bgp_debug_update(peer, p, NULL, 1)) {
@@ -3916,6 +3916,14 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
}
bgp_path_info_restore(dest, pi);
+
+ /*
+ * If the BGP_PATH_REMOVED flag is set, then EVPN
+ * routes would have been unimported already when a
+ * prior BGP withdraw processing happened. Such routes
+ * need to be imported again, so flag accordingly.
+ */
+ force_evpn_import = true;
}
/* Received Logging. */
@@ -3942,11 +3950,11 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
bgp_aggregate_decrement(bgp, p, pi, afi, safi);
/* Update bgp route dampening information. */
- if (get_active_bdc_from_pi(pi, afi, safi)
+ if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
&& peer->sort == BGP_PEER_EBGP) {
/* This is implicit withdraw so we should update
- * dampening information.
- */
+ dampening
+ information. */
if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
bgp_damp_withdraw(pi, dest, afi, safi, 1);
}
@@ -4069,7 +4077,7 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
#endif
/* Update bgp route dampening information. */
- if (get_active_bdc_from_pi(pi, afi, safi)
+ if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
&& peer->sort == BGP_PEER_EBGP) {
/* Now we do normal update dampening. */
ret = bgp_damp_update(pi, dest, afi, safi);
@@ -4103,7 +4111,8 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr);
if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi,
- safi, pi, NULL, connected)
+ safi, pi, NULL, connected,
+ p)
|| CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
bgp_path_info_set_flag(dest, pi,
BGP_PATH_VALID);
@@ -4137,7 +4146,7 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
#endif
/* If this is an EVPN route and some attribute has changed,
- * process
+ * or we are explicitly told to perform a route import, process
* route for import. If the extended community has changed, we
* would
* have done the un-import earlier and the import would result
@@ -4148,7 +4157,8 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
* updating
* the attributes for the route in the VNI(s).
*/
- if (safi == SAFI_EVPN && !same_attr &&
+ if (safi == SAFI_EVPN &&
+ (!same_attr || force_evpn_import) &&
CHECK_FLAG(pi->flags, BGP_PATH_VALID))
bgp_evpn_import_route(bgp, afi, safi, p, pi);
@@ -4244,7 +4254,7 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
nh_afi = BGP_ATTR_NH_AFI(afi, new->attr);
if (bgp_find_or_add_nexthop(bgp, bgp, nh_afi, safi, new, NULL,
- connected)
+ connected, p)
|| CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
else {
@@ -5683,7 +5693,7 @@ void bgp_static_update(struct bgp *bgp, const struct prefix *p,
if (bgp_find_or_add_nexthop(bgp, bgp_nexthop,
afi, safi, pi, NULL,
- 0))
+ 0, p))
bgp_path_info_set_flag(dest, pi,
BGP_PATH_VALID);
else {
@@ -5735,7 +5745,8 @@ void bgp_static_update(struct bgp *bgp, const struct prefix *p,
/* Nexthop reachability check. */
if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
&& (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
- if (bgp_find_or_add_nexthop(bgp, bgp, afi, safi, new, NULL, 0))
+ if (bgp_find_or_add_nexthop(bgp, bgp, afi, safi, new, NULL, 0,
+ p))
bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
else {
if (BGP_DEBUG(nht, NHT)) {
@@ -6023,16 +6034,28 @@ static void bgp_static_update_safi(struct bgp *bgp, const struct prefix *p,
/* Configure static BGP network. When user don't run zebra, static
route should be installed as valid. */
-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)
+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)
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int ret;
struct prefix p;
struct bgp_static *bgp_static;
struct bgp_dest *dest;
uint8_t need_update = 0;
- prefix_copy(&p, pfx);
+ /* 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;
+ }
+
apply_mask(&p);
if (negate) {
@@ -6041,25 +6064,26 @@ int bgp_static_set(struct bgp *bgp, const char *negate, struct prefix *pfx,
dest = bgp_node_lookup(bgp->route[afi][safi], &p);
if (!dest) {
- snprintf(errmsg, errmsg_len,
- "Can't find static route specified\n");
- return -1;
+ vty_out(vty, "%% Can't find static route specified\n");
+ return CMD_WARNING_CONFIG_FAILED;
}
bgp_static = bgp_dest_get_bgp_static_info(dest);
if ((label_index != BGP_INVALID_LABEL_INDEX)
&& (label_index != bgp_static->label_index)) {
- snprintf(errmsg, errmsg_len,
- "label-index doesn't match static route\n");
- return -1;
+ vty_out(vty,
+ "%% label-index doesn't match static route\n");
+ bgp_dest_unlock_node(dest);
+ return CMD_WARNING_CONFIG_FAILED;
}
if ((rmap && bgp_static->rmap.name)
&& strcmp(rmap, bgp_static->rmap.name)) {
- snprintf(errmsg, errmsg_len,
- "route-map name doesn't match static route\n");
- return -1;
+ vty_out(vty,
+ "%% route-map name doesn't match static route\n");
+ bgp_dest_unlock_node(dest);
+ return CMD_WARNING_CONFIG_FAILED;
}
/* Update BGP RIB. */
@@ -6080,9 +6104,8 @@ int bgp_static_set(struct bgp *bgp, const char *negate, struct prefix *pfx,
/* Configuration change. */
/* Label index cannot be changed. */
if (bgp_static->label_index != label_index) {
- snprintf(errmsg, errmsg_len,
- "cannot change label-index\n");
- return -1;
+ vty_out(vty, "%% cannot change label-index\n");
+ return CMD_WARNING_CONFIG_FAILED;
}
/* Check previous routes are installed into BGP. */
@@ -6144,7 +6167,7 @@ int bgp_static_set(struct bgp *bgp, const char *negate, struct prefix *pfx,
bgp_static_update(bgp, &p, bgp_static, afi, safi);
}
- return 0;
+ return CMD_SUCCESS;
}
void bgp_static_add(struct bgp *bgp)
@@ -6596,27 +6619,25 @@ DEFUN (no_bgp_table_map,
argv[idx_word]->arg);
}
-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;
+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];
if (address_str) {
int ret;
@@ -6630,102 +6651,27 @@ DEFPY_YANG (bgp_network, bgp_network_cmd,
}
}
- 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_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")
-{
- 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);
+ 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);
}
-void cli_show_bgp_global_afi_safi_network_config(struct vty *vty,
- struct lyd_node *dnode,
- bool show_defaults)
+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")
{
- 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");
+ 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);
}
static struct bgp_aggregate *bgp_aggregate_new(void)
@@ -7801,32 +7747,35 @@ static const char *bgp_rpki_validation2str(enum rpki_states v_state)
return "ERROR";
}
-int bgp_aggregate_unset(struct bgp *bgp, struct prefix *prefix, afi_t afi,
- safi_t safi, char *errmsg, size_t errmsg_len)
+static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
+ afi_t afi, safi_t safi)
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int ret;
+ struct prefix p;
struct bgp_dest *dest;
struct bgp_aggregate *aggregate;
- /* If the bgp instance is being deleted or self peer is deleted
- * then do not create aggregate route
- */
- if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
- || (bgp->peer_self == NULL))
- return 0;
+ /* 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], prefix);
+ dest = bgp_node_lookup(bgp->aggregate[afi][safi], &p);
if (!dest) {
- snprintf(errmsg, errmsg_len,
- "There is no aggregate-address configuration.\n");
- return -1;
+ vty_out(vty,
+ "%% There is no aggregate-address configuration.\n");
+ return CMD_WARNING_CONFIG_FAILED;
}
aggregate = bgp_dest_get_bgp_aggregate_info(dest);
- bgp_aggregate_delete(bgp, prefix, afi, safi, aggregate);
- bgp_aggregate_install(bgp, afi, safi, prefix, 0, NULL, NULL, NULL, NULL,
- 0, aggregate);
+ bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
+ bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL,
+ NULL, NULL, 0, aggregate);
/* Unlock aggregate address configuration. */
bgp_dest_set_bgp_aggregate_info(dest, NULL);
@@ -7887,53 +7836,55 @@ int bgp_aggregate_unset(struct bgp *bgp, struct prefix *prefix, afi_t afi,
bgp_dest_unlock_node(dest);
bgp_dest_unlock_node(dest);
- return 0;
+ return CMD_SUCCESS;
}
-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)
+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,
+ const char *suppress_map)
{
+ 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];
if (suppress_map && summary_only) {
- snprintf(errmsg, errmsg_len,
+ vty_out(vty,
"'summary-only' and 'suppress-map' can't be used at the same time\n");
- return -1;
+ return CMD_WARNING_CONFIG_FAILED;
}
- apply_mask(prefix);
+ /* 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);
- 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;
+ 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;
}
/* Old configuration check. */
- dest = bgp_node_get(bgp->aggregate[afi][safi], prefix);
+ dest = bgp_node_get(bgp->aggregate[afi][safi], &p);
aggregate = bgp_dest_get_bgp_aggregate_info(dest);
if (aggregate) {
- snprintf(errmsg, errmsg_len,
- "There is already same aggregate network.\n");
+ vty_out(vty, "There is already same aggregate network.\n");
/* try to remove the old entry */
- ret = bgp_aggregate_unset(bgp, prefix, afi, safi, errmsg,
- errmsg_len);
+ ret = bgp_aggregate_unset(vty, prefix_str, afi, safi);
if (ret) {
- snprintf(errmsg, errmsg_len,
- "Error deleting aggregate.\n");
+ vty_out(vty, "Error deleting aggregate.\n");
bgp_dest_unlock_node(dest);
- return -1;
+ return CMD_WARNING_CONFIG_FAILED;
}
}
@@ -7956,8 +7907,7 @@ int bgp_aggregate_set(struct bgp *bgp, struct prefix *prefix, afi_t afi,
zlog_warn(
"%s: Ignoring as-set because `bgp reject-as-sets` is enabled.",
__func__);
- snprintf(
- errmsg, errmsg_len,
+ vty_out(vty,
"Ignoring as-set because `bgp reject-as-sets` is enabled.\n");
}
}
@@ -7994,40 +7944,39 @@ int bgp_aggregate_set(struct bgp *bgp, struct prefix *prefix, afi_t afi,
bgp_dest_set_bgp_aggregate_info(dest, aggregate);
/* Aggregate address insert into BGP routing table. */
- bgp_aggregate_route(bgp, prefix, afi, safi, aggregate);
+ bgp_aggregate_route(bgp, &p, afi, safi, aggregate);
- return 0;
+ return CMD_SUCCESS;
}
-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];
+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"
+ "|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")
+{
+ const char *prefix_s = NULL;
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) {
@@ -8037,158 +7986,78 @@ DEFPY_YANG(
vty_out(vty, "%% Inconsistent address and mask\n");
return CMD_WARNING_CONFIG_FAILED;
}
- } else {
- strlcpy(prefix_buf, prefix_str, sizeof(prefix_buf));
- }
-
- 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);
+ prefix_s = prefix_buf;
+ } else
+ prefix_s = prefix_str;
- 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);
+ 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;
+ }
- 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);
+ if (as_set_s)
+ as_set = AGGREGATE_AS_SET;
+ /* Handle configuration removal, otherwise installation. */
if (no)
- 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);
-
+ 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, suppress_map);
+}
+
+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"
+ "|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")
+{
+ 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. */
if (no)
- 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"));
-
- 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");
+ return bgp_aggregate_unset(vty, prefix_str, AFI_IP6,
+ SAFI_UNICAST);
- vty_out(vty, "\n");
+ return bgp_aggregate_set(vty, prefix_str, AFI_IP6, SAFI_UNICAST,
+ rmap_name, summary_only != NULL, as_set,
+ origin, match_med != NULL, suppress_map);
}
/* Redistribute route treatment. */
@@ -9517,14 +9386,18 @@ void route_vty_out_overlay(struct vty *vty, const struct prefix *p,
static void damp_route_vty_out(struct vty *vty, const struct prefix *p,
struct bgp_path_info *path, int display,
afi_t afi, safi_t safi, bool use_json,
- json_object *json)
+ json_object *json_paths)
{
- struct attr *attr;
+ struct attr *attr = path->attr;
int len;
char timebuf[BGP_UPTIME_LEN];
+ json_object *json_path = NULL;
+
+ if (use_json)
+ json_path = json_object_new_object();
/* short status lead text */
- route_vty_short_status_out(vty, path, p, json);
+ route_vty_short_status_out(vty, path, p, json_path);
/* print prefix and mask */
if (!use_json) {
@@ -9532,147 +9405,125 @@ static void damp_route_vty_out(struct vty *vty, const struct prefix *p,
route_vty_out_route(path->net, p, vty, NULL, false);
else
vty_out(vty, "%*s", 17, " ");
- }
- len = vty_out(vty, "%s", path->peer->host);
- len = 17 - len;
- if (len < 1) {
- if (!use_json)
+ len = vty_out(vty, "%s", path->peer->host);
+ len = 17 - len;
+
+ if (len < 1)
vty_out(vty, "\n%*s", 34, " ");
- } else {
- if (use_json)
- json_object_int_add(json, "peerHost", len);
else
vty_out(vty, "%*s", len, " ");
- }
- if (use_json)
- bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN, afi,
- safi, use_json, json);
- else
vty_out(vty, "%s ",
bgp_damp_reuse_time_vty(vty, path, timebuf,
BGP_UPTIME_LEN, afi, safi,
- use_json, json));
-
- /* Print attribute */
- attr = path->attr;
+ use_json, NULL));
- /* Print aspath */
- if (attr->aspath) {
- if (use_json)
- json_object_string_add(json, "asPath",
- attr->aspath->str);
- else
+ if (attr->aspath)
aspath_print_vty(vty, "%s", attr->aspath, " ");
- }
- /* Print origin */
- if (use_json)
- json_object_string_add(json, "origin",
- bgp_origin_str[attr->origin]);
- else
vty_out(vty, "%s", bgp_origin_str[attr->origin]);
- if (!use_json)
vty_out(vty, "\n");
+ } else {
+ bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN, afi,
+ safi, use_json, json_path);
+
+ if (attr->aspath)
+ json_object_string_add(json_path, "asPath",
+ attr->aspath->str);
+
+ json_object_string_add(json_path, "origin",
+ bgp_origin_str[attr->origin]);
+ json_object_string_add(json_path, "peerHost", path->peer->host);
+
+ json_object_array_add(json_paths, json_path);
+ }
}
/* flap route */
static void flap_route_vty_out(struct vty *vty, const struct prefix *p,
struct bgp_path_info *path, int display,
afi_t afi, safi_t safi, bool use_json,
- json_object *json)
+ json_object *json_paths)
{
- struct attr *attr;
+ struct attr *attr = path->attr;
struct bgp_damp_info *bdi;
char timebuf[BGP_UPTIME_LEN];
int len;
+ json_object *json_path = NULL;
if (!path->extra)
return;
+ if (use_json)
+ json_path = json_object_new_object();
+
bdi = path->extra->damp_info;
/* short status lead text */
- route_vty_short_status_out(vty, path, p, json);
+ route_vty_short_status_out(vty, path, p, json_path);
- /* print prefix and mask */
if (!use_json) {
if (!display)
route_vty_out_route(path->net, p, vty, NULL, false);
else
vty_out(vty, "%*s", 17, " ");
- }
- len = vty_out(vty, "%s", path->peer->host);
- len = 16 - len;
- if (len < 1) {
- if (!use_json)
+ len = vty_out(vty, "%s", path->peer->host);
+ len = 16 - len;
+ if (len < 1)
vty_out(vty, "\n%*s", 33, " ");
- } else {
- if (use_json)
- json_object_int_add(json, "peerHost", len);
else
vty_out(vty, "%*s", len, " ");
- }
- len = vty_out(vty, "%d", bdi->flap);
- len = 5 - len;
- if (len < 1) {
- if (!use_json)
+ len = vty_out(vty, "%d", bdi->flap);
+ len = 5 - len;
+ if (len < 1)
vty_out(vty, " ");
- } else {
- if (use_json)
- json_object_int_add(json, "bdiFlap", len);
else
vty_out(vty, "%*s", len, " ");
- }
- if (use_json)
- peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
- json);
- else
vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
BGP_UPTIME_LEN, 0, NULL));
- if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
- && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
- if (use_json)
- bgp_damp_reuse_time_vty(vty, path, timebuf,
- BGP_UPTIME_LEN, afi, safi,
- use_json, json);
- else
+ if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
+ && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
vty_out(vty, "%s ",
bgp_damp_reuse_time_vty(vty, path, timebuf,
BGP_UPTIME_LEN, afi,
- safi, use_json, json));
- } else {
- if (!use_json)
+ safi, use_json, NULL));
+ else
vty_out(vty, "%*s ", 8, " ");
- }
- /* Print attribute */
- attr = path->attr;
-
- /* Print aspath */
- if (attr->aspath) {
- if (use_json)
- json_object_string_add(json, "asPath",
- attr->aspath->str);
- else
+ if (attr->aspath)
aspath_print_vty(vty, "%s", attr->aspath, " ");
- }
- /* Print origin */
- if (use_json)
- json_object_string_add(json, "origin",
- bgp_origin_str[attr->origin]);
- else
vty_out(vty, "%s", bgp_origin_str[attr->origin]);
- if (!use_json)
vty_out(vty, "\n");
+ } else {
+ json_object_string_add(json_path, "peerHost", path->peer->host);
+ json_object_int_add(json_path, "bdiFlap", bdi->flap);
+
+ peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
+ json_path);
+
+ if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
+ && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
+ bgp_damp_reuse_time_vty(vty, path, timebuf,
+ BGP_UPTIME_LEN, afi, safi,
+ use_json, json_path);
+
+ if (attr->aspath)
+ json_object_string_add(json_path, "asPath",
+ attr->aspath->str);
+
+ json_object_string_add(json_path, "origin",
+ bgp_origin_str[attr->origin]);
+
+ json_object_array_add(json_paths, json_path);
+ }
}
static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
@@ -10587,7 +10438,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
}
if (path->extra && path->extra->damp_info)
- bgp_damp_info_vty(vty, bgp, path, afi, safi, json_path);
+ bgp_damp_info_vty(vty, path, afi, safi, json_path);
/* Remote Label */
if (path->extra && bgp_is_valid_label(&path->extra->label[0])
@@ -10876,8 +10727,7 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
const char *com2alias =
bgp_community2alias(
communities[i]);
- if (strncmp(alias, com2alias,
- strlen(com2alias))
+ if (strcmp(alias, com2alias)
== 0) {
found = true;
break;
@@ -10892,8 +10742,7 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
const char *com2alias =
bgp_community2alias(
communities[i]);
- if (strncmp(alias, com2alias,
- strlen(com2alias))
+ if (strcmp(alias, com2alias)
== 0) {
found = true;
break;
@@ -11643,7 +11492,8 @@ static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
if (!table)
continue;
- if ((rm = bgp_node_match(table, &match)) == NULL)
+ rm = bgp_node_match(table, &match);
+ if (rm == NULL)
continue;
const struct prefix *rm_p = bgp_dest_get_prefix(rm);
@@ -11735,7 +11585,8 @@ static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
json_object_free(json_paths);
}
} else {
- if ((dest = bgp_node_match(rib, &match)) != NULL) {
+ dest = bgp_node_match(rib, &match);
+ if (dest != NULL) {
const struct prefix *dest_p = bgp_dest_get_prefix(dest);
if (!prefix_check
|| dest_p->prefixlen == match.prefixlen) {
@@ -12192,7 +12043,7 @@ DEFPY(show_ip_bgp_json, show_ip_bgp_json_cmd,
|route-filter-translated-v4] [exact-match]\
|rpki <invalid|valid|notfound>\
|version (1-4294967295)\
- |alias WORD\
+ |alias ALIAS_NAME\
] [json$uj [detail$detail] | wide$wide]",
SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
BGP_SAFI_WITH_LABEL_HELP_STR
@@ -14314,21 +14165,28 @@ static void bgp_distance_free(struct bgp_distance *bdistance)
XFREE(MTYPE_BGP_DISTANCE, bdistance);
}
-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)
+static int bgp_distance_set(struct vty *vty, const char *distance_str,
+ const char *ip_str, const char *access_list_str)
{
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) {
- snprintf(errmsg, errmsg_len, "Malformed prefix\n");
+ vty_out(vty, "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);
@@ -14351,32 +14209,38 @@ int bgp_distance_set(uint8_t distance, const char *ip_str,
return CMD_SUCCESS;
}
-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)
+static int bgp_distance_unset(struct vty *vty, const char *distance_str,
+ const char *ip_str, const char *access_list_str)
{
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) {
- snprintf(errmsg, errmsg_len, "Malformed prefix\n");
+ vty_out(vty, "Malformed prefix\n");
return CMD_WARNING_CONFIG_FAILED;
}
dest = bgp_node_lookup(bgp_distance_table[afi][safi], &p);
if (!dest) {
- snprintf(errmsg, errmsg_len, "Can't find specified prefix\n");
+ vty_out(vty, "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) {
- snprintf(errmsg, errmsg_len,
- "Distance does not match configured\n");
+ vty_out(vty, "Distance does not match configured\n");
+ bgp_dest_unlock_node(dest);
return CMD_WARNING_CONFIG_FAILED;
}
@@ -14463,8 +14327,9 @@ uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo,
* we should tell ZEBRA update the routes for a specific
* AFI/SAFI to reflect changes in RIB.
*/
-void bgp_announce_routes_distance_update(struct bgp *bgp, afi_t update_afi,
- safi_t update_safi)
+static void bgp_announce_routes_distance_update(struct bgp *bgp,
+ afi_t update_afi,
+ safi_t update_safi)
{
afi_t afi;
safi_t safi;
@@ -14484,228 +14349,237 @@ void bgp_announce_routes_distance_update(struct bgp *bgp, afi_t update_afi,
}
}
-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")
+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")
{
+ 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);
- 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];
-
- 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, 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")
+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")
{
+ 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 (!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);
+ 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);
}
+ 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);
- return nb_cli_apply_changes(vty, xpath);
+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;
}
-void cli_show_bgp_global_afi_safi_unicast_admin_distance_route(
- struct vty *vty, struct lyd_node *dnode, bool show_defaults)
+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")
{
- 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")
- : "");
+ 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;
}
-DEFPY_YANG(
- bgp_dampening, bgp_dampening_cmd,
- "[no] bgp dampening [(1-45)$halflife [(1-20000)$reuse (1-20000)$suppress (1-255)$max_suppress]]",
- NO_STR
- "BGP Specific commands\n"
- "Enable route-flap dampening\n"
- "Half-life time for the penalty\n"
- "Value to start reusing a route\n"
- "Value to start suppressing a route\n"
- "Maximum duration to suppress a stable route\n")
+DEFUN (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")
{
- afi_t afi;
- safi_t safi;
- char xpath[XPATH_MAXLEN];
+ 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 = bgp_node_afi(vty);
- safi = bgp_node_safi(vty);
+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;
+}
- 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_suppress_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 (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;
+}
- 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 (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;
+}
- return nb_cli_apply_changes(vty, xpath);
+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;
}
-void cli_show_bgp_global_afi_safi_route_flap_dampening(struct vty *vty,
- struct lyd_node *dnode,
- bool show_defaults)
+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")
{
- if (!yang_dnode_get_bool(dnode, "./enable"))
- return;
+ bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
+ return CMD_SUCCESS;
+}
+DEFUN (bgp_damp_set,
+ bgp_damp_set_cmd,
+ "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
+ "BGP Specific commands\n"
+ "Enable route-flap dampening\n"
+ "Half-life time for the penalty\n"
+ "Value to start reusing a route\n"
+ "Value to start suppressing a route\n"
+ "Maximum duration to suppress a stable route\n")
+{
+ 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;
-
- 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);
+ 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));
}
/* Display specified route of BGP table. */
@@ -14758,7 +14632,8 @@ static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
table = bgp_dest_get_bgp_table_info(dest);
if (!table)
continue;
- if ((rm = bgp_node_match(table, &match)) == NULL)
+ rm = bgp_node_match(table, &match);
+ if (rm == NULL)
continue;
const struct prefix *rm_p = bgp_dest_get_prefix(dest);
@@ -14770,8 +14645,7 @@ static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
if (pi->extra && pi->extra->damp_info) {
pi_temp = pi->next;
bgp_damp_info_free(
- &pi->extra->damp_info,
- &bgp->damp[afi][safi],
+ pi->extra->damp_info,
1, afi, safi);
pi = pi_temp;
} else
@@ -14782,8 +14656,8 @@ static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
bgp_dest_unlock_node(rm);
}
} else {
- if ((dest = bgp_node_match(bgp->rib[afi][safi], &match))
- != NULL) {
+ dest = bgp_node_match(bgp->rib[afi][safi], &match);
+ if (dest != NULL) {
const struct prefix *dest_p = bgp_dest_get_prefix(dest);
if (!prefix_check
@@ -14792,24 +14666,8 @@ static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
while (pi) {
if (pi->extra && pi->extra->damp_info) {
pi_temp = pi->next;
- struct bgp_damp_info *bdi =
- pi->extra->damp_info;
- if (bdi->lastrecord
- == BGP_RECORD_UPDATE) {
- bgp_aggregate_increment(
- bgp,
- &bdi->dest->p,
- bdi->path,
- bdi->afi,
- bdi->safi);
- bgp_process(bgp,
- bdi->dest,
- bdi->afi,
- bdi->safi);
- }
bgp_damp_info_free(
- &pi->extra->damp_info,
- &bgp->damp[afi][safi],
+ pi->extra->damp_info,
1, afi, safi);
pi = pi_temp;
} else
@@ -14832,9 +14690,7 @@ DEFUN (clear_ip_bgp_dampening,
BGP_STR
"Clear route flap dampening information\n")
{
- VTY_DECLVAR_CONTEXT(bgp, bgp);
- bgp_damp_info_clean(bgp, &bgp->damp[AFI_IP][SAFI_UNICAST], AFI_IP,
- SAFI_UNICAST);
+ bgp_damp_info_clean(AFI_IP, SAFI_UNICAST);
return CMD_SUCCESS;
}
@@ -15254,27 +15110,54 @@ void bgp_route_init(void)
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, &bgp_distance_source_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_IPV6M_NODE, &bgp_distance_cmd);
install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
- install_element(BGP_IPV6M_NODE, &bgp_distance_source_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);
/* BGP dampening */
- 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);
+ 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);
/* Large Communities */
install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);