tunnel: Hide 'struct tnl_port' internally.
[sliver-openvswitch.git] / ofproto / ofproto-dpif.c
index c6a7abc..f8a1912 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;
                 }
             }
@@ -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;
         }
     }
@@ -1674,7 +1673,7 @@ set_cfm(struct ofport *ofport_, const struct cfm_settings *s)
 
         error = EINVAL;
     }
-    cfm_destroy(ofport->cfm);
+    cfm_unref(ofport->cfm);
     ofport->cfm = NULL;
     return error;
 }
@@ -2245,8 +2244,8 @@ bundle_destroy(struct ofbundle *bundle)
     hmap_remove(&ofproto->bundles, &bundle->hmap_node);
     free(bundle->name);
     free(bundle->trunks);
-    lacp_destroy(bundle->lacp);
-    bond_destroy(bundle->bond);
+    lacp_unref(bundle->lacp);
+    bond_unref(bundle->bond);
     free(bundle);
 }
 
@@ -2309,7 +2308,7 @@ bundle_set(struct ofproto *ofproto_, void *aux,
         }
         lacp_configure(bundle->lacp, s->lacp);
     } else {
-        lacp_destroy(bundle->lacp);
+        lacp_unref(bundle->lacp);
         bundle->lacp = NULL;
     }
 
@@ -2420,7 +2419,7 @@ bundle_set(struct ofproto *ofproto_, void *aux,
             bond_slave_register(bundle->bond, port, port->up.netdev);
         }
     } else {
-        bond_destroy(bundle->bond);
+        bond_unref(bundle->bond);
         bundle->bond = NULL;
     }
 
@@ -2444,7 +2443,7 @@ bundle_remove(struct ofport *port_)
         if (list_is_empty(&bundle->ports)) {
             bundle_destroy(bundle);
         } else if (list_is_short(&bundle->ports)) {
-            bond_destroy(bundle->bond);
+            bond_unref(bundle->bond);
             bundle->bond = NULL;
         }
     }
@@ -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
@@ -3361,6 +3357,15 @@ flow_miss_should_make_facet(struct flow_miss *miss, struct flow_wildcards *wc)
     struct dpif_backer *backer = miss->ofproto->backer;
     uint32_t hash;
 
+    switch (flow_miss_model) {
+    case OFPROTO_HANDLE_MISS_AUTO:
+        break;
+    case OFPROTO_HANDLE_MISS_WITH_FACETS:
+        return true;
+    case OFPROTO_HANDLE_MISS_WITHOUT_FACETS:
+        return false;
+    }
+
     if (!backer->governor) {
         size_t n_subfacets;
 
@@ -3637,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) {
@@ -4835,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);
         }
 
@@ -5498,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.
  *
@@ -5891,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;
@@ -5901,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")) {
@@ -5921,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) {
@@ -6001,6 +6023,7 @@ exit:
     ds_destroy(&result);
     ofpbuf_delete(packet);
     ofpbuf_uninit(&odp_key);
+    ofpbuf_uninit(&odp_mask);
 }
 
 void
@@ -6810,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 */
 };