summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2019-10-10 21:28:51 -0400
committerGitHub <noreply@github.com>2019-10-10 21:28:51 -0400
commitf043157c5880d9958542557c35b7cc56a055b39a (patch)
tree68f3b3e301a519aa8fac267d4002e14cb43270d7
parentd09e0a81b4e6bc407de0960d5dfba8572663c950 (diff)
parent60ca3cc27d6d61e7a5a7921d00ed76ca42d44bd7 (diff)
Merge pull request #4265 from pguibert6WIND/bgp_export_entries_to_table
bgpd: ability to export prefixes entries to a kernel table identifier
-rw-r--r--bgpd/bgp_attr.c2
-rw-r--r--bgpd/bgp_attr.h3
-rw-r--r--bgpd/bgp_route.c7
-rw-r--r--bgpd/bgp_routemap.c56
-rw-r--r--bgpd/bgp_zebra.c10
-rw-r--r--doc/user/routemap.rst5
-rw-r--r--zebra/zapi_msg.c4
7 files changed, 85 insertions, 2 deletions
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index a7cd3fee88..10e78cbc96 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -520,6 +520,7 @@ unsigned int attrhash_key_make(const void *p)
key = jhash(attr->mp_nexthop_global.s6_addr, IPV6_MAX_BYTELEN, key);
key = jhash(attr->mp_nexthop_local.s6_addr, IPV6_MAX_BYTELEN, key);
MIX3(attr->nh_ifindex, attr->nh_lla_ifindex, attr->distance);
+ MIX(attr->rmap_table_id);
return key;
}
@@ -546,6 +547,7 @@ bool attrhash_cmp(const void *p1, const void *p2)
&& attr1->lcommunity == attr2->lcommunity
&& attr1->cluster == attr2->cluster
&& attr1->transit == attr2->transit
+ && attr1->rmap_table_id == attr2->rmap_table_id
&& (attr1->encap_tunneltype == attr2->encap_tunneltype)
&& encap_same(attr1->encap_subtlvs, attr2->encap_subtlvs)
#if ENABLE_BGP_VNC
diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h
index cfa428a796..eacd37b652 100644
--- a/bgpd/bgp_attr.h
+++ b/bgpd/bgp_attr.h
@@ -209,6 +209,9 @@ struct attr {
/* Distance as applied by Route map */
uint8_t distance;
+
+ /* rmap set table */
+ uint32_t rmap_table_id;
};
/* rmap_change_flags definition */
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index f0629fca08..3f30441f7b 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -3165,6 +3165,13 @@ int bgp_update(struct peer *peer, struct prefix *p, uint32_t addpath_id,
goto filtered;
}
+ if (pi && pi->attr &&
+ pi->attr->rmap_table_id != new_attr.rmap_table_id) {
+ if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
+ /* remove from RIB previous entry */
+ bgp_zebra_withdraw(p, pi, bgp, safi);
+ }
+
if (peer->sort == BGP_PEER_EBGP) {
/* If we receive the graceful-shutdown community from an eBGP
diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c
index a5286cea69..a038b0e7a9 100644
--- a/bgpd/bgp_routemap.c
+++ b/bgpd/bgp_routemap.c
@@ -114,6 +114,7 @@ o Cisco route-map
origin : Done
tag : Done
weight : Done
+ table : Done
o Local extensions
@@ -1754,6 +1755,32 @@ struct route_map_rule_cmd route_set_metric_cmd = {
"metric", route_set_metric, route_value_compile, route_value_free,
};
+/* `set table (1-4294967295)' */
+
+static enum route_map_cmd_result_t route_set_table_id(void *rule,
+ const struct prefix *prefix,
+ route_map_object_t type,
+ void *object)
+{
+ struct rmap_value *rv;
+ struct bgp_path_info *path;
+
+ if (type == RMAP_BGP) {
+ /* Fetch routemap's rule information. */
+ rv = rule;
+ path = object;
+
+ path->attr->rmap_table_id = rv->value;
+ }
+ return RMAP_OKAY;
+}
+
+/* Set table_id rule structure. */
+static struct route_map_rule_cmd route_set_table_id_cmd = {
+ "table", route_set_table_id,
+ route_value_compile, route_value_free
+};
+
/* `set as-path prepend ASPATH' */
/* For AS path prepend mechanism. */
@@ -4058,6 +4085,32 @@ DEFUN (no_match_origin,
RMAP_EVENT_MATCH_DELETED);
}
+DEFUN (set_table_id,
+ set_table_id_cmd,
+ "set table (1-4294967295)",
+ SET_STR
+ "export route to non-main kernel table\n"
+ "Kernel routing table id\n")
+{
+ int idx_id = 2;
+
+ VTY_DECLVAR_CONTEXT(route_map_index, index);
+
+ return generic_set_add(vty, index, "table", argv[idx_id]->arg);
+}
+
+DEFUN (no_set_table_id,
+ no_set_table_id_cmd,
+ "no set table",
+ NO_STR
+ SET_STR
+ "export route to non-main kernel table\n")
+{
+ VTY_DECLVAR_CONTEXT(route_map_index, index);
+
+ return generic_set_delete(vty, index, "table", NULL);
+}
+
DEFUN (set_ip_nexthop_peer,
set_ip_nexthop_peer_cmd,
"[no] set ip next-hop peer-address",
@@ -5167,6 +5220,7 @@ void bgp_route_map_init(void)
route_map_install_match(&route_match_evpn_default_route_cmd);
route_map_install_match(&route_match_vrl_source_vrf_cmd);
+ route_map_install_set(&route_set_table_id_cmd);
route_map_install_set(&route_set_ip_nexthop_cmd);
route_map_install_set(&route_set_local_pref_cmd);
route_map_install_set(&route_set_weight_cmd);
@@ -5223,6 +5277,8 @@ void bgp_route_map_init(void)
install_element(RMAP_NODE, &match_probability_cmd);
install_element(RMAP_NODE, &no_match_probability_cmd);
+ install_element(RMAP_NODE, &no_set_table_id_cmd);
+ install_element(RMAP_NODE, &set_table_id_cmd);
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);
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 8970e9d1d1..7923f076c1 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -1228,6 +1228,11 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
SET_FLAG(api.flags, ZEBRA_FLAG_ALLOW_RECURSION);
+ if (info->attr->rmap_table_id) {
+ SET_FLAG(api.message, ZAPI_MESSAGE_TABLEID);
+ api.tableid = info->attr->rmap_table_id;
+ }
+
/* Metric is currently based on the best-path only */
metric = info->attr->med;
for (mpinfo = info; mpinfo; mpinfo = bgp_path_info_mpath_next(mpinfo)) {
@@ -1494,6 +1499,11 @@ void bgp_zebra_withdraw(struct prefix *p, struct bgp_path_info *info,
api.safi = safi;
api.prefix = *p;
+ if (info->attr->rmap_table_id) {
+ SET_FLAG(api.message, ZAPI_MESSAGE_TABLEID);
+ api.tableid = info->attr->rmap_table_id;
+ }
+
/* If the route's source is EVPN, flag as such. */
if (is_route_parent_evpn(info))
SET_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE);
diff --git a/doc/user/routemap.rst b/doc/user/routemap.rst
index e36783d176..5c2b41b63c 100644
--- a/doc/user/routemap.rst
+++ b/doc/user/routemap.rst
@@ -306,6 +306,11 @@ Route Map Set Command
Set BGP route origin.
+.. index:: set table (1-4294967295)
+.. clicmd:: set table (1-4294967295)
+
+ Set the BGP table to a given table identifier
+
.. _route-map-call-command:
Route Map Call Command
diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c
index ffdc4dc512..b0488b7559 100644
--- a/zebra/zapi_msg.c
+++ b/zebra/zapi_msg.c
@@ -1425,7 +1425,7 @@ static void zread_route_add(ZAPI_HANDLER_ARGS)
re->flags = api.flags;
re->uptime = monotime(NULL);
re->vrf_id = vrf_id;
- if (api.tableid && vrf_id == VRF_DEFAULT)
+ if (api.tableid)
re->table = api.tableid;
else
re->table = zvrf->table_id;
@@ -1624,7 +1624,7 @@ static void zread_route_del(ZAPI_HANDLER_ARGS)
if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX))
src_p = &api.src_prefix;
- if (api.vrf_id == VRF_DEFAULT && api.tableid != 0)
+ if (api.tableid)
table_id = api.tableid;
else
table_id = zvrf->table_id;