mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-14 10:37:29 +00:00
lib: Optimizing route-maps - Part-3
* This commit implements the code style suggestions from Polychaeta. * This commit also introduces a CLI to toggle the optimization and, a hidden CLI to display the contents of the constructed prefix tree. Signed-off-by: NaveenThanikachalam <nthanikachal@vmware.com>
This commit is contained in:
parent
819a23f9fc
commit
2d26f094c1
@ -303,8 +303,7 @@ static void prefix_list_delete(struct prefix_list *plist)
|
||||
|
||||
/* If prefix-list contain prefix_list_entry free all of it. */
|
||||
for (pentry = plist->head; pentry; pentry = next) {
|
||||
route_map_notify_pentry_dependencies(plist->name,
|
||||
pentry,
|
||||
route_map_notify_pentry_dependencies(plist->name, pentry,
|
||||
RMAP_EVENT_PLIST_DELETED);
|
||||
next = pentry->next;
|
||||
prefix_list_trie_del(plist, pentry);
|
||||
@ -521,8 +520,7 @@ static void prefix_list_entry_delete(struct prefix_list *plist,
|
||||
else
|
||||
plist->tail = pentry->prev;
|
||||
|
||||
route_map_notify_pentry_dependencies(plist->name,
|
||||
pentry,
|
||||
route_map_notify_pentry_dependencies(plist->name, pentry,
|
||||
RMAP_EVENT_PLIST_DELETED);
|
||||
prefix_list_entry_free(pentry);
|
||||
|
||||
|
405
lib/routemap.c
405
lib/routemap.c
@ -50,15 +50,15 @@ DEFINE_QOBJ_TYPE(route_map)
|
||||
#define IPv4_MATCH_RULE "ip "
|
||||
#define IPv6_MATCH_RULE "ipv6 "
|
||||
|
||||
#define IS_RULE_IPv4_PREFIX_LIST(S) (strncmp(S, IPv4_PREFIX_LIST, \
|
||||
strlen(IPv4_PREFIX_LIST)) == 0)
|
||||
#define IS_RULE_IPv6_PREFIX_LIST(S) (strncmp(S, IPv6_PREFIX_LIST, \
|
||||
strlen(IPv6_PREFIX_LIST)) == 0)
|
||||
#define IS_RULE_IPv4_PREFIX_LIST(S) \
|
||||
(strncmp(S, IPv4_PREFIX_LIST, strlen(IPv4_PREFIX_LIST)) == 0)
|
||||
#define IS_RULE_IPv6_PREFIX_LIST(S) \
|
||||
(strncmp(S, IPv6_PREFIX_LIST, strlen(IPv6_PREFIX_LIST)) == 0)
|
||||
|
||||
#define IS_IPv4_RULE(S) (strncmp(S, IPv4_MATCH_RULE, \
|
||||
strlen(IPv4_MATCH_RULE)) == 0)
|
||||
#define IS_IPv6_RULE(S) (strncmp(S, IPv6_MATCH_RULE, \
|
||||
strlen(IPv6_MATCH_RULE)) == 0)
|
||||
#define IS_IPv4_RULE(S) \
|
||||
(strncmp(S, IPv4_MATCH_RULE, strlen(IPv4_MATCH_RULE)) == 0)
|
||||
#define IS_IPv6_RULE(S) \
|
||||
(strncmp(S, IPv6_MATCH_RULE, strlen(IPv6_MATCH_RULE)) == 0)
|
||||
struct route_map_pentry_dep {
|
||||
struct prefix_list_entry *pentry;
|
||||
const char *plist_name;
|
||||
@ -71,34 +71,25 @@ static vector route_match_vec;
|
||||
/* Vector for route set rules. */
|
||||
static vector route_set_vec;
|
||||
|
||||
static void
|
||||
route_map_pfx_tbl_update(route_map_event_t event,
|
||||
struct route_map_index *index,
|
||||
afi_t afi,
|
||||
static void route_map_pfx_tbl_update(route_map_event_t event,
|
||||
struct route_map_index *index, afi_t afi,
|
||||
const char *plist_name);
|
||||
static void
|
||||
route_map_pfx_table_add_default(afi_t afi,
|
||||
static void route_map_pfx_table_add_default(afi_t afi,
|
||||
struct route_map_index *index);
|
||||
static void
|
||||
route_map_pfx_table_del_default(afi_t afi,
|
||||
static void route_map_pfx_table_del_default(afi_t afi,
|
||||
struct route_map_index *index);
|
||||
static void
|
||||
route_map_add_plist_entries(afi_t afi,
|
||||
static void route_map_add_plist_entries(afi_t afi,
|
||||
struct route_map_index *index,
|
||||
const char *plist_name,
|
||||
struct prefix_list_entry *entry);
|
||||
static void
|
||||
route_map_del_plist_entries(afi_t afi,
|
||||
static void route_map_del_plist_entries(afi_t afi,
|
||||
struct route_map_index *index,
|
||||
const char *plist_name,
|
||||
struct prefix_list_entry *entry);
|
||||
static bool
|
||||
route_map_is_ip_rule_present(struct route_map_index *index);
|
||||
static bool
|
||||
route_map_is_ipv6_rule_present(struct route_map_index *index);
|
||||
static bool route_map_is_ip_rule_present(struct route_map_index *index);
|
||||
static bool route_map_is_ipv6_rule_present(struct route_map_index *index);
|
||||
|
||||
static struct hash *
|
||||
route_map_get_dep_hash(route_map_event_t event);
|
||||
static struct hash *route_map_get_dep_hash(route_map_event_t event);
|
||||
|
||||
struct route_map_match_set_hooks rmap_match_set_hook;
|
||||
|
||||
@ -986,13 +977,10 @@ void route_map_index_delete(struct route_map_index *index, int notify)
|
||||
/* Free route match. */
|
||||
while ((rule = index->match_list.head) != NULL) {
|
||||
if (IS_RULE_IPv4_PREFIX_LIST(rule->cmd->str))
|
||||
route_map_pfx_tbl_update(
|
||||
RMAP_EVENT_PLIST_DELETED,
|
||||
index, AFI_IP,
|
||||
rule->rule_str);
|
||||
route_map_pfx_tbl_update(RMAP_EVENT_PLIST_DELETED,
|
||||
index, AFI_IP, rule->rule_str);
|
||||
else if (IS_RULE_IPv6_PREFIX_LIST(rule->cmd->str))
|
||||
route_map_pfx_tbl_update(
|
||||
RMAP_EVENT_PLIST_DELETED,
|
||||
route_map_pfx_tbl_update(RMAP_EVENT_PLIST_DELETED,
|
||||
index, AFI_IP6,
|
||||
rule->rule_str);
|
||||
|
||||
@ -1017,8 +1005,7 @@ void route_map_index_delete(struct route_map_index *index, int notify)
|
||||
/* Free 'char *nextrm' if not NULL */
|
||||
XFREE(MTYPE_ROUTE_MAP_NAME, index->nextrm);
|
||||
|
||||
route_map_pfx_tbl_update(RMAP_EVENT_INDEX_DELETED,
|
||||
index, 0, NULL);
|
||||
route_map_pfx_tbl_update(RMAP_EVENT_INDEX_DELETED, index, 0, NULL);
|
||||
|
||||
/* Execute event hook. */
|
||||
if (route_map_master.event_hook && notify) {
|
||||
@ -1079,8 +1066,7 @@ route_map_index_add(struct route_map *map, enum route_map_type type, int pref)
|
||||
point->prev = index;
|
||||
}
|
||||
|
||||
route_map_pfx_tbl_update(RMAP_EVENT_INDEX_ADDED,
|
||||
index, 0, NULL);
|
||||
route_map_pfx_tbl_update(RMAP_EVENT_INDEX_ADDED, index, 0, NULL);
|
||||
|
||||
/* Execute event hook. */
|
||||
if (route_map_master.event_hook) {
|
||||
@ -1335,14 +1321,12 @@ enum rmap_compile_rets route_map_add_match(struct route_map_index *index,
|
||||
*/
|
||||
if (IS_RULE_IPv4_PREFIX_LIST(match_name))
|
||||
route_map_pfx_tbl_update(
|
||||
RMAP_EVENT_PLIST_DELETED,
|
||||
index, AFI_IP,
|
||||
RMAP_EVENT_PLIST_DELETED, index, AFI_IP,
|
||||
rule->rule_str);
|
||||
else if (IS_RULE_IPv6_PREFIX_LIST(match_name))
|
||||
route_map_pfx_tbl_update(
|
||||
RMAP_EVENT_PLIST_DELETED,
|
||||
index, AFI_IP6,
|
||||
rule->rule_str);
|
||||
RMAP_EVENT_PLIST_DELETED, index,
|
||||
AFI_IP6, rule->rule_str);
|
||||
|
||||
/* Remove the dependency of the route-map on the rule
|
||||
* that is being replaced.
|
||||
@ -1377,12 +1361,10 @@ enum rmap_compile_rets route_map_add_match(struct route_map_index *index,
|
||||
* the route-map's prefix table.
|
||||
*/
|
||||
if (IS_RULE_IPv4_PREFIX_LIST(match_name)) {
|
||||
route_map_pfx_tbl_update(RMAP_EVENT_PLIST_ADDED,
|
||||
index, AFI_IP,
|
||||
route_map_pfx_tbl_update(RMAP_EVENT_PLIST_ADDED, index, AFI_IP,
|
||||
match_arg);
|
||||
} else if (IS_RULE_IPv6_PREFIX_LIST(match_name)) {
|
||||
route_map_pfx_tbl_update(RMAP_EVENT_PLIST_ADDED,
|
||||
index, AFI_IP6,
|
||||
route_map_pfx_tbl_update(RMAP_EVENT_PLIST_ADDED, index, AFI_IP6,
|
||||
match_arg);
|
||||
} else {
|
||||
/* If IPv4 match criteria has been added to the route-map
|
||||
@ -1393,8 +1375,7 @@ enum rmap_compile_rets route_map_add_match(struct route_map_index *index,
|
||||
* default route's trie node.
|
||||
*/
|
||||
if (IS_IPv4_RULE(match_name))
|
||||
route_map_del_plist_entries(AFI_IP6, index,
|
||||
NULL, NULL);
|
||||
route_map_del_plist_entries(AFI_IP6, index, NULL, NULL);
|
||||
|
||||
/* If IPv6 match criteria has been added to the route-map
|
||||
* index, check for IPv4 prefix-list match rule presence and
|
||||
@ -1404,8 +1385,7 @@ enum rmap_compile_rets route_map_add_match(struct route_map_index *index,
|
||||
* default route's trie node.
|
||||
*/
|
||||
else if (IS_IPv6_RULE(match_name))
|
||||
route_map_del_plist_entries(AFI_IP, index,
|
||||
NULL, NULL);
|
||||
route_map_del_plist_entries(AFI_IP, index, NULL, NULL);
|
||||
}
|
||||
|
||||
/* Execute event hook. */
|
||||
@ -1462,14 +1442,12 @@ enum rmap_compile_rets route_map_delete_match(struct route_map_index *index,
|
||||
*/
|
||||
if (IS_RULE_IPv4_PREFIX_LIST(match_name)) {
|
||||
route_map_pfx_tbl_update(
|
||||
RMAP_EVENT_PLIST_DELETED,
|
||||
index, AFI_IP,
|
||||
RMAP_EVENT_PLIST_DELETED, index, AFI_IP,
|
||||
match_arg);
|
||||
} else if (IS_RULE_IPv6_PREFIX_LIST(match_name)) {
|
||||
route_map_pfx_tbl_update(
|
||||
RMAP_EVENT_PLIST_DELETED,
|
||||
index, AFI_IP6,
|
||||
match_arg);
|
||||
RMAP_EVENT_PLIST_DELETED, index,
|
||||
AFI_IP6, match_arg);
|
||||
} else {
|
||||
/* If no more IPv4 match rules are present in
|
||||
* this index, check for IPv6 prefix-list match
|
||||
@ -1480,9 +1458,8 @@ enum rmap_compile_rets route_map_delete_match(struct route_map_index *index,
|
||||
* default route's trie node.
|
||||
*/
|
||||
if (!route_map_is_ip_rule_present(index))
|
||||
route_map_add_plist_entries(AFI_IP6,
|
||||
index, NULL,
|
||||
NULL);
|
||||
route_map_add_plist_entries(
|
||||
AFI_IP6, index, NULL, NULL);
|
||||
|
||||
/* If no more IPv6 match rules are present in
|
||||
* this index, check for IPv4 prefix-list match
|
||||
@ -1493,9 +1470,8 @@ enum rmap_compile_rets route_map_delete_match(struct route_map_index *index,
|
||||
* default route's trie node.
|
||||
*/
|
||||
if (!route_map_is_ipv6_rule_present(index))
|
||||
route_map_add_plist_entries(AFI_IP,
|
||||
index, NULL,
|
||||
NULL);
|
||||
route_map_add_plist_entries(
|
||||
AFI_IP, index, NULL, NULL);
|
||||
}
|
||||
|
||||
return RMAP_COMPILE_SUCCESS;
|
||||
@ -1663,8 +1639,7 @@ route_map_apply_match(struct route_map_rule_list *match_list,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct list *
|
||||
route_map_get_index_list(struct route_node **rn,
|
||||
static struct list *route_map_get_index_list(struct route_node **rn,
|
||||
const struct prefix *prefix,
|
||||
struct route_table *table)
|
||||
{
|
||||
@ -1706,11 +1681,8 @@ route_map_get_index_list(struct route_node **rn,
|
||||
* This function returns the route-map index that best matches the prefix.
|
||||
*/
|
||||
static struct route_map_index *
|
||||
route_map_get_index(struct route_map *map,
|
||||
const struct prefix *prefix,
|
||||
route_map_object_t type,
|
||||
void *object,
|
||||
uint8_t *match_ret)
|
||||
route_map_get_index(struct route_map *map, const struct prefix *prefix,
|
||||
route_map_object_t type, void *object, uint8_t *match_ret)
|
||||
{
|
||||
int ret = 0;
|
||||
struct list *candidate_rmap_list = NULL;
|
||||
@ -1730,8 +1702,8 @@ route_map_get_index(struct route_map *map,
|
||||
return NULL;
|
||||
|
||||
do {
|
||||
candidate_rmap_list = route_map_get_index_list(&rn, prefix,
|
||||
table);
|
||||
candidate_rmap_list =
|
||||
route_map_get_index_list(&rn, prefix, table);
|
||||
if (!rn)
|
||||
break;
|
||||
|
||||
@ -1739,10 +1711,10 @@ route_map_get_index(struct route_map *map,
|
||||
* than that in best_index, ignore the list and get the
|
||||
* parent node's list.
|
||||
*/
|
||||
head_index = (struct route_map_index *)
|
||||
(listgetdata(listhead(candidate_rmap_list)));
|
||||
if (best_index && head_index &&
|
||||
(best_index->pref < head_index->pref)) {
|
||||
head_index = (struct route_map_index *)(listgetdata(
|
||||
listhead(candidate_rmap_list)));
|
||||
if (best_index && head_index
|
||||
&& (best_index->pref < head_index->pref)) {
|
||||
route_unlock_node(rn);
|
||||
continue;
|
||||
}
|
||||
@ -1755,9 +1727,8 @@ route_map_get_index(struct route_map *map,
|
||||
if (best_index && (best_index->pref < index->pref))
|
||||
break;
|
||||
|
||||
ret = route_map_apply_match(
|
||||
&index->match_list,
|
||||
prefix, type, object);
|
||||
ret = route_map_apply_match(&index->match_list, prefix,
|
||||
type, object);
|
||||
|
||||
if (ret == RMAP_MATCH) {
|
||||
*match_ret = ret;
|
||||
@ -1787,8 +1758,7 @@ route_map_get_index(struct route_map *map,
|
||||
return best_index;
|
||||
}
|
||||
|
||||
static int
|
||||
route_map_candidate_list_cmp(struct route_map_index *idx1,
|
||||
static int route_map_candidate_list_cmp(struct route_map_index *idx1,
|
||||
struct route_map_index *idx2)
|
||||
{
|
||||
if (!idx1)
|
||||
@ -1803,8 +1773,7 @@ route_map_candidate_list_cmp(struct route_map_index *idx1,
|
||||
* This function adds the route-map index into the default route's
|
||||
* route-node in the route-map's IPv4/IPv6 prefix-table.
|
||||
*/
|
||||
static void
|
||||
route_map_pfx_table_add_default(afi_t afi,
|
||||
static void route_map_pfx_table_add_default(afi_t afi,
|
||||
struct route_map_index *index)
|
||||
{
|
||||
struct route_node *rn = NULL;
|
||||
@ -1856,8 +1825,7 @@ route_map_pfx_table_add_default(afi_t afi,
|
||||
* This function removes the route-map index from the default route's
|
||||
* route-node in the route-map's IPv4/IPv6 prefix-table.
|
||||
*/
|
||||
static void
|
||||
route_map_pfx_table_del_default(afi_t afi,
|
||||
static void route_map_pfx_table_del_default(afi_t afi,
|
||||
struct route_map_index *index)
|
||||
{
|
||||
struct route_node *rn = NULL;
|
||||
@ -1895,8 +1863,7 @@ route_map_pfx_table_del_default(afi_t afi,
|
||||
* This function adds the route-map index to the route-node for
|
||||
* the prefix-entry in the route-map's IPv4/IPv6 prefix-table.
|
||||
*/
|
||||
static void
|
||||
route_map_pfx_table_add(struct route_table *table,
|
||||
static void route_map_pfx_table_add(struct route_table *table,
|
||||
struct route_map_index *index,
|
||||
struct prefix_list_entry *pentry)
|
||||
{
|
||||
@ -1927,8 +1894,7 @@ route_map_pfx_table_add(struct route_table *table,
|
||||
* This function removes the route-map index from the route-node for
|
||||
* the prefix-entry in the route-map's IPv4/IPv6 prefix-table.
|
||||
*/
|
||||
static void
|
||||
route_map_pfx_table_del(struct route_table *table,
|
||||
static void route_map_pfx_table_del(struct route_table *table,
|
||||
struct route_map_index *index,
|
||||
struct prefix_list_entry *pentry)
|
||||
{
|
||||
@ -1954,8 +1920,7 @@ route_map_pfx_table_del(struct route_table *table,
|
||||
/* This function checks for the presence of an IPv4 match rule
|
||||
* in the given route-map index.
|
||||
*/
|
||||
static bool
|
||||
route_map_is_ip_rule_present(struct route_map_index *index)
|
||||
static bool route_map_is_ip_rule_present(struct route_map_index *index)
|
||||
{
|
||||
struct route_map_rule_list *match_list = NULL;
|
||||
struct route_map_rule *rule = NULL;
|
||||
@ -1971,8 +1936,7 @@ route_map_is_ip_rule_present(struct route_map_index *index)
|
||||
/* This function checks for the presence of an IPv6 match rule
|
||||
* in the given route-map index.
|
||||
*/
|
||||
static bool
|
||||
route_map_is_ipv6_rule_present(struct route_map_index *index)
|
||||
static bool route_map_is_ipv6_rule_present(struct route_map_index *index)
|
||||
{
|
||||
struct route_map_rule_list *match_list = NULL;
|
||||
struct route_map_rule *rule = NULL;
|
||||
@ -2000,8 +1964,7 @@ route_map_is_ipv6_rule_present(struct route_map_index *index)
|
||||
* prefix-list, create a route-node for this entry and
|
||||
* add this index to the route-node.
|
||||
*/
|
||||
static void
|
||||
route_map_add_plist_entries(afi_t afi,
|
||||
static void route_map_add_plist_entries(afi_t afi,
|
||||
struct route_map_index *index,
|
||||
const char *plist_name,
|
||||
struct prefix_list_entry *entry)
|
||||
@ -2017,15 +1980,17 @@ route_map_add_plist_entries(afi_t afi,
|
||||
|
||||
for (match = match_list->head; match; match = match->next) {
|
||||
if (afi == AFI_IP) {
|
||||
if (IS_RULE_IPv4_PREFIX_LIST(match->cmd->str))
|
||||
if (IS_RULE_IPv4_PREFIX_LIST(match->cmd->str)) {
|
||||
plist_rule_is_present = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (IS_RULE_IPv6_PREFIX_LIST(match->cmd->str))
|
||||
if (IS_RULE_IPv6_PREFIX_LIST(match->cmd->str)) {
|
||||
plist_rule_is_present = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (plist_rule_is_present)
|
||||
plist = prefix_list_lookup(afi, match->rule_str);
|
||||
@ -2042,24 +2007,22 @@ route_map_add_plist_entries(afi_t afi,
|
||||
|
||||
if (entry) {
|
||||
if (afi == AFI_IP) {
|
||||
route_map_pfx_table_add(
|
||||
index->map->ipv4_prefix_table,
|
||||
route_map_pfx_table_add(index->map->ipv4_prefix_table,
|
||||
index, entry);
|
||||
} else {
|
||||
route_map_pfx_table_add(
|
||||
index->map->ipv6_prefix_table,
|
||||
route_map_pfx_table_add(index->map->ipv6_prefix_table,
|
||||
index, entry);
|
||||
}
|
||||
} else {
|
||||
for (pentry = plist->head; pentry; pentry = pentry->next) {
|
||||
if (afi == AFI_IP) {
|
||||
route_map_pfx_table_add(
|
||||
index->map->ipv4_prefix_table,
|
||||
index, pentry);
|
||||
index->map->ipv4_prefix_table, index,
|
||||
pentry);
|
||||
} else {
|
||||
route_map_pfx_table_add(
|
||||
index->map->ipv6_prefix_table,
|
||||
index, pentry);
|
||||
index->map->ipv6_prefix_table, index,
|
||||
pentry);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2078,8 +2041,7 @@ route_map_add_plist_entries(afi_t afi,
|
||||
* prefix-list, remove this index from the route-node
|
||||
* for the prefix in this prefix-entry.
|
||||
*/
|
||||
static void
|
||||
route_map_del_plist_entries(afi_t afi,
|
||||
static void route_map_del_plist_entries(afi_t afi,
|
||||
struct route_map_index *index,
|
||||
const char *plist_name,
|
||||
struct prefix_list_entry *entry)
|
||||
@ -2095,15 +2057,17 @@ route_map_del_plist_entries(afi_t afi,
|
||||
|
||||
for (match = match_list->head; match; match = match->next) {
|
||||
if (afi == AFI_IP) {
|
||||
if (IS_RULE_IPv4_PREFIX_LIST(match->cmd->str))
|
||||
if (IS_RULE_IPv4_PREFIX_LIST(match->cmd->str)) {
|
||||
plist_rule_is_present = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (IS_RULE_IPv6_PREFIX_LIST(match->cmd->str))
|
||||
if (IS_RULE_IPv6_PREFIX_LIST(match->cmd->str)) {
|
||||
plist_rule_is_present = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (plist_rule_is_present)
|
||||
plist = prefix_list_lookup(afi, match->rule_str);
|
||||
@ -2118,24 +2082,22 @@ route_map_del_plist_entries(afi_t afi,
|
||||
|
||||
if (entry) {
|
||||
if (afi == AFI_IP) {
|
||||
route_map_pfx_table_del(
|
||||
index->map->ipv4_prefix_table,
|
||||
route_map_pfx_table_del(index->map->ipv4_prefix_table,
|
||||
index, entry);
|
||||
} else {
|
||||
route_map_pfx_table_del(
|
||||
index->map->ipv6_prefix_table,
|
||||
route_map_pfx_table_del(index->map->ipv6_prefix_table,
|
||||
index, entry);
|
||||
}
|
||||
} else {
|
||||
for (pentry = plist->head; pentry; pentry = pentry->next) {
|
||||
if (afi == AFI_IP) {
|
||||
route_map_pfx_table_del(
|
||||
index->map->ipv4_prefix_table,
|
||||
index, pentry);
|
||||
index->map->ipv4_prefix_table, index,
|
||||
pentry);
|
||||
} else {
|
||||
route_map_pfx_table_del(
|
||||
index->map->ipv6_prefix_table,
|
||||
index, pentry);
|
||||
index->map->ipv6_prefix_table, index,
|
||||
pentry);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2146,17 +2108,14 @@ route_map_del_plist_entries(afi_t afi,
|
||||
* as a match command from a particular route-map index.
|
||||
* It updates the prefix-table of the route-map accordingly.
|
||||
*/
|
||||
static void
|
||||
route_map_trie_update(afi_t afi,
|
||||
route_map_event_t event,
|
||||
static void route_map_trie_update(afi_t afi, route_map_event_t event,
|
||||
struct route_map_index *index,
|
||||
const char *plist_name)
|
||||
{
|
||||
if (event == RMAP_EVENT_PLIST_ADDED) {
|
||||
if (afi == AFI_IP) {
|
||||
if (!route_map_is_ipv6_rule_present(index)) {
|
||||
route_map_pfx_table_del_default(AFI_IP6,
|
||||
index);
|
||||
route_map_pfx_table_del_default(AFI_IP6, index);
|
||||
route_map_add_plist_entries(afi, index,
|
||||
plist_name, NULL);
|
||||
} else {
|
||||
@ -2165,38 +2124,35 @@ route_map_trie_update(afi_t afi,
|
||||
}
|
||||
} else {
|
||||
if (!route_map_is_ip_rule_present(index)) {
|
||||
route_map_pfx_table_del_default(AFI_IP,
|
||||
index);
|
||||
route_map_pfx_table_del_default(AFI_IP, index);
|
||||
route_map_add_plist_entries(afi, index,
|
||||
plist_name, NULL);
|
||||
} else {
|
||||
route_map_del_plist_entries(AFI_IP, index,
|
||||
NULL, NULL);
|
||||
route_map_del_plist_entries(AFI_IP, index, NULL,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
} else if (event == RMAP_EVENT_PLIST_DELETED) {
|
||||
if (afi == AFI_IP) {
|
||||
route_map_del_plist_entries(afi, index,
|
||||
plist_name, NULL);
|
||||
route_map_del_plist_entries(afi, index, plist_name,
|
||||
NULL);
|
||||
|
||||
if (!route_map_is_ipv6_rule_present(index))
|
||||
route_map_pfx_table_add_default(afi, index);
|
||||
|
||||
if (!route_map_is_ip_rule_present(index))
|
||||
route_map_add_plist_entries(AFI_IP6,
|
||||
index,
|
||||
route_map_add_plist_entries(AFI_IP6, index,
|
||||
NULL, NULL);
|
||||
} else {
|
||||
route_map_del_plist_entries(afi, index,
|
||||
plist_name, NULL);
|
||||
route_map_del_plist_entries(afi, index, plist_name,
|
||||
NULL);
|
||||
|
||||
if (!route_map_is_ip_rule_present(index))
|
||||
route_map_pfx_table_add_default(afi, index);
|
||||
|
||||
if (!route_map_is_ipv6_rule_present(index))
|
||||
route_map_add_plist_entries(AFI_IP,
|
||||
index,
|
||||
NULL, NULL);
|
||||
route_map_add_plist_entries(AFI_IP, index, NULL,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2206,10 +2162,8 @@ route_map_trie_update(afi_t afi,
|
||||
* prefix-list is added/removed.
|
||||
* It updates the prefix-table of the route-map accordingly.
|
||||
*/
|
||||
static void
|
||||
route_map_pfx_tbl_update(route_map_event_t event,
|
||||
struct route_map_index *index,
|
||||
afi_t afi,
|
||||
static void route_map_pfx_tbl_update(route_map_event_t event,
|
||||
struct route_map_index *index, afi_t afi,
|
||||
const char *plist_name)
|
||||
{
|
||||
struct route_map *rmap = NULL;
|
||||
@ -2227,8 +2181,7 @@ route_map_pfx_tbl_update(route_map_event_t event,
|
||||
route_map_pfx_table_del_default(AFI_IP, index);
|
||||
route_map_pfx_table_del_default(AFI_IP6, index);
|
||||
|
||||
if ((index->map->head == NULL) &&
|
||||
(index->map->tail == NULL)) {
|
||||
if ((index->map->head == NULL) && (index->map->tail == NULL)) {
|
||||
rmap = index->map;
|
||||
|
||||
if (rmap->ipv4_prefix_table) {
|
||||
@ -2246,8 +2199,7 @@ route_map_pfx_tbl_update(route_map_event_t event,
|
||||
|
||||
/* Handle prefix-list match rule addition/deletion.
|
||||
*/
|
||||
route_map_trie_update(afi, event,
|
||||
index, plist_name);
|
||||
route_map_trie_update(afi, event, index, plist_name);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2255,8 +2207,7 @@ route_map_pfx_tbl_update(route_map_event_t event,
|
||||
* a prefix-list or, an existing prefix-entry is removed from the prefix-list.
|
||||
* It updates the prefix-table of the route-map accordingly.
|
||||
*/
|
||||
static void
|
||||
route_map_pentry_update(route_map_event_t event,
|
||||
static void route_map_pentry_update(route_map_event_t event,
|
||||
const char *plist_name,
|
||||
struct route_map_index *index,
|
||||
struct prefix_list_entry *pentry)
|
||||
@ -2277,18 +2228,16 @@ route_map_pentry_update(route_map_event_t event,
|
||||
if (plist->count == 1) {
|
||||
if (afi == AFI_IP) {
|
||||
if (!route_map_is_ipv6_rule_present(index))
|
||||
route_map_add_plist_entries(afi, index,
|
||||
plist_name,
|
||||
pentry);
|
||||
route_map_add_plist_entries(
|
||||
afi, index, plist_name, pentry);
|
||||
} else {
|
||||
if (!route_map_is_ip_rule_present(index))
|
||||
route_map_add_plist_entries(afi, index,
|
||||
plist_name,
|
||||
pentry);
|
||||
route_map_add_plist_entries(
|
||||
afi, index, plist_name, pentry);
|
||||
}
|
||||
} else {
|
||||
route_map_add_plist_entries(afi, index,
|
||||
plist_name, pentry);
|
||||
route_map_add_plist_entries(afi, index, plist_name,
|
||||
pentry);
|
||||
}
|
||||
} else if (event == RMAP_EVENT_PLIST_DELETED) {
|
||||
route_map_del_plist_entries(afi, index, plist_name, pentry);
|
||||
@ -2307,8 +2256,7 @@ route_map_pentry_update(route_map_event_t event,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
route_map_pentry_process_dependency(struct hash_backet *backet,
|
||||
static void route_map_pentry_process_dependency(struct hash_backet *backet,
|
||||
void *data)
|
||||
{
|
||||
char *rmap_name = NULL;
|
||||
@ -2339,21 +2287,18 @@ route_map_pentry_process_dependency(struct hash_backet *backet,
|
||||
for (match = match_list->head; match; match = match->next) {
|
||||
if (strcmp(match->rule_str, pentry_dep->plist_name)
|
||||
== 0) {
|
||||
if (IS_RULE_IPv4_PREFIX_LIST(
|
||||
match->cmd->str) &&
|
||||
family == AF_INET) {
|
||||
if (IS_RULE_IPv4_PREFIX_LIST(match->cmd->str)
|
||||
&& family == AF_INET) {
|
||||
route_map_pentry_update(
|
||||
pentry_dep->event,
|
||||
pentry_dep->plist_name,
|
||||
index,
|
||||
pentry_dep->plist_name, index,
|
||||
pentry_dep->pentry);
|
||||
} else if (IS_RULE_IPv6_PREFIX_LIST(
|
||||
match->cmd->str) &&
|
||||
family == AF_INET6) {
|
||||
match->cmd->str)
|
||||
&& family == AF_INET6) {
|
||||
route_map_pentry_update(
|
||||
pentry_dep->event,
|
||||
pentry_dep->plist_name,
|
||||
index,
|
||||
pentry_dep->plist_name, index,
|
||||
pentry_dep->pentry);
|
||||
}
|
||||
}
|
||||
@ -2361,8 +2306,7 @@ route_map_pentry_process_dependency(struct hash_backet *backet,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
route_map_notify_pentry_dependencies(const char *affected_name,
|
||||
void route_map_notify_pentry_dependencies(const char *affected_name,
|
||||
struct prefix_list_entry *pentry,
|
||||
route_map_event_t event)
|
||||
{
|
||||
@ -2468,11 +2412,9 @@ route_map_result_t route_map_apply(struct route_map *map,
|
||||
|
||||
map->applied++;
|
||||
|
||||
if ((!map->optimization_disabled) &&
|
||||
(map->ipv4_prefix_table ||
|
||||
map->ipv6_prefix_table)) {
|
||||
index = route_map_get_index(map, prefix,
|
||||
type, object,
|
||||
if ((!map->optimization_disabled)
|
||||
&& (map->ipv4_prefix_table || map->ipv6_prefix_table)) {
|
||||
index = route_map_get_index(map, prefix, type, object,
|
||||
(uint8_t *)&match_ret);
|
||||
if (index) {
|
||||
if (rmap_debug)
|
||||
@ -2483,7 +2425,8 @@ route_map_result_t route_map_apply(struct route_map *map,
|
||||
route_map_cmd_result_str(match_ret));
|
||||
} else {
|
||||
if (rmap_debug)
|
||||
zlog_debug("No match for pfx: %s in route-map: %s, result: %s",
|
||||
zlog_debug(
|
||||
"No best match sequence for pfx: %s in route-map: %s, result: %s",
|
||||
prefix2str(prefix, buf, sizeof(buf)),
|
||||
map->name,
|
||||
route_map_cmd_result_str(match_ret));
|
||||
@ -2964,8 +2907,8 @@ void route_map_notify_dependencies(const char *affected_name,
|
||||
XFREE(MTYPE_ROUTE_MAP_NAME, name);
|
||||
}
|
||||
|
||||
DEFUN (no_routemap_optimization,
|
||||
no_routemap_optimization_cmd,
|
||||
/* VTY related functions. */
|
||||
DEFUN(no_routemap_optimization, no_routemap_optimization_cmd,
|
||||
"no route-map optimization",
|
||||
NO_STR
|
||||
"route-map\n"
|
||||
@ -2977,8 +2920,7 @@ DEFUN (no_routemap_optimization,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (routemap_optimization,
|
||||
routemap_optimization_cmd,
|
||||
DEFUN(routemap_optimization, routemap_optimization_cmd,
|
||||
"route-map optimization",
|
||||
"route-map\n"
|
||||
"optimization\n")
|
||||
@ -3163,6 +3105,121 @@ void route_map_counter_decrement(struct route_map *map)
|
||||
}
|
||||
}
|
||||
|
||||
DEFUN_HIDDEN(show_route_map_pfx_tbl, show_route_map_pfx_tbl_cmd,
|
||||
"show route-map WORD prefix-table",
|
||||
SHOW_STR
|
||||
"route-map\n"
|
||||
"route-map name\n"
|
||||
"internal prefix-table\n")
|
||||
{
|
||||
const char *rmap_name = argv[2]->arg;
|
||||
struct route_map *rmap = NULL;
|
||||
struct route_table *rm_pfx_tbl4 = NULL;
|
||||
struct route_table *rm_pfx_tbl6 = NULL;
|
||||
struct route_node *rn = NULL, *prn = NULL;
|
||||
struct list *rmap_index_list = NULL;
|
||||
struct listnode *ln = NULL, *nln = NULL;
|
||||
struct route_map_index *index = NULL;
|
||||
struct prefix *p = NULL, *pp = NULL;
|
||||
char buf[SU_ADDRSTRLEN], pbuf[SU_ADDRSTRLEN];
|
||||
uint8_t len = 54;
|
||||
|
||||
vty_out(vty, "%s:\n", frr_protonameinst);
|
||||
rmap = route_map_lookup_by_name(rmap_name);
|
||||
if (rmap) {
|
||||
rm_pfx_tbl4 = rmap->ipv4_prefix_table;
|
||||
if (rm_pfx_tbl4) {
|
||||
vty_out(vty, "\n%s%43s%s\n", "IPv4 Prefix", "",
|
||||
"Route-map Index List");
|
||||
vty_out(vty, "%s%39s%s\n", "_______________", "",
|
||||
"____________________");
|
||||
for (rn = route_top(rm_pfx_tbl4); rn;
|
||||
rn = route_next(rn)) {
|
||||
p = &rn->p;
|
||||
|
||||
vty_out(vty, " %s/%d (%d)\n",
|
||||
inet_ntop(p->family, &p->u.prefix, buf,
|
||||
SU_ADDRSTRLEN),
|
||||
p->prefixlen, rn->lock);
|
||||
|
||||
vty_out(vty, "(P) ");
|
||||
prn = rn->parent;
|
||||
if (prn) {
|
||||
pp = &prn->p;
|
||||
vty_out(vty, "%s/%d\n",
|
||||
inet_ntop(pp->family,
|
||||
&pp->u.prefix, pbuf,
|
||||
SU_ADDRSTRLEN),
|
||||
pp->prefixlen);
|
||||
}
|
||||
|
||||
vty_out(vty, "\n");
|
||||
rmap_index_list = (struct list *)rn->info;
|
||||
if (!rmap_index_list
|
||||
|| !listcount(rmap_index_list))
|
||||
vty_out(vty, "%*s%s\n", len, "", "-");
|
||||
else
|
||||
for (ALL_LIST_ELEMENTS(rmap_index_list,
|
||||
ln, nln,
|
||||
index)) {
|
||||
vty_out(vty, "%*s%s seq %d\n",
|
||||
len, "",
|
||||
index->map->name,
|
||||
index->pref);
|
||||
}
|
||||
vty_out(vty, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
rm_pfx_tbl6 = rmap->ipv6_prefix_table;
|
||||
if (rm_pfx_tbl6) {
|
||||
vty_out(vty, "\n%s%43s%s\n", "IPv6 Prefix", "",
|
||||
"Route-map Index List");
|
||||
vty_out(vty, "%s%39s%s\n", "_______________", "",
|
||||
"____________________");
|
||||
for (rn = route_top(rm_pfx_tbl6); rn;
|
||||
rn = route_next(rn)) {
|
||||
p = &rn->p;
|
||||
|
||||
vty_out(vty, " %s/%d (%d)\n",
|
||||
inet_ntop(p->family, &p->u.prefix, buf,
|
||||
SU_ADDRSTRLEN),
|
||||
p->prefixlen, rn->lock);
|
||||
|
||||
vty_out(vty, "(P) ");
|
||||
prn = rn->parent;
|
||||
if (prn) {
|
||||
pp = &prn->p;
|
||||
vty_out(vty, "%s/%d\n",
|
||||
inet_ntop(pp->family,
|
||||
&pp->u.prefix, pbuf,
|
||||
SU_ADDRSTRLEN),
|
||||
pp->prefixlen);
|
||||
}
|
||||
|
||||
vty_out(vty, "\n");
|
||||
rmap_index_list = (struct list *)rn->info;
|
||||
if (!rmap_index_list
|
||||
|| !listcount(rmap_index_list))
|
||||
vty_out(vty, "%*s%s\n", len, "", "-");
|
||||
else
|
||||
for (ALL_LIST_ELEMENTS(rmap_index_list,
|
||||
ln, nln,
|
||||
index)) {
|
||||
vty_out(vty, "%*s%s seq %d\n",
|
||||
len, "",
|
||||
index->map->name,
|
||||
index->pref);
|
||||
}
|
||||
vty_out(vty, "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vty_out(vty, "\n");
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
/* Initialization of route map vector. */
|
||||
void route_map_init(void)
|
||||
{
|
||||
@ -3202,4 +3259,6 @@ void route_map_init(void)
|
||||
|
||||
install_element(RMAP_NODE, &routemap_optimization_cmd);
|
||||
install_element(RMAP_NODE, &no_routemap_optimization_cmd);
|
||||
|
||||
install_element(ENABLE_NODE, &show_route_map_pfx_tbl_cmd);
|
||||
}
|
||||
|
@ -319,8 +319,8 @@ extern void route_map_upd8_dependency(route_map_event_t type, const char *arg,
|
||||
const char *rmap_name);
|
||||
extern void route_map_notify_dependencies(const char *affected_name,
|
||||
route_map_event_t event);
|
||||
extern void route_map_notify_pentry_dependencies(
|
||||
const char *affected_name,
|
||||
extern void
|
||||
route_map_notify_pentry_dependencies(const char *affected_name,
|
||||
struct prefix_list_entry *pentry,
|
||||
route_map_event_t event);
|
||||
extern int generic_match_add(struct vty *vty, struct route_map_index *index,
|
||||
|
Loading…
Reference in New Issue
Block a user