ofpbuf: Fix trivial spelling typo.
[cascardo/ovs.git] / ofproto / ofproto-dpif.c
index 8186f6b..b963ff2 100644 (file)
@@ -296,6 +296,10 @@ struct ofproto_dpif {
     struct ofproto up;
     struct dpif_backer *backer;
 
+    /* Unique identifier for this instantiation of this bridge in this running
+     * process.  */
+    struct uuid uuid;
+
     ATOMIC(cls_version_t) tables_version;  /* For classifier lookups. */
 
     uint64_t dump_seq; /* Last read of udpif_dump_seq(). */
@@ -341,9 +345,9 @@ struct ofproto_dpif {
     uint64_t change_seq;           /* Connectivity status changes. */
 
     /* Work queues. */
-    struct guarded_list pins;      /* Contains "struct ofputil_packet_in"s. */
-    struct seq *pins_seq;          /* For notifying 'pins' reception. */
-    uint64_t pins_seqno;
+    struct guarded_list ams;      /* Contains "struct ofproto_async_msgs"s. */
+    struct seq *ams_seq;          /* For notifying 'ams' reception. */
+    uint64_t ams_seqno;
 };
 
 /* All existing ofproto_dpif instances, indexed by ->up.name. */
@@ -400,20 +404,19 @@ ofproto_dpif_flow_mod(struct ofproto_dpif *ofproto,
     ofproto_flow_mod(&ofproto->up, &ofm);
 }
 
-/* Appends 'pin' to the queue of "packet ins" to be sent to the controller.
- * Takes ownership of 'pin' and pin->packet. */
+/* Appends 'am' to the queue of asynchronous messages to be sent to the
+ * controller.  Takes ownership of 'am' and any data it points to. */
 void
-ofproto_dpif_send_packet_in(struct ofproto_dpif *ofproto,
-                            struct ofproto_packet_in *pin)
+ofproto_dpif_send_async_msg(struct ofproto_dpif *ofproto,
+                            struct ofproto_async_msg *am)
 {
-    if (!guarded_list_push_back(&ofproto->pins, &pin->list_node, 1024)) {
+    if (!guarded_list_push_back(&ofproto->ams, &am->list_node, 1024)) {
         COVERAGE_INC(packet_in_overflow);
-        free(CONST_CAST(void *, pin->up.packet));
-        free(pin);
+        ofproto_async_msg_free(am);
     }
 
     /* Wakes up main thread for packet-in I/O. */
-    seq_change(ofproto->pins_seq);
+    seq_change(ofproto->ams_seq);
 }
 
 /* The default "table-miss" behaviour for OpenFlow1.3+ is to drop the
@@ -561,7 +564,7 @@ type_run(const char *type)
         udpif_set_threads(backer->udpif, n_handlers, n_revalidators);
     }
 
-    dpif_poll_threads_set(backer->dpif, n_dpdk_rxqs, pmd_cpu_mask);
+    dpif_poll_threads_set(backer->dpif, pmd_cpu_mask);
 
     if (backer->need_revalidate) {
         struct ofproto_dpif *ofproto;
@@ -1313,6 +1316,7 @@ construct(struct ofproto *ofproto_)
         return error;
     }
 
+    uuid_generate(&ofproto->uuid);
     atomic_init(&ofproto->tables_version, CLS_MIN_VERSION);
     ofproto->netflow = NULL;
     ofproto->sflow = NULL;
@@ -1329,7 +1333,7 @@ construct(struct ofproto *ofproto_)
     ovs_mutex_init_adaptive(&ofproto->stats_mutex);
     ovs_mutex_init(&ofproto->vsp_mutex);
 
-    guarded_list_init(&ofproto->pins);
+    guarded_list_init(&ofproto->ams);
 
     hmap_init(&ofproto->vlandev_map);
     hmap_init(&ofproto->realdev_vid_map);
@@ -1339,8 +1343,8 @@ construct(struct ofproto *ofproto_)
     sset_init(&ofproto->port_poll_set);
     ofproto->port_poll_errno = 0;
     ofproto->change_seq = 0;
-    ofproto->pins_seq = seq_create();
-    ofproto->pins_seqno = seq_read(ofproto->pins_seq);
+    ofproto->ams_seq = seq_create();
+    ofproto->ams_seqno = seq_read(ofproto->ams_seq);
 
 
     SHASH_FOR_EACH_SAFE (node, next, &init_ofp_ports) {
@@ -1406,7 +1410,8 @@ add_internal_flows(struct ofproto_dpif *ofproto)
     controller = ofpact_put_CONTROLLER(&ofpacts);
     controller->max_len = UINT16_MAX;
     controller->controller_id = 0;
-    controller->reason = OFPR_NO_MATCH;
+    controller->reason = OFPR_IMPLICIT_MISS;
+    ofpact_finish(&ofpacts, &controller->ofpact);
 
     error = add_internal_miss_flow(ofproto, id++, &ofpacts,
                                    &ofproto->miss_rule);
@@ -1444,10 +1449,10 @@ static void
 destruct(struct ofproto *ofproto_)
 {
     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
-    struct ofproto_packet_in *pin;
+    struct ofproto_async_msg *am;
     struct rule_dpif *rule;
     struct oftable *table;
-    struct ovs_list pins;
+    struct ovs_list ams;
 
     ofproto->backer->need_revalidate = REV_RECONFIGURE;
     xlate_txn_start();
@@ -1467,12 +1472,11 @@ destruct(struct ofproto *ofproto_)
     }
     ofproto_group_delete_all(&ofproto->up);
 
-    guarded_list_pop_all(&ofproto->pins, &pins);
-    LIST_FOR_EACH_POP (pin, list_node, &pins) {
-        free(CONST_CAST(void *, pin->up.packet));
-        free(pin);
+    guarded_list_pop_all(&ofproto->ams, &ams);
+    LIST_FOR_EACH_POP (am, list_node, &ams) {
+        ofproto_async_msg_free(am);
     }
-    guarded_list_destroy(&ofproto->pins);
+    guarded_list_destroy(&ofproto->ams);
 
     recirc_free_ofproto(ofproto, ofproto->up.name);
 
@@ -1495,7 +1499,7 @@ destruct(struct ofproto *ofproto_)
     ovs_mutex_destroy(&ofproto->stats_mutex);
     ovs_mutex_destroy(&ofproto->vsp_mutex);
 
-    seq_destroy(ofproto->pins_seq);
+    seq_destroy(ofproto->ams_seq);
 
     close_dpif_backer(ofproto->backer);
 }
@@ -1514,23 +1518,22 @@ run(struct ofproto *ofproto_)
         mcast_snooping_mdb_flush(ofproto->ms);
     }
 
-    /* Always updates the ofproto->pins_seqno to avoid frequent wakeup during
+    /* Always updates the ofproto->ams_seqno to avoid frequent wakeup during
      * flow restore.  Even though nothing is processed during flow restore,
-     * all queued 'pins' will be handled immediately when flow restore
+     * all queued 'ams' will be handled immediately when flow restore
      * completes. */
-    ofproto->pins_seqno = seq_read(ofproto->pins_seq);
+    ofproto->ams_seqno = seq_read(ofproto->ams_seq);
 
     /* Do not perform any periodic activity required by 'ofproto' while
      * waiting for flow restore to complete. */
     if (!ofproto_get_flow_restore_wait()) {
-        struct ofproto_packet_in *pin;
-        struct ovs_list pins;
+        struct ofproto_async_msg *am;
+        struct ovs_list ams;
 
-        guarded_list_pop_all(&ofproto->pins, &pins);
-        LIST_FOR_EACH_POP (pin, list_node, &pins) {
-            connmgr_send_packet_in(ofproto->up.connmgr, pin);
-            free(CONST_CAST(void *, pin->up.packet));
-            free(pin);
+        guarded_list_pop_all(&ofproto->ams, &ams);
+        LIST_FOR_EACH_POP (am, list_node, &ams) {
+            connmgr_send_async_msg(ofproto->up.connmgr, am);
+            ofproto_async_msg_free(am);
         }
     }
 
@@ -1641,7 +1644,7 @@ wait(struct ofproto *ofproto_)
     }
 
     seq_wait(udpif_dump_seq(ofproto->backer->udpif), ofproto->dump_seq);
-    seq_wait(ofproto->pins_seq, ofproto->pins_seqno);
+    seq_wait(ofproto->ams_seq, ofproto->ams_seqno);
 }
 
 static void
@@ -1800,7 +1803,7 @@ port_construct(struct ofport *port_)
 }
 
 static void
