aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Yourtchenko <ayourtch@gmail.com>2017-07-19 13:23:59 -0400
committerFlorin Coras <florin.coras@gmail.com>2017-07-20 21:48:31 +0000
commitfaee17e8b866fe16ce706af31d1e9cbc6d06b961 (patch)
tree98657c1284dcdc2ec31ec90db0893b19490e7556
parentfb3288fe56ba9f0efc1ffc7fdca56f2412749df0 (diff)
acl-plugin: assertion failed at hash_lookup.c:226 when modifying ACLs applied as part of many (VPP-910)
change 7385 has added the code which has the first ACE's "prev" entry within the linked list of shadowed ACEs pointing to the last ACE, in order to avoid the frequent linear list traversal. That change was not complete and did not update this "prev" entry whenever the last ACE was deleted. As a result the changes within the applied ACLs which caused the calls to hash_acl_unapply/hash_acl_apply may result in hitting assert which does the sanity check. The solution is to add the missing update logic. Change-Id: I9cbe9a7c68b92fa3a22a8efd11b679667d38f186 Signed-off-by: Andrew Yourtchenko <ayourtch@gmail.com> (cherry picked from commit 45fe7399152f5ca511ba0b03fee3d5a3dffd1897)
-rw-r--r--src/plugins/acl/hash_lookup.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/src/plugins/acl/hash_lookup.c b/src/plugins/acl/hash_lookup.c
index 3600faf1..027dabd0 100644
--- a/src/plugins/acl/hash_lookup.c
+++ b/src/plugins/acl/hash_lookup.c
@@ -382,6 +382,17 @@ deactivate_applied_ace_hash_entry(acl_main_t *am,
applied_hash_ace_entry_t *prev_pae = &((*applied_hash_aces)[pae->prev_applied_entry_index]);
ASSERT(prev_pae->next_applied_entry_index == old_index);
prev_pae->next_applied_entry_index = pae->next_applied_entry_index;
+ if (pae->next_applied_entry_index == ~0) {
+ /* it was a last entry we removed, update the pointer on the first one */
+ u32 an_index = pae->prev_applied_entry_index;
+ applied_hash_ace_entry_t *head_pae = &((*applied_hash_aces)[pae->prev_applied_entry_index]);
+ while(!head_pae->is_first_entry) {
+ an_index = head_pae->prev_applied_entry_index;
+ head_pae = &((*applied_hash_aces)[an_index]);
+ }
+ ASSERT(head_pae->prev_applied_entry_index == old_index);
+ head_pae->prev_applied_entry_index = pae->prev_applied_entry_index;
+ }
} else {
/* It was the first entry. We need either to reset the hash entry or delete it */
pae->is_first_entry = 0;