Merge remote branch 'repo/master' into stats
[openvswitch] / datapath / datapath.c
index 5cd6c40c283e9b0ea1b1f256bf3b7e05301a65ae..639a4836e2c0b81d90f3f956f5947d5f82894ce6 100644 (file)
@@ -6,6 +6,7 @@
 
 /* Functions for managing the dp interface/device. */
 
+#include <linux/init.h>
 #include <linux/module.h>
 #include <linux/if_arp.h>
 #include <linux/if_bridge.h>
@@ -531,7 +532,19 @@ int dp_output_port(struct datapath *dp, struct sk_buff *skb, int out_port)
        else if (out_port == OFPP_CONTROLLER)
                return dp_output_control(dp, skb, fwd_save_skb(skb), 0,
                                                  OFPR_ACTION);
-       else if (out_port >= OFPP_MAX)
+       else if (out_port == OFPP_TABLE) {
+               struct sw_flow_key key;
+               struct sw_flow *flow;
+
+               flow_extract(skb, skb->dev->br_port->port_no, &key);
+               flow = chain_lookup(dp->chain, &key);
+               if (likely(flow != NULL)) {
+                       flow_used(flow, skb);
+                       execute_actions(dp, skb, &key, flow->actions, flow->n_actions);
+                       return 0;
+               }
+               return -ESRCH;
+       } else if (out_port >= OFPP_MAX)
                goto bad_port;
 
        p = dp->ports[out_port];
@@ -752,8 +765,6 @@ static void
 fill_flow_stats(struct ofp_flow_stats *ofs, struct sw_flow *flow,
                int table_idx)
 {
-       int duration;
-       
        ofs->match.wildcards = htons(flow->key.wildcards);
        ofs->match.in_port   = flow->key.in_port;
        memcpy(ofs->match.dl_src, flow->key.dl_src, ETH_ALEN);
@@ -766,9 +777,8 @@ fill_flow_stats(struct ofp_flow_stats *ofs, struct sw_flow *flow,
        memset(ofs->match.pad, 0, sizeof ofs->match.pad);
        ofs->match.tp_src    = flow->key.tp_src;
        ofs->match.tp_dst    = flow->key.tp_dst;
-       duration = (jiffies - flow->init_time) / HZ;
-       ofs->duration        = htons(min(65535, duration));
-       ofs->table_id        = htons(table_idx);
+       ofs->duration        = htonl((jiffies - flow->init_time) / HZ);
+       ofs->table_id        = table_idx;
        ofs->packet_count    = cpu_to_be64(flow->packet_count);
        ofs->byte_count      = cpu_to_be64(flow->byte_count);
 }
@@ -888,7 +898,7 @@ dp_send_table_stats(struct datapath *dp, const struct sender *sender)
                struct sw_table_stats stats;
                dp->chain->tables[i]->stats(dp->chain->tables[i], &stats);
                strncpy(ots->name, stats.name, sizeof ots->name);
-               ots->table_id = htons(i);
+               ots->table_id = i;
                ots->pad[0] = ots->pad[1] = 0;
                ots->max_entries = htonl(stats.max_flows);
                ots->active_count = htonl(stats.n_flows);