Fix setting "of" device name based on unitialized dp_idx.
[sliver-openvswitch.git] / datapath / table-linear.c
index 80f07c2..1d5e186 100644 (file)
@@ -72,25 +72,47 @@ static int table_linear_insert(struct sw_table *swt, struct sw_flow *flow)
        return 1;
 }
 
-static int do_delete(struct sw_table *swt, struct sw_flow *flow) 
+static int table_linear_modify(struct sw_table *swt,
+                               const struct sw_flow_key *key, uint16_t priority, int strict,
+                               const struct ofp_action_header *actions, size_t actions_len)
 {
+       struct sw_table_linear *tl = (struct sw_table_linear *) swt;
+       struct sw_flow *flow;
+       unsigned int count = 0;
+
+       list_for_each_entry (flow, &tl->flows, node) {
+               if (flow_matches_desc(&flow->key, key, strict)
+                               && (!strict || (flow->priority == priority))) {
+                       flow_replace_acts(flow, actions, actions_len);
+                       count++;
+               }
+       }
+       return count;
+}
+
+static int do_delete(struct datapath *dp, struct sw_table *swt, 
+                       struct sw_flow *flow, enum nx_flow_end_reason reason) 
+{
+       dp_send_flow_end(dp, flow, reason);
        list_del_rcu(&flow->node);
        list_del_rcu(&flow->iter_node);
        flow_deferred_free(flow);
        return 1;
 }
 
-static int table_linear_delete(struct sw_table *swt,
-                               const struct sw_flow_key *key, uint16_t priority, int strict)
+static int table_linear_delete(struct datapath *dp, struct sw_table *swt,
+                               const struct sw_flow_key *key, uint16_t out_port,
+                               uint16_t priority, int strict)
 {
        struct sw_table_linear *tl = (struct sw_table_linear *) swt;
        struct sw_flow *flow;
        unsigned int count = 0;
 
        list_for_each_entry (flow, &tl->flows, node) {
-               if (flow_del_matches(&flow->key, key, strict)
+               if (flow_matches_desc(&flow->key, key, strict)
+                               && flow_has_out_port(flow, out_port)
                                && (!strict || (flow->priority == priority)))
-                       count += do_delete(swt, flow);
+                       count += do_delete(dp, swt, flow, NXFER_DELETE);
        }
        tl->n_flows -= count;
        return count;
@@ -106,8 +128,7 @@ static int table_linear_timeout(struct datapath *dp, struct sw_table *swt)
        list_for_each_entry (flow, &tl->flows, node) {
                int reason = flow_timeout(flow);
                if (reason >= 0) {
-                       count += do_delete(swt, flow);
-                       dp_send_flow_expired(dp, flow, reason);
+                       count += do_delete(dp, swt, flow, reason);
                }
        }
        tl->n_flows -= count;
@@ -129,7 +150,7 @@ static void table_linear_destroy(struct sw_table *swt)
 }
 
 static int table_linear_iterate(struct sw_table *swt,
-                               const struct sw_flow_key *key,
+                               const struct sw_flow_key *key, uint16_t out_port,
                                struct sw_table_position *position,
                                int (*callback)(struct sw_flow *, void *),
                                void *private)
@@ -141,7 +162,8 @@ static int table_linear_iterate(struct sw_table *swt,
        start = position->private[0];
        list_for_each_entry (flow, &tl->iter_flows, iter_node) {
                if (flow->serial >= start
-                   && flow_matches_2wild(key, &flow->key)) {
+                               && flow_matches_2wild(key, &flow->key)
+                               && flow_has_out_port(flow, out_port)) {
                        int error = callback(flow, private);
                        if (error) {
                                position->private[0] = flow->serial;
@@ -160,6 +182,7 @@ static void table_linear_stats(struct sw_table *swt,
        stats->wildcards = OFPFW_ALL;
        stats->n_flows   = tl->n_flows;
        stats->max_flows = tl->max_flows;
+       stats->n_lookup  = swt->n_lookup;
        stats->n_matched = swt->n_matched;
 }
 
@@ -176,6 +199,7 @@ struct sw_table *table_linear_create(unsigned int max_flows)
        swt = &tl->swt;
        swt->lookup = table_linear_lookup;
        swt->insert = table_linear_insert;
+       swt->modify = table_linear_modify;
        swt->delete = table_linear_delete;
        swt->timeout = table_linear_timeout;
        swt->destroy = table_linear_destroy;