From 951745bdabeb4aeb63a968a683dc18df6a744091 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Mon, 29 Apr 2019 15:26:01 +0200 Subject: [PATCH] bgpd: ability to export prefixes entries to a kernel table identifier this table identifier can be used for policy routing. incoming entries are locally exported to that local table identifier. note that so that the user applies the new table identifier to all entries, the user should flush local tables first. Signed-off-by: Philippe Guibert --- bgpd/bgp_attr.c | 2 ++ bgpd/bgp_attr.h | 3 +++ bgpd/bgp_routemap.c | 56 +++++++++++++++++++++++++++++++++++++++++++ bgpd/bgp_zebra.c | 5 ++++ doc/user/routemap.rst | 5 ++++ 5 files changed, 71 insertions(+) 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_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..c9dd0f4bcb 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)) { 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