[ovs-dev] [PATCH] groups: Add groups API to ofproto-provider.h

Casey Barker crbarker at google.com
Fri Aug 30 18:54:47 UTC 2013


This declares a new API extension between ofproto and the ofproto-provider
to
support Openflow forwarding groups as introduced in the 1.1 spec. This patch
depends on an earlier submission that defines 'struct ofpbucket.' There is
no
executable code in this patch.

The API is modeled after that for flows, and supports asynchronous
completion
for construct, destruct, and modify.

Signed-off-by: Casey Barker <crbarker at google.com>
---
Ben: As before, please feel free to accept or reject this.  (However, I'd be
surprised if your implementation were substantially different, as the API
mimics flows.)  Sorry I've been lax in getting my changes to you, but I'll
adapt to whatever you end up with.  Thanks!

Patch attached to prevent gmail from eating it.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openvswitch.org/pipermail/ovs-dev/attachments/20130830/dbc5e3f8/attachment-0003.html>
-------------- next part --------------
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 820ec34..73aa082 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -6356,6 +6356,12 @@ const struct ofproto_class ofproto_dpif_class = {
     rule_get_stats,
     rule_execute,
     rule_modify_actions,
+    NULL,                       /* group_alloc */
+    NULL,                       /* group_construct */
+    NULL,                       /* group_destruct */
+    NULL,                       /* group_dealloc */
+    NULL,                       /* group_get_stats */
+    NULL,                       /* group_modify */
     set_frag_handling,
     packet_out,
     set_netflow,
diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h
index d6a8a0b..fc46d25 100644
--- a/ofproto/ofproto-provider.h
+++ b/ofproto/ofproto-provider.h
@@ -286,6 +286,23 @@ void ofproto_rule_reduce_timeouts(struct rule *rule, uint16_t idle_timeout,
 
 bool ofproto_rule_has_out_port(const struct rule *, ofp_port_t out_port);
 
+/* An OpenFlow forwarding group within a "struct ofproto".
+ *
+ * As a rule, ofproto implementations may look at these fields but should
+ * not modify them. */
+struct group {
+    struct ofproto *ofproto;     /* The ofproto that contains this group. */
+    struct hmap_node hmap_node;  /* In struct ofproto's 'groups' hmap. */
+    struct list ofproto_node;    /* Owned by ofproto base code. */
+    struct ofoperation *pending; /* Operation now in progress, if nonnull. */
+    long long int created;       /* Creation time. */
+
+    uint32_t group_id;           /* Which group this is. */
+    uint8_t type;                /* What kind of group.  One of OFPGT_*. */
+    struct ofpbucket *ofpbuckets;/* Array of "struct ofpbucket". */
+    size_t n_ofpbuckets;         /* Number of 'ofpbucket' in the array. */
+};
+
 void ofoperation_complete(struct ofoperation *, enum ofperr);
 
 bool ofoperation_has_out_port(const struct ofoperation *, ofp_port_t out_port);
@@ -1107,6 +1124,108 @@ struct ofproto_class {
      * rule. */
     void (*rule_modify_actions)(struct rule *rule, bool reset_counters);
 
+
+    /* ## ------------------------ ## */
+    /* ## OpenFlow Group Functions ## */
+    /* ## ------------------------ ## */
+
+    /* Life-cycle functions for a "struct group" (see "Life Cycle" above).
+     *
+     * Asynchronous Operation Support
+     * ==============================
+     *
+     * The life-cycle operations on groups can operate asynchronously,
+     * just as for rules.  See the rules description for more information.
+     *
+     * Construction
+     * ============
+     *
+     * When ->group_construct() is called, the caller has already inserted
+     * 'group' into 'group->ofproto''s group table.  Unlike rules, there
+     * is no "victim" handling for groups.
+     *
+     * ->group_construct() should set the following in motion:
+     *
+     *   - Validate that 'group->buckets' and 'group->buckets_len' are
+     *     well-formed OpenFlow action buckets that the datapath can
+     *     correctly implement.
+     *
+     *   - If the group is valid, update the datapath group table, adding
+     *     the new group or replacing the existing one.
+     *
+     * (On failure, the ofproto code will roll back the insertion from the
+     * group table, either removing 'group' or replacing it by the group
+     * that was originally in its place.)
+     *
+     * ->group_construct() must act in one of the following ways:
+     *
+     *   - If it succeeds, it must call ofoperation_complete() and return 0.
+     *
+     *   - If it fails, it must act in one of the following ways:
+     *
+     *       * Call ofoperation_complete() and return 0.
+     *
+     *       * Return an OpenFlow error code (as returned by ofp_mkerr()).
+     *        (Do not call ofoperation_complete() in this case.)
+     *
+     *     In either failure case, ->group_destruct() will not be called and
+     *     ->group_dealloc() will be called.
+     *
+     *   - If the operation is only partially complete, then it must return
+     *     0.  Later, when the operation is complete, the ->run() or
+     *     ->destruct() function must call ofoperation_complete() to
+     *     report success or failure.
+     *
+     * ->group_construct() should not modify any base members of
+     * struct group.
+     *
+     * Destruction
+     * ===========
+     *
+     * When ->group_destruct() is called, the caller has already removed
+     * 'group' from 'group->ofproto''s group table.  ->group_destruct()
+     * should set in motion removing 'group' from the datapath group table.
+     * If removal completes synchronously, it should call
+     * ofoperation_complete().  Otherwise, the ->run() or ->destruct()
+     * function must later call ofoperation_complete() after the operation
+     * completes.
+     *
+     * Group destruction must not fail. */
+    struct group *(*group_alloc)(void);
+    int (*group_construct)(struct group *group);
+    void (*group_destruct)(struct group *group);
+    void (*group_dealloc)(struct group *group);
+
+    /* Obtains statistics for 'group', storing the number of packets that have
+     * been sent to it in '*packet_count' and the number of bytes in those
+     * packets in '*byte_count'.  UINT64_MAX indicates that the packet count
+     * or byte count is unknown. */
+    void (*group_get_stats)(struct group *group, uint64_t *packet_count,
+                            uint64_t *byte_count);
+
+    /* When ->group_modify() is called, the caller has already replaced
+     * the OpenFlow buckets and type in 'group' by a new set.  (The original
+     * set is in group->pending.)
+     *
+     * ->group_modify() should set the following in motion:
+     *
+     *   - Validate that the buckets now in 'group' are well-formed OpenFlow
+     *     buckets that the datapath can correctly implement.
+     *
+     *   - Update the datapath group table with the new buckets.
+     *
+     * If the operation synchronously completes, ->group_modify() may
+     * call ofoperation_complete() before it returns.  Otherwise, ->run()
+     * should call ofoperation_complete() later, after the operation does
+     * complete.
+     *
+     * If the operation fails, then the base ofproto code will restore the
+     * original 'type,' 'buckets' and 'bucket_size' of 'group'.
+     *
+     * ->group_modify() should not modify any base members of struct
+     * group. */
+    void (*group_modify)(struct group *group);
+
     /* Changes the OpenFlow IP fragment handling policy to 'frag_handling',
      * which takes one of the following values, with the corresponding
      * meanings:


More information about the dev mailing list