/*
- * 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.
/* Actions. */
struct nlattr *actions;
- unsigned int actions_len;
+ size_t actions_len;
};
/* Interface to netdev-based datapath. */
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;
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;
}
}
+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);
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;
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));
}
}
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)) {
}
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;
}
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)) {
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;
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,