mesh: Fix wholesale deletion of appkeys bound to a netkey 24/222924/1
authorInga Stotland <inga.stotland@intel.com>
Fri, 10 Jan 2020 01:41:45 +0000 (17:41 -0800)
committerAbhay Agarwal <ay.agarwal@samsung.com>
Mon, 20 Jan 2020 05:29:50 +0000 (10:59 +0530)
When a netkey is deleted all the appkeys bound to this key has
to be deleted as well. This fixes app_key queue manipulation to
avoid issues caused by modifying the queue while iterating over it:
instead of iteration over all the entries, find a first bound key,
delete it, find next... and so on, until there are no bound keys
left in the app_keys queue.

Change-Id: I152cbb3959401e1c333ee3afc5103672d06d8979
Signed-off-by: Abhay Agarwal <ay.agarwal@samsung.com>
mesh/appkey.c

index 0024b0e..39c5bed 100644 (file)
@@ -57,6 +57,14 @@ static bool match_key_index(const void *a, const void *b)
        return key->app_idx == idx;
 }
 
+static bool match_bound_key(const void *a, const void *b)
+{
+       const struct mesh_app_key *key = a;
+       uint16_t idx = L_PTR_TO_UINT(b);
+
+       return key->net_idx == idx;
+}
+
 static bool match_replay_cache(const void *a, const void *b)
 {
        const struct mesh_msg *msg = a;
@@ -433,19 +441,27 @@ int appkey_key_delete(struct mesh_net *net, uint16_t net_idx,
 
 void appkey_delete_bound_keys(struct mesh_net *net, uint16_t net_idx)
 {
-       const struct l_queue_entry *entry;
        struct l_queue *app_keys;
+       struct mesh_node *node;
+       struct mesh_app_key *key;
 
        app_keys = mesh_net_get_app_keys(net);
        if (!app_keys)
                return;
 
-       entry = l_queue_get_entries(app_keys);
+       node = mesh_net_node_get(net);
 
-       for (; entry; entry = entry->next) {
-               struct mesh_app_key *key = entry->data;
+       key = l_queue_remove_if(app_keys, match_bound_key,
+                                       L_UINT_TO_PTR(net_idx));
+
+       while (key) {
+               node_app_key_delete(node, net_idx, key->app_idx);
+               mesh_config_app_key_del(node_config_get(node), net_idx,
+                                                               key->app_idx);
+               appkey_key_free(key);
 
-               appkey_key_delete(net, net_idx, key->app_idx);
+               key = l_queue_remove_if(app_keys, match_bound_key,
+                                       L_UINT_TO_PTR(net_idx));
        }
 }