While this patch passes the ovn test suite, it is not working correctly, so consider this is "Self-NACK" and I'll work on getting it fixed tomorrow...
Ryan Ryan Moats/Omaha/IBM@IBMUS wrote on 02/16/2016 02:30:20 PM: > From: Ryan Moats/Omaha/IBM@IBMUS > To: dev@openvswitch.org > Cc: russ...@ovn.org, Ryan Moats/Omaha/IBM@IBMUS > Date: 02/16/2016 02:30 PM > Subject: [PATCH v4 2/3] [ovn-controller] Add logical flow > incremental processing > > From: RYAN D. MOATS <rmo...@us.ibm.com> > > Make flow table persistent in ovn controller > > This is a prerequisite for incremental processing. > > Signed-off-by: RYAN D. MOATS <rmo...@us.ibm.com> > --- > ovn/controller/ofctrl.c | 99 +++++++++++++++++++++++++++ > +----------- > ovn/controller/ofctrl.h | 2 + > ovn/controller/ovn-controller.c | 4 +- > 3 files changed, 75 insertions(+), 30 deletions(-) > > diff --git a/ovn/controller/ofctrl.c b/ovn/controller/ofctrl.c > index 3297fb3..e5f4ebf 100644 > --- a/ovn/controller/ofctrl.c > +++ b/ovn/controller/ofctrl.c > @@ -50,6 +50,8 @@ struct ovn_flow { > static uint32_t ovn_flow_hash(const struct ovn_flow *); > static struct ovn_flow *ovn_flow_lookup(struct hmap *flow_table, > const struct ovn_flow *target); > +static struct ovn_flow *ovn_flow_lookup2(struct hmap *flow_table, > + const struct ovn_flow *target); > static char *ovn_flow_to_string(const struct ovn_flow *); > static void ovn_flow_log(const struct ovn_flow *, const char *action); > static void ovn_flow_destroy(struct ovn_flow *); > @@ -484,21 +486,41 @@ ofctrl_add_flow(struct hmap *desired_flows, > f->ofpacts_len = actions->size; > f->hmap_node.hash = ovn_flow_hash(f); > > - if (ovn_flow_lookup(desired_flows, f)) { > - static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 5); > - if (!VLOG_DROP_INFO(&rl)) { > - char *s = ovn_flow_to_string(f); > - VLOG_INFO("dropping duplicate flow: %s", s); > - free(s); > - } > + struct ovn_flow *d = ovn_flow_lookup2(desired_flows, f); > + if (d) { > + if (!match_equal(&d->match, &f->match)) { > > - ovn_flow_destroy(f); > - return; > + hmap_remove(desired_flows, &d->hmap_node); > + ovn_flow_destroy(d); > + } else { > + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 5); > + if (!VLOG_DROP_INFO(&rl)) { > + char *s = ovn_flow_to_string(f); > + VLOG_INFO("dropping duplicate flow: %s", s); > + free(s); > + } > + > + ovn_flow_destroy(f); > + return; > + } > } > > hmap_insert(desired_flows, &f->hmap_node, f->hmap_node.hash); > } > > +/* duplicate an ovn_flow structure */ > +struct ovn_flow *ofctrl_dup_flow(struct ovn_flow *source) > +{ > + struct ovn_flow *answer = xmalloc(sizeof *answer); > + answer->table_id = source->table_id; > + answer->priority = source->priority; > + answer->match = source->match; > + answer->ofpacts = xmemdup(source->ofpacts, source->ofpacts_len); > + answer->ofpacts_len = source->ofpacts_len; > + answer->hmap_node.hash = ovn_flow_hash(answer); > + return answer; > +} > + > /* ovn_flow. */ > > /* Returns a hash of the key in 'f'. */ > @@ -528,6 +550,25 @@ ovn_flow_lookup(struct hmap *flow_table, const > struct ovn_flow *target) > return NULL; > } > > +/* Finds and returns an ovn_flow in 'flow_table" whose table_id, priority > + * and actions are the same as the target, or NULL if there is none */ > +static struct ovn_flow * > +ovn_flow_lookup2(struct hmap *flow_table, const struct ovn_flow *target) > +{ > + struct ovn_flow *f; > + > + HMAP_FOR_EACH_WITH_HASH (f, hmap_node, target->hmap_node.hash, > + flow_table) { > + if (f->table_id == target->table_id > + && f->priority == target->priority > + && ofpacts_equal(f->ofpacts, f->ofpacts_len, > + target->ofpacts, target->ofpacts_len)) { > + return f; > + } > + } > + return NULL; > +} > + > static char * > ovn_flow_to_string(const struct ovn_flow *f) > { > @@ -607,7 +648,6 @@ ofctrl_put(struct hmap *flow_table) > * to wake up and retry. */ > if (state != S_UPDATE_FLOWS > || rconn_packet_counter_n_packets(tx_counter)) { > - ovn_flow_table_clear(flow_table); > return; > } > > @@ -659,25 +699,28 @@ ofctrl_put(struct hmap *flow_table) > } > } > > - /* The previous loop removed from 'flow_table' all of the flows that are > - * already installed. Thus, any flows remaining in 'flow_table' need to > - * be added to the flow table. */ > + /* Since flow table has all flows, now we need to add the ones that > + * aren't in the installed flow table. */ > struct ovn_flow *d; > HMAP_FOR_EACH_SAFE (d, next, hmap_node, flow_table) { > - /* Send flow_mod to add flow. */ > - struct ofputil_flow_mod fm = { > - .match = d->match, > - .priority = d->priority, > - .table_id = d->table_id, > - .ofpacts = d->ofpacts, > - .ofpacts_len = d->ofpacts_len, > - .command = OFPFC_ADD, > - }; > - queue_flow_mod(&fm); > - ovn_flow_log(d, "adding"); > - > - /* Move 'd' from 'flow_table' to installed_flows. */ > - hmap_remove(flow_table, &d->hmap_node); > - hmap_insert(&installed_flows, &d->hmap_node, d->hmap_node.hash); > + struct ovn_flow *i = ovn_flow_lookup(&installed_flows, d); > + if (!i) { > + /* Send flow_mod to add flow. */ > + struct ofputil_flow_mod fm = { > + .match = d->match, > + .priority = d->priority, > + .table_id = d->table_id, > + .ofpacts = d->ofpacts, > + .ofpacts_len = d->ofpacts_len, > + .command = OFPFC_ADD, > + }; > + queue_flow_mod(&fm); > + ovn_flow_log(d, "adding"); > + > + /* Copy 'd' from 'flow_table' to installed_flows. */ > + struct ovn_flow *new_node = ofctrl_dup_flow(d); > + hmap_insert(&installed_flows, &new_node->hmap_node, > + new_node->hmap_node.hash); > + } > } > } > diff --git a/ovn/controller/ofctrl.h b/ovn/controller/ofctrl.h > index 93ef8ea..d3fabc0 100644 > --- a/ovn/controller/ofctrl.h > +++ b/ovn/controller/ofctrl.h > @@ -34,6 +34,8 @@ void ofctrl_put(struct hmap *flows); > void ofctrl_wait(void); > void ofctrl_destroy(void); > > +struct ovn_flow *ofctrl_dup_flow(struct ovn_flow *source); > + > /* Flow table interface to the rest of ovn-controller. */ > void ofctrl_add_flow(struct hmap *flows, uint8_t table_id, uint16_tpriority, > const struct match *, const struct ofpbuf *ofpacts); > diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c > index 3638342..5a4174e 100644 > --- a/ovn/controller/ovn-controller.c > +++ b/ovn/controller/ovn-controller.c > @@ -205,6 +205,8 @@ main(int argc, char *argv[]) > bool exiting; > int retval; > > + struct hmap flow_table = HMAP_INITIALIZER(&flow_table); > + > ovs_cmdl_proctitle_init(argc, argv); > set_program_name(argv[0]); > service_start(&argc, &argv); > @@ -299,14 +301,12 @@ 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); > if (chassis_id) { > physical_run(&ctx, mff_ovn_geneve, > br_int, chassis_id, &ct_zones, &flow_table); > } > ofctrl_put(&flow_table); > - hmap_destroy(&flow_table); > } > > /* local_datapaths contains bare hmap_node instances. > -- > 1.7.1 > _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev