Skip to content

Commit 4470328

Browse files
jayhawk87blp
authored andcommitted
lport: Persist lport_index and mcgroup_index structures.
This is preparatory to making physical_run and lflow_run process incrementally as changes to the data in these structures control that processing. Signed-off-by: RYAN D. MOATS <rmoats@us.ibm.com> Signed-off-by: Ben Pfaff <blp@ovn.org>
1 parent 40ebbf7 commit 4470328

3 files changed

Lines changed: 213 additions & 46 deletions

File tree

ovn/controller/lport.c

Lines changed: 183 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -17,55 +17,116 @@
1717

1818
#include "lport.h"
1919
#include "hash.h"
20+
#include "lflow.h"
2021
#include "openvswitch/vlog.h"
2122
#include "ovn/lib/ovn-sb-idl.h"
2223

2324
VLOG_DEFINE_THIS_MODULE(lport);
2425

2526
/* A logical port. */
2627
struct lport {
27-
struct hmap_node name_node; /* Index by name. */
28-
struct hmap_node key_node; /* Index by (dp_key, port_key). */
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. */
31+
const struct uuid *uuid;
2932
const struct sbrec_port_binding *pb;
3033
};
3134

35+
static bool full_lport_rebuild = false;
36+
37+
void
38+
lport_index_reset(void)
39+
{
40+
full_lport_rebuild = true;
41+
}
42+
3243
void
33-
lport_index_init(struct lport_index *lports, struct ovsdb_idl *ovnsb_idl)
44+
lport_index_init(struct lport_index *lports)
3445
{
3546
hmap_init(&lports->by_name);
3647
hmap_init(&lports->by_key);
48+
hmap_init(&lports->by_uuid);
49+
}
3750

38-
const struct sbrec_port_binding *pb;
39-
SBREC_PORT_BINDING_FOR_EACH (pb, ovnsb_idl) {
40-
if (lport_lookup_by_name(lports, pb->logical_port)) {
41-
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
42-
VLOG_WARN_RL(&rl, "duplicate logical port name '%s'",
43-
pb->logical_port);
44-
continue;
45-
}
46-
47-
struct lport *p = xmalloc(sizeof *p);
48-
hmap_insert(&lports->by_name, &p->name_node,
49-
hash_string(pb->logical_port, 0));
50-
hmap_insert(&lports->by_key, &p->key_node,
51-
hash_int(pb->tunnel_key, pb->datapath->tunnel_key));
52-
p->pb = pb;
51+
void
52+
lport_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);
5361
}
5462
}
5563

5664
void
57-
lport_index_destroy(struct lport_index *lports)
65+
lport_index_clear(struct lport_index *lports)
5866
{
5967
/* Destroy all of the "struct lport"s.
6068
*
61-
* We don't have to remove the node from both indexes. */
62-
struct lport *port;
63-
HMAP_FOR_EACH_POP (port, name_node, &lports->by_name) {
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);
6475
free(port);
6576
}
77+
}
78+
79+
static void
80+
consider_lport_index(struct lport_index *lports,
81+
const struct sbrec_port_binding *pb)
82+
{
83+
if (lport_lookup_by_name(lports, pb->logical_port)) {
84+
return;
85+
}
86+
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+
p->uuid = &pb->header_.uuid;
95+
p->pb = pb;
96+
}
97+
98+
void
99+
lport_index_fill(struct lport_index *lports, struct ovsdb_idl *ovnsb_idl)
100+
{
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);
106+
}
107+
full_lport_rebuild = false;
108+
} else {
109+
SBREC_PORT_BINDING_FOR_EACH_TRACKED (pb, ovnsb_idl) {
110+
bool is_delete = sbrec_port_binding_row_get_seqno(pb,
111+
OVSDB_IDL_CHANGE_DELETE) > 0;
112+
113+
if (is_delete) {
114+
lport_index_remove(lports, &pb->header_.uuid);
115+
continue;
116+
}
117+
consider_lport_index(lports, pb);
118+
}
119+
}
120+
}
121+
122+
void
123+
lport_index_destroy(struct lport_index *lports)
124+
{
125+
lport_index_clear(lports);
66126

67127
hmap_destroy(&lports->by_name);
68128
hmap_destroy(&lports->by_key);
129+
hmap_destroy(&lports->by_uuid);
69130
}
70131

