ofproto: Inline actions in struct rule_actions.
[sliver-openvswitch.git] / ofproto / ofproto-provider.h
index 2844e4c..9431be8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
+ * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 #include "heap.h"
 #include "hindex.h"
 #include "list.h"
+#include "ofp-actions.h"
 #include "ofp-errors.h"
 #include "ofp-util.h"
 #include "ofproto/ofproto.h"
 #include "ovs-atomic.h"
+#include "ovs-rcu.h"
 #include "ovs-thread.h"
 #include "shash.h"
 #include "simap.h"
 #include "timeval.h"
 
 struct match;
-struct ofpact;
 struct ofputil_flow_mod;
 struct bfd_cfg;
 struct meter;
@@ -85,6 +86,7 @@ struct ofproto {
     uint16_t alloc_port_no;     /* Last allocated OpenFlow port number. */
     uint16_t max_ports;         /* Max possible OpenFlow port num, plus one. */
     struct hmap ofport_usage;   /* Map ofport to last used time. */
+    uint64_t change_seq;        /* Change sequence for netdev status. */
 
     /* Flow tables. */
     long long int eviction_group_timer; /* For rate limited reheapification. */
@@ -161,6 +163,8 @@ struct ofproto *ofproto_lookup(const char *name);
 struct ofport *ofproto_get_port(const struct ofproto *, ofp_port_t ofp_port);
 
 /* An OpenFlow port within a "struct ofproto".
+ *
+ * The port's name is netdev_get_name(port->netdev).
  *
  * With few exceptions, ofproto implementations may look at these fields but
  * should not modify them. */
@@ -170,7 +174,7 @@ struct ofport {
     struct netdev *netdev;
     struct ofputil_phy_port pp;
     ofp_port_t ofp_port;        /* OpenFlow port number. */
-    unsigned int change_seq;
+    uint64_t change_seq;
     long long int created;      /* Time created, in msec. */
     int mtu;
 };
@@ -202,7 +206,8 @@ void ofproto_port_set_state(struct ofport *, enum ofputil_port_state);
  */
 enum oftable_flags {
     OFTABLE_HIDDEN = 1 << 0,   /* Hide from most OpenFlow operations. */
-    OFTABLE_READONLY = 1 << 1  /* Don't allow OpenFlow to change this table. */
+    OFTABLE_READONLY = 1 << 1  /* Don't allow OpenFlow controller to change
+                                  this table. */
 };
 
 /* A flow table within a "struct ofproto".
@@ -258,6 +263,9 @@ struct oftable {
     uint32_t eviction_group_id_basis;
     struct hmap eviction_groups_by_id;
     struct heap eviction_groups_by_size;
+
+    /* Table config: contains enum ofproto_table_config; accessed atomically. */
+    atomic_uint config;
 };
 
 /* Assigns TABLE to each oftable, in turn, in OFPROTO.
@@ -334,14 +342,16 @@ struct rule {
 
     /* Protects members marked OVS_GUARDED.
      * Readers only need to hold this mutex.
-     * Writers must hold both this mutex AND ofproto_mutex. */
+     * Writers must hold both this mutex AND ofproto_mutex.
+     * By implication writers can read *without* taking this mutex while they
+     * hold ofproto_mutex. */
     struct ovs_mutex mutex OVS_ACQ_AFTER(ofproto_mutex);
 
     /* Number of references.
      * The classifier owns one reference.
      * Any thread trying to keep a rule from being freed should hold its own
      * reference. */
-    atomic_uint ref_count;
+    struct ovs_refcount ref_count;
 
     /* Operation now in progress, if nonnull. */
     struct ofoperation *pending OVS_GUARDED_BY(ofproto_mutex);
