Replace all uses of strerror() by ovs_strerror(), for thread safety.
[sliver-openvswitch.git] / ofproto / ofproto-dpif.c
index 87b44f2..5ca16b7 100644 (file)
@@ -571,7 +571,7 @@ type_run(const char *type)
                 char namebuf[NETDEV_VPORT_NAME_BUFSIZE];
                 const char *dp_port;
 
-                if (!iter->tnl_port) {
+                if (!iter->is_tunnel) {
                     continue;
                 }
 
@@ -597,8 +597,8 @@ type_run(const char *type)
                 }
 
                 iter->odp_port = node ? u32_to_odp(node->data) : ODPP_NONE;
-                if (tnl_port_reconfigure(&iter->up, iter->odp_port,
-                                         &iter->tnl_port)) {
+                if (tnl_port_reconfigure(iter, iter->up.netdev,
+                                         iter->odp_port)) {
                     backer->need_revalidate = REV_RECONFIGURE;
                 }
             }
@@ -932,7 +932,7 @@ open_dpif_backer(const char *type, struct dpif_backer **backerp)
     free(backer_name);
     if (error) {
         VLOG_ERR("failed to open datapath of type %s: %s", type,
-                 strerror(error));
+                 ovs_strerror(error));
         free(backer);
         return error;
     }
@@ -979,7 +979,7 @@ open_dpif_backer(const char *type, struct dpif_backer **backerp)
     error = dpif_recv_set(backer->dpif, backer->recv_set_enable);
     if (error) {
         VLOG_ERR("failed to listen on datapath of type %s: %s",
-                 type, strerror(error));
+                 type, ovs_strerror(error));
         close_dpif_backer(backer);
         return error;
     }
@@ -1045,8 +1045,6 @@ construct(struct ofproto *ofproto_)
     ofproto_dpif_unixctl_init();
 
     ofproto->has_mirrors = false;
-    ofproto->has_bundle_action = false;
-
     hmap_init(&ofproto->vlandev_map);
     hmap_init(&ofproto->realdev_vid_map);
 
@@ -1195,9 +1193,9 @@ destruct(struct ofproto *ofproto_)
     }
 
     netflow_destroy(ofproto->netflow);
-    dpif_sflow_destroy(ofproto->sflow);
+    dpif_sflow_unref(ofproto->sflow);
     hmap_destroy(&ofproto->bundles);
-    mac_learning_destroy(ofproto->ml);
+    mac_learning_unref(ofproto->ml);
 
     classifier_destroy(&ofproto->facets);
 
@@ -1459,7 +1457,7 @@ port_construct(struct ofport *port_)
     port->may_enable = true;
     port->stp_port = NULL;
     port->stp_state = STP_DISABLED;
-    port->tnl_port = NULL;
+    port->is_tunnel = false;
     port->peer = NULL;
     hmap_init(&port->priorities);
     port->realdev_ofp_port = 0;
@@ -1488,7 +1486,8 @@ port_construct(struct ofport *port_)
     port->odp_port = dpif_port.port_no;
 
     if (netdev_get_tunnel_config(netdev)) {
-        port->tnl_port = tnl_port_add(&port->up, port->odp_port);
+        tnl_port_add(port, port->up.netdev, port->odp_port);
+        port->is_tunnel = true;
     } else {
         /* Sanity-check that a mapping doesn't already exist.  This
          * shouldn't happen for non-tunnel ports. */
@@ -1529,7 +1528,7 @@ port_destruct(struct ofport *port_)
          * happens when the ofproto is being destroyed, since the caller
          * assumes that removal of attached ports will happen as part of
          * destruction. */
-        if (!port->tnl_port) {
+        if (!port->is_tunnel) {
             dpif_port_del(ofproto->backer->dpif, port->odp_port);
         }
     }
@@ -1539,11 +1538,11 @@ port_destruct(struct ofport *port_)
         port->peer = NULL;
     }
 
