struct emc_entry {
uint32_t hash;
+ uint32_t mf_len;
struct netdev_flow_key mf;
struct dp_netdev_flow *flow;
};
for (i = 0; i < ARRAY_SIZE(flow_cache->entries); i++) {
flow_cache->entries[i].flow = NULL;
flow_cache->entries[i].hash = 0;
+ flow_cache->entries[i].mf_len = 0;
miniflow_initialize(&flow_cache->entries[i].mf.flow,
flow_cache->entries[i].mf.buf);
}
/* Used to compare 'netdev_flow_key's (miniflows) in the exact match cache. */
static inline bool
netdev_flow_key_equal(const struct netdev_flow_key *a,
- const struct netdev_flow_key *b)
+ const struct netdev_flow_key *b,
+ uint32_t size)
{
- uint32_t size = count_1bits(a->flow.map);
-
- return !memcmp(a, b, netdev_flow_key_size(size));
+ return !memcmp(a, b, size);
}
static inline void
const struct netdev_flow_key *src,
uint32_t size)
{
- memcpy(dst, src, netdev_flow_key_size(size));
+ memcpy(dst, src, size);
}
static inline bool
}
}
if (mf) {
- netdev_flow_key_clone(&ce->mf, mf, count_1bits(mf->flow.map));
+ uint32_t mf_len = netdev_flow_key_size(count_1bits(mf->flow.map));
+
+ netdev_flow_key_clone(&ce->mf, mf, mf_len);
ce->hash = hash;
+ ce->mf_len = mf_len;
}
}
EMC_FOR_EACH_POS_WITH_HASH(cache, current_entry, hash) {
if (current_entry->hash == hash
&& netdev_flow_key_equal(¤t_entry->mf,
- miniflow_to_netdev_flow_key(mf))) {
+ miniflow_to_netdev_flow_key(mf),
+ current_entry->mf_len)) {
/* We found the entry with the 'mf' miniflow */
emc_change_entry(current_entry, flow, NULL, 0);
EMC_FOR_EACH_POS_WITH_HASH(cache, current_entry, hash) {
if (current_entry->hash == hash && emc_entry_alive(current_entry)
&& netdev_flow_key_equal(¤t_entry->mf,
- miniflow_to_netdev_flow_key(mf))) {
+ miniflow_to_netdev_flow_key(mf),
+ current_entry->mf_len)) {
/* We found the entry with the 'mf' miniflow */
return current_entry->flow;