diff options
author | Andrew Yourtchenko <ayourtch@gmail.com> | 2017-07-19 13:23:59 -0400 |
---|---|---|
committer | Dave Barach <openvpp@barachs.net> | 2017-07-20 12:05:36 +0000 |
commit | 45fe7399152f5ca511ba0b03fee3d5a3dffd1897 (patch) | |
tree | 1ae88f3cdd548a479e2d4b5aee6b50fee62b6b75 | |
parent | f4f635e7c05a4430e834a725f611cb83a9179146 (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>
-rw-r--r-- | src/plugins/acl/hash_lookup.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/src/plugins/acl/hash_lookup.c b/src/plugins/acl/hash_lookup.c index 3600faf13ea..027dabd0e6a 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; |