]>
git.proxmox.com Git - ovs.git/blob - ovn/lib/extend-table.c
2 * Copyright (c) 2017 DtDream Technology Co.,Ltd.
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:
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
23 #include "openvswitch/vlog.h"
24 #include "ovn/lib/extend-table.h"
26 VLOG_DEFINE_THIS_MODULE(extend_table
);
29 ovn_extend_table_init(struct ovn_extend_table
*table
)
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
);
38 ovn_extend_table_info_destroy(struct hmap
*target
)
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
);
50 ovn_extend_table_destroy(struct ovn_extend_table
*table
)
52 bitmap_free(table
->table_ids
);
54 ovn_extend_table_info_destroy(&table
->desired
);
55 ovn_extend_table_info_destroy(&table
->existing
);
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
)
64 struct ovn_extend_table_info
*e
;
66 HMAP_FOR_EACH_WITH_HASH (e
, hmap_node
, target
->hmap_node
.hash
,
68 if (e
->table_id
== target
->table_id
) {
75 /* Clear either desired or existing in ovn_extend_table. */
77 ovn_extend_table_clear(struct ovn_extend_table
*table
, bool existing
)
79 struct ovn_extend_table_info
*g
, *next
;
80 struct hmap
*target
= existing
? &table
->existing
: &table
->desired
;
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
);
94 /* Remove an entry from existing table */
96 ovn_extend_table_remove_existing(struct ovn_extend_table
*table
,
97 struct ovn_extend_table_info
*existing
)
99 /* Remove 'existing' from 'groups->existing' */
100 hmap_remove(&table
->existing
, &existing
->hmap_node
);
101 free(existing
->name
);
103 /* Dealloc group_id. */
104 bitmap_set0(table
->table_ids
, existing
->table_id
);
108 /* Remove entries in desired table that are created by the lflow_uuid */
110 ovn_extend_table_remove_desired(struct ovn_extend_table
*table
,
111 const struct uuid
*lflow_uuid
)
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
);
118 if (e
->new_table_id
) {
119 bitmap_set0(table
->table_ids
, e
->table_id
);
127 static struct ovn_extend_table_info
*
128 ovn_extend_info_clone(struct ovn_extend_table_info
*source
)
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
;
140 ovn_extend_table_sync(struct ovn_extend_table
*table
)
142 struct ovn_extend_table_info
*desired
, *next
;
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
);
156 /* Assign a new table ID for the table information from the bitmap.
157 * If it already exists, return the old ID. */
159 ovn_extend_table_assign_id(struct ovn_extend_table
*table
, const char *name
,
160 struct uuid lflow_uuid
)
162 uint32_t table_id
= 0, hash
;
163 struct ovn_extend_table_info
*table_info
;
165 hash
= hash_string(name
, 0);
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
;
175 /* Check whether we already have an installed entry for this
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
;
183 bool new_table_id
= false;
185 /* Reserve a new group_id. */
186 table_id
= bitmap_scan(table
->table_ids
, 0, 1, MAX_EXT_TABLE_ID
+ 1);
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
;
195 bitmap_set1(table
->table_ids
, table_id
);
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
;
204 hmap_insert(&table
->desired
,
205 &table_info
->hmap_node
, table_info
->hmap_node
.hash
);