]> git.proxmox.com Git - ovs.git/blob - ovn/lib/extend-table.c
ovn-controller: Initial use of incremental engine - quiet mode.
[ovs.git] / ovn / lib / extend-table.c
1 /*
2 * Copyright (c) 2017 DtDream Technology Co.,Ltd.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <config.h>
18 #include <string.h>
19
20 #include "bitmap.h"
21 #include "hash.h"
22 #include "lib/uuid.h"
23 #include "openvswitch/vlog.h"
24 #include "ovn/lib/extend-table.h"
25
26 VLOG_DEFINE_THIS_MODULE(extend_table);
27
28 void
29 ovn_extend_table_init(struct ovn_extend_table *table)
30 {
31 table->table_ids = bitmap_allocate(MAX_EXT_TABLE_ID);
32 bitmap_set1(table->table_ids, 0); /* table id 0 is invalid. */
33 hmap_init(&table->desired);
34 hmap_init(&table->existing);
35 }
36
37 static void
38 ovn_extend_table_info_destroy(struct hmap *target)
39 {
40 struct ovn_extend_table_info *e, *next;
41 HMAP_FOR_EACH_SAFE (e, next, hmap_node, target) {
42 hmap_remove(target, &e->hmap_node);
43 free(e->name);
44 free(e);
45 }
46 hmap_destroy(target);
47 }
48
49 void
50 ovn_extend_table_destroy(struct ovn_extend_table *table)
51 {
52 bitmap_free(table->table_ids);
53
54 ovn_extend_table_info_destroy(&table->desired);
55 ovn_extend_table_info_destroy(&table->existing);
56 }
57
58 /* Finds and returns a group_info in 'existing' whose key is identical
59 * to 'target''s key, or NULL if there is none. */
60 struct ovn_extend_table_info *
61 ovn_extend_table_lookup(struct hmap *exisiting,
62 const struct ovn_extend_table_info *target)
63 {
64 struct ovn_extend_table_info *e;
65
66 HMAP_FOR_EACH_WITH_HASH (e, hmap_node, target->hmap_node.hash,
67 exisiting) {
68 if (e->table_id == target->table_id) {
69 return e;
70 }
71 }
72 return NULL;
73 }
74
75 /* Clear either desired or existing in ovn_extend_table. */
76 void
77 ovn_extend_table_clear(struct ovn_extend_table *table, bool existing)
78 {
79 struct ovn_extend_table_info *g, *next;
80 struct hmap *target = existing ? &table->existing : &table->desired;
81
82 HMAP_FOR_EACH_SAFE (g, next, hmap_node, target) {
83 hmap_remove(target, &g->hmap_node);
84 /* Don't unset bitmap for desired group_info if the group_id
85 * was not freshly reserved. */
86 if (existing || g->new_table_id) {
87 bitmap_set0(table->table_ids, g->table_id);
88 }
89 free(g->name);
90 free(g);
91 }
92 }
93
94 /* Remove an entry from existing table */
95 void
96 ovn_extend_table_remove_existing(struct ovn_extend_table *table,
97 struct ovn_extend_table_info *existing)
98 {
99 /* Remove 'existing' from 'groups->existing' */
100 hmap_remove(&table->existing, &existing->hmap_node);
101 free(existing->name);
102
103 /* Dealloc group_id. */
104 bitmap_set0(table->table_ids, existing->table_id);
105 free(existing);
106 }
107
108 /* Remove entries in desired table that are created by the lflow_uuid */
109 void
110 ovn_extend_table_remove_desired(struct ovn_extend_table *table,
111 const struct uuid *lflow_uuid)
112 {
113 struct ovn_extend_table_info *e, *next_e;
114 HMAP_FOR_EACH_SAFE (e, next_e, hmap_node, &table->desired) {
115 if (uuid_equals(&e->lflow_uuid, lflow_uuid)) {
116 hmap_remove(&table->desired, &e->hmap_node);
117 free(e->name);
118 if (e->new_table_id) {
119 bitmap_set0(table->table_ids, e->table_id);
120 }
121 free(e);
122 }
123 }
124
125 }
126
127 static struct ovn_extend_table_info*
128 ovn_extend_info_clone(struct ovn_extend_table_info *source)
129 {
130 struct ovn_extend_table_info *clone = xmalloc(sizeof *clone);
131 clone->name = xstrdup(source->name);
132 clone->table_id = source->table_id;
133 clone->new_table_id = source->new_table_id;
134 clone->hmap_node.hash = source->hmap_node.hash;
135 clone->lflow_uuid = source->lflow_uuid;
136 return clone;
137 }
138
139 void
140 ovn_extend_table_sync(struct ovn_extend_table *table)
141 {
142 struct ovn_extend_table_info *desired, *next;
143
144 /* Copy the contents of desired to existing. */
145 HMAP_FOR_EACH_SAFE (desired, next, hmap_node, &table->desired) {
146 if (!ovn_extend_table_lookup(&table->existing, desired)) {
147 desired->new_table_id = false;
148 struct ovn_extend_table_info *clone =
149 ovn_extend_info_clone(desired);
150 hmap_insert(&table->existing, &clone->hmap_node,
151 clone->hmap_node.hash);
152 }
153 }
154 }
155
156 /* Assign a new table ID for the table information from the bitmap.
157 * If it already exists, return the old ID. */
158 uint32_t
159 ovn_extend_table_assign_id(struct ovn_extend_table *table, const char *name,
160 struct uuid lflow_uuid)
161 {
162 uint32_t table_id = 0, hash;
163 struct ovn_extend_table_info *table_info;
164
165 hash = hash_string(name, 0);
166
167 /* Check whether we have non installed but allocated group_id. */
168 HMAP_FOR_EACH_WITH_HASH (table_info, hmap_node, hash, &table->desired) {
169 if (!strcmp(table_info->name, name) &&
170 table_info->new_table_id) {
171 return table_info->table_id;
172 }
173 }
174
175 /* Check whether we already have an installed entry for this
176 * combination. */
177 HMAP_FOR_EACH_WITH_HASH (table_info, hmap_node, hash, &table->existing) {
178 if (!strcmp(table_info->name, name)) {
179 table_id = table_info->table_id;
180 }
181 }
182
183 bool new_table_id = false;
184 if (!table_id) {
185 /* Reserve a new group_id. */
186 table_id = bitmap_scan(table->table_ids, 0, 1, MAX_EXT_TABLE_ID + 1);
187 new_table_id = true;
188 }
189
190 if (table_id == MAX_EXT_TABLE_ID + 1) {
191 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
192 VLOG_ERR_RL(&rl, "%"PRIu32" out of table ids.", table_id);
193 return EXT_TABLE_ID_INVALID;
194 }
195 bitmap_set1(table->table_ids, table_id);
196
197 table_info = xmalloc(sizeof *table_info);
198 table_info->name = xstrdup(name);
199 table_info->table_id = table_id;
200 table_info->hmap_node.hash = hash;
201 table_info->new_table_id = new_table_id;
202 table_info->lflow_uuid = lflow_uuid;
203
204 hmap_insert(&table->desired,
205 &table_info->hmap_node, table_info->hmap_node.hash);
206
207 return table_id;
208 }