datapath: Change listing flows to use an iterator concept.
[sliver-openvswitch.git] / lib / dpif-netdev.c
index 0f95c5f..5d7fa20 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010 Nicira Networks.
+ * Copyright (c) 2009, 2010, 2011 Nicira Networks.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -109,7 +109,7 @@ struct dp_netdev_flow {
 
     /* Actions. */
     struct nlattr *actions;
-    unsigned int actions_len;
+    size_t actions_len;
 };
 
 /* Interface to netdev-based datapath. */
@@ -138,11 +138,11 @@ static int do_del_port(struct dp_netdev *, uint16_t port_no);
 static int dpif_netdev_open(const struct dpif_class *, const char *name,
                             bool create, struct dpif **);
 static int dp_netdev_output_control(struct dp_netdev *, const struct ofpbuf *,
-                                    int queue_no, int port_no, uint32_t arg);
+                                    int queue_no, int port_no, uint64_t arg);
 static int dp_netdev_execute_actions(struct dp_netdev *,
                                      struct ofpbuf *, struct flow *,
                                      const struct nlattr *actions,
-                                     unsigned int actions_len);
+                                     size_t actions_len);
 
 static struct dpif_class dpif_dummy_class;
 
@@ -621,7 +621,7 @@ dpif_netdev_flow_get(const struct dpif *dpif, struct odp_flow flows[], int n)
 
 static int
 dpif_netdev_validate_actions(const struct nlattr *actions,
-                             unsigned int actions_len, bool *mutates)
+                             size_t actions_len, bool *mutates)
 {
     const struct nlattr *a;
     unsigned int left;
@@ -779,29 +779,49 @@ dpif_netdev_flow_del(struct dpif *dpif, struct odp_flow *odp_flow)
     }
 }
 
+struct dp_netdev_flow_state {
+    uint32_t bucket;
+    uint32_t offset;
+};
+
 static int
