Add support for listing and deleting entries based on an output port.
[sliver-openvswitch.git] / datapath / datapath.c
index e9d51a8..570cdcf 100644 (file)
@@ -265,7 +265,6 @@ static int new_dp(int dp_idx)
                goto err_free_dp;
 
        dp->dp_idx = dp_idx;
-       dp->id = get_datapath_id(dp->netdev);
        dp->chain = chain_create(dp);
        if (dp->chain == NULL)
                goto err_destroy_dp_dev;
@@ -466,7 +465,6 @@ do_port_input(struct net_bridge_port *p, struct sk_buff *skb)
 #ifdef SUPPORT_SNAT
        /* Check if this packet needs early SNAT processing. */
        if (snat_pre_route(skb)) {
-               kfree_skb(skb);
                return;
        }
 #endif
@@ -670,7 +668,6 @@ dp_output_control(struct datapath *dp, struct sk_buff *skb,
         * forward the whole packet? */
        struct sk_buff *f_skb;
        struct ofp_packet_in *opi;
-       struct net_bridge_port *p;
        size_t fwd_len, opi_len;
        int err;
 
@@ -686,11 +683,12 @@ dp_output_control(struct datapath *dp, struct sk_buff *skb,
        }
        opi->buffer_id      = htonl(buffer_id);
        opi->total_len      = htons(skb->len);
-       p = skb->dev->br_port;
-       opi->in_port        = htons(p ? p->port_no : OFPP_LOCAL);
+       opi->in_port        = htons(skb->dev && skb->dev->br_port
+                                   ? skb->dev->br_port->port_no
+                                   : OFPP_LOCAL);
        opi->reason         = reason;
        opi->pad            = 0;
-       memcpy(opi->data, skb_mac_header(skb), fwd_len);
+       skb_copy_bits(skb, 0, opi->data, fwd_len);
        err = send_openflow_skb(f_skb, NULL);
 
 out:
@@ -806,9 +804,10 @@ static int
 fill_features_reply(struct datapath *dp, struct ofp_switch_features *ofr)
 {
        struct net_bridge_port *p;
+       uint64_t dpid = get_datapath_id(dp->netdev);
        int port_count = 0;
 
-       ofr->datapath_id  = cpu_to_be64(dp->id); 
+       ofr->datapath_id  = cpu_to_be64(dpid);
 
        ofr->n_buffers    = htonl(N_PKT_BUFFERS);
        ofr->n_tables     = dp->chain->n_tables;
@@ -1176,13 +1175,11 @@ static int dp_genl_query(struct sk_buff *skb, struct genl_info *info)
 
                genlmsg_end(ans_skb, data);
                err = genlmsg_reply(ans_skb, info);
-               if (!err)
-                       ans_skb = NULL;
+               ans_skb = NULL;
        }
 err:
 nla_put_failure:
-       if (ans_skb)
-               kfree_skb(ans_skb);
+       kfree_skb(ans_skb);
        rcu_read_unlock();
        return err;
 }
@@ -1385,8 +1382,8 @@ static int flow_stats_dump(struct datapath *dp, void *state,
        {
                struct sw_table *table = dp->chain->tables[s->table_idx];
 
-               error = table->iterate(table, &match_key, &s->position,
-                                      flow_stats_dump_callback, s);
+               error = table->iterate(table, &match_key, s->rq->out_port, 
+                               &s->position, flow_stats_dump_callback, s);
                if (error)
                        break;
 
@@ -1450,7 +1447,7 @@ static int aggregate_stats_dump(struct datapath *dp, void *state,
                struct sw_table *table = dp->chain->tables[table_idx];
                int error;
 
-               error = table->iterate(table, &match_key, &position,
+               error = table->iterate(table, &match_key, rq->out_port, &position,
                                       aggregate_stats_dump_callback, rpy);
                if (error)
                        return error;