ofproto: Encapsulate classifier tables in new "struct oftable".
[sliver-openvswitch.git] / ofproto / ofproto-dpif.c
index 344f9d4..246b34a 100644 (file)
@@ -34,6 +34,7 @@
 #include "lacp.h"
 #include "learn.h"
 #include "mac-learning.h"
+#include "meta-flow.h"
 #include "multipath.h"
 #include "netdev.h"
 #include "netlink.h"
@@ -704,7 +705,7 @@ destruct(struct ofproto *ofproto_)
 {
     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
     struct rule_dpif *rule, *next_rule;
-    struct classifier *table;
+    struct oftable *table;
     int i;
 
     hmap_remove(&all_ofproto_dpifs, &ofproto->all_ofproto_dpifs_node);
@@ -713,7 +714,7 @@ destruct(struct ofproto *ofproto_)
     OFPROTO_FOR_EACH_TABLE (table, &ofproto->up) {
         struct cls_cursor cursor;
 
-        cls_cursor_init(&cursor, table, NULL);
+        cls_cursor_init(&cursor, &table->cls, NULL);
         CLS_CURSOR_FOR_EACH_SAFE (rule, next_rule, up.cr, &cursor) {
             ofproto_rule_destroy(&rule->up);
         }
@@ -2424,7 +2425,7 @@ struct flow_miss_op {
  * OpenFlow controller as necessary according to their individual
  * configurations. */
 static void
-send_packet_in_miss(struct ofproto_dpif *ofproto, struct ofpbuf *packet,
+send_packet_in_miss(struct ofproto_dpif *ofproto, const struct ofpbuf *packet,
                     const struct flow *flow)
 {
     struct ofputil_packet_in pin;
@@ -2579,7 +2580,6 @@ handle_flow_miss(struct ofproto_dpif *ofproto, struct flow_miss *miss,
             continue;
         }
 
-        list_remove(&packet->list_node);
         if (flow->vlan_tci != subfacet->initial_tci) {
             /* This packet was received on a VLAN splinter port.  We added
              * a VLAN to the packet to make the packet resemble the flow,
@@ -2742,14 +2742,10 @@ handle_miss_upcalls(struct ofproto_dpif *ofproto, struct dpif_upcall *upcalls,
     /* Process each element in the to-do list, constructing the set of
      * operations to batch. */
     n_ops = 0;
-    HMAP_FOR_EACH_SAFE (miss, next_miss, hmap_node, &todo) {
+    HMAP_FOR_EACH (miss, hmap_node, &todo) {
         handle_flow_miss(ofproto, miss, flow_miss_ops, &n_ops);
-        ofpbuf_list_delete(&miss->packets);
-        hmap_remove(&todo, &miss->hmap_node);
-        free(miss);
     }
     assert(n_ops <= ARRAY_SIZE(flow_miss_ops));
-    hmap_destroy(&todo);
 
     /* Execute batch. */
     for (i = 0; i < n_ops; i++) {
@@ -2768,7 +2764,6 @@ handle_miss_upcalls(struct ofproto_dpif *ofproto, struct dpif_upcall *upcalls,
             if (op->subfacet->actions != execute->actions) {
                 free((struct nlattr *) execute->actions);
             }
-            ofpbuf_delete((struct ofpbuf *) execute->packet);
             break;
 
         case DPIF_OP_FLOW_PUT:
@@ -2778,6 +2773,12 @@ handle_miss_upcalls(struct ofproto_dpif *ofproto, struct dpif_upcall *upcalls,
             break;
         }
     }
+    HMAP_FOR_EACH_SAFE (miss, next_miss, hmap_node, &todo) {
+        ofpbuf_list_delete(&miss->packets);
+        hmap_remove(&todo, &miss->hmap_node);
+        free(miss);
+    }
+    hmap_destroy(&todo);
 }
 
 static void
@@ -2869,7 +2870,7 @@ static int
 expire(struct ofproto_dpif *ofproto)
 {
     struct rule_dpif *rule, *next_rule;
-    struct classifier *table;
+    struct oftable *table;
     int dp_max_idle;
 
     /* Update stats for each flow in the datapath. */
@@ -2883,7 +2884,7 @@ expire(struct ofproto_dpif *ofproto)
     OFPROTO_FOR_EACH_TABLE (table, &ofproto->up) {
         struct cls_cursor cursor;
 
-        cls_cursor_init(&cursor, table, NULL);
+        cls_cursor_init(&cursor, &table->cls, NULL);
         CLS_CURSOR_FOR_EACH_SAFE (rule, next_rule, up.cr, &cursor) {
             rule_expire(rule);
         }
@@ -3973,7 +3974,7 @@ rule_dpif_lookup(struct ofproto_dpif *ofproto, const struct flow *flow,
         return NULL;
     }
 
-    cls = &ofproto->up.tables[table_id];
+    cls = &ofproto->up.tables[table_id].cls;
     if (flow->nw_frag & FLOW_NW_FRAG_ANY
         && ofproto->up.frag_handling == OFPC_FRAG_NORMAL) {
         /* For OFPC_NORMAL frag_handling, we must pretend that transport ports
@@ -4568,9 +4569,11 @@ static void
 xlate_output_reg_action(struct action_xlate_ctx *ctx,
                         const struct nx_action_output_reg *naor)
 {
+    struct mf_subfield src;
     uint64_t ofp_port;
 
-    ofp_port = nxm_read_field_bits(naor->src, naor->ofs_nbits, &ctx->flow);
+    nxm_decode(&src, naor->src, naor->ofs_nbits);
+    ofp_port = mf_get_subfield(&src, &ctx->flow);
 
     if (ofp_port <= UINT16_MAX) {
         xlate_output_action__(ctx, ofp_port, ntohs(naor->max_len));
@@ -5615,13 +5618,13 @@ static void
 table_update_taggable(struct ofproto_dpif *ofproto, uint8_t table_id)
 {
     struct table_dpif *table = &ofproto->tables[table_id];
-    const struct classifier *cls = &ofproto->up.tables[table_id];
+    const struct oftable *oftable = &ofproto->up.tables[table_id];
     struct cls_table *catchall, *other;
     struct cls_table *t;
 
     catchall = other = NULL;
 
-    switch (hmap_count(&cls->tables)) {
+    switch (hmap_count(&oftable->cls.tables)) {
     case 0:
         /* We could tag this OpenFlow table but it would make the logic a
          * little harder and it's a corner case that doesn't seem worth it
@@ -5630,7 +5633,7 @@ table_update_taggable(struct ofproto_dpif *ofproto, uint8_t table_id)
 
     case 1:
     case 2:
-        HMAP_FOR_EACH (t, hmap_node, &cls->tables) {
+        HMAP_FOR_EACH (t, hmap_node, &oftable->cls.tables) {
             if (cls_table_is_catchall(t)) {
                 catchall = t;
             } else if (!other) {