Avoid printf type modifiers not supported by MSVC C runtime library.
[cascardo/ovs.git] / ofproto / ofproto-dpif-upcall.c
index 4c92db3..dde6430 100644 (file)
@@ -19,6 +19,7 @@
 #include <stdbool.h>
 #include <inttypes.h>
 
+#include "connmgr.h"
 #include "coverage.h"
 #include "dynamic-string.h"
 #include "dpif.h"
@@ -31,7 +32,6 @@
 #include "ofpbuf.h"
 #include "ofproto-dpif-ipfix.h"
 #include "ofproto-dpif-sflow.h"
-#include "ofproto-dpif.h"
 #include "packets.h"
 #include "poll-loop.h"
 #include "vlog.h"
@@ -59,6 +59,7 @@ struct handler {
     size_t n_upcalls OVS_GUARDED;
 
     size_t n_new_upcalls;              /* Only changed by the dispatcher. */
+    bool need_signal;                  /* Only changed by the dispatcher. */
 
     pthread_cond_t wake_cond;          /* Wakes 'thread' while holding
                                           'mutex'. */
@@ -222,6 +223,7 @@ udpif_recv_set(struct udpif *udpif, size_t n_handlers, bool enable)
 
             handler->udpif = udpif;
             list_init(&handler->upcalls);
+            handler->need_signal = false;
             xpthread_cond_init(&handler->wake_cond, NULL);
             ovs_mutex_init(&handler->mutex);
             xpthread_create(&handler->thread, NULL, udpif_upcall_handler,
@@ -392,7 +394,7 @@ udpif_upcall_handler(void *arg)
 {
     struct handler *handler = arg;
 
-    set_subprogram_name("upcall_handler");
+    set_subprogram_name("upcall_%u", ovsthread_id_self());
     for (;;) {
         struct list misses = LIST_INITIALIZER(&misses);
         size_t i;
@@ -419,6 +421,8 @@ udpif_upcall_handler(void *arg)
         ovs_mutex_unlock(&handler->mutex);
 
         handle_upcalls(handler->udpif, &misses);
+
+        coverage_clear();
     }
 }
 \f
@@ -458,7 +462,7 @@ classify_upcall(const struct upcall *upcall)
     userdata_len = nl_attr_get_size(dpif_upcall->userdata);
     if (userdata_len < sizeof cookie.type
         || userdata_len > sizeof cookie) {
-        VLOG_WARN_RL(&rl, "action upcall cookie has unexpected size %zu",
+        VLOG_WARN_RL(&rl, "action upcall cookie has unexpected size %"PRIuSIZE,
                      userdata_len);
         return BAD_UPCALL;
     }
@@ -478,7 +482,7 @@ classify_upcall(const struct upcall *upcall)
         return IPFIX_UPCALL;
     } else {
         VLOG_WARN_RL(&rl, "invalid user cookie of type %"PRIu16
-                     " and size %zu", cookie.type, userdata_len);
+                     " and size %"PRIuSIZE, cookie.type, userdata_len);
         return BAD_UPCALL;
     }
 }
