It is super annoying to send a nagging message every day.  Do not do it.

On Fri, Jul 13, 2018 at 08:03:22AM +0530, Aravind Prasad wrote:
> Hi  Aaron/Ben/All,
> If possible, Kindly review the patch and let me know
> your views.
> 
> On Thu, Jul 12, 2018 at 11:34 PM, Aravind Prasad S <raja....@gmail.com>
> wrote:
> 
> > Currently, rule_insert() API does not have return value. There are some
> > possible
> > scenarios where rule insertions can fail at run-time even though the static
> > checks during rule_construct() had passed previously.
> > Some possible scenarios for failure of rule insertions:
> > **) Rule insertions can fail dynamically in Hybrid mode (both Openflow and
> > Normal switch functioning coexist) where the CAM space could get suddenly
> > filled up by Normal switch functioning and Openflow gets devoid of
> > available space.
> > **) Some deployments could have separate independent layers for HW rule
> > insertions and application layer to interact with OVS. HW layer
> > could face any dynamic issue during rule handling which application could
> > not have predicted/captured in rule-construction phase.
> > Rule-insert errors for bundles are handled too in this pull-request.
> >
> > Signed-off-by: Aravind Prasad S <raja....@gmail.com>
> > ---
> >  ofproto/ofproto-dpif.c     |   4 +-
> >  ofproto/ofproto-provider.h |   6 +--
> >  ofproto/ofproto.c          | 105 ++++++++++++++++++++++++++++++
> > ++++-----------
> >  3 files changed, 85 insertions(+), 30 deletions(-)
> >
> > diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
> > index ad1e8af..d1678ed 100644
> > --- a/ofproto/ofproto-dpif.c
> > +++ b/ofproto/ofproto-dpif.c
> > @@ -4443,7 +4443,7 @@ rule_construct(struct rule *rule_)
> >      return 0;
> >  }
> >
> > -static void
> > +static enum ofperr
> >  rule_insert(struct rule *rule_, struct rule *old_rule_, bool
> > forward_counts)
> >      OVS_REQUIRES(ofproto_mutex)
> >  {
> > @@ -4473,6 +4473,8 @@ rule_insert(struct rule *rule_, struct rule
> > *old_rule_, bool forward_counts)
> >          ovs_mutex_unlock(&rule->stats_mutex);
> >          ovs_mutex_unlock(&old_rule->stats_mutex);
> >      }
> > +
> > +    return 0;
> >  }
> >
> >  static void
> > diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h
> > index 2b77b89..3f3d110 100644
> > --- a/ofproto/ofproto-provider.h
> > +++ b/ofproto/ofproto-provider.h
> > @@ -1297,8 +1297,8 @@ struct ofproto_class {
> >      struct rule *(*rule_alloc)(void);
> >      enum ofperr (*rule_construct)(struct rule *rule)
> >          /* OVS_REQUIRES(ofproto_mutex) */;
> > -    void (*rule_insert)(struct rule *rule, struct rule *old_rule,
> > -                        bool forward_counts)
> > +    enum ofperr (*rule_insert)(struct rule *rule, struct rule *old_rule,
> > +                               bool forward_counts)
> >          /* OVS_REQUIRES(ofproto_mutex) */;
> >      void (*rule_delete)(struct rule *rule) /* OVS_REQUIRES(ofproto_mutex)
> > */;
> >      void (*rule_destruct)(struct rule *rule);
> > @@ -1952,7 +1952,7 @@ enum ofperr ofproto_flow_mod_learn_start(struct
> > ofproto_flow_mod *ofm)
> >      OVS_REQUIRES(ofproto_mutex);
> >  void ofproto_flow_mod_learn_revert(struct ofproto_flow_mod *ofm)
> >      OVS_REQUIRES(ofproto_mutex);
> > -void ofproto_flow_mod_learn_finish(struct ofproto_flow_mod *ofm,
> > +enum ofperr ofproto_flow_mod_learn_finish(struct ofproto_flow_mod *ofm,
> >                                            struct ofproto *orig_ofproto)
> >      OVS_REQUIRES(ofproto_mutex);
> >  void ofproto_add_flow(struct ofproto *, const struct match *, int
> > priority,
> > diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
> > index f946e27..cb09ee6 100644
> > --- a/ofproto/ofproto.c
> > +++ b/ofproto/ofproto.c
> > @@ -245,10 +245,12 @@ static void replace_rule_revert(struct ofproto *,
> > struct rule *old_rule,
> >                                  struct rule *new_rule)
> >      OVS_REQUIRES(ofproto_mutex);
> >
> > -static void replace_rule_finish(struct ofproto *, struct ofproto_flow_mod
> > *,
> > -                                const struct openflow_mod_requester *,
> > -                                struct rule *old_rule, struct rule
> > *new_rule,
> > -                                struct ovs_list *dead_cookies)
> > +static enum ofperr replace_rule_finish(struct ofproto *,
> > +                                       struct ofproto_flow_mod *,
> > +                                       const struct
> > openflow_mod_requester *,
> > +                                       struct rule *old_rule,
> > +                                       struct rule *new_rule,
> > +                                       struct ovs_list *dead_cookies)
> >      OVS_REQUIRES(ofproto_mutex);
> >  static void delete_flows__(struct rule_collection *,
> >                             enum ofp_flow_removed_reason,
> > @@ -270,7 +272,7 @@ static enum ofperr ofproto_flow_mod_start(struct
> > ofproto *,
> >  static void ofproto_flow_mod_revert(struct ofproto *,
> >                                      struct ofproto_flow_mod *)
> >      OVS_REQUIRES(ofproto_mutex);
> > -static void ofproto_flow_mod_finish(struct ofproto *,
> > +static enum ofperr ofproto_flow_mod_finish(struct ofproto *,
> >                                      struct ofproto_flow_mod *,
> >                                      const struct openflow_mod_requester *)
> >      OVS_REQUIRES(ofproto_mutex);
> > @@ -4855,7 +4857,7 @@ add_flow_revert(struct ofproto *ofproto, struct
> > ofproto_flow_mod *ofm)
> >  }
> >
> >  /* To be called after version bump. */
> > -static void
> > +static enum ofperr
> >  add_flow_finish(struct ofproto *ofproto, struct ofproto_flow_mod *ofm,
> >                  const struct openflow_mod_requester *req)
> >      OVS_REQUIRES(ofproto_mutex)
> > @@ -4864,8 +4866,14 @@ add_flow_finish(struct ofproto *ofproto, struct
> > ofproto_flow_mod *ofm,
> >          ? rule_collection_rules(&ofm->old_rules)[0] : NULL;
> >      struct rule *new_rule = rule_collection_rules(&ofm->new_rules)[0];
> >      struct ovs_list dead_cookies = OVS_LIST_INITIALIZER(&dead_cookies);
> > +    enum ofperr error = 0;
> > +
> > +    error = replace_rule_finish(ofproto, ofm, req, old_rule, new_rule,
> > +                                &dead_cookies);
> > +    if (error) {
> > +        return error;
> > +    }
> >
> > -    replace_rule_finish(ofproto, ofm, req, old_rule, new_rule,
> > &dead_cookies);
> >      learned_cookies_flush(ofproto, &dead_cookies);
> >
> >      if (old_rule) {
> > @@ -4878,6 +4886,8 @@ add_flow_finish(struct ofproto *ofproto, struct
> > ofproto_flow_mod *ofm,
> >          /* Send Vacancy Events for OF1.4+. */
> >          send_table_status(ofproto, new_rule->table_id);
> >      }
> > +
> > +    return error;
> >  }
> >
> >  /* OFPFC_MODIFY and OFPFC_MODIFY_STRICT. */
> > @@ -5074,22 +5084,25 @@ ofproto_flow_mod_learn_revert(struct
> > ofproto_flow_mod *ofm)
> >      ofproto_flow_mod_revert(rule->ofproto, ofm);
> >  }
> >
> > -void
> > +enum ofperr
> >  ofproto_flow_mod_learn_finish(struct ofproto_flow_mod *ofm,
> >                                struct ofproto *orig_ofproto)
> >      OVS_REQUIRES(ofproto_mutex)
> >  {
> >      struct rule *rule = rule_collection_rules(&ofm->new_rules)[0];
> > +    enum ofperr error = 0;
> >
> >      /* If learning on a different bridge, must bump its version
> >       * number and flush connmgr afterwards. */
> >      if (rule->ofproto != orig_ofproto) {
> >          ofproto_bump_tables_version(rule->ofproto);
> >      }
> > -    ofproto_flow_mod_finish(rule->ofproto, ofm, NULL);
> > +    error = ofproto_flow_mod_finish(rule->ofproto, ofm, NULL);
> >      if (rule->ofproto != orig_ofproto) {
> >          ofmonitor_flush(rule->ofproto->connmgr);
> >      }
> > +
> > +    return error;
> >  }
> >
> >  /* Refresh 'ofm->temp_rule', for which the caller holds a reference, if
> > already
> > @@ -5144,7 +5157,7 @@ ofproto_flow_mod_learn(struct ofproto_flow_mod *ofm,
> > bool keep_ref,
> >
> >              error = ofproto_flow_mod_learn_start(ofm);
> >              if (!error) {
> > -                ofproto_flow_mod_learn_finish(ofm, NULL);
> > +                error = ofproto_flow_mod_learn_finish(ofm, NULL);
> >              }
> >          } else {
> >              static struct vlog_rate_limit rll = VLOG_RATE_LIMIT_INIT(1,
> > 5);
> > @@ -5244,7 +5257,7 @@ replace_rule_revert(struct ofproto *ofproto,
> >  }
> >
> >  /* Adds the 'new_rule', replacing the 'old_rule'. */
> > -static void
> > +static enum ofperr
> >  replace_rule_finish(struct ofproto *ofproto, struct ofproto_flow_mod *ofm,
> >                      const struct openflow_mod_requester *req,
> >                      struct rule *old_rule, struct rule *new_rule,
> > @@ -5252,6 +5265,8 @@ replace_rule_finish(struct ofproto *ofproto, struct
> > ofproto_flow_mod *ofm,
> >      OVS_REQUIRES(ofproto_mutex)
> >  {
> >      struct rule *replaced_rule;
> > +    enum ofperr error = 0;
> > +    struct oftable *table = &ofproto->tables[new_rule->table_id];
> >
> >      replaced_rule = (old_rule && old_rule->removed_reason !=
> > OFPRR_EVICTION)
> >          ? old_rule : NULL;
> > @@ -5261,8 +5276,15 @@ replace_rule_finish(struct ofproto *ofproto, struct
> > ofproto_flow_mod *ofm,
> >       * link the packet and byte counts from the old rule to the new one if
> >       * 'modify_keep_counts' is 'true'.  The 'replaced_rule' will be
> > deleted
> >       * right after this call. */
> > -    ofproto->ofproto_class->rule_insert(new_rule, replaced_rule,
> > -                                        ofm->modify_keep_counts);
> > +    error = ofproto->ofproto_class->rule_insert(new_rule, replaced_rule,
> > +                                                ofm->modify_keep_counts);
> > +    if (error) {
> > +        if (classifier_remove(&table->cls, &new_rule->cr)) {
> > +            ofproto_rule_destroy__(new_rule);
> > +        }
> > +        return error;
> > +    }
> > +
> >      learned_cookies_inc(ofproto, rule_get_actions(new_rule));
> >
> >      if (old_rule) {
> > @@ -5298,6 +5320,8 @@ replace_rule_finish(struct ofproto *ofproto, struct
> > ofproto_flow_mod *ofm,
> >                               req ? req->request->xid : 0, NULL);
> >          }
> >      }
> > +
> > +    return error;
> >  }
> >
> >  /* ofm->temp_rule is consumed only in the successful case. */
> > @@ -5448,17 +5472,18 @@ modify_flows_revert(struct ofproto *ofproto,
> > struct ofproto_flow_mod *ofm)
> >      }
> >  }
> >
> > -static void
> > +static enum ofperr
> >  modify_flows_finish(struct ofproto *ofproto, struct ofproto_flow_mod *ofm,
> >                      const struct openflow_mod_requester *req)
> >      OVS_REQUIRES(ofproto_mutex)
> >  {
> >      struct rule_collection *old_rules = &ofm->old_rules;
> >      struct rule_collection *new_rules = &ofm->new_rules;
> > +    enum ofperr error = 0;
> >
> >      if (rule_collection_n(old_rules) == 0
> >          && rule_collection_n(new_rules) == 1) {
> > -        add_flow_finish(ofproto, ofm, req);
> > +        error = add_flow_finish(ofproto, ofm, req);
> >      } else if (rule_collection_n(old_rules) > 0) {
> >          struct ovs_list dead_cookies = OVS_LIST_INITIALIZER(&dead_
> > cookies);
> >
> > @@ -5467,12 +5492,17 @@ modify_flows_finish(struct ofproto *ofproto,
> > struct ofproto_flow_mod *ofm,
> >
> >          struct rule *old_rule, *new_rule;
> >          RULE_COLLECTIONS_FOR_EACH (old_rule, new_rule, old_rules,
> > new_rules) {
> > -            replace_rule_finish(ofproto, ofm, req, old_rule, new_rule,
> > -                                &dead_cookies);
> > +            error = replace_rule_finish(ofproto, ofm, req, old_rule,
> > new_rule,
> > +                                        &dead_cookies);
> > +            if (error) {
> > +                return error;
> > +            }
> >          }
> >          learned_cookies_flush(ofproto, &dead_cookies);
> >          remove_rules_postponed(old_rules);
> >      }
> > +
> > +    return error;
> >  }
> >
> >  static enum ofperr
> > @@ -5838,7 +5868,7 @@ handle_flow_mod__(struct ofproto *ofproto, const
> > struct ofputil_flow_mod *fm,
> >      error = ofproto_flow_mod_start(ofproto, &ofm);
> >      if (!error) {
> >          ofproto_bump_tables_version(ofproto);
> > -        ofproto_flow_mod_finish(ofproto, &ofm, req);
> > +        error = ofproto_flow_mod_finish(ofproto, &ofm, req);
> >          ofmonitor_flush(ofproto->connmgr);
> >      }
> >      ovs_mutex_unlock(&ofproto_mutex);
> > @@ -7668,19 +7698,21 @@ ofproto_flow_mod_revert(struct ofproto *ofproto,
> > struct ofproto_flow_mod *ofm)
> >      rule_collection_destroy(&ofm->new_rules);
> >  }
> >
> > -static void
> > +static enum ofperr
> >  ofproto_flow_mod_finish(struct ofproto *ofproto, struct ofproto_flow_mod
> > *ofm,
> >                          const struct openflow_mod_requester *req)
> >      OVS_REQUIRES(ofproto_mutex)
> >  {
> > +    enum ofperr error = 0;
> > +
> >      switch (ofm->command) {
> >      case OFPFC_ADD:
> > -        add_flow_finish(ofproto, ofm, req);
> > +        error = add_flow_finish(ofproto, ofm, req);
> >          break;
> >
> >      case OFPFC_MODIFY:
> >      case OFPFC_MODIFY_STRICT:
> > -        modify_flows_finish(ofproto, ofm, req);
> > +        error = modify_flows_finish(ofproto, ofm, req);
> >          break;
> >
> >      case OFPFC_DELETE:
> > @@ -7698,6 +7730,8 @@ ofproto_flow_mod_finish(struct ofproto *ofproto,
> > struct ofproto_flow_mod *ofm,
> >      if (req) {
> >          ofconn_report_flow_mod(req->ofconn, ofm->command);
> >      }
> > +
> > +    return error;
> >  }
> >
> >  /* Commit phases (all while locking ofproto_mutex):
> > @@ -7781,10 +7815,8 @@ do_bundle_commit(struct ofconn *ofconn, uint32_t
> > id, uint16_t flags)
> >
> >          if (error) {
> >              /* Send error referring to the original message. */
> > -            if (error) {
> > -                ofconn_send_error(ofconn, be->msg, error);
> > -                error = OFPERR_OFPBFC_MSG_FAILED;
> > -            }
> > +            ofconn_send_error(ofconn, be->msg, error);
> > +            error = OFPERR_OFPBFC_MSG_FAILED;
> >
> >              /* 2. Revert.  Undo all the changes made above. */
> >              LIST_FOR_EACH_REVERSE_CONTINUE(be, node, &bundle->msg_list) {
> > @@ -7827,13 +7859,34 @@ do_bundle_commit(struct ofconn *ofconn, uint32_t
> > id, uint16_t flags)
> >                      struct openflow_mod_requester req = { ofconn, be->msg
> > };
> >
> >                      if (be->type == OFPTYPE_FLOW_MOD) {
> > -                        ofproto_flow_mod_finish(ofproto, &be->ofm, &req);
> > +                        error = ofproto_flow_mod_finish(ofproto,
> > &be->ofm,
> > +                                                        &req);
> >                      } else if (be->type == OFPTYPE_GROUP_MOD) {
> >                          ofproto_group_mod_finish(ofproto, &be->ogm,
> > &req);
> >                      } else if (be->type == OFPTYPE_PACKET_OUT) {
> >                          ofproto_packet_out_finish(ofproto, &be->opo);
> >                      }
> >                  }
> > +                if (error) {
> > +                    break;
> > +                }
> > +            }
> > +            if (error) {
> > +                /* Send error referring to the original message. */
> > +                ofconn_send_error(ofconn, be->msg, error);
> > +                error = OFPERR_OFPBFC_MSG_FAILED;
> > +
> > +                /* Revert.  Undo all the changes made above. */
> > +                LIST_FOR_EACH_REVERSE_CONTINUE (be, node,
> > &bundle->msg_list) {
> > +                    if (be->type == OFPTYPE_FLOW_MOD) {
> > +                        ofproto_flow_mod_revert(ofproto, &be->ofm);
> > +                    } else if (be->type == OFPTYPE_GROUP_MOD) {
> > +                        ofproto_group_mod_revert(ofproto, &be->ogm);
> > +                    } else if (be->type == OFPTYPE_PACKET_OUT) {
> > +                        ofproto_packet_out_revert(ofproto, &be->opo);
> > +                    }
> > +                    /* Nothing needs to be reverted for a port mod. */
> > +                }
> >              }
> >          }
> >
> > --
> > 1.9.1
> >
> >
> _______________________________________________
> dev mailing list
> d...@openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to