@@ -273,25 +273,60 @@ lflow_init(void)
/* Translates logical flows in the Logical_Flow table in the OVN_SB database
* into OpenFlow flows. See ovn-architecture(7) for more information. */
-void
+unsigned int
lflow_run(struct controller_ctx *ctx, struct hmap *flow_table,
const struct simap *ct_zones,
- struct hmap *local_datapaths)
+ struct hmap *local_datapaths,
+ unsigned int seqno)
{
struct hmap flows = HMAP_INITIALIZER(&flows);
uint32_t conj_id_ofs = 1;
+ unsigned int skipped_seqno;
+ unsigned int processed_seqno = seqno;
+ unsigned int last_seqno = 0;
ldp_run(ctx);
const struct sbrec_logical_flow *lflow;
- SBREC_LOGICAL_FLOW_FOR_EACH (lflow, ctx->ovnsb_idl) {
- /* Find the "struct logical_datapath" associated with this
+ SBREC_LOGICAL_FLOW_FOR_EACH_TRACKED (lflow, ctx->ovnsb_idl) {
+ unsigned int del_seqno = sbrec_logical_flow_row_get_seqno(lflow,
+ OVSDB_IDL_CHANGE_DELETE);
+ unsigned int mod_seqno = sbrec_logical_flow_row_get_seqno(lflow,
+ OVSDB_IDL_CHANGE_MODIFY);
+ unsigned int ins_seqno = sbrec_logical_flow_row_get_seqno(lflow,
+ OVSDB_IDL_CHANGE_INSERT);
+ if (del_seqno < seqno && mod_seqno < seqno && ins_seqno < seqno) {
+ continue;
+ }
+ if (del_seqno > processed_seqno) {
+ processed_seqno = del_seqno;
+ }
+ if (mod_seqno > processed_seqno) {
+ processed_seqno = mod_seqno;
+ }
+ if (ins_seqno > processed_seqno) {
+ processed_seqno = ins_seqno;
+ }
+
+ /* Find the "struct logical_datapath" asssociated with this
* Logical_Flow row. If there's no such struct, that must be because
* no logical ports are bound to that logical datapath, so there's no
- * point in maintaining any flows for it anyway, so skip it. */
+ * point in maintaining any flows for it anyway, so skip it.
+ * Further, we have to remember the smallest sequence number of
+ * a skipped flow to ensure that we return the correct value
+ * and don't skip things in a later pass */
const struct logical_datapath *ldp;
ldp = ldp_lookup(lflow->logical_datapath);
if (!ldp) {
+ if (last_seqno == 0 || (del_seqno > 0 && last_seqno > del_seqno)) {
+ last_seqno = del_seqno;
+ }
+ if (last_seqno == 0 || (mod_seqno > 0 && last_seqno > mod_seqno)) {
+ last_seqno = mod_seqno;
+ }
+ if (last_seqno == 0 || (ins_seqno > 0 && last_seqno > ins_seqno)) {
+ last_seqno = ins_seqno;
+ }
continue;
}
@@ -425,6 +460,10 @@ lflow_run(struct controller_ctx *ctx, struct hmap *flow_table,
ofpbuf_uninit(&ofpacts);
conj_id_ofs += n_conjs;
}
+ if (last_seqno > 0) {
+ processed_seqno = last_seqno;
+ }
+ return(processed_seqno);
}
void
@@ -56,9 +56,10 @@ struct uuid;
#define LOG_PIPELINE_LEN 16
void lflow_init(void);
-void lflow_run(struct controller_ctx *, struct hmap *flow_table,
+unsigned int lflow_run(struct controller_ctx *, struct hmap *flow_table,
const struct simap *ct_zones,
- struct hmap *local_datapaths);
+ struct hmap *local_datapaths,
+ unsigned int seqno);
void lflow_destroy(void);
#endif /* ovn/lflow.h */
@@ -204,6 +204,7 @@ main(int argc, char *argv[])
struct unixctl_server *unixctl;
bool exiting;
int retval;
+ unsigned int last_seqno;
ovs_cmdl_proctitle_init(argc, argv);
set_program_name(argv[0]);
@@ -257,9 +258,16 @@ main(int argc, char *argv[])
/* Connect to OVN SB database. */
char *ovnsb_remote = get_ovnsb_remote(ovs_idl_loop.idl);
- struct ovsdb_idl_loop ovnsb_idl_loop = OVSDB_IDL_LOOP_INITIALIZER(
- ovsdb_idl_create(ovnsb_remote, &sbrec_idl_class, true, true));
- ovsdb_idl_get_initial_snapshot(ovnsb_idl_loop.idl);
+ struct ovsdb_idl *sb_idl = ovsdb_idl_create(ovnsb_remote,
+ &sbrec_idl_class, true, true);
+ /* set to track the southbound idl */
+ ovsdb_idl_track_add_column(sb_idl, &sbrec_logical_flow_col_match);
+
+ /*ovsdb_idl_track_add_all(sb_idl);*/
+ struct ovsdb_idl_loop ovnsb_idl_loop = OVSDB_IDL_LOOP_INITIALIZER(sb_idl);
+
+
+ ovsdb_idl_get_initial_snapshot(sb_idl);
/* Initialize connection tracking zones. */
struct simap ct_zones = SIMAP_INITIALIZER(&ct_zones);
@@ -271,6 +279,9 @@ main(int argc, char *argv[])
/* Main loop. */
exiting = false;
while (!exiting) {
+ if (last_seqno == 0) {
+ last_seqno = ovsdb_idl_get_seqno(ovnsb_idl_loop.idl);
+ }
struct controller_ctx ctx = {
.ovs_idl = ovs_idl_loop.idl,
.ovs_idl_txn = ovsdb_idl_loop_run(&ovs_idl_loop),
@@ -300,7 +311,8 @@ main(int argc, char *argv[])
pinctrl_run(&ctx, br_int);
struct hmap flow_table = HMAP_INITIALIZER(&flow_table);
- lflow_run(&ctx, &flow_table, &ct_zones, &local_datapaths);
+ last_seqno = lflow_run(&ctx, &flow_table, &ct_zones,
+ &local_datapaths, last_seqno);
if (chassis_id) {
physical_run(&ctx, mff_ovn_geneve,
br_int, chassis_id, &ct_zones, &flow_table);