@@ -351,10 +361,6 @@ struct rule {
     ovs_be64 flow_cookie OVS_GUARDED;
     struct hindex_node cookie_node OVS_GUARDED_BY(ofproto_mutex);
 
-    /* Times. */
-    long long int created OVS_GUARDED; /* Creation time. */
-    long long int modified OVS_GUARDED; /* Time of last modification. */
-    long long int used OVS_GUARDED; /* Last use; time created if never used. */
     enum ofputil_flow_mod_flags flags OVS_GUARDED;
 
     /* Timeouts. */
@@ -371,7 +377,7 @@ struct rule {
 
     /* OpenFlow actions.  See struct rule_actions for more thread-safety
      * notes. */
-    struct rule_actions *actions OVS_GUARDED;
+    OVSRCU_TYPE(const struct rule_actions *) actions;
 
     /* In owning meter's 'rules' list.  An empty list if there is no meter. */
     struct list meter_list_node OVS_GUARDED_BY(ofproto_mutex);
@@ -388,15 +394,23 @@ struct rule {
     /* Optimisation for flow expiry.  In ofproto's 'expirable' list if this
      * rule is expirable, otherwise empty. */
     struct list expirable OVS_GUARDED_BY(ofproto_mutex);
+
+    /* Times.  Last so that they are more likely close to the stats managed
+     * by the provider. */
+    long long int created OVS_GUARDED; /* Creation time. */
+
+    /* Must hold 'mutex' for both read/write, 'ofproto_mutex' not needed. */
+    long long int modified OVS_GUARDED; /* Time of last modification. */
 };
 
 void ofproto_rule_ref(struct rule *);
 void ofproto_rule_unref(struct rule *);
 
-struct rule_actions *rule_get_actions(const struct rule *rule)
-    OVS_EXCLUDED(rule->mutex);
-struct rule_actions *rule_get_actions__(const struct rule *rule)
-    OVS_REQUIRES(rule->mutex);
+static inline const struct rule_actions *
+rule_get_actions(const struct rule *rule)
+{
+    return ovsrcu_get(const struct rule_actions *, &rule->actions);
+}
 
 /* Returns true if 'rule' is an OpenFlow 1.3 "table-miss" rule, false
  * otherwise.
@@ -409,6 +423,7 @@ rule_is_table_miss(const struct rule *rule)
 {
     return rule->cr.priority == 0 && cls_rule_is_catchall(&rule->cr);
 }
+bool rule_is_internal(const struct rule *);
 
 /* A set of actions within a "struct rule".
  *
@@ -416,24 +431,22 @@ rule_is_table_miss(const struct rule *rule)
  * Thread-safety
  * =============
  *
- * A struct rule_actions 'actions' may be accessed without a risk of being
+ * A struct rule_actions may be accessed without a risk of being
  * freed by code that holds a read-lock or write-lock on 'rule->mutex' (where
- * 'rule' is the rule for which 'rule->actions == actions') or that owns a
- * reference to 'actions->ref_count' (or both). */
+ * 'rule' is the rule for which 'rule->actions == actions') or during the RCU
+ * active period. */
 struct rule_actions {
-    atomic_uint ref_count;
-
     /* These members are immutable: they do not change during the struct's
      * lifetime.  */
-    struct ofpact *ofpacts;     /* Sequence of "struct ofpacts". */
-    unsigned int ofpacts_len;   /* Size of 'ofpacts', in bytes. */
-    uint32_t provider_meter_id; /* Datapath meter_id, or UINT32_MAX. */
+    uint32_t ofpacts_len;         /* Size of 'ofpacts', in bytes. */
+    uint32_t provider_meter_id;   /* Datapath meter_id, or UINT32_MAX. */
+    struct ofpact ofpacts[];      /* Sequence of "struct ofpacts". */
 };
+BUILD_ASSERT_DECL(offsetof(struct rule_actions, ofpacts) % OFPACT_ALIGNTO == 0);
 
-struct rule_actions *rule_actions_create(const struct ofproto *,
-                                         const struct ofpact *, size_t);
-void rule_actions_ref(struct rule_actions *);
-void rule_actions_unref(struct rule_actions *);
+const struct rule_actions *rule_actions_create(const struct ofproto *,
+                                               const struct ofpact *, size_t);
+void rule_actions_destroy(const struct rule_actions *);
 
 /* A set of rules to which an OpenFlow operation applies. */
 struct rule_collection {
@@ -450,17 +463,18 @@ void rule_collection_ref(struct rule_collection *) OVS_REQUIRES(ofproto_mutex);
 void rule_collection_unref(struct rule_collection *);
 void rule_collection_destroy(struct rule_collection *);
 
-/* Threshold at which to begin flow table eviction. Only affects the
- * ofproto-dpif implementation */
-extern unsigned flow_eviction_threshold;
+/* Limits the number of flows allowed in the datapath. Only affects the
+ * ofproto-dpif implementation. */
+extern unsigned ofproto_flow_limit;
 
-/* Number of upcall handler threads. Only affects the ofproto-dpif
- * implementation. */
-extern unsigned n_handler_threads;
+/* Maximum idle time (in ms) for flows to be cached in the datapath.
+ * Revalidators may expire flows more quickly than the configured value based
+ * on system load and other factors. This variable is subject to change. */
+extern unsigned ofproto_max_idle;
 
-/* Determines which model to use for handling misses in the ofproto-dpif
- * implementation */
-extern enum ofproto_flow_miss_model flow_miss_model;
+/* Number of upcall handler and revalidator threads. Only affects the
+ * ofproto-dpif implementation. */
+extern size_t n_handlers, n_revalidators;
 
 static inline struct rule *
 rule_from_cls_rule(const struct cls_rule *cls_rule)
@@ -686,16 +700,6 @@ struct ofproto_class {
      * Returns 0 if successful, otherwise a positive errno value. */
     int (*type_run)(const char *type);
 
-    /* Performs periodic activity required on ofprotos of type 'type'
-     * that needs to be done with the least possible latency.
-     *
-     * This is run multiple times per main loop.  An ofproto provider may
-     * implement it or not, according to whether it provides a performance
-     * boost for that ofproto implementation.
-     *
-     * Returns 0 if successful, otherwise a positive errno value. */
-    int (*type_run_fast)(const char *type);
-
     /* Causes the poll loop to wake up when a type 'type''s 'run'
      * function needs to be called, e.g. by calling the timer or fd
      * waiting functions in poll-loop.h.
@@ -779,14 +783,6 @@ struct ofproto_class {
      * Returns 0 if successful, otherwise a positive errno value. */
     int (*run)(struct ofproto *ofproto);
 
-    /* Performs periodic activity required by 'ofproto' that needs to be done
-     * with the least possible latency.
-     *
-     * This is run multiple times per main loop.  An ofproto provider may
-     * implement it or not, according to whether it provides a performance
-     * boost for that ofproto implementation. */
-    int (*run_fast)(struct ofproto *ofproto);
-
     /* Causes the poll loop to wake up when 'ofproto''s 'run' function needs to
      * be called, e.g. by calling the timer or fd waiting functions in
      * poll-loop.h.  */
@@ -799,6 +795,12 @@ struct ofproto_class {
     void (*get_memory_usage)(const struct ofproto *ofproto,
                              struct simap *usage);
 
+    /* Adds some memory usage statistics for the implementation of 'type'
+     * into 'usage', for use with memory_report().
+     *
+     * This function is optional. */
+    void (*type_get_memory_usage)(const char *type, struct simap *usage);
+
     /* Every "struct rule" in 'ofproto' is about to be deleted, one by one.
      * This function may prepare for that, for example by clearing state in
      * advance.  It should *not* actually delete any "struct rule"s from
@@ -836,7 +838,7 @@ struct ofproto_class {
      *
      *   - 'write_setfields' and 'apply_setfields' to OFPXMT12_MASK.
      *
-     *   - 'metadata_match' and 'metadata_write' to UINT64_MAX.
+     *   - 'metadata_match' and 'metadata_write' to OVS_BE64_MAX.
      *
      *   - 'instructions' to OFPIT11_ALL.
      *
@@ -943,8 +945,9 @@ struct ofproto_class {
     void (*port_reconfigured)(struct ofport *ofport,
                               enum ofputil_port_config old_config);
 
-    /* Looks up a port named 'devname' in 'ofproto'.  On success, initializes
-     * '*port' appropriately.
+    /* Looks up a port named 'devname' in 'ofproto'.  On success, returns 0 and
+     * initializes '*port' appropriately. Otherwise, returns a positive errno
+     * value.
      *
      * The caller owns the data in 'port' and must free it with
      * ofproto_port_destroy() when it is no longer needed. */
@@ -1286,7 +1289,7 @@ struct ofproto_class {
      * in '*byte_count'.  UINT64_MAX indicates that the packet count or byte
      * count is unknown. */
     void (*rule_get_stats)(struct rule *rule, uint64_t *packet_count,
-                           uint64_t *byte_count)
+                           uint64_t *byte_count, long long int *used)
         /* OVS_EXCLUDED(ofproto_mutex) */;
 
     /* Applies the actions in 'rule' to 'packet'.  (This implements sending
@@ -1299,8 +1302,8 @@ struct ofproto_class {
      * information in 'flow' is extracted from 'packet', except for
      * 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.
+     * header pointers and offsets (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'.
      *
@@ -1458,15 +1461,19 @@ struct ofproto_class {
      * support CFM, as does a null pointer. */
     int (*set_cfm)(struct ofport *ofport, const struct cfm_settings *s);
 
-    /* Checks the status of CFM configured on 'ofport'.  Returns true if the
-     * port's CFM status was successfully stored into '*status'.  Returns false
-     * if the port did not have CFM configured, in which case '*status' is
-     * indeterminate.
+    /* Checks the status of CFM configured on 'ofport'.  Returns 0 if the
+     * port's CFM status was successfully stored into '*status'.  Returns
+     * negative number if there is no status change since last update.
+     * Returns positive errno otherwise.
      *
-     * The caller must provide and owns '*status', but it does not own and must
-     * not modify or free the array returned in 'status->rmps'. */
-    bool (*get_cfm_status)(const struct ofport *ofport,
-                           struct ofproto_cfm_status *status);
+     * EOPNOTSUPP as a return value indicates that this ofproto_class does not
+     * support CFM, as does a null pointer.
+     *
+     * The caller must provide and own '*status', and it must free the array
+     * returned in 'status->rmps'.  '*status' is indeterminate if the return
+     * value is non-zero. */
+    int (*get_cfm_status)(const struct ofport *ofport,
+                          struct ofproto_cfm_status *status);
 
     /* Configures BFD on 'ofport'.
      *
@@ -1479,8 +1486,11 @@ struct ofproto_class {
     int (*set_bfd)(struct ofport *ofport, const struct smap *cfg);
 
     /* Populates 'smap' with the status of BFD on 'ofport'.  Returns 0 on
-     * success, or a positive errno.  EOPNOTSUPP as a return value indicates
-     * that this ofproto_class does not support BFD, as does a null pointer. */
+     * success.  Returns a negative number if there is no status change since
+     * last update.  Returns a positive errno otherwise.
+     *
+     * EOPNOTSUPP as a return value indicates that this ofproto_class does not
+     * support BFD, as does a null pointer. */
     int (*get_bfd_status)(struct ofport *ofport, struct smap *smap);
 
     /* Configures spanning tree protocol (STP) on 'ofproto' using the
@@ -1530,6 +1540,16 @@ struct ofproto_class {
     int (*get_stp_port_status)(struct ofport *ofport,
                                struct ofproto_port_stp_status *s);
 
+    /* Retrieves spanning tree protocol (STP) port statistics of 'ofport'.
+     *
+     * Stores STP state for 'ofport' in 's'.  If the 'enabled' member is
+     * false, the other member values are not meaningful.
+     *
+     * EOPNOTSUPP as a return value indicates that this ofproto_class does not
+     * support STP, as does a null pointer. */
+    int (*get_stp_port_stats)(struct ofport *ofport,
+                              struct ofproto_port_stp_stats *s);
+
     /* Registers meta-data associated with the 'n_qdscp' Qualities of Service
      * 'queues' attached to 'ofport'.  This data is not intended to be
      * sufficient to implement QoS.  Instead, providers may use this
@@ -1715,6 +1735,8 @@ BUILD_ASSERT_DECL(OFPROTO_POSTPONE < OFPERR_OFS);
 
 int ofproto_flow_mod(struct ofproto *, struct ofputil_flow_mod *)
     OVS_EXCLUDED(ofproto_mutex);
+struct rule *ofproto_refresh_rule(struct rule *rule)
+    OVS_EXCLUDED(ofproto_mutex);
 void ofproto_add_flow(struct ofproto *, const struct match *,
                       unsigned int priority,
                       const struct ofpact *ofpacts, size_t ofpacts_len)