Eliminate ODPL_* from userspace-facing interface.
[openvswitch] / ofproto / ofproto.c
index dd492258318031ccd3fb78d9cffb317bbb9e624d..5c7a497ecd72a5cd05e5c2d1c8fb3f5ffda8973f 100644 (file)
@@ -301,7 +301,8 @@ struct ofconn {
 
     /* OFPT_PACKET_IN related data. */
     struct rconn_packet_counter *packet_in_counter; /* # queued on 'rconn'. */
-    struct pinsched *schedulers[2]; /* Indexed by reason code; see below. */
+#define N_SCHEDULERS 2
+    struct pinsched *schedulers[N_SCHEDULERS];
     struct pktbuf *pktbuf;         /* OpenFlow packet buffers. */
     int miss_send_len;             /* Bytes to send of buffered packets. */
 
@@ -319,15 +320,6 @@ struct ofconn {
     enum ofproto_band band;      /* In-band or out-of-band? */
 };
 
-/* We use OFPR_NO_MATCH and OFPR_ACTION as indexes into struct ofconn's
- * "schedulers" array.  Their values are 0 and 1, and their meanings and values
- * coincide with _ODPL_MISS_NR and _ODPL_ACTION_NR, so this is convenient.  In
- * case anything ever changes, check their values here.  */
-#define N_SCHEDULERS 2
-BUILD_ASSERT_DECL(OFPR_NO_MATCH == 0);
-BUILD_ASSERT_DECL(OFPR_NO_MATCH == _ODPL_MISS_NR);
-BUILD_ASSERT_DECL(OFPR_ACTION == 1);
-BUILD_ASSERT_DECL(OFPR_ACTION == _ODPL_ACTION_NR);
 
 static struct ofconn *ofconn_create(struct ofproto *, struct rconn *,
                                     enum ofconn_type);
@@ -444,7 +436,10 @@ ofproto_create(const char *datapath, const char *datapath_type,
         VLOG_ERR("failed to open datapath %s: %s", datapath, strerror(error));
         return error;
     }
-    error = dpif_recv_set_mask(dpif, ODPL_MISS | ODPL_ACTION | ODPL_SFLOW);
+    error = dpif_recv_set_mask(dpif,
+                               ((1u << DPIF_UC_MISS) |
+                                (1u << DPIF_UC_ACTION) |
+                                (1u << DPIF_UC_SAMPLE)));
     if (error) {
         VLOG_ERR("failed to listen on datapath %s: %s",
                  datapath, strerror(error));
@@ -2099,7 +2094,7 @@ execute_odp_actions(struct ofproto *ofproto, const struct flow *flow,
          * buffers along the way. */
         struct dpif_upcall upcall;
 
-        upcall.type = _ODPL_ACTION_NR;
+        upcall.type = DPIF_UC_ACTION;
         upcall.packet = packet;
         upcall.key = NULL;
         upcall.key_len = 0;
@@ -2308,17 +2303,24 @@ facet_make_actions(struct ofproto *p, struct facet *facet,
 
 static int
 facet_put__(struct ofproto *ofproto, struct facet *facet,
-            enum dpif_flow_put_flags flags)
+            const struct nlattr *actions, size_t actions_len,
+            struct dpif_flow_stats *stats)
 {
     uint32_t keybuf[ODPUTIL_FLOW_KEY_U32S];
+    enum dpif_flow_put_flags flags;
     struct ofpbuf key;
 
+    flags = DPIF_FP_CREATE | DPIF_FP_MODIFY;
+    if (stats) {
+        flags |= DPIF_FP_ZERO_STATS;
+    }
+
     ofpbuf_use_stack(&key, keybuf, sizeof keybuf);
     odp_flow_key_from_flow(&key, &facet->flow);
     assert(key.base == keybuf);
 
     return dpif_flow_put(ofproto->dpif, flags, key.data, key.size,
-                         facet->actions, facet->actions_len, NULL);
+                         actions, actions_len, stats);
 }
 
 /* If 'facet' is installable, inserts or re-inserts it into 'p''s datapath.  If
@@ -2327,14 +2329,12 @@ facet_put__(struct ofproto *ofproto, struct facet *facet,
 static void
 facet_install(struct ofproto *p, struct facet *facet, bool zero_stats)
 {
-    if (facet->may_install) {
-        enum dpif_flow_put_flags flags = DPIF_FP_CREATE | DPIF_FP_MODIFY;
-        if (zero_stats) {
-            flags |= DPIF_FP_ZERO_STATS;
-        }
-        if (!facet_put__(p, facet, flags)) {
-            facet->installed = true;
-        }
+    struct dpif_flow_stats stats;
+
+    if (facet->may_install
+        && !facet_put__(p, facet, facet->actions, facet->actions_len,
+                        zero_stats ? &stats : NULL)) {
+        facet->installed = true;
     }
 }
 
@@ -2501,18 +2501,10 @@ facet_revalidate(struct ofproto *ofproto, struct facet *facet)
      * to talk to the datapath. */
     if (actions_changed || ctx.may_set_up_flow != facet->installed) {
         if (ctx.may_set_up_flow) {
-            uint32_t keybuf[ODPUTIL_FLOW_KEY_U32S];
             struct dpif_flow_stats stats;
-            struct ofpbuf key;
-
-            ofpbuf_use_stack(&key, keybuf, sizeof keybuf);
-            odp_flow_key_from_flow(&key, &facet->flow);
-
-            dpif_flow_put(ofproto->dpif,
-                          DPIF_FP_CREATE | DPIF_FP_MODIFY | DPIF_FP_ZERO_STATS,
-                          key.data, key.size,
-                          odp_actions->data, odp_actions->size, &stats);
 
+            facet_put__(ofproto, facet,
+                        odp_actions->data, odp_actions->size, &stats);
             facet_update_stats(ofproto, facet, &stats);
         } else {
             facet_uninstall(ofproto, facet);
@@ -3482,7 +3474,7 @@ query_stats(struct ofproto *p, struct rule *rule,
 
         ofpbuf_clear(&key);
         odp_flow_key_from_flow(&key, &facet->flow);
-        dpif_flow_get(p->dpif, 0, key.data, key.size, NULL, &stats);
+        dpif_flow_get(p->dpif, key.data, key.size, NULL, &stats);
 
         packet_count += stats.n_packets + facet->packet_count;
         byte_count += stats.n_bytes + facet->byte_count;
@@ -4442,13 +4434,13 @@ handle_upcall(struct ofproto *p, struct dpif_upcall *upcall)
     struct flow flow;
 
     switch (upcall->type) {
-    case _ODPL_ACTION_NR:
+    case DPIF_UC_ACTION:
         COVERAGE_INC(ofproto_ctlr_action);
         odp_flow_key_to_flow(upcall->key, upcall->key_len, &flow);
         send_packet_in(p, upcall, &flow, false);
         break;
 
-    case _ODPL_SFLOW_NR:
+    case DPIF_UC_SAMPLE:
         if (p->sflow) {
             odp_flow_key_to_flow(upcall->key, upcall->key_len, &flow);
             ofproto_sflow_received(p->sflow, upcall, &flow);
@@ -4456,7 +4448,7 @@ handle_upcall(struct ofproto *p, struct dpif_upcall *upcall)
         ofpbuf_delete(upcall->packet);
         break;
 
-    case _ODPL_MISS_NR:
+    case DPIF_UC_MISS:
         handle_miss_upcall(p, upcall);
         break;
 
@@ -4647,36 +4639,18 @@ facet_active_timeout(struct ofproto *ofproto, struct facet *facet)
         netflow_active_timeout_expired(ofproto->netflow, &facet->nf_flow)) {
         struct ofexpired expired;
 
-        expired.flow = facet->flow;
-        expired.packet_count = facet->packet_count;
-        expired.byte_count = facet->byte_count;
-        expired.used = facet->used;
-
-        /* Get updated flow stats.
-         *
-         * XXX We could avoid this call entirely if (1) ofproto_update_used()
-         * updated TCP flags and (2) the dpif_flow_list_all() in
-         * ofproto_update_used() zeroed TCP flags. */
         if (facet->installed) {
-            uint32_t keybuf[ODPUTIL_FLOW_KEY_U32S];
             struct dpif_flow_stats stats;
-            struct ofpbuf key;
-
-            ofpbuf_use_stack(&key, keybuf, sizeof keybuf);
-            odp_flow_key_from_flow(&key, &facet->flow);
-
-            if (!dpif_flow_get(ofproto->dpif, ODPFF_ZERO_TCP_FLAGS,
-                               key.data, key.size, NULL, &stats)) {
-                expired.packet_count += stats.n_packets;
-                expired.byte_count += stats.n_bytes;
-                if (stats.n_packets) {
-                    facet_update_time(ofproto, facet, &stats);
-                    netflow_flow_update_flags(&facet->nf_flow,
-                                              stats.tcp_flags);
-                }
-            }
+
+            facet_put__(ofproto, facet, facet->actions, facet->actions_len,
+                        &stats);
+            facet_update_stats(ofproto, facet, &stats);
         }
 
+        expired.flow = facet->flow;
+        expired.packet_count = facet->packet_count;
+        expired.byte_count = facet->byte_count;
+        expired.used = facet->used;
         netflow_expire(ofproto->netflow, &facet->nf_flow, &expired);
     }
 }
@@ -4830,9 +4804,10 @@ schedule_packet_in(struct ofconn *ofconn, struct dpif_upcall *upcall,
     int total_len, send_len;
     struct ofpbuf *packet;
     uint32_t buffer_id;
+    int idx;
 
     /* Get OpenFlow buffer_id. */
-    if (upcall->type == _ODPL_ACTION_NR) {
+    if (upcall->type == DPIF_UC_ACTION) {
         buffer_id = UINT32_MAX;
     } else if (ofproto->fail_open && fail_open_is_active(ofproto->fail_open)) {
         buffer_id = pktbuf_get_null();
@@ -4847,7 +4822,7 @@ schedule_packet_in(struct ofconn *ofconn, struct dpif_upcall *upcall,
     if (buffer_id != UINT32_MAX) {
         send_len = MIN(send_len, ofconn->miss_send_len);
     }
-    if (upcall->type == _ODPL_ACTION_NR) {
+    if (upcall->type == DPIF_UC_ACTION) {
         send_len = MIN(send_len, upcall->userdata);
     }
 
@@ -4866,18 +4841,19 @@ schedule_packet_in(struct ofconn *ofconn, struct dpif_upcall *upcall,
     opi->header.type = OFPT_PACKET_IN;
     opi->total_len = htons(total_len);
     opi->in_port = htons(odp_port_to_ofp_port(flow->in_port));
-    opi->reason = upcall->type == _ODPL_MISS_NR ? OFPR_NO_MATCH : OFPR_ACTION;
+    opi->reason = upcall->type == DPIF_UC_MISS ? OFPR_NO_MATCH : OFPR_ACTION;
     opi->buffer_id = htonl(buffer_id);
     update_openflow_length(packet);
 
     /* Hand over to packet scheduler.  It might immediately call into
      * do_send_packet_in() or it might buffer it for a while (until a later
      * call to pinsched_run()). */
-    pinsched_send(ofconn->schedulers[opi->reason], flow->in_port,
+    idx = upcall->type == DPIF_UC_MISS ? 0 : 1;
+    pinsched_send(ofconn->schedulers[idx], flow->in_port,
                   packet, do_send_packet_in, ofconn);
 }
 
-/* Given 'upcall', of type _ODPL_ACTION_NR or _ODPL_MISS_NR, sends an
+/* Given 'upcall', of type DPIF_UC_ACTION or DPIF_UC_MISS, sends an
  * OFPT_PACKET_IN message to each OpenFlow controller as necessary according to
  * their individual configurations.
  *