]> git.proxmox.com Git - ovs.git/blame - ovn/controller/lport.c
ofproto: Consider datapath_type when looking for internal ports.
[ovs.git] / ovn / controller / lport.c
CommitLineData
bce7cf45
BP
1/* Copyright (c) 2015, 2016 Nicira, Inc.
2 *
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:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
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.
14 */
15
16#include <config.h>
17
18#include "lport.h"
19#include "hash.h"
4470328b 20#include "lflow.h"
bce7cf45
BP
21#include "openvswitch/vlog.h"
22#include "ovn/lib/ovn-sb-idl.h"
23
24VLOG_DEFINE_THIS_MODULE(lport);
25
26/* A logical port. */
27struct lport {
4470328b
RM
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. */
8e9f1c13 31 struct uuid uuid;
bce7cf45
BP
32 const struct sbrec_port_binding *pb;
33};
34
4470328b
RM
35static bool full_lport_rebuild = false;
36
37void
38lport_index_reset(void)
39{
40 full_lport_rebuild = true;
41}
42
bce7cf45 43void
4470328b 44lport_index_init(struct lport_index *lports)
bce7cf45
BP
45{
46 hmap_init(&lports->by_name);
47 hmap_init(&lports->by_key);
4470328b
RM
48 hmap_init(&lports->by_uuid);
49}
bce7cf45 50
70c7cfef 51bool
4470328b
RM
52lport_index_remove(struct lport_index *lports, const struct uuid *uuid)
53{
54 const struct lport *port_ = lport_lookup_by_uuid(lports, uuid);
55 struct lport *port = CONST_CAST(struct lport *, port_);
56 if (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);
60 free(port);
70c7cfef 61 return true;
bce7cf45 62 }
70c7cfef 63 return false;
bce7cf45
BP
64}
65
66void
4470328b 67lport_index_clear(struct lport_index *lports)
bce7cf45
BP
68{
69 /* Destroy all of the "struct lport"s.
70 *
4470328b
RM
71 * We have to remove the node from all indexes. */
72 struct lport *port, *next;
73 HMAP_FOR_EACH_SAFE (port, next, name_node, &lports->by_name) {
74 hmap_remove(&lports->by_name, &port->name_node);
75 hmap_remove(&lports->by_key, &port->key_node);
76 hmap_remove(&lports->by_uuid, &port->uuid_node);
bce7cf45
BP
77 free(port);
78 }
70c7cfef 79 lflow_reset_processing();
4470328b
RM
80}
81
82static void
83consider_lport_index(struct lport_index *lports,
84 const struct sbrec_port_binding *pb)
85{
86 if (lport_lookup_by_name(lports, pb->logical_port)) {
87 return;
88 }
89
90 struct lport *p = xmalloc(sizeof *p);
91 hmap_insert(&lports->by_name, &p->name_node,
92 hash_string(pb->logical_port, 0));
93 hmap_insert(&lports->by_key, &p->key_node,
94 hash_int(pb->tunnel_key, pb->datapath->tunnel_key));
95 hmap_insert(&lports->by_uuid, &p->uuid_node,
96 uuid_hash(&pb->header_.uuid));
8e9f1c13 97 memcpy(&p->uuid, &pb->header_.uuid, sizeof p->uuid);
4470328b 98 p->pb = pb;
70c7cfef 99 lflow_reset_processing();
4470328b
RM
100}
101
102void
103lport_index_fill(struct lport_index *lports, struct ovsdb_idl *ovnsb_idl)
104{
105 const struct sbrec_port_binding *pb;
106 if (full_lport_rebuild) {
107 lport_index_clear(lports);
108 SBREC_PORT_BINDING_FOR_EACH (pb, ovnsb_idl) {
109 consider_lport_index(lports, pb);
110 }
111 full_lport_rebuild = false;
112 } else {
113 SBREC_PORT_BINDING_FOR_EACH_TRACKED (pb, ovnsb_idl) {
9a33cd70 114 if (sbrec_port_binding_is_deleted(pb)) {
70c7cfef
RM
115 while (lport_index_remove(lports, &pb->header_.uuid)) {
116 ;
117 }
118 lflow_reset_processing();
9a33cd70
BP
119 } else {
120 consider_lport_index(lports, pb);
4470328b 121 }
4470328b
RM
122 }
123 }
124}
125
126void
127lport_index_destroy(struct lport_index *lports)
128{
129 lport_index_clear(lports);
bce7cf45
BP
130
131 hmap_destroy(&lports->by_name);
132 hmap_destroy(&lports->by_key);
4470328b 133 hmap_destroy(&lports->by_uuid);
bce7cf45
BP
134}
135
136/* Finds and returns the lport with the given 'name', or NULL if no such lport
137 * exists. */
138const struct sbrec_port_binding *
139lport_lookup_by_name(const struct lport_index *lports, const char *name)
140{
141 const struct lport *lport;
142 HMAP_FOR_EACH_WITH_HASH (lport, name_node, hash_string(name, 0),
143 &lports->by_name) {
144 if (!strcmp(lport->pb->logical_port, name)) {
145 return lport->pb;
146 }
147 }
148 return NULL;
149}
150
4470328b
RM
151const struct lport *
152lport_lookup_by_uuid(const struct lport_index *lports,
153 const struct uuid *uuid)
154{
155 const struct lport *lport;
156 HMAP_FOR_EACH_WITH_HASH (lport, uuid_node, uuid_hash(uuid),
157 &lports->by_uuid) {
8e9f1c13 158 if (uuid_equals(uuid, &lport->uuid)) {
4470328b
RM
159 return lport;
160 }
161 }
162 return NULL;
163}
164
bce7cf45
BP
165const struct sbrec_port_binding *
166lport_lookup_by_key(const struct lport_index *lports,
167 uint32_t dp_key, uint16_t port_key)
168{
169 const struct lport *lport;
170 HMAP_FOR_EACH_WITH_HASH (lport, key_node, hash_int(port_key, dp_key),
171 &lports->by_key) {
172 if (port_key == lport->pb->tunnel_key
173 && dp_key == lport->pb->datapath->tunnel_key) {
174 return lport->pb;
175 }
176 }
177 return NULL;
178}
179\f
180struct mcgroup {
181 struct hmap_node dp_name_node; /* Index by (logical datapath, name). */
4470328b 182 struct hmap_node uuid_node; /* Index by insert uuid. */
8e9f1c13 183 struct uuid uuid;
bce7cf45
BP
184 const struct sbrec_multicast_group *mg;
185};
186
4470328b
RM
187static bool full_mc_rebuild = false;
188
bce7cf45 189void
4470328b 190mcgroup_index_reset(void)
bce7cf45 191{
4470328b
RM
192 full_mc_rebuild = true;
193}
bce7cf45 194
4470328b
RM
195void
196mcgroup_index_init(struct mcgroup_index *mcgroups)
197{
198 hmap_init(&mcgroups->by_dp_name);
199 hmap_init(&mcgroups->by_uuid);
200}
bce7cf45 201
4470328b
RM
202void
203mcgroup_index_remove(struct mcgroup_index *mcgroups, const struct uuid *uuid)
204{
205 const struct mcgroup *mcgroup_ = mcgroup_lookup_by_uuid(mcgroups, uuid);
206 struct mcgroup *mcgroup = CONST_CAST(struct mcgroup *, mcgroup_);
207 if (mcgroup) {
208 hmap_remove(&mcgroups->by_dp_name, &mcgroup->dp_name_node);
209 hmap_remove(&mcgroups->by_uuid, &mcgroup->uuid_node);
210 free(mcgroup);
bce7cf45 211 }
70c7cfef 212 lflow_reset_processing();
bce7cf45
BP
213}
214
215void
4470328b 216mcgroup_index_clear(struct mcgroup_index *mcgroups)
bce7cf45
BP
217{
218 struct mcgroup *mcgroup, *next;
219 HMAP_FOR_EACH_SAFE (mcgroup, next, dp_name_node, &mcgroups->by_dp_name) {
220 hmap_remove(&mcgroups->by_dp_name, &mcgroup->dp_name_node);
4470328b 221 hmap_remove(&mcgroups->by_uuid, &mcgroup->uuid_node);
bce7cf45
BP
222 free(mcgroup);
223 }
4470328b
RM
224}
225
226static void
227consider_mcgroup_index(struct mcgroup_index *mcgroups,
228 const struct sbrec_multicast_group *mg)
229{
230 const struct uuid *dp_uuid = &mg->datapath->header_.uuid;
231 if (mcgroup_lookup_by_dp_name(mcgroups, mg->datapath, mg->name)) {
232 return;
233 }
234
235 struct mcgroup *m = xmalloc(sizeof *m);
236 hmap_insert(&mcgroups->by_dp_name, &m->dp_name_node,
237 hash_string(mg->name, uuid_hash(dp_uuid)));
238 hmap_insert(&mcgroups->by_uuid, &m->uuid_node,
239 uuid_hash(&mg->header_.uuid));
8e9f1c13 240 memcpy(&m->uuid, &mg->header_.uuid, sizeof m->uuid);
4470328b 241 m->mg = mg;
70c7cfef 242 lflow_reset_processing();
4470328b
RM
243}
244
245void
246mcgroup_index_fill(struct mcgroup_index *mcgroups, struct ovsdb_idl *ovnsb_idl)
247{
248 const struct sbrec_multicast_group *mg;
249 if (full_mc_rebuild) {
250 mcgroup_index_clear(mcgroups);
251 SBREC_MULTICAST_GROUP_FOR_EACH (mg, ovnsb_idl) {
252 consider_mcgroup_index(mcgroups, mg);
253 }
254 full_mc_rebuild = false;
255 } else {
256 SBREC_MULTICAST_GROUP_FOR_EACH_TRACKED (mg, ovnsb_idl) {
9a33cd70 257 if (sbrec_multicast_group_is_deleted(mg)) {
4470328b 258 mcgroup_index_remove(mcgroups, &mg->header_.uuid);
70c7cfef 259 lflow_reset_processing();
9a33cd70
BP
260 } else {
261 consider_mcgroup_index(mcgroups, mg);
4470328b 262 }
4470328b
RM
263 }
264 }
265}
266
267void
268mcgroup_index_destroy(struct mcgroup_index *mcgroups)
269{
270 mcgroup_index_clear(mcgroups);
bce7cf45
BP
271
272 hmap_destroy(&mcgroups->by_dp_name);
273}
274
4470328b
RM
275const struct mcgroup *
276mcgroup_lookup_by_uuid(const struct mcgroup_index *mcgroups,
277 const struct uuid *uuid)
278{
279 const struct mcgroup *mcgroup;
280 HMAP_FOR_EACH_WITH_HASH (mcgroup, uuid_node, uuid_hash(uuid),
281 &mcgroups->by_uuid) {
8e9f1c13 282 if (uuid_equals(&mcgroup->uuid, uuid)) {
4470328b
RM
283 return mcgroup;
284 }
285 }
286 return NULL;
287}
288
bce7cf45
BP
289const struct sbrec_multicast_group *
290mcgroup_lookup_by_dp_name(const struct mcgroup_index *mcgroups,
291 const struct sbrec_datapath_binding *dp,
292 const char *name)
293{
294 const struct uuid *dp_uuid = &dp->header_.uuid;
295 const struct mcgroup *mcgroup;
296 HMAP_FOR_EACH_WITH_HASH (mcgroup, dp_name_node,
297 hash_string(name, uuid_hash(dp_uuid)),
298 &mcgroups->by_dp_name) {
299 if (uuid_equals(&mcgroup->mg->datapath->header_.uuid, dp_uuid)
300 && !strcmp(mcgroup->mg->name, name)) {
301 return mcgroup->mg;
302 }
303 }
304 return NULL;
305}