@@ -486,7 +490,6 @@ classify_upcall(const struct upcall *upcall)
 static void
 recv_upcalls(struct udpif *udpif)
 {
-    size_t n_udpif_new_upcalls = 0;
     int n;
 
     for (;;) {
@@ -515,7 +518,7 @@ recv_upcalls(struct udpif *udpif)
                 || type == OVS_KEY_ATTR_TCP
                 || type == OVS_KEY_ATTR_UDP) {
                 if (nl_attr_get_size(nla) == 4) {
-                    hash = mhash_add(hash, nl_attr_get_be32(nla));
+                    hash = mhash_add(hash, nl_attr_get_u32(nla));
                     n_bytes += 4;
                 } else {
                     VLOG_WARN_RL(&rl,
@@ -530,9 +533,13 @@ recv_upcalls(struct udpif *udpif)
         ovs_mutex_lock(&handler->mutex);
         if (handler->n_upcalls < MAX_QUEUE_LENGTH) {
             list_push_back(&handler->upcalls, &upcall->list_node);
-            handler->n_new_upcalls = ++handler->n_upcalls;
-
-            if (handler->n_new_upcalls >= FLOW_MISS_MAX_BATCH) {
+            if (handler->n_upcalls == 0) {
+                handler->need_signal = true;
+            }
+            handler->n_upcalls++;
+            if (handler->need_signal &&
+                handler->n_upcalls >= FLOW_MISS_MAX_BATCH) {
+                handler->need_signal = false;
                 xpthread_cond_signal(&handler->wake_cond);
             }
             ovs_mutex_unlock(&handler->mutex);
@@ -555,16 +562,13 @@ recv_upcalls(struct udpif *udpif)
     for (n = 0; n < udpif->n_handlers; ++n) {
         struct handler *handler = &udpif->handlers[n];
 
-        if (handler->n_new_upcalls) {
-            handler->n_new_upcalls = 0;
+        if (handler->need_signal) {
+            handler->need_signal = false;
             ovs_mutex_lock(&handler->mutex);
             xpthread_cond_signal(&handler->wake_cond);
             ovs_mutex_unlock(&handler->mutex);
         }
     }
-    if (n_udpif_new_upcalls) {
-        seq_change(udpif->wait_seq);
-    }
 }
 
 static struct flow_miss *
@@ -757,23 +761,14 @@ handle_upcalls(struct udpif *udpif, struct list *upcalls)
      * all the packets in each miss. */
     fail_open = false;
     HMAP_FOR_EACH (miss, hmap_node, &fmb->misses) {
-        struct flow_wildcards wc;
-        struct rule_dpif *rule;
         struct xlate_in xin;
 
-        flow_wildcards_init_catchall(&wc);
-        rule_dpif_lookup(miss->ofproto, &miss->flow, &wc, &rule);
-        if (rule_dpif_fail_open(rule)) {
-            fail_open = true;
-        }
-        rule_dpif_credit_stats(rule, &miss->stats);
-        xlate_in_init(&xin, miss->ofproto, &miss->flow, rule,
+        xlate_in_init(&xin, miss->ofproto, &miss->flow, NULL,
                       miss->stats.tcp_flags, NULL);
         xin.may_learn = true;
         xin.resubmit_stats = &miss->stats;
         xlate_actions(&xin, &miss->xout);
-        flow_wildcards_or(&miss->xout.wc, &miss->xout.wc, &wc);
-        rule_dpif_unref(rule);
+        fail_open = fail_open || miss->xout.fail_open;
     }
 
     /* Now handle the packets individually in order of arrival.  In the common
@@ -794,13 +789,10 @@ handle_upcalls(struct udpif *udpif, struct list *upcalls)
         struct ofpbuf *packet = upcall->dpif_upcall.packet;
 
         if (miss->xout.slow) {
-            struct rule_dpif *rule;
             struct xlate_in xin;
 
-            rule_dpif_lookup(miss->ofproto, &miss->flow, NULL, &rule);
-            xlate_in_init(&xin, miss->ofproto, &miss->flow, rule, 0, packet);
+            xlate_in_init(&xin, miss->ofproto, &miss->flow, NULL, 0, packet);
             xlate_actions_for_side_effects(&xin);
-            rule_dpif_unref(rule);
         }
 
         if (miss->xout.odp_actions.size) {
@@ -826,6 +818,7 @@ handle_upcalls(struct udpif *udpif, struct list *upcalls)
             op->u.execute.packet = packet;
             op->u.execute.actions = miss->xout.odp_actions.data;
             op->u.execute.actions_len = miss->xout.odp_actions.size;
+            op->u.execute.needs_help = (miss->xout.slow & SLOW_ACTION) != 0;
         }
     }
 
@@ -846,17 +839,17 @@ handle_upcalls(struct udpif *udpif, struct list *upcalls)
         LIST_FOR_EACH (upcall, list_node, upcalls) {
             struct flow_miss *miss = upcall->flow_miss;
             struct ofpbuf *packet = upcall->dpif_upcall.packet;
-            struct ofputil_packet_in *pin;
+            struct ofproto_packet_in *pin;
 
             pin = xmalloc(sizeof *pin);
-            pin->packet = xmemdup(packet->data, packet->size);
-            pin->packet_len = packet->size;
-            pin->reason = OFPR_NO_MATCH;
-            pin->controller_id = 0;
-            pin->table_id = 0;
-            pin->cookie = 0;
+            pin->up.packet = xmemdup(packet->data, packet->size);
+            pin->up.packet_len = packet->size;
+            pin->up.reason = OFPR_NO_MATCH;
+            pin->up.table_id = 0;
+            pin->up.cookie = OVS_BE64_MAX;
+            flow_get_metadata(&miss->flow, &pin->up.fmd);
             pin->send_len = 0; /* Not used for flow table misses. */
-            flow_get_metadata(&miss->flow, &pin->fmd);
+            pin->generated_by_table_miss = false;
             ofproto_dpif_send_packet_in(miss->ofproto, pin);
         }
     }