-    if (port->odp_port != ODPP_NONE && !port->tnl_port) {
+    if (port->odp_port != ODPP_NONE && !port->is_tunnel) {
         hmap_remove(&ofproto->backer->odp_to_ofport_map, &port->odp_port_node);
     }
 
-    tnl_port_del(port->tnl_port);
+    tnl_port_del(port);
     sset_find_and_delete(&ofproto->ports, devname);
     sset_find_and_delete(&ofproto->ghost_ports, devname);
     bundle_remove(port_);
@@ -1570,8 +1569,8 @@ port_modified(struct ofport *port_)
         cfm_set_netdev(port->cfm, port->up.netdev);
     }
 
-    if (port->tnl_port && tnl_port_reconfigure(&port->up, port->odp_port,
-                                               &port->tnl_port)) {
+    if (port->is_tunnel && tnl_port_reconfigure(port, port->up.netdev,
+                                                port->odp_port)) {
         ofproto_dpif_cast(port->up.ofproto)->backer->need_revalidate =
             REV_RECONFIGURE;
     }
@@ -1617,7 +1616,7 @@ set_sflow(struct ofproto *ofproto_,
         dpif_sflow_set_options(ds, sflow_options);
     } else {
         if (ds) {
-            dpif_sflow_destroy(ds);
+            dpif_sflow_unref(ds);
             ofproto->backer->need_revalidate = REV_RECONFIGURE;
             ofproto->sflow = NULL;
         }
@@ -1644,7 +1643,7 @@ set_ipfix(
             n_flow_exporters_options);
     } else {
         if (di) {
-            dpif_ipfix_destroy(di);
+            dpif_ipfix_unref(di);
             ofproto->ipfix = NULL;
         }
     }
@@ -2473,7 +2472,7 @@ send_pdu_cb(void *port_, const void *pdu, size_t pdu_size)
     } else {
         VLOG_ERR_RL(&rl, "port %s: cannot obtain Ethernet address of iface "
                     "%s (%s)", port->bundle->name,
-                    netdev_get_name(port->up.netdev), strerror(error));
+                    netdev_get_name(port->up.netdev), ovs_strerror(error));
     }
 }
 
@@ -2512,7 +2511,7 @@ bundle_send_learning_packets(struct ofbundle *bundle)
         static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
         VLOG_WARN_RL(&rl, "bond %s: %d errors sending %d gratuitous learning "
                      "packets, last error was: %s",
-                     bundle->name, n_errors, n_packets, strerror(error));
+                     bundle->name, n_errors, n_packets, ovs_strerror(error));
     } else {
         VLOG_DBG("bond %s: sent %d gratuitous learning packets",
                  bundle->name, n_packets);
@@ -2956,10 +2955,7 @@ port_run(struct ofport_dpif *ofport)
 
     if (ofport->may_enable != enable) {
         struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofport->up.ofproto);
-
-        if (ofproto->has_bundle_action) {
-            ofproto->backer->need_revalidate = REV_PORT_TOGGLED;
-        }
+        ofproto->backer->need_revalidate = REV_PORT_TOGGLED;
     }
 
     ofport->may_enable = enable;
@@ -3064,7 +3060,7 @@ port_del(struct ofproto *ofproto_, ofp_port_t ofp_port)
     sset_find_and_delete(&ofproto->ghost_ports,
                          netdev_get_name(ofport->up.netdev));
     ofproto->backer->need_revalidate = REV_RECONFIGURE;
