/*
- * Copyright (c) 2014, 2015 Nicira, Inc.
+ * Copyright (c) 2014, 2015, 2016 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#define RECIRC_POOL_STATIC_IDS 1024
+static void recirc_id_node_free(struct recirc_id_node *);
+
void
recirc_init(void)
{
* finished. */
LIST_FOR_EACH_POP (node, exp_node, &expired) {
cmap_remove(&id_map, &node->id_node, node->id);
- ovsrcu_postpone(free, node);
+ ovsrcu_postpone(recirc_id_node_free, node);
}
if (!list_is_empty(&expiring)) {
hash = hash_pointer(state->ofproto, 0);
hash = hash_int(state->table_id, hash);
- if (state->metadata.tunnel->ip_dst) {
+ if (flow_tnl_dst_is_set(state->metadata.tunnel)) {
/* We may leave remainder bytes unhashed, but that is unlikely as
* the tunnel is not in the datapath format. */
hash = hash_words64((const uint64_t *) state->metadata.tunnel,
flow_tnl_size(state->metadata.tunnel)
/ sizeof(uint64_t), hash);
}
+ hash = hash_boolean(state->conntracked, hash);
hash = hash_words64((const uint64_t *) &state->metadata.metadata,
(sizeof state->metadata - sizeof state->metadata.tunnel)
/ sizeof(uint64_t),
(!b->stack || !b->stack->size))
|| (a->stack && b->stack && ofpbuf_equal(a->stack, b->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));
}
}
+static void
+recirc_state_free(struct recirc_state *state)
+{
+ ofpbuf_delete(state->stack);
+ free(state->ofpacts);
+}
+
/* Allocate a unique recirculation id for the given set of flow metadata.
* The ID space is 2^^32, so there should never be a situation in which all
* the IDs are used up. We loop until we find a free one.
{
struct flow_tnl tunnel;
tunnel.ip_dst = htonl(0);
+ tunnel.ipv6_dst = in6addr_any;
struct recirc_state state = {
.table_id = TBL_INTERNAL,
.ofproto = ofproto,
return recirc_alloc_id__(&state, recirc_metadata_hash(&state))->id;
}
+static void
+recirc_id_node_free(struct recirc_id_node *node)
+{
+ recirc_state_free(CONST_CAST(struct recirc_state *, &node->state));
+ free(node);
+}
+
void
recirc_id_node_unref(const struct recirc_id_node *node_)
OVS_EXCLUDED(mutex)