struct dp_netdev_flow_iter {
uint32_t bucket;
uint32_t offset;
- void *state;
+ int status;
+ struct ovs_mutex mutex;
};
static void
*iterp = iter = xmalloc(sizeof *iter);
iter->bucket = 0;
iter->offset = 0;
- dpif_netdev_flow_dump_state_init(&iter->state);
+ iter->status = 0;
+ ovs_mutex_init(&iter->mutex);
return 0;
}
static int
-dpif_netdev_flow_dump_next(const struct dpif *dpif, void *iter_,
+dpif_netdev_flow_dump_next(const struct dpif *dpif, void *iter_, void *state_,
const struct nlattr **key, size_t *key_len,
const struct nlattr **mask, size_t *mask_len,
const struct nlattr **actions, size_t *actions_len,
const struct dpif_flow_stats **stats)
{
struct dp_netdev_flow_iter *iter = iter_;
- struct dp_netdev_flow_state *state = iter->state;
+ struct dp_netdev_flow_state *state = state_;
struct dp_netdev *dp = get_dp_netdev(dpif);
struct dp_netdev_flow *netdev_flow;
- struct hmap_node *node;
+ int error;
- fat_rwlock_rdlock(&dp->cls.rwlock);
- node = hmap_at_position(&dp->flow_table, &iter->bucket, &iter->offset);
- if (node) {
- netdev_flow = CONTAINER_OF(node, struct dp_netdev_flow, node);
- dp_netdev_flow_ref(netdev_flow);
+ ovs_mutex_lock(&iter->mutex);
+ error = iter->status;
+ if (!error) {
+ struct hmap_node *node;
+
+ fat_rwlock_rdlock(&dp->cls.rwlock);
+ node = hmap_at_position(&dp->flow_table, &iter->bucket, &iter->offset);
+ if (node) {
+ netdev_flow = CONTAINER_OF(node, struct dp_netdev_flow, node);
+ dp_netdev_flow_ref(netdev_flow);
+ }
+ fat_rwlock_unlock(&dp->cls.rwlock);
+ if (!node) {
+ iter->status = error = EOF;
+ }
}
- fat_rwlock_unlock(&dp->cls.rwlock);
- if (!node) {
- return EOF;
+ ovs_mutex_unlock(&iter->mutex);
+ if (error) {
+ return error;
}
if (key) {
{
struct dp_netdev_flow_iter *iter = iter_;
- dpif_netdev_flow_dump_state_uninit(iter->state);
+ ovs_mutex_destroy(&iter->mutex);
free(iter);
return 0;
}
}
/* Extract flow key. */
- flow_extract(execute->packet, md->skb_priority, md->pkt_mark, &md->tunnel,
- (union flow_in_port *)&md->in_port, &key);
+ flow_extract(execute->packet, md, &key);
ovs_rwlock_rdlock(&dp->port_rwlock);
dp_netdev_execute_actions(dp, &key, execute->packet, md, execute->actions,
if (!error) {
struct pkt_metadata md
= PKT_METADATA_INITIALIZER(port->port_no);
- dp_netdev_port_input(dp, &packet, &md);
+ dp_netdev_port_input(dp, &packet, &md);
received_anything = true;
} else if (error != EAGAIN && error != EOPNOTSUPP) {
static struct vlog_rate_limit rl
if (packet->size < ETH_HEADER_LEN) {
return;
}
- flow_extract(packet, md->skb_priority, md->pkt_mark, &md->tunnel,
- (union flow_in_port *)&md->in_port, &key);
+ flow_extract(packet, md, &key);
netdev_flow = dp_netdev_lookup_flow(dp, &key);
if (netdev_flow) {
struct dp_netdev_actions *actions;
dpif_netdev_flow_dump_state_init,
dpif_netdev_flow_dump_start,
dpif_netdev_flow_dump_next,
+ NULL,
dpif_netdev_flow_dump_done,
dpif_netdev_flow_dump_state_uninit,
dpif_netdev_execute,