}
static uint32_t
-recirc_metadata_hash(const struct recirc_state *state)
+recirc_state_hash(const struct recirc_state *state)
{
uint32_t hash;
}
hash = hash_int(state->mirrors, hash);
hash = hash_int(state->action_set_len, hash);
+ if (state->action_set_len) {
+ hash = hash_bytes64(ALIGNED_CAST(const uint64_t *, state->action_set),
+ state->action_set_len, hash);
+ }
if (state->ofpacts_len) {
hash = hash_bytes64(ALIGNED_CAST(const uint64_t *, state->ofpacts),
state->ofpacts_len, hash);
}
static bool
-recirc_metadata_equal(const struct recirc_state *a,
+recirc_state_equal(const struct recirc_state *a,
const struct recirc_state *b)
{
return (a->table_id == b->table_id
&& !memcmp(a->stack, b->stack, a->n_stack * sizeof *a->stack)
&& a->mirrors == b->mirrors
&& a->conntracked == b->conntracked
- && a->action_set_len == b->action_set_len
&& ofpacts_equal(a->ofpacts, a->ofpacts_len,
- b->ofpacts, b->ofpacts_len));
+ b->ofpacts, b->ofpacts_len)
+ && ofpacts_equal(a->action_set, a->action_set_len,
+ b->action_set, b->action_set_len));
}
/* Lockless RCU protected lookup. If node is needed accross RCU quiescent
struct recirc_id_node *node;
CMAP_FOR_EACH_WITH_HASH (node, metadata_node, hash, &metadata_map) {
- if (recirc_metadata_equal(&node->state, target)) {
+ if (recirc_state_equal(&node->state, target)) {
return node;
}
}
new->ofpacts = (new->ofpacts_len
? xmemdup(new->ofpacts, new->ofpacts_len)
: NULL);
+ new->action_set = (new->action_set_len
+ ? xmemdup(new->action_set, new->action_set_len)
+ : NULL);
}
static void
{
free(state->stack);
free(state->ofpacts);
+ free(state->action_set);
}
/* Allocate a unique recirculation id for the given set of flow metadata.
uint32_t
recirc_find_id(const struct recirc_state *target)
{
- uint32_t hash = recirc_metadata_hash(target);
+ uint32_t hash = recirc_state_hash(target);
struct recirc_id_node *node = recirc_find_equal(target, hash);
return node ? node->id : 0;
}
uint32_t
recirc_alloc_id_ctx(const struct recirc_state *state)
{
- uint32_t hash = recirc_metadata_hash(state);
+ uint32_t hash = recirc_state_hash(state);
struct recirc_id_node *node = recirc_ref_equal(state, hash);
if (!node) {
node = recirc_alloc_id__(state, hash);
.ofproto = ofproto,
.metadata = { .tunnel = &tunnel, .in_port = OFPP_NONE },
};
- return recirc_alloc_id__(&state, recirc_metadata_hash(&state))->id;
+ return recirc_alloc_id__(&state, recirc_state_hash(&state))->id;
}
static void