71132
/* Finds and returns the lport with the given 'name', or NULL if no such lport
@@ -83,6 +144,20 @@ lport_lookup_by_name(const struct lport_index *lports, const char *name)
83144
return NULL;
84145
}
85146

147+
const struct lport *
148+
lport_lookup_by_uuid(const struct lport_index *lports,
149+
const struct uuid *uuid)
150+
{
151+
const struct lport *lport;
152+
HMAP_FOR_EACH_WITH_HASH (lport, uuid_node, uuid_hash(uuid),
153+
&lports->by_uuid) {
154+
if (uuid_equals(uuid, lport->uuid)) {
155+
return lport;
156+
}
157+
}
158+
return NULL;
159+
}
160+
86161
const struct sbrec_port_binding *
87162
lport_lookup_by_key(const struct lport_index *lports,
88163
uint32_t dp_key, uint16_t port_key)
@@ -100,43 +175,113 @@ lport_lookup_by_key(const struct lport_index *lports,
100175

101176
struct mcgroup {
102177
struct hmap_node dp_name_node; /* Index by (logical datapath, name). */
178+
struct hmap_node uuid_node; /* Index by insert uuid. */
179+
const struct uuid *uuid;
103180
const struct sbrec_multicast_group *mg;
104181
};
105182

183+
static bool full_mc_rebuild = false;
184+
106185
void
107-
mcgroup_index_init(struct mcgroup_index *mcgroups, struct ovsdb_idl *ovnsb_idl)
186+
mcgroup_index_reset(void)
108187
{
109-
hmap_init(&mcgroups->by_dp_name);
188+
full_mc_rebuild = true;
189+
}
110190

