Use enum ofp11_group_type in struct ofgroup
[sliver-openvswitch.git] / ofproto / ofproto-provider.h
index 63d2687..0b8a5e5 100644 (file)
@@ -69,6 +69,7 @@ struct ofproto {
     uint16_t max_ports;         /* Max possible OpenFlow port num, plus one. */
 
     /* Flow tables. */
+    long long int eviction_group_timer; /* For rate limited reheapification. */
     struct oftable *tables;
     int n_tables;
 
@@ -111,6 +112,12 @@ struct ofproto {
     unsigned long int *vlan_bitmap; /* 4096-bit bitmap of in-use VLANs. */
     bool vlans_changed;             /* True if new VLANs are in use. */
     int min_mtu;                    /* Current MTU of non-internal ports. */
+
+    /* Groups. */
+    struct ovs_rwlock groups_rwlock;
+    struct hmap groups OVS_GUARDED;   /* Contains "struct ofgroup"s. */
+    uint32_t n_groups[4] OVS_GUARDED; /* # of existing groups of each type. */
+    struct ofputil_group_features ogf;
 };
 
 void ofproto_init_tables(struct ofproto *, int n_tables);
@@ -216,7 +223,8 @@ struct rule {
 
     struct ofoperation *pending; /* Operation now in progress, if nonnull. */
 
-    ovs_be64 flow_cookie;        /* Controller-issued identifier. */
+    ovs_be64 flow_cookie;        /* Controller-issued identifier. Guarded by
+                                    rwlock. */
     struct hindex_node cookie_node; /* In owning ofproto's 'cookies' index. */
 
     long long int created;       /* Creation time. */
@@ -233,15 +241,18 @@ struct rule {
     struct heap_node evg_node;   /* In eviction_group's "rules" heap. */
     struct eviction_group *eviction_group; /* NULL if not in any group. */
 
-    /* The evict lock is used to prevent rules from being evicted while child
-     * threads are using them to xlate flows.  A read lock means the rule is
-     * currently being used.  A write lock means the rule is in the process of
-     * being evicted and should be considered gone.  A rule will not be evicted
-     * unless both its own and its classifiers write locks are held.
-     * Therefore, while holding a classifier readlock, one can be assured that
-     * even write locked rules are safe. */
-    struct ovs_rwlock evict;
+    /* The rwlock is used to protect those elements in struct rule which are
+     * accessed by multiple threads.  While maintaining a pointer to struct
+     * rule, threads are required to hold a readlock.  The main ofproto code is
+     * guaranteed not to evict the rule, or change any of the elements "Guarded
+     * by rwlock" without holding the writelock.
+     *
+     * A rule will not be evicted unless both its own and its classifier's
+     * write locks are held.  Therefore, while holding a classifier readlock,
+     * one can be assured that write locked rules are safe to reference. */
+    struct ovs_rwlock rwlock;
 
+    /* Guarded by rwlock. */
     struct ofpact *ofpacts;      /* Sequence of "struct ofpacts". */
     unsigned int ofpacts_len;    /* Size of 'ofpacts', in bytes. */
 
@@ -276,7 +287,6 @@ rule_from_cls_rule(const struct cls_rule *cls_rule)
     return cls_rule ? CONTAINER_OF(cls_rule, struct rule, cr) : NULL;
 }
 
-void ofproto_rule_update_used(struct rule *, long long int used);
 void ofproto_rule_expire(struct rule *rule, uint8_t reason);
 void ofproto_rule_delete(struct ofproto *, struct classifier *cls,
                          struct rule *) OVS_REQ_WRLOCK(cls->rwlock);
@@ -289,16 +299,50 @@ bool ofproto_rule_has_out_port(const struct rule *, ofp_port_t out_port);
 void ofoperation_complete(struct ofoperation *, enum ofperr);
 
 bool ofoperation_has_out_port(const struct ofoperation *, ofp_port_t out_port);
+bool ofproto_rule_has_out_group(const struct rule *, uint32_t group_id);
 
 bool ofproto_rule_is_hidden(const struct rule *);
 
+/* A group within a "struct ofproto".
+ *
+ * With few exceptions, ofproto implementations may look at these fields but
+ * should not modify them. */
+struct ofgroup {
+    /* The rwlock is used to prevent groups from being deleted while child
+     * threads are using them to xlate flows.  A read lock means the
+     * group is currently being used.  A write lock means the group is
+     * in the process of being deleted or updated.  Note that since
+     * a read lock on the groups container is held while searching, and
+     * a group is ever write locked only while holding a write lock
+     * on the container, the user's of groups will never face a group
+     * in the write locked state. */
+    struct ovs_rwlock rwlock;
+    struct hmap_node hmap_node; /* In struct ofproto's "groups" hmap. */
+    struct ofproto *ofproto;    /* The ofproto that contains this group. */
+    uint32_t group_id;
+    enum ofp11_group_type type; /* One of OFPGT_*. */
+
+    long long int created;      /* Creation time. */
+    long long int modified;     /* Time of last modification. */
+
+    struct list buckets;        /* Contains "struct ofputil_bucket"s. */
+    uint32_t n_buckets;
+};
+
+bool ofproto_group_lookup(const struct ofproto *ofproto, uint32_t group_id,
+                          struct ofgroup **group)
+    OVS_TRY_RDLOCK(true, (*group)->rwlock);
+
+void ofproto_group_release(struct ofgroup *group)
+    OVS_RELEASES(group->rwlock);
+
 /* ofproto class structure, to be defined by each ofproto implementation.
  *
  *
  * Data Structures
  * ===============
  *
- * These functions work primarily with three different kinds of data
+ * These functions work primarily with four different kinds of data
  * structures:
  *
  *   - "struct ofproto", which represents an OpenFlow switch.
@@ -307,6 +351,9 @@ bool ofproto_rule_is_hidden(const struct rule *);
  *
  *   - "struct rule", which represents an OpenFlow flow within an ofproto.
  *
+ *   - "struct ofgroup", which represents an OpenFlow 1.1+ group within an
+ *     ofproto.
+ *
  * Each of these data structures contains all of the implementation-independent
  * generic state for the respective concept, called the "base" state.  None of
  * them contains any extra space for ofproto implementations to use.  Instead,
@@ -328,9 +375,10 @@ bool ofproto_rule_is_hidden(const struct rule *);
  *   ofproto  ->alloc       ->construct       ->destruct       ->dealloc
  *   ofport   ->port_alloc  ->port_construct  ->port_destruct  ->port_dealloc
  *   rule     ->rule_alloc  ->rule_construct  ->rule_destruct  ->rule_dealloc
+ *   group    ->group_alloc ->group_construct ->group_destruct ->group_dealloc
  *
- * "ofproto" and "ofport" have this exact life cycle.  The "rule" data
- * structure also follow this life cycle with some additional elaborations
+ * "ofproto", "ofport", and "group" have this exact life cycle.  The "rule"
+ * data structure also follow this life cycle with some additional elaborations
  * described under "Rule Life Cycle" below.
  *
  * Any instance of a given data structure goes through the following life
@@ -1072,6 +1120,7 @@ struct ofproto_class {
      * flow->tunnel and flow->in_port, which are assigned the correct values
      * for the incoming packet.  The register values are zeroed.  'packet''s
      * header pointers (e.g. packet->l3) are appropriately initialized.
+     * packet->l3 is aligned on a 32-bit boundary.
      *
      * The implementation should add the statistics for 'packet' into 'rule'.
      *
@@ -1450,6 +1499,21 @@ struct ofproto_class {
     /* Deletes a meter, making the 'ofproto_meter_id' invalid for any
      * further calls. */
     void (*meter_del)(struct ofproto *, ofproto_meter_id);
+
+
+/* ## -------------------- ## */
+/* ## OpenFlow 1.1+ groups ## */
+/* ## -------------------- ## */
+
+    struct ofgroup *(*group_alloc)(void);
+    enum ofperr (*group_construct)(struct ofgroup *);
+    void (*group_destruct)(struct ofgroup *);
+    void (*group_dealloc)(struct ofgroup *);
+
+    enum ofperr (*group_modify)(struct ofgroup *, struct ofgroup *victim);
+
+    enum ofperr (*group_get_stats)(const struct ofgroup *,
+                                   struct ofputil_group_stats *);
 };
 
 extern const struct ofproto_class ofproto_dpif_class;