mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-12 12:53:26 +00:00
Merge pull request #6403 from NaveenThanikachalam/FRR_RMAP_FIX
lib: Fix erroneous r-map behavior
This commit is contained in:
commit
f24db7598e
130
lib/routemap.c
130
lib/routemap.c
@ -47,18 +47,12 @@ DEFINE_QOBJ_TYPE(route_map)
|
|||||||
|
|
||||||
#define IPv4_PREFIX_LIST "ip address prefix-list"
|
#define IPv4_PREFIX_LIST "ip address prefix-list"
|
||||||
#define IPv6_PREFIX_LIST "ipv6 address prefix-list"
|
#define IPv6_PREFIX_LIST "ipv6 address prefix-list"
|
||||||
#define IPv4_MATCH_RULE "ip "
|
|
||||||
#define IPv6_MATCH_RULE "ipv6 "
|
|
||||||
|
|
||||||
#define IS_RULE_IPv4_PREFIX_LIST(S) \
|
#define IS_RULE_IPv4_PREFIX_LIST(S) \
|
||||||
(strncmp(S, IPv4_PREFIX_LIST, strlen(IPv4_PREFIX_LIST)) == 0)
|
(strncmp(S, IPv4_PREFIX_LIST, strlen(IPv4_PREFIX_LIST)) == 0)
|
||||||
#define IS_RULE_IPv6_PREFIX_LIST(S) \
|
#define IS_RULE_IPv6_PREFIX_LIST(S) \
|
||||||
(strncmp(S, IPv6_PREFIX_LIST, strlen(IPv6_PREFIX_LIST)) == 0)
|
(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)
|
|
||||||
struct route_map_pentry_dep {
|
struct route_map_pentry_dep {
|
||||||
struct prefix_list_entry *pentry;
|
struct prefix_list_entry *pentry;
|
||||||
const char *plist_name;
|
const char *plist_name;
|
||||||
@ -86,8 +80,6 @@ static void route_map_del_plist_entries(afi_t afi,
|
|||||||
struct route_map_index *index,
|
struct route_map_index *index,
|
||||||
const char *plist_name,
|
const char *plist_name,
|
||||||
struct prefix_list_entry *entry);
|
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 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);
|
||||||
|
|
||||||
@ -1370,26 +1362,6 @@ enum rmap_compile_rets route_map_add_match(struct route_map_index *index,
|
|||||||
} else if (IS_RULE_IPv6_PREFIX_LIST(match_name)) {
|
} 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);
|
match_arg);
|
||||||
} else {
|
|
||||||
/* If IPv4 match criteria has been added to the route-map
|
|
||||||
* index, check for IPv6 prefix-list match rule presence and
|
|
||||||
* remove this index from the trie node created for each of the
|
|
||||||
* prefix-entry within the prefix-list. If no IPv6 prefix-list
|
|
||||||
* match rule is present, remove this index from the IPv6
|
|
||||||
* default route's trie node.
|
|
||||||
*/
|
|
||||||
if (IS_IPv4_RULE(match_name))
|
|
||||||
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
|
|
||||||
* remove this index from the trie node created for each of the
|
|
||||||
* prefix-entry within the prefix-list. If no IPv4 prefix-list
|
|
||||||
* match rule is present, remove this index from the IPv4
|
|
||||||
* default route's trie node.
|
|
||||||
*/
|
|
||||||
else if (IS_IPv6_RULE(match_name))
|
|
||||||
route_map_del_plist_entries(AFI_IP, index, NULL, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Execute event hook. */
|
/* Execute event hook. */
|
||||||
@ -1441,7 +1413,7 @@ enum rmap_compile_rets route_map_delete_match(struct route_map_index *index,
|
|||||||
route_map_rule_delete(&index->match_list, rule);
|
route_map_rule_delete(&index->match_list, rule);
|
||||||
|
|
||||||
/* If IPv4 or IPv6 prefix-list match criteria
|
/* If IPv4 or IPv6 prefix-list match criteria
|
||||||
* has been delete to the route-map index, update
|
* has been delete from the route-map index, update
|
||||||
* the route-map's prefix table.
|
* the route-map's prefix table.
|
||||||
*/
|
*/
|
||||||
if (IS_RULE_IPv4_PREFIX_LIST(match_name)) {
|
if (IS_RULE_IPv4_PREFIX_LIST(match_name)) {
|
||||||
@ -1452,30 +1424,6 @@ enum rmap_compile_rets route_map_delete_match(struct route_map_index *index,
|
|||||||
route_map_pfx_tbl_update(
|
route_map_pfx_tbl_update(
|
||||||
RMAP_EVENT_PLIST_DELETED, index,
|
RMAP_EVENT_PLIST_DELETED, index,
|
||||||
AFI_IP6, match_arg);
|
AFI_IP6, match_arg);
|
||||||
} else {
|
|
||||||
/* If no more IPv4 match rules are present in
|
|
||||||
* this index, check for IPv6 prefix-list match
|
|
||||||
* rule presence and add this index to trie node
|
|
||||||
* created for each of the prefix-entry within
|
|
||||||
* the prefix-list. If no IPv6 prefix-list match
|
|
||||||
* rule is present, add this index to the IPv6
|
|
||||||
* default route's trie node.
|
|
||||||
*/
|
|
||||||
if (!route_map_is_ip_rule_present(index))
|
|
||||||
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
|
|
||||||
* rule presence and add this index to trie node
|
|
||||||
* created for each of the prefix-entry within
|
|
||||||
* the prefix-list. If no IPv6 prefix-list match
|
|
||||||
* rule is present, add this index to the IPv4
|
|
||||||
* default route's trie node.
|
|
||||||
*/
|
|
||||||
if (!route_map_is_ipv6_rule_present(index))
|
|
||||||
route_map_add_plist_entries(
|
|
||||||
AFI_IP, index, NULL, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return RMAP_COMPILE_SUCCESS;
|
return RMAP_COMPILE_SUCCESS;
|
||||||
@ -1921,33 +1869,34 @@ static void route_map_pfx_table_del(struct route_table *table,
|
|||||||
route_unlock_node(rn);
|
route_unlock_node(rn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function checks for the presence of an IPv4 match rule
|
/* This function checks for the presence of an IPv4 prefix-list
|
||||||
* in the given route-map index.
|
* 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_pfx_list_rule_present(struct route_map_index *index)
|
||||||
{
|
{
|
||||||
struct route_map_rule_list *match_list = NULL;
|
struct route_map_rule_list *match_list = NULL;
|
||||||
struct route_map_rule *rule = NULL;
|
struct route_map_rule *rule = NULL;
|
||||||
|
|
||||||
match_list = &index->match_list;
|
match_list = &index->match_list;
|
||||||
for (rule = match_list->head; rule; rule = rule->next)
|
for (rule = match_list->head; rule; rule = rule->next)
|
||||||
if (IS_IPv4_RULE(rule->cmd->str))
|
if (IS_RULE_IPv4_PREFIX_LIST(rule->cmd->str))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function checks for the presence of an IPv6 match rule
|
/* This function checks for the presence of an IPv6 prefix-list
|
||||||
* in the given route-map index.
|
* 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_pfx_list_rule_present(struct route_map_index *index)
|
||||||
{
|
{
|
||||||
struct route_map_rule_list *match_list = NULL;
|
struct route_map_rule_list *match_list = NULL;
|
||||||
struct route_map_rule *rule = NULL;
|
struct route_map_rule *rule = NULL;
|
||||||
|
|
||||||
match_list = &index->match_list;
|
match_list = &index->match_list;
|
||||||
for (rule = match_list->head; rule; rule = rule->next)
|
for (rule = match_list->head; rule; rule = rule->next)
|
||||||
if (IS_IPv6_RULE(rule->cmd->str))
|
if (IS_RULE_IPv6_PREFIX_LIST(rule->cmd->str))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -2118,7 +2067,7 @@ static void route_map_trie_update(afi_t afi, route_map_event_t event,
|
|||||||
{
|
{
|
||||||
if (event == RMAP_EVENT_PLIST_ADDED) {
|
if (event == RMAP_EVENT_PLIST_ADDED) {
|
||||||
if (afi == AFI_IP) {
|
if (afi == AFI_IP) {
|
||||||
if (!route_map_is_ipv6_rule_present(index)) {
|
if (!route_map_is_ipv6_pfx_list_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,
|
route_map_add_plist_entries(afi, index,
|
||||||
plist_name, NULL);
|
plist_name, NULL);
|
||||||
@ -2127,7 +2076,7 @@ static void route_map_trie_update(afi_t afi, route_map_event_t event,
|
|||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!route_map_is_ip_rule_present(index)) {
|
if (!route_map_is_ip_pfx_list_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,
|
route_map_add_plist_entries(afi, index,
|
||||||
plist_name, NULL);
|
plist_name, NULL);
|
||||||
@ -2141,22 +2090,36 @@ static void route_map_trie_update(afi_t afi, route_map_event_t event,
|
|||||||
route_map_del_plist_entries(afi, index, plist_name,
|
route_map_del_plist_entries(afi, index, plist_name,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (!route_map_is_ipv6_rule_present(index))
|
/* If IPv6 prefix-list match rule is not present,
|
||||||
|
* add this index to the IPv4 default route's trie
|
||||||
|
* node.
|
||||||
|
* Also, add this index to the trie nodes created
|
||||||
|
* for each of the prefix-entries within the IPv6
|
||||||
|
* prefix-list, if the IPv6 prefix-list match rule
|
||||||
|
* is present. Else, add this index to the IPv6
|
||||||
|
* default route's trie node.
|
||||||
|
*/
|
||||||
|
if (!route_map_is_ipv6_pfx_list_rule_present(index))
|
||||||
route_map_pfx_table_add_default(afi, 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, NULL, NULL);
|
||||||
route_map_add_plist_entries(AFI_IP6, index,
|
|
||||||
NULL, NULL);
|
|
||||||
} else {
|
} else {
|
||||||
route_map_del_plist_entries(afi, index, plist_name,
|
route_map_del_plist_entries(afi, index, plist_name,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (!route_map_is_ip_rule_present(index))
|
/* If IPv4 prefix-list match rule is not present,
|
||||||
|
* add this index to the IPv6 default route's trie
|
||||||
|
* node.
|
||||||
|
* Also, add this index to the trie nodes created
|
||||||
|
* for each of the prefix-entries within the IPv4
|
||||||
|
* prefix-list, if the IPv4 prefix-list match rule
|
||||||
|
* is present. Else, add this index to the IPv4
|
||||||
|
* default route's trie node.
|
||||||
|
*/
|
||||||
|
if (!route_map_is_ip_pfx_list_rule_present(index))
|
||||||
route_map_pfx_table_add_default(afi, 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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2229,30 +2192,27 @@ static void route_map_pentry_update(route_map_event_t event,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (event == RMAP_EVENT_PLIST_ADDED) {
|
if (event == RMAP_EVENT_PLIST_ADDED) {
|
||||||
if (plist->count == 1) {
|
if (afi == AFI_IP) {
|
||||||
if (afi == AFI_IP) {
|
if (!route_map_is_ipv6_pfx_list_rule_present(index))
|
||||||
if (!route_map_is_ipv6_rule_present(index))
|
route_map_add_plist_entries(afi, index,
|
||||||
route_map_add_plist_entries(
|
plist_name, pentry);
|
||||||
afi, index, plist_name, pentry);
|
|
||||||
} else {
|
|
||||||
if (!route_map_is_ip_rule_present(index))
|
|
||||||
route_map_add_plist_entries(
|
|
||||||
afi, index, plist_name, pentry);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
route_map_add_plist_entries(afi, index, plist_name,
|
if (!route_map_is_ip_pfx_list_rule_present(index))
|
||||||
pentry);
|
route_map_add_plist_entries(afi, index,
|
||||||
|
plist_name, pentry);
|
||||||
}
|
}
|
||||||
} else if (event == RMAP_EVENT_PLIST_DELETED) {
|
} else if (event == RMAP_EVENT_PLIST_DELETED) {
|
||||||
route_map_del_plist_entries(afi, index, plist_name, pentry);
|
route_map_del_plist_entries(afi, index, plist_name, pentry);
|
||||||
|
|
||||||
if (plist->count == 1) {
|
if (plist->count == 1) {
|
||||||
if (afi == AFI_IP) {
|
if (afi == AFI_IP) {
|
||||||
if (!route_map_is_ipv6_rule_present(index))
|
if (!route_map_is_ipv6_pfx_list_rule_present(
|
||||||
|
index))
|
||||||
route_map_pfx_table_add_default(afi,
|
route_map_pfx_table_add_default(afi,
|
||||||
index);
|
index);
|
||||||
} else {
|
} else {
|
||||||
if (!route_map_is_ip_rule_present(index))
|
if (!route_map_is_ip_pfx_list_rule_present(
|
||||||
|
index))
|
||||||
route_map_pfx_table_add_default(afi,
|
route_map_pfx_table_add_default(afi,
|
||||||
index);
|
index);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user