111-
const struct sbrec_multicast_group *mg;
112-
SBREC_MULTICAST_GROUP_FOR_EACH (mg, ovnsb_idl) {
113-
const struct uuid *dp_uuid = &mg->datapath->header_.uuid;
114-
if (mcgroup_lookup_by_dp_name(mcgroups, mg->datapath, mg->name)) {
115-
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
116-
VLOG_WARN_RL(&rl, "datapath "UUID_FMT" contains duplicate "
117-
"multicast group '%s'", UUID_ARGS(dp_uuid), mg->name);
118-
continue;
119-
}
191+
void
192+
mcgroup_index_init(struct mcgroup_index *mcgroups)
193+
{
194+
hmap_init(&mcgroups->by_dp_name);
195+
hmap_init(&mcgroups->by_uuid);
196+
}
120197

121-
struct mcgroup *m = xmalloc(sizeof *m);
122-
hmap_insert(&mcgroups->by_dp_name, &m->dp_name_node,
123-
hash_string(mg->name, uuid_hash(dp_uuid)));
124-
m->mg = mg;
198+
void
199+
mcgroup_index_remove(struct mcgroup_index *mcgroups, const struct uuid *uuid)
200+
{
201+
const struct mcgroup *mcgroup_ = mcgroup_lookup_by_uuid(mcgroups, uuid);
202+
struct mcgroup *mcgroup = CONST_CAST(struct mcgroup *, mcgroup_);
203+
if (mcgroup) {
204+
hmap_remove(&mcgroups->by_dp_name, &mcgroup->dp_name_node);
205+
hmap_remove(&mcgroups->by_uuid, &mcgroup->uuid_node);
206+
free(mcgroup);
125207
}
126208
}
127209

128210
void
129-
mcgroup_index_destroy(struct mcgroup_index *mcgroups)
211+
mcgroup_index_clear(struct mcgroup_index *mcgroups)
130212
{
131213
struct mcgroup *mcgroup, *next;
132214
HMAP_FOR_EACH_SAFE (mcgroup, next, dp_name_node, &mcgroups->by_dp_name) {
133215
hmap_remove(&mcgroups->by_dp_name, &mcgroup->dp_name_node);
216+
hmap_remove(&mcgroups->by_uuid, &mcgroup->uuid_node);
134217
free(mcgroup);
135218
}
219+
}
220+
221+
static void
222+
consider_mcgroup_index(struct mcgroup_index *mcgroups,
223+
const struct sbrec_multicast_group *mg)
224+
{
225+
const struct uuid *dp_uuid = &mg->datapath->header_.uuid;
226+
if (mcgroup_lookup_by_dp_name(mcgroups, mg->datapath, mg->name)) {
227+
return;
228+
}
229+
230+
struct mcgroup *m = xmalloc(sizeof *m);
231+
hmap_insert(&mcgroups->by_dp_name, &m->dp_name_node,
232+
hash_string(mg->name, uuid_hash(dp_uuid)));
233+
hmap_insert(&mcgroups->by_uuid, &m->uuid_node,
234+
uuid_hash(&mg->header_.uuid));
235+
m->uuid = &mg->header_.uuid;
236+
m->mg = mg;
237+
}
238+
239+
void
240+
mcgroup_index_fill(struct mcgroup_index *mcgroups, struct ovsdb_idl *ovnsb_idl)
241+
{
242+
const struct sbrec_multicast_group *mg;
243+
if (full_mc_rebuild) {
244+
mcgroup_index_clear(mcgroups);
245+
SBREC_MULTICAST_GROUP_FOR_EACH (mg, ovnsb_idl) {
246+
consider_mcgroup_index(mcgroups, mg);
247+
}
248+
full_mc_rebuild = false;
249+
} else {
250+
SBREC_MULTICAST_GROUP_FOR_EACH_TRACKED (mg, ovnsb_idl) {
251+
bool is_delete = sbrec_multicast_group_row_get_seqno(mg,
252+
OVSDB_IDL_CHANGE_DELETE) > 0;
253+
254+
if (is_delete) {
255+
mcgroup_index_remove(mcgroups, &mg->header_.uuid);
256+
continue;
257+
}
258+
consider_mcgroup_index(mcgroups, mg);
259+
}
260+
}
261+
}
262+
263+
void
264+
mcgroup_index_destroy(struct mcgroup_index *mcgroups)
265+
{
266+
mcgroup_index_clear(mcgroups);
136267

137268
hmap_destroy(&mcgroups->by_dp_name);
138269
}
139270

271+
const struct mcgroup *
272+
mcgroup_lookup_by_uuid(const struct mcgroup_index *mcgroups,
273+
const struct uuid *uuid)
274+
{
275+
const struct mcgroup *mcgroup;
276+
HMAP_FOR_EACH_WITH_HASH (mcgroup, uuid_node, uuid_hash(uuid),
277+
&mcgroups->by_uuid) {
278+
if (uuid_equals(mcgroup->uuid, uuid)) {
279+
return mcgroup;
280+
}
281+
}
282+
return NULL;
283+
}
284+
140285
const struct sbrec_multicast_group *
141286
mcgroup_lookup_by_dp_name(const struct mcgroup_index *mcgroups,
142287
const struct sbrec_datapath_binding *dp,

ovn/controller/lport.h

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#include <stdint.h>
2020
#include "hmap.h"
21+
#include "uuid.h"
2122

2223
struct ovsdb_idl;
2324
struct sbrec_datapath_binding;
@@ -32,15 +33,24 @@ struct sbrec_datapath_binding;
3233
struct lport_index {
3334
struct hmap by_name;
3435
struct hmap by_key;
36+
struct hmap by_uuid;
3537
};
3638

37-
void lport_index_init(struct lport_index *, struct ovsdb_idl *);
39+
void lport_index_reset(void);
40+
void lport_index_init(struct lport_index *);
41+
void lport_index_fill(struct lport_index *, struct ovsdb_idl *);
42+
void lport_index_remove(struct lport_index *, const struct uuid *);
43+
void lport_index_clear(struct lport_index *);
3844
void lport_index_destroy(struct lport_index *);
3945

4046
const struct sbrec_port_binding *lport_lookup_by_name(
4147
const struct lport_index *, const char *name);
4248
const struct sbrec_port_binding *lport_lookup_by_key(
4349
const struct lport_index *, uint32_t dp_key, uint16_t port_key);
50+
51+
const struct lport *lport_lookup_by_uuid(
52+
const struct lport_index *, const struct uuid *uuid);
53+
4454

4555
/* Multicast group index
4656
* =====================
@@ -54,14 +64,22 @@ const struct sbrec_port_binding *lport_lookup_by_key(
5464

5565
struct mcgroup_index {
5666
struct hmap by_dp_name;
67+
struct hmap by_uuid;
5768
};
5869

59-
void mcgroup_index_init(struct mcgroup_index *, struct ovsdb_idl *);
70+
void mcgroup_index_reset(void);
71+
void mcgroup_index_init(struct mcgroup_index *);
72+
void mcgroup_index_fill(struct mcgroup_index *, struct ovsdb_idl *);
73+
void mcgroup_index_remove(struct mcgroup_index *, const struct uuid *);
74+
void mcgroup_index_clear(struct mcgroup_index *);
6075
void mcgroup_index_destroy(struct mcgroup_index *);
6176

6277
const struct sbrec_multicast_group *mcgroup_lookup_by_dp_name(
6378
const struct mcgroup_index *,
6479
const struct sbrec_datapath_binding *,
6580
const char *name);
6681

82+
const struct mcgroup *mcgroup_lookup_by_uuid(
83+
const struct mcgroup_index *, const struct uuid *uuid);
84+
6785
#endif /* ovn/lport.h */

ovn/controller/ovn-controller.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,9 @@ update_ct_zones(struct sset *lports, struct hmap *patched_datapaths,
327327
static struct hmap local_datapaths = HMAP_INITIALIZER(&local_datapaths);
328328
static struct hmap patched_datapaths = HMAP_INITIALIZER(&patched_datapaths);
329329

330+
static struct lport_index lports;
331+
static struct mcgroup_index mcgroups;
332+
330333
int
331334
main(int argc, char *argv[])
332335
{
@@ -357,6 +360,9 @@ main(int argc, char *argv[])
357360
pinctrl_init();
358361
lflow_init();
359362

363+
lport_index_init(&lports);
364+
mcgroup_index_init(&mcgroups);
365+
360366
/* Connect to OVS OVSDB instance. We do not monitor all tables by
361367
* default, so modules must register their interest explicitly. */
362368
struct ovsdb_idl_loop ovs_idl_loop = OVSDB_IDL_LOOP_INITIALIZER(
@@ -417,6 +423,8 @@ main(int argc, char *argv[])
417423
ovnsb_remote = new_ovnsb_remote;
418424
ovsdb_idl_set_remote(ovnsb_idl_loop.idl, ovnsb_remote, true);
419425
binding_reset_processing();
426+
lport_index_clear(&lports);
427+
mcgroup_index_clear(&mcgroups);
420428
} else {
421429
free(new_ovnsb_remote);
422430
}
@@ -443,10 +451,8 @@ main(int argc, char *argv[])
443451
patch_run(&ctx, br_int, chassis_id, &local_datapaths,
444452
&patched_datapaths);
445453

446-
struct lport_index lports;
447-
struct mcgroup_index mcgroups;
448-
lport_index_init(&lports, ctx.ovnsb_idl);
449-
mcgroup_index_init(&mcgroups, ctx.ovnsb_idl);
454+
lport_index_fill(&lports, ctx.ovnsb_idl);
455+
mcgroup_index_fill(&mcgroups, ctx.ovnsb_idl);
450456

451457
enum mf_field_id mff_ovn_geneve = ofctrl_run(br_int);
452458

@@ -464,8 +470,6 @@ main(int argc, char *argv[])
464470
}
465471
ofctrl_put(&flow_table);
466472
hmap_destroy(&flow_table);
467-
mcgroup_index_destroy(&mcgroups);
468-
lport_index_destroy(&lports);
469473
}
470474

471475
sset_destroy(&all_lports);

0 commit comments

Comments
 (0)