summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_attr.c6
-rw-r--r--bgpd/bgp_attr.h3
-rw-r--r--bgpd/bgp_route.c3
-rw-r--r--bgpd/bgp_routemap.c50
4 files changed, 59 insertions, 3 deletions
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index ab9dc3092a..db12098deb 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -519,8 +519,7 @@ unsigned int attrhash_key_make(const void *p)
MIX(attr->mp_nexthop_len);
key = jhash(attr->mp_nexthop_global.s6_addr, IPV6_MAX_BYTELEN, key);
key = jhash(attr->mp_nexthop_local.s6_addr, IPV6_MAX_BYTELEN, key);
- MIX(attr->nh_ifindex);
- MIX(attr->nh_lla_ifindex);
+ MIX3(attr->nh_ifindex, attr->nh_lla_ifindex, attr->distance);
return key;
}
@@ -562,7 +561,8 @@ bool attrhash_cmp(const void *p1, const void *p2)
&attr2->originator_id)
&& overlay_index_same(attr1, attr2)
&& attr1->nh_ifindex == attr2->nh_ifindex
- && attr1->nh_lla_ifindex == attr2->nh_lla_ifindex)
+ && attr1->nh_lla_ifindex == attr2->nh_lla_ifindex
+ && attr1->distance == attr2->distance)
return true;
}
diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h
index f1a871fe43..cfa428a796 100644
--- a/bgpd/bgp_attr.h
+++ b/bgpd/bgp_attr.h
@@ -206,6 +206,9 @@ struct attr {
/* EVPN local router-mac */
struct ethaddr rmac;
+
+ /* Distance as applied by Route map */
+ uint8_t distance;
};
/* rmap_change_flags definition */
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 962f0b3375..05974bb2ba 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -11877,6 +11877,9 @@ uint8_t bgp_distance_apply(struct prefix *p, struct bgp_path_info *pinfo,
peer = pinfo->peer;
+ if (pinfo->attr->distance)
+ return pinfo->attr->distance;
+
/* Check source address. */
sockunion2hostprefix(&peer->su, &q);
rn = bgp_node_match(bgp_distance_table[afi][safi], &q);
diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c
index da702ec857..55b6e670ba 100644
--- a/bgpd/bgp_routemap.c
+++ b/bgpd/bgp_routemap.c
@@ -1683,6 +1683,30 @@ struct route_map_rule_cmd route_set_weight_cmd = {
"weight", route_set_weight, route_value_compile, route_value_free,
};
+/* `set distance DISTANCE */
+static enum route_map_cmd_result_t
+route_set_distance(void *rule, const struct prefix *prefix,
+ route_map_object_t type, void *object)
+{
+ struct bgp_path_info *path = object;
+ struct rmap_value *rv = rule;
+
+ if (type != RMAP_BGP)
+ return RMAP_OKAY;
+
+ path->attr->distance = rv->value;
+
+ return RMAP_OKAY;
+}
+
+/* set distance rule structure */
+struct route_map_rule_cmd route_set_distance_cmd = {
+ "distance",
+ route_set_distance,
+ route_value_compile,
+ route_value_free,
+};
+
/* `set metric METRIC' */
/* Set metric to attribute. */
@@ -4064,6 +4088,29 @@ DEFUN (set_ip_nexthop_unchanged,
"unchanged");
}
+DEFUN (set_distance,
+ set_distance_cmd,
+ "set distance (0-255)",
+ SET_STR
+ "BGP Administrative Distance to use\n"
+ "Distance value\n")
+{
+ int idx_number = 2;
+
+ return generic_set_add(vty, VTY_GET_CONTEXT(route_map_index),
+ "distance", argv[idx_number]->arg);
+}
+
+DEFUN (no_set_distance,
+ no_set_distance_cmd,
+ "no set distance [(0-255)]",
+ NO_STR SET_STR
+ "BGP Administrative Distance to use\n"
+ "Distance value\n")
+{
+ return generic_set_delete(vty, VTY_GET_CONTEXT(route_map_index),
+ "distance", NULL);
+}
DEFUN (set_local_pref,
set_local_pref_cmd,
@@ -5119,6 +5166,7 @@ void bgp_route_map_init(void)
route_map_install_set(&route_set_weight_cmd);
route_map_install_set(&route_set_label_index_cmd);
route_map_install_set(&route_set_metric_cmd);
+ route_map_install_set(&route_set_distance_cmd);
route_map_install_set(&route_set_aspath_prepend_cmd);
route_map_install_set(&route_set_aspath_exclude_cmd);
route_map_install_set(&route_set_origin_cmd);
@@ -5172,6 +5220,8 @@ void bgp_route_map_init(void)
install_element(RMAP_NODE, &set_ip_nexthop_peer_cmd);
install_element(RMAP_NODE, &set_ip_nexthop_unchanged_cmd);
install_element(RMAP_NODE, &set_local_pref_cmd);
+ install_element(RMAP_NODE, &set_distance_cmd);
+ install_element(RMAP_NODE, &no_set_distance_cmd);
install_element(RMAP_NODE, &no_set_local_pref_cmd);
install_element(RMAP_NODE, &set_weight_cmd);
install_element(RMAP_NODE, &set_label_index_cmd);