-port_destruct(struct ofport *port_)
+port_destruct(struct ofport *port_, bool del)
 {
     struct ofport_dpif *port = ofport_dpif_cast(port_);
     struct ofproto_dpif *ofproto = ofproto_dpif_cast(port->up.ofproto);
@@ -1815,7 +1818,7 @@ port_destruct(struct ofport *port_)
 
     dp_port_name = netdev_vport_get_dpif_port(port->up.netdev, namebuf,
                                               sizeof namebuf);
-    if (dpif_port_exists(ofproto->backer->dpif, dp_port_name)) {
+    if (del && dpif_port_exists(ofproto->backer->dpif, dp_port_name)) {
         /* The underlying device is still there, so delete it.  This
          * happens when the ofproto is being destroyed, since the caller
          * assumes that removal of attached ports will happen as part of
@@ -4422,6 +4425,39 @@ packet_out(struct ofproto *ofproto_, struct dp_packet *packet,
                                  ofpacts_len, packet);
     return 0;
 }
+
+static enum ofperr
+nxt_resume(struct ofproto *ofproto_,
+           const struct ofputil_packet_in_private *pin)
+{
+    struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
+
+    /* Translate pin into datapath actions. */
+    uint64_t odp_actions_stub[1024 / 8];
+    struct ofpbuf odp_actions = OFPBUF_STUB_INITIALIZER(odp_actions_stub);
+    enum slow_path_reason slow;
+    enum ofperr error = xlate_resume(ofproto, pin, &odp_actions, &slow);
+
+    /* Steal 'pin->packet' and put it into a dp_packet. */
+    struct dp_packet packet;
+    dp_packet_init(&packet, pin->public.packet_len);
+    dp_packet_put(&packet, pin->public.packet, pin->public.packet_len);
+
+    /* Execute the datapath actions on the packet. */
+    struct dpif_execute execute = {
+        .actions = odp_actions.data,
+        .actions_len = odp_actions.size,
+        .needs_help = (slow & SLOW_ACTION) != 0,
+        .packet = &packet,
+    };
+    dpif_execute(ofproto->backer->dpif, &execute);
+
+    /* Clean up. */
+    ofpbuf_uninit(&odp_actions);
+    dp_packet_uninit(&packet);
+
+    return error;
+}
 \f
 /* NetFlow. */
 
@@ -5716,6 +5752,12 @@ ofproto_dpif_delete_internal_flow(struct ofproto_dpif *ofproto,
     return 0;
 }
 
+const struct uuid *
+ofproto_dpif_get_uuid(const struct ofproto_dpif *ofproto)
+{
+    return &ofproto->uuid;
+}
+
 const struct ofproto_class ofproto_dpif_class = {
     init,
     enumerate_types,
@@ -5763,6 +5805,7 @@ const struct ofproto_class ofproto_dpif_class = {
     rule_execute,
     set_frag_handling,
     packet_out,
+    nxt_resume,
     set_netflow,
     get_netflow_ids,
     set_sflow,