update the interface list version on config reload, fixes removing old interfaces
[project/netifd.git] / utils.c
1 #include <string.h>
2 #include <stdlib.h>
3 #include "utils.h"
4
5 int
6 avl_strcmp(const void *k1, const void *k2, void *ptr)
7 {
8 return strcmp(k1, k2);
9 }
10
11 void
12 __vlist_init(struct vlist_tree *tree, avl_tree_comp cmp,
13 vlist_update_cb update, int offset)
14 {
15 tree->key_offset = offset;
16 tree->update = update;
17 tree->version = 1;
18
19 avl_init(&tree->avl, cmp, 0, tree);
20 }
21
22 void
23 vlist_delete(struct vlist_tree *tree, struct vlist_node *node)
24 {
25 if (!tree->no_delete)
26 avl_delete(&tree->avl, &node->avl);
27 tree->update(tree, NULL, node);
28 }
29
30 void
31 vlist_add(struct vlist_tree *tree, struct vlist_node *node)
32 {
33 struct vlist_node *old_node = NULL;
34 struct avl_node *anode;
35 void *key = (char *) node + tree->key_offset;
36
37 node->avl.key = key;
38 node->version = tree->version;
39
40 anode = avl_find(&tree->avl, key);
41 if (anode) {
42 old_node = container_of(anode, struct vlist_node, avl);
43 if (tree->keep_old || tree->no_delete) {
44 old_node->version = tree->version;
45 goto update_only;
46 }
47
48 avl_delete(&tree->avl, anode);
49 }
50
51 avl_insert(&tree->avl, &node->avl);
52
53 update_only:
54 tree->update(tree, node, old_node);
55 }
56
57 void
58 vlist_flush(struct vlist_tree *tree)
59 {
60 struct vlist_node *node, *tmp;
61
62 avl_for_each_element_safe(&tree->avl, node, avl, tmp) {
63 if (node->version == tree->version)
64 continue;
65
66 vlist_delete(tree, node);
67 }
68 }
69
70 void
71 vlist_flush_all(struct vlist_tree *tree)
72 {
73 tree->version++;
74 vlist_flush(tree);
75 }
76
77
78 void
79 __vlist_simple_init(struct vlist_simple_tree *tree, int offset)
80 {
81 INIT_LIST_HEAD(&tree->list);
82 tree->version = 1;
83 tree->head_offset = offset;
84 }
85
86 void
87 vlist_simple_delete(struct vlist_simple_tree *tree, struct vlist_simple_node *node)
88 {
89 char *ptr;
90
91 list_del(&node->list);
92 ptr = (char *) node - tree->head_offset;
93 free(ptr);
94 }
95
96 void
97 vlist_simple_flush(struct vlist_simple_tree *tree)
98 {
99 struct vlist_simple_node *n, *tmp;
100
101 list_for_each_entry_safe(n, tmp, &tree->list, list) {
102 if (n->version == tree->version)
103 continue;
104
105 vlist_simple_delete(tree, n);
106 }
107 }
108
109 void
110 vlist_simple_flush_all(struct vlist_simple_tree *tree)
111 {
112 tree->version++;
113 vlist_simple_flush(tree);
114 }