-dpif_netdev_flow_list(const struct dpif *dpif, struct odp_flow flows[], int n)
+dpif_netdev_flow_dump_start(const struct dpif *dpif OVS_UNUSED, void **statep)
 {
+    *statep = xzalloc(sizeof(struct dp_netdev_flow_state));
+    return 0;
+}
+
+static int
+dpif_netdev_flow_dump_next(const struct dpif *dpif, void *state_,
+                           struct odp_flow *odp_flow)
+{
+    struct dp_netdev_flow_state *state = state_;
     struct dp_netdev *dp = get_dp_netdev(dpif);
     struct dp_netdev_flow *flow;
-    int i;
-
-    i = 0;
-    HMAP_FOR_EACH (flow, node, &dp->flow_table) {
-        if (i >= n) {
-            break;
-        }
+    struct hmap_node *node;
 
-        odp_flow_key_from_flow(&flows[i].key, &flow->key);
-        answer_flow_query(flow, 0, &flows[i]);
-        i++;
+    node = hmap_at_position(&dp->flow_table, &state->bucket, &state->offset);
+    if (!node) {
+        return EOF;
     }
-    return hmap_count(&dp->flow_table);
+
+    flow = CONTAINER_OF(node, struct dp_netdev_flow, node);
+    odp_flow_key_from_flow(&odp_flow->key, &flow->key);
+    answer_flow_query(flow, 0, odp_flow);
+
+    return 0;
+}
+
+static int
+dpif_netdev_flow_dump_done(const struct dpif *dpif OVS_UNUSED, void *state)
+{
+    free(state);
+    return 0;
 }
 
 static int
 dpif_netdev_execute(struct dpif *dpif,
-                    const struct nlattr *actions, unsigned int actions_len,
+                    const struct nlattr *actions, size_t actions_len,
                     const struct ofpbuf *packet)
 {
     struct dp_netdev *dp = get_dp_netdev(dpif);
@@ -950,7 +970,7 @@ dp_netdev_run(void)
     struct shash_node *node;
     struct ofpbuf packet;
 
-    ofpbuf_init(&packet, DP_NETDEV_HEADROOM + max_mtu);
+    ofpbuf_init(&packet, DP_NETDEV_HEADROOM + VLAN_ETH_HEADER_LEN + max_mtu);
     SHASH_FOR_EACH (node, &dp_netdevs) {
         struct dp_netdev *dp = node->data;
         struct dp_netdev_port *port;
@@ -966,7 +986,7 @@ dp_netdev_run(void)
             if (!error) {
                 dp_netdev_port_input(dp, port, &packet);
             } else if (error != EAGAIN && error != EOPNOTSUPP) {
-                struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
+                static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
                 VLOG_ERR_RL(&rl, "error receiving data from %s: %s",
                             netdev_get_name(port->netdev), strerror(error));
             }
@@ -1060,7 +1080,7 @@ is_ip(const struct ofpbuf *packet, const struct flow *key)
 }
 
 static void
-dp_netdev_set_nw_addr(struct ofpbuf *packet, struct flow *key,
+dp_netdev_set_nw_addr(struct ofpbuf *packet, const struct flow *key,
                       const struct nlattr *a)
 {
     if (is_ip(packet, key)) {
@@ -1088,7 +1108,8 @@ dp_netdev_set_nw_addr(struct ofpbuf *packet, struct flow *key,
 }
 
 static void
-dp_netdev_set_nw_tos(struct ofpbuf *packet, struct flow *key, uint8_t nw_tos)
+dp_netdev_set_nw_tos(struct ofpbuf *packet, const struct flow *key,
+                     uint8_t nw_tos)
 {
     if (is_ip(packet, key)) {
         struct ip_header *nh = packet->l3;
@@ -1104,7 +1125,7 @@ dp_netdev_set_nw_tos(struct ofpbuf *packet, struct flow *key, uint8_t nw_tos)
 }
 
 static void
-dp_netdev_set_tp_port(struct ofpbuf *packet, struct flow *key,
+dp_netdev_set_tp_port(struct ofpbuf *packet, const struct flow *key,
                       const struct nlattr *a)
 {
        if (is_ip(packet, key)) {
@@ -1140,7 +1161,7 @@ dp_netdev_output_port(struct dp_netdev *dp, struct ofpbuf *packet,
 
 static int
 dp_netdev_output_control(struct dp_netdev *dp, const struct ofpbuf *packet,
-                         int queue_no, int port_no, uint32_t arg)
+                         int queue_no, int port_no, uint64_t arg)
 {
     struct odp_msg *header;
     struct ofpbuf *msg;
@@ -1197,7 +1218,7 @@ static int
 dp_netdev_execute_actions(struct dp_netdev *dp,
                           struct ofpbuf *packet, struct flow *key,
                           const struct nlattr *actions,
-                          unsigned int actions_len)
+                          size_t actions_len)
 {
     const struct nlattr *a;
     unsigned int left;
@@ -1210,7 +1231,7 @@ dp_netdev_execute_actions(struct dp_netdev *dp,
 
         case ODPAT_CONTROLLER:
             dp_netdev_output_control(dp, packet, _ODPL_ACTION_NR,
-                                     key->in_port, nl_attr_get_u32(a));
+                                     key->in_port, nl_attr_get_u64(a));
             break;
 
         case ODPAT_SET_DL_TCI:
@@ -1275,7 +1296,9 @@ const struct dpif_class dpif_netdev_class = {
     dpif_netdev_flow_put,
     dpif_netdev_flow_del,
     dpif_netdev_flow_flush,
-    dpif_netdev_flow_list,
+    dpif_netdev_flow_dump_start,
+    dpif_netdev_flow_dump_next,
+    dpif_netdev_flow_dump_done,
     dpif_netdev_execute,
     dpif_netdev_recv_get_mask,
     dpif_netdev_recv_set_mask,