return ERR_PTR(-ENOMEM);
spin_lock_init(&flow->lock);
- atomic_set(&flow->refcnt, 1);
flow->sf_acts = NULL;
- flow->dead = false;
return flow;
}
return table;
}
-static void flow_free(struct sw_flow *flow)
-{
- flow->dead = true;
- ovs_flow_put(flow);
-}
-
void ovs_flow_tbl_destroy(struct flow_table *table)
{
int i;
hlist_for_each_entry_safe(flow, node, n, head, hash_node[ver]) {
hlist_del_rcu(&flow->hash_node[ver]);
- flow_free(flow);
+ ovs_flow_free(flow);
}
}
return __flow_tbl_rehash(table, table->n_buckets * 2);
}
+void ovs_flow_free(struct sw_flow *flow)
+{
+ if (unlikely(!flow))
+ return;
+
+ kfree((struct sf_flow_acts __force *)flow->sf_acts);
+ kmem_cache_free(flow_cache, flow);
+}
+
/* RCU callback used by ovs_flow_deferred_free. */
static void rcu_free_flow_callback(struct rcu_head *rcu)
{
struct sw_flow *flow = container_of(rcu, struct sw_flow, rcu);
- flow->dead = true;
- ovs_flow_put(flow);
+ ovs_flow_free(flow);
}
/* Schedules 'flow' to be freed after the next RCU grace period.
call_rcu(&flow->rcu, rcu_free_flow_callback);
}
-void ovs_flow_hold(struct sw_flow *flow)
-{
- atomic_inc(&flow->refcnt);
-}
-
-void ovs_flow_put(struct sw_flow *flow)
-{
- if (unlikely(!flow))
- return;
-
- if (atomic_dec_and_test(&flow->refcnt)) {
- kfree((struct sf_flow_acts __force *)flow->sf_acts);
- kmem_cache_free(flow_cache, flow);
- }
-}
-
/* RCU callback used by ovs_flow_deferred_free_acts. */
static void rcu_free_acts_callback(struct rcu_head *rcu)
{
[OVS_KEY_ATTR_ICMPV6] = sizeof(struct ovs_key_icmpv6),
[OVS_KEY_ATTR_ARP] = sizeof(struct ovs_key_arp),
[OVS_KEY_ATTR_ND] = sizeof(struct ovs_key_nd),
+ [OVS_KEY_ATTR_IPV4_TUNNEL] = sizeof(struct ovs_key_ipv4_tunnel),
/* Not upstream. */
[OVS_KEY_ATTR_TUN_ID] = sizeof(__be64),
- [OVS_KEY_ATTR_IPV4_TUNNEL] = sizeof(struct ovs_key_ipv4_tunnel),
};
static int ipv4_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_len,
if (tun_id != tun_key->tun_id)
return -EINVAL;
- memcpy(&swkey->phy.tun.tun_key, tun_key, sizeof(swkey->phy.tun.tun_key));
- attrs &= ~(1ULL << OVS_KEY_ATTR_TUN_ID);
- attrs &= ~(1ULL << OVS_KEY_ATTR_IPV4_TUNNEL);
- } else if (attrs & (1ULL << OVS_KEY_ATTR_TUN_ID)) {
- swkey->phy.tun.tun_key.tun_id = nla_get_be64(a[OVS_KEY_ATTR_TUN_ID]);
- swkey->phy.tun.tun_key.tun_flags |= OVS_FLOW_TNL_F_KEY;
+ memcpy(&swkey->phy.tun.tun_key, tun_key,
+ sizeof(swkey->phy.tun.tun_key));
attrs &= ~(1ULL << OVS_KEY_ATTR_TUN_ID);
+ attrs &= ~(1ULL << OVS_KEY_ATTR_IPV4_TUNNEL);
} else if (attrs & (1ULL << OVS_KEY_ATTR_IPV4_TUNNEL)) {
struct ovs_key_ipv4_tunnel *tun_key;
tun_key = nla_data(a[OVS_KEY_ATTR_IPV4_TUNNEL]);
if (!tun_key->ipv4_dst)
return -EINVAL;
- memcpy(&swkey->phy.tun.tun_key, tun_key, sizeof(swkey->phy.tun.tun_key));
+ memcpy(&swkey->phy.tun.tun_key, tun_key,
+ sizeof(swkey->phy.tun.tun_key));
+
attrs &= ~(1ULL << OVS_KEY_ATTR_IPV4_TUNNEL);
}