-    if (!ofport->tnl_port) {
+    if (!ofport->is_tunnel) {
         error = dpif_port_del(ofproto->backer->dpif, ofport->odp_port);
         if (!error) {
             /* The caller is going to close ofport->up.netdev.  If this is a
@@ -3591,8 +3587,8 @@ drop_key_clear(struct dpif_backer *backer)
         if (error && !VLOG_DROP_WARN(&rl)) {
             struct ds ds = DS_EMPTY_INITIALIZER;
             odp_flow_key_format(drop_key->key, drop_key->key_len, &ds);
-            VLOG_WARN("Failed to delete drop key (%s) (%s)", strerror(error),
-                      ds_cstr(&ds));
+            VLOG_WARN("Failed to delete drop key (%s) (%s)",
+                      ovs_strerror(error), ds_cstr(&ds));
             ds_destroy(&ds);
         }
 
@@ -3646,7 +3642,7 @@ ofproto_receive(const struct dpif_backer *backer, struct ofpbuf *packet,
     }
 
     port = (tnl_port_should_receive(flow)
-            ? ofport_dpif_cast(tnl_port_receive(flow))
+            ? tnl_port_receive(flow)
             : odp_port_to_ofport(backer, flow->in_port.odp_port));
     flow->in_port.ofp_port = port ? port->up.ofp_port : OFPP_NONE;
     if (!port) {
@@ -4844,7 +4840,7 @@ facet_push_stats(struct facet *facet, bool may_learn)
         facet->prev_used = facet->used;
 
         in_port = get_ofp_port(ofproto, facet->flow.in_port.ofp_port);
-        if (in_port && in_port->tnl_port) {
+        if (in_port && in_port->is_tunnel) {
             netdev_vport_inc_rx(in_port->up.netdev, &stats);
         }
 
@@ -5418,7 +5414,7 @@ send_packet(const struct ofport_dpif *ofport, struct ofpbuf *packet)
     if (error) {
         VLOG_WARN_RL(&rl, "%s: failed to send packet on port %s (%s)",
                      ofproto->up.name, netdev_get_name(ofport->up.netdev),
-                     strerror(error));
+                     ovs_strerror(error));
     }
 
     ofproto->stats.tx_packets++;
@@ -5507,6 +5503,22 @@ update_mirror_stats(struct ofproto_dpif *ofproto, mirror_mask_t mirrors,
     }
 }
 
+tag_type
+calculate_flow_tag(struct ofproto_dpif *ofproto, const struct flow *flow,
+                   uint8_t table_id, struct rule_dpif *rule)
+{
+    if (table_id > 0 && table_id < N_TABLES) {
+        struct table_dpif *table = &ofproto->tables[table_id];
+        if (table->other_table) {
+            return (rule && rule->tag
+                    ? rule->tag
+                    : rule_calculate_tag(flow, &table->other_table->mask,
+                                         table->basis));
+        }
+    }
+
+    return 0;
+}
 \f
 /* Optimized flow revalidation.
  *
@@ -5900,7 +5912,7 @@ ofproto_unixctl_trace(struct unixctl_conn *conn, int argc, const char *argv[],
 {
     const struct dpif_backer *backer;
     struct ofproto_dpif *ofproto;
-    struct ofpbuf odp_key;
+    struct ofpbuf odp_key, odp_mask;
     struct ofpbuf *packet;
     struct ds result;
     struct flow flow;
@@ -5910,6 +5922,7 @@ ofproto_unixctl_trace(struct unixctl_conn *conn, int argc, const char *argv[],
     backer = NULL;
     ds_init(&result);
     ofpbuf_init(&odp_key, 0);
+    ofpbuf_init(&odp_mask, 0);
 
     /* Handle "-generate" or a hex string as the last argument. */
     if (!strcmp(argv[argc - 1], "-generate")) {
@@ -5930,7 +5943,7 @@ ofproto_unixctl_trace(struct unixctl_conn *conn, int argc, const char *argv[],
      * bridge is specified. If function odp_flow_key_from_string()
      * returns 0, the flow is a odp_flow. If function
      * parse_ofp_exact_flow() returns 0, the flow is a br_flow. */
-    if (!odp_flow_from_string(argv[argc - 1], NULL, &odp_key, NULL)) {
+    if (!odp_flow_from_string(argv[argc - 1], NULL, &odp_key, &odp_mask)) {
         /* If the odp_flow is the second argument,
          * the datapath name is the first argument. */
         if (argc == 3) {
@@ -6010,6 +6023,7 @@ exit:
     ds_destroy(&result);
     ofpbuf_delete(packet);
     ofpbuf_uninit(&odp_key);
+    ofpbuf_uninit(&odp_mask);
 }
 
 void
@@ -6819,4 +6833,8 @@ const struct ofproto_class ofproto_dpif_class = {
     forward_bpdu_changed,
     set_mac_table_config,
     set_realdev,
+    NULL,                       /* meter_get_features */
+    NULL,                       /* meter_set */
+    NULL,                       /* meter_get */
+    NULL,                       /* meter_del */
 };