1 /* Copyright (c) 2015, 2016 Nicira, Inc.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
21 #include "openvswitch/vlog.h"
22 #include "ovn/lib/ovn-sb-idl.h"
24 VLOG_DEFINE_THIS_MODULE(lport);
28 struct hmap_node name_node; /* Index by name. */
29 struct hmap_node key_node; /* Index by (dp_key, port_key). */
30 struct hmap_node uuid_node; /* Index by row uuid. */
32 const struct sbrec_port_binding *pb;
35 static bool full_lport_rebuild = false;
38 lport_index_reset(void)
40 full_lport_rebuild = true;
44 lport_index_init(struct lport_index *lports)
46 hmap_init(&lports->by_name);
47 hmap_init(&lports->by_key);
48 hmap_init(&lports->by_uuid);
52 lport_index_remove(struct lport_index *lports, const struct uuid *uuid)
54 const struct lport *port_ = lport_lookup_by_uuid(lports, uuid);
55 struct lport *port = CONST_CAST(struct lport *, port_);
57 hmap_remove(&lports->by_name, &port->name_node);
58 hmap_remove(&lports->by_key, &port->key_node);
59 hmap_remove(&lports->by_uuid, &port->uuid_node);
65 lport_index_clear(struct lport_index *lports)
67 /* Destroy all of the "struct lport"s.
69 * We have to remove the node from all indexes. */
70 struct lport *port, *next;
71 HMAP_FOR_EACH_SAFE (port, next, name_node, &lports->by_name) {
72 hmap_remove(&lports->by_name, &port->name_node);
73 hmap_remove(&lports->by_key, &port->key_node);
74 hmap_remove(&lports->by_uuid, &port->uuid_node);
80 consider_lport_index(struct lport_index *lports,
81 const struct sbrec_port_binding *pb)
83 if (lport_lookup_by_name(lports, pb->logical_port)) {
87 struct lport *p = xmalloc(sizeof *p);
88 hmap_insert(&lports->by_name, &p->name_node,
89 hash_string(pb->logical_port, 0));
90 hmap_insert(&lports->by_key, &p->key_node,
91 hash_int(pb->tunnel_key, pb->datapath->tunnel_key));
92 hmap_insert(&lports->by_uuid, &p->uuid_node,
93 uuid_hash(&pb->header_.uuid));
94 memcpy(&p->uuid, &pb->header_.uuid, sizeof p->uuid);
99 lport_index_fill(struct lport_index *lports, struct ovsdb_idl *ovnsb_idl)
101 const struct sbrec_port_binding *pb;
102 if (full_lport_rebuild) {
103 lport_index_clear(lports);
104 SBREC_PORT_BINDING_FOR_EACH (pb, ovnsb_idl) {
105 consider_lport_index(lports, pb);
107 full_lport_rebuild = false;
109 SBREC_PORT_BINDING_FOR_EACH_TRACKED (pb, ovnsb_idl) {
110 if (sbrec_port_binding_is_deleted(pb)) {
111 lport_index_remove(lports, &pb->header_.uuid);
113 consider_lport_index(lports, pb);
120 lport_index_destroy(struct lport_index *lports)
122 lport_index_clear(lports);
124 hmap_destroy(&lports->by_name);
125 hmap_destroy(&lports->by_key);
126 hmap_destroy(&lports->by_uuid);
129 /* Finds and returns the lport with the given 'name', or NULL if no such lport
131 const struct sbrec_port_binding *
132 lport_lookup_by_name(const struct lport_index *lports, const char *name)
134 const struct lport *lport;
135 HMAP_FOR_EACH_WITH_HASH (lport, name_node, hash_string(name, 0),
137 if (!strcmp(lport->pb->logical_port, name)) {
145 lport_lookup_by_uuid(const struct lport_index *lports,
146 const struct uuid *uuid)
148 const struct lport *lport;
149 HMAP_FOR_EACH_WITH_HASH (lport, uuid_node, uuid_hash(uuid),
151 if (uuid_equals(uuid, &lport->uuid)) {
158 const struct sbrec_port_binding *
159 lport_lookup_by_key(const struct lport_index *lports,
160 uint32_t dp_key, uint16_t port_key)
162 const struct lport *lport;
163 HMAP_FOR_EACH_WITH_HASH (lport, key_node, hash_int(port_key, dp_key),
165 if (port_key == lport->pb->tunnel_key
166 && dp_key == lport->pb->datapath->tunnel_key) {
174 struct hmap_node dp_name_node; /* Index by (logical datapath, name). */
175 struct hmap_node uuid_node; /* Index by insert uuid. */
177 const struct sbrec_multicast_group *mg;
180 static bool full_mc_rebuild = false;
183 mcgroup_index_reset(void)
185 full_mc_rebuild = true;
189 mcgroup_index_init(struct mcgroup_index *mcgroups)
191 hmap_init(&mcgroups->by_dp_name);
192 hmap_init(&mcgroups->by_uuid);
196 mcgroup_index_remove(struct mcgroup_index *mcgroups, const struct uuid *uuid)
198 const struct mcgroup *mcgroup_ = mcgroup_lookup_by_uuid(mcgroups, uuid);
199 struct mcgroup *mcgroup = CONST_CAST(struct mcgroup *, mcgroup_);
201 hmap_remove(&mcgroups->by_dp_name, &mcgroup->dp_name_node);
202 hmap_remove(&mcgroups->by_uuid, &mcgroup->uuid_node);
208 mcgroup_index_clear(struct mcgroup_index *mcgroups)
210 struct mcgroup *mcgroup, *next;
211 HMAP_FOR_EACH_SAFE (mcgroup, next, dp_name_node, &mcgroups->by_dp_name) {
212 hmap_remove(&mcgroups->by_dp_name, &mcgroup->dp_name_node);
213 hmap_remove(&mcgroups->by_uuid, &mcgroup->uuid_node);
219 consider_mcgroup_index(struct mcgroup_index *mcgroups,
220 const struct sbrec_multicast_group *mg)
222 const struct uuid *dp_uuid = &mg->datapath->header_.uuid;
223 if (mcgroup_lookup_by_dp_name(mcgroups, mg->datapath, mg->name)) {
227 struct mcgroup *m = xmalloc(sizeof *m);
228 hmap_insert(&mcgroups->by_dp_name, &m->dp_name_node,
229 hash_string(mg->name, uuid_hash(dp_uuid)));
230 hmap_insert(&mcgroups->by_uuid, &m->uuid_node,
231 uuid_hash(&mg->header_.uuid));
232 memcpy(&m->uuid, &mg->header_.uuid, sizeof m->uuid);
237 mcgroup_index_fill(struct mcgroup_index *mcgroups, struct ovsdb_idl *ovnsb_idl)
239 const struct sbrec_multicast_group *mg;
240 if (full_mc_rebuild) {
241 mcgroup_index_clear(mcgroups);
242 SBREC_MULTICAST_GROUP_FOR_EACH (mg, ovnsb_idl) {
243 consider_mcgroup_index(mcgroups, mg);
245 full_mc_rebuild = false;
247 SBREC_MULTICAST_GROUP_FOR_EACH_TRACKED (mg, ovnsb_idl) {
248 if (sbrec_multicast_group_is_deleted(mg)) {
249 mcgroup_index_remove(mcgroups, &mg->header_.uuid);
251 consider_mcgroup_index(mcgroups, mg);
258 mcgroup_index_destroy(struct mcgroup_index *mcgroups)
260 mcgroup_index_clear(mcgroups);
262 hmap_destroy(&mcgroups->by_dp_name);
265 const struct mcgroup *
266 mcgroup_lookup_by_uuid(const struct mcgroup_index *mcgroups,
267 const struct uuid *uuid)
269 const struct mcgroup *mcgroup;
270 HMAP_FOR_EACH_WITH_HASH (mcgroup, uuid_node, uuid_hash(uuid),
271 &mcgroups->by_uuid) {
272 if (uuid_equals(&mcgroup->uuid, uuid)) {
279 const struct sbrec_multicast_group *
280 mcgroup_lookup_by_dp_name(const struct mcgroup_index *mcgroups,
281 const struct sbrec_datapath_binding *dp,
284 const struct uuid *dp_uuid = &dp->header_.uuid;
285 const struct mcgroup *mcgroup;
286 HMAP_FOR_EACH_WITH_HASH (mcgroup, dp_name_node,
287 hash_string(name, uuid_hash(dp_uuid)),
288 &mcgroups->by_dp_name) {
289 if (uuid_equals(&mcgroup->mg->datapath->header_.uuid, dp_uuid)
290 && !strcmp(mcgroup->mg->name, name)) {