[ovs-dev] [classifier-opt 09/28] ofproto: Move 'max_ports' from ofproto-dpif.c to ofproto.c.

Ethan Jackson ethan at nicira.com
Mon Jul 30 21:29:05 UTC 2012


Looks good, thanks.

Ethan

On Fri, Jul 20, 2012 at 4:25 PM, Ben Pfaff <blp at nicira.com> wrote:
> This allows port numbers in actions and elsewhere in OpenFlow messages to
> be checked at a higher level.
>
> Signed-off-by: Ben Pfaff <blp at nicira.com>
> ---
>  ofproto/ofproto-dpif.c     |   16 +++++++---------
>  ofproto/ofproto-provider.h |   30 +++++++++++++++++++-----------
>  ofproto/ofproto.c          |   26 ++++++++++++++++++++++++++
>  3 files changed, 52 insertions(+), 20 deletions(-)
>
> diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
> index b95179a..f1d2ae0 100644
> --- a/ofproto/ofproto-dpif.c
> +++ b/ofproto/ofproto-dpif.c
> @@ -588,7 +588,6 @@ struct ofproto_dpif {
>      struct hmap_node all_ofproto_dpifs_node; /* In 'all_ofproto_dpifs'. */
>      struct ofproto up;
>      struct dpif *dpif;
> -    int max_ports;
>
>      /* Special OpenFlow rules. */
>      struct rule_dpif *miss_rule; /* Sends flow table misses to controller. */
> @@ -734,6 +733,7 @@ construct(struct ofproto *ofproto_)
>  {
>      struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
>      const char *name = ofproto->up.name;
> +    int max_ports;
>      int error;
>      int i;
>
> @@ -743,7 +743,9 @@ construct(struct ofproto *ofproto_)
>          return error;
>      }
>
> -    ofproto->max_ports = dpif_get_max_ports(ofproto->dpif);
> +    max_ports = dpif_get_max_ports(ofproto->dpif);
> +    ofproto_init_max_ports(ofproto_, MIN(max_ports, OFPP_MAX));
> +
>      ofproto->n_matches = 0;
>
>      dpif_flow_flush(ofproto->dpif);
> @@ -4593,7 +4595,7 @@ rule_construct(struct rule *rule_)
>      enum ofperr error;
>
>      error = ofpacts_check(rule->up.ofpacts, rule->up.ofpacts_len,
> -                          &rule->up.cr.flow, ofproto->max_ports);
> +                          &rule->up.cr.flow, ofproto->up.max_ports);
>      if (error) {
>          return error;
>      }
> @@ -4703,7 +4705,7 @@ rule_modify_actions(struct rule *rule_)
>      enum ofperr error;
>
>      error = ofpacts_check(rule->up.ofpacts, rule->up.ofpacts_len,
> -                          &rule->up.cr.flow, ofproto->max_ports);
> +                          &rule->up.cr.flow, ofproto->up.max_ports);
>      if (error) {
>          ofoperation_complete(rule->up.pending, error);
>          return;
> @@ -6359,11 +6361,7 @@ packet_out(struct ofproto *ofproto_, struct ofpbuf *packet,
>      struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
>      enum ofperr error;
>
> -    if (flow->in_port >= ofproto->max_ports && flow->in_port < OFPP_MAX) {
> -        return OFPERR_NXBRC_BAD_IN_PORT;
> -    }
> -
> -    error = ofpacts_check(ofpacts, ofpacts_len, flow, ofproto->max_ports);
> +    error = ofpacts_check(ofpacts, ofpacts_len, flow, ofproto->up.max_ports);
>      if (!error) {
>          struct odputil_keybuf keybuf;
>          struct dpif_flow_stats stats;
> diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h
> index 6eef106..2f62473 100644
> --- a/ofproto/ofproto-provider.h
> +++ b/ofproto/ofproto-provider.h
> @@ -61,6 +61,7 @@ struct ofproto {
>      /* Datapath. */
>      struct hmap ports;          /* Contains "struct ofport"s. */
>      struct shash port_by_name;
> +    uint16_t max_ports;         /* Max possible OpenFlow port num, plus one. */
>
>      /* Flow tables. */
>      struct oftable *tables;
> @@ -93,6 +94,7 @@ struct ofproto {
>  };
>
>  void ofproto_init_tables(struct ofproto *, int n_tables);
> +void ofproto_init_max_ports(struct ofproto *, uint16_t max_ports);
>
>  struct ofproto *ofproto_lookup(const char *name);
>  struct ofport *ofproto_get_port(const struct ofproto *, uint16_t ofp_port);
> @@ -365,6 +367,11 @@ struct ofproto_class {
>       * ->construct() should delete flows from the underlying datapath, if
>       * necessary, rather than populating the tables.
>       *
> +     * If the ofproto knows the maximum port number that the datapath can have,
> +     * then it can call ofproto_init_max_ports().  If it does so, then the
> +     * client will ensure that the actions it allows to be used through
> +     * OpenFlow do not refer to ports above that maximum number.
> +     *
>       * Only one ofproto instance needs to be supported for any given datapath.
>       * If a datapath is already open as part of one "ofproto", then another
>       * attempt to "construct" the same datapath as part of another ofproto is
> @@ -946,17 +953,18 @@ struct ofproto_class {
>       *
>       * flow->in_port comes from the OpenFlow OFPT_PACKET_OUT message.  The
>       * implementation should reject invalid flow->in_port values by returning
> -     * OFPERR_NXBRC_BAD_IN_PORT.  For consistency, the implementation should
> -     * consider valid for flow->in_port any value that could possibly be seen
> -     * in a packet that it passes to connmgr_send_packet_in().  Ideally, even
> -     * an implementation that never generates packet-ins (e.g. due to hardware
> -     * limitations) should still allow flow->in_port values for every possible
> -     * physical port and OFPP_LOCAL.  The only virtual ports (those above
> -     * OFPP_MAX) that the caller will ever pass in as flow->in_port, other than
> -     * OFPP_LOCAL, are OFPP_NONE and OFPP_CONTROLLER.  The implementation
> -     * should allow both of these, treating each of them as packets generated
> -     * by the controller as opposed to packets originating from some switch
> -     * port.
> +     * OFPERR_NXBRC_BAD_IN_PORT.  (If the implementation called
> +     * ofproto_init_max_ports(), then the client will reject these ports
> +     * itself.)  For consistency, the implementation should consider valid for
> +     * flow->in_port any value that could possibly be seen in a packet that it
> +     * passes to connmgr_send_packet_in().  Ideally, even an implementation
> +     * that never generates packet-ins (e.g. due to hardware limitations)
> +     * should still allow flow->in_port values for every possible physical port
> +     * and OFPP_LOCAL.  The only virtual ports (those above OFPP_MAX) that the
> +     * caller will ever pass in as flow->in_port, other than OFPP_LOCAL, are
> +     * OFPP_NONE and OFPP_CONTROLLER.  The implementation should allow both of
> +     * these, treating each of them as packets generated by the controller as
> +     * opposed to packets originating from some switch port.
>       *
>       * (Ordinarily the only effect of flow->in_port is on output actions that
>       * involve the input port, such as actions that output to OFPP_IN_PORT,
> diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
> index 467dfda..cbcf0d2 100644
> --- a/ofproto/ofproto.c
> +++ b/ofproto/ofproto.c
> @@ -389,6 +389,7 @@ ofproto_create(const char *datapath_name, const char *datapath_type,
>      ofproto->frag_handling = OFPC_FRAG_NORMAL;
>      hmap_init(&ofproto->ports);
>      shash_init(&ofproto->port_by_name);
> +    ofproto->max_ports = OFPP_MAX;
>      ofproto->tables = NULL;
>      ofproto->n_tables = 0;
>      ofproto->connmgr = connmgr_create(ofproto, datapath_name, datapath_name);
> @@ -421,6 +422,9 @@ ofproto_create(const char *datapath_name, const char *datapath_type,
>      return 0;
>  }
>
> +/* Must be called (only) by an ofproto implementation in its constructor
> + * function.  See the large comment on 'construct' in struct ofproto_class for
> + * details. */
>  void
>  ofproto_init_tables(struct ofproto *ofproto, int n_tables)
>  {
> @@ -436,6 +440,24 @@ ofproto_init_tables(struct ofproto *ofproto, int n_tables)
>      }
>  }
>
> +/* To be optionally called (only) by an ofproto implementation in its
> + * constructor function.  See the large comment on 'construct' in struct
> + * ofproto_class for details.
> + *
> + * Sets the maximum number of ports to 'max_ports'.  The ofproto generic layer
> + * will then ensure that actions passed into the ofproto implementation will
> + * not refer to OpenFlow ports numbered 'max_ports' or higher.  If this
> + * function is not called, there will be no such restriction.
> + *
> + * Reserved ports numbered OFPP_MAX and higher are special and not subject to
> + * the 'max_ports' restriction. */
> +void
> +ofproto_init_max_ports(struct ofproto *ofproto, uint16_t max_ports)
> +{
> +    assert(max_ports <= OFPP_MAX);
> +    ofproto->max_ports = max_ports;
> +}
> +
>  uint64_t
>  ofproto_get_datapath_id(const struct ofproto *ofproto)
>  {
> @@ -2100,6 +2122,10 @@ handle_packet_out(struct ofconn *ofconn, const struct ofp_packet_out *opo)
>      if (error) {
>          goto exit_free_ofpacts;
>      }
> +    if (po.in_port >= p->max_ports && po.in_port < OFPP_MAX) {
> +        error = OFPERR_NXBRC_BAD_IN_PORT;
> +        goto exit_free_ofpacts;
> +    }
>
>      /* Get payload. */
>      if (po.buffer_id != UINT32_MAX) {
> --
> 1.7.2.5
>



More information about the dev mailing list