1c9422999SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2e6445719SPravin B Shelar /* 39b996e54SPravin B Shelar * Copyright (c) 2007-2014 Nicira, Inc. 4e6445719SPravin B Shelar */ 5e6445719SPravin B Shelar 6e6445719SPravin B Shelar #include "flow.h" 7e6445719SPravin B Shelar #include "datapath.h" 834ae932aSThomas Graf #include "flow_netlink.h" 9e6445719SPravin B Shelar #include <linux/uaccess.h> 10e6445719SPravin B Shelar #include <linux/netdevice.h> 11e6445719SPravin B Shelar #include <linux/etherdevice.h> 12e6445719SPravin B Shelar #include <linux/if_ether.h> 13e6445719SPravin B Shelar #include <linux/if_vlan.h> 14e6445719SPravin B Shelar #include <net/llc_pdu.h> 15e6445719SPravin B Shelar #include <linux/kernel.h> 1687545899SDaniel Borkmann #include <linux/jhash.h> 17e6445719SPravin B Shelar #include <linux/jiffies.h> 18e6445719SPravin B Shelar #include <linux/llc.h> 19e6445719SPravin B Shelar #include <linux/module.h> 20e6445719SPravin B Shelar #include <linux/in.h> 21e6445719SPravin B Shelar #include <linux/rcupdate.h> 22db74a333SThadeu Lima de Souza Cascardo #include <linux/cpumask.h> 23e6445719SPravin B Shelar #include <linux/if_arp.h> 24e6445719SPravin B Shelar #include <linux/ip.h> 25e6445719SPravin B Shelar #include <linux/ipv6.h> 26e6445719SPravin B Shelar #include <linux/sctp.h> 27e6445719SPravin B Shelar #include <linux/tcp.h> 28e6445719SPravin B Shelar #include <linux/udp.h> 29e6445719SPravin B Shelar #include <linux/icmp.h> 30e6445719SPravin B Shelar #include <linux/icmpv6.h> 31e6445719SPravin B Shelar #include <linux/rculist.h> 32e6445719SPravin B Shelar #include <net/ip.h> 33e6445719SPravin B Shelar #include <net/ipv6.h> 34e6445719SPravin B Shelar #include <net/ndisc.h> 35e6445719SPravin B Shelar 36b637e498SPravin B Shelar #define TBL_MIN_BUCKETS 1024 37b637e498SPravin B Shelar #define REHASH_INTERVAL (10 * 60 * HZ) 38b637e498SPravin B Shelar 39e6445719SPravin B Shelar static struct kmem_cache *flow_cache; 4063e7959cSJarno Rajahalme struct kmem_cache *flow_stats_cache __read_mostly; 41e6445719SPravin B Shelar 42e6445719SPravin B Shelar static u16 range_n_bytes(const struct sw_flow_key_range *range) 43e6445719SPravin B Shelar { 44e6445719SPravin B Shelar return range->end - range->start; 45e6445719SPravin B Shelar } 46e6445719SPravin B Shelar 47e6445719SPravin B Shelar void ovs_flow_mask_key(struct sw_flow_key *dst, const struct sw_flow_key *src, 48ae5f2fb1SJesse Gross bool full, const struct sw_flow_mask *mask) 49e6445719SPravin B Shelar { 50ae5f2fb1SJesse Gross int start = full ? 0 : mask->range.start; 51ae5f2fb1SJesse Gross int len = full ? sizeof *dst : range_n_bytes(&mask->range); 52ae5f2fb1SJesse Gross const long *m = (const long *)((const u8 *)&mask->key + start); 53ae5f2fb1SJesse Gross const long *s = (const long *)((const u8 *)src + start); 54ae5f2fb1SJesse Gross long *d = (long *)((u8 *)dst + start); 55e6445719SPravin B Shelar int i; 56e6445719SPravin B Shelar 57ae5f2fb1SJesse Gross /* If 'full' is true then all of 'dst' is fully initialized. Otherwise, 58ae5f2fb1SJesse Gross * if 'full' is false the memory outside of the 'mask->range' is left 59ae5f2fb1SJesse Gross * uninitialized. This can be used as an optimization when further 60ae5f2fb1SJesse Gross * operations on 'dst' only use contents within 'mask->range'. 61e6445719SPravin B Shelar */ 62ae5f2fb1SJesse Gross for (i = 0; i < len; i += sizeof(long)) 63e6445719SPravin B Shelar *d++ = *s++ & *m++; 64e6445719SPravin B Shelar } 65e6445719SPravin B Shelar 6623dabf88SJarno Rajahalme struct sw_flow *ovs_flow_alloc(void) 67e6445719SPravin B Shelar { 68e6445719SPravin B Shelar struct sw_flow *flow; 69*aef833c5SPablo Neira Ayuso struct sw_flow_stats *stats; 70e6445719SPravin B Shelar 71db74a333SThadeu Lima de Souza Cascardo flow = kmem_cache_zalloc(flow_cache, GFP_KERNEL); 72e6445719SPravin B Shelar if (!flow) 73e6445719SPravin B Shelar return ERR_PTR(-ENOMEM); 74e6445719SPravin B Shelar 75db74a333SThadeu Lima de Souza Cascardo flow->stats_last_writer = -1; 76e6445719SPravin B Shelar 7763e7959cSJarno Rajahalme /* Initialize the default stat node. */ 7863e7959cSJarno Rajahalme stats = kmem_cache_alloc_node(flow_stats_cache, 79598c12d0SKonstantin Khlebnikov GFP_KERNEL | __GFP_ZERO, 80598c12d0SKonstantin Khlebnikov node_online(0) ? 0 : NUMA_NO_NODE); 8163e7959cSJarno Rajahalme if (!stats) 82e298e505SPravin B Shelar goto err; 83e298e505SPravin B Shelar 8463e7959cSJarno Rajahalme spin_lock_init(&stats->lock); 85e298e505SPravin B Shelar 8663e7959cSJarno Rajahalme RCU_INIT_POINTER(flow->stats[0], stats); 8763e7959cSJarno Rajahalme 88c4b2bf6bSTonghao Zhang cpumask_set_cpu(0, &flow->cpu_used_mask); 89c4b2bf6bSTonghao Zhang 90e6445719SPravin B Shelar return flow; 91e298e505SPravin B Shelar err: 92ece37c87SWei Yongjun kmem_cache_free(flow_cache, flow); 93e298e505SPravin B Shelar return ERR_PTR(-ENOMEM); 94e6445719SPravin B Shelar } 95e6445719SPravin B Shelar 9612eb18f7SThomas Graf int ovs_flow_tbl_count(const struct flow_table *table) 97b637e498SPravin B Shelar { 98b637e498SPravin B Shelar return table->count; 99b637e498SPravin B Shelar } 100b637e498SPravin B Shelar 101e6445719SPravin B Shelar static void flow_free(struct sw_flow *flow) 102e6445719SPravin B Shelar { 103db74a333SThadeu Lima de Souza Cascardo int cpu; 10463e7959cSJarno Rajahalme 10574ed7ab9SJoe Stringer if (ovs_identifier_is_key(&flow->id)) 10674ed7ab9SJoe Stringer kfree(flow->id.unmasked_key); 10734ae932aSThomas Graf if (flow->sf_acts) 10834ae932aSThomas Graf ovs_nla_free_flow_actions((struct sw_flow_actions __force *)flow->sf_acts); 109db74a333SThadeu Lima de Souza Cascardo /* We open code this to make sure cpu 0 is always considered */ 110c4b2bf6bSTonghao Zhang for (cpu = 0; cpu < nr_cpu_ids; cpu = cpumask_next(cpu, &flow->cpu_used_mask)) 111db74a333SThadeu Lima de Souza Cascardo if (flow->stats[cpu]) 11263e7959cSJarno Rajahalme kmem_cache_free(flow_stats_cache, 113*aef833c5SPablo Neira Ayuso (struct sw_flow_stats __force *)flow->stats[cpu]); 114e6445719SPravin B Shelar kmem_cache_free(flow_cache, flow); 115e6445719SPravin B Shelar } 116e6445719SPravin B Shelar 117e6445719SPravin B Shelar static void rcu_free_flow_callback(struct rcu_head *rcu) 118e6445719SPravin B Shelar { 119e6445719SPravin B Shelar struct sw_flow *flow = container_of(rcu, struct sw_flow, rcu); 120e6445719SPravin B Shelar 121e6445719SPravin B Shelar flow_free(flow); 122e6445719SPravin B Shelar } 123e6445719SPravin B Shelar 124e80857ccSAndy Zhou void ovs_flow_free(struct sw_flow *flow, bool deferred) 125618ed0c8SPravin B Shelar { 126e80857ccSAndy Zhou if (!flow) 127618ed0c8SPravin B Shelar return; 128618ed0c8SPravin B Shelar 129e6445719SPravin B Shelar if (deferred) 130e6445719SPravin B Shelar call_rcu(&flow->rcu, rcu_free_flow_callback); 131e6445719SPravin B Shelar else 132e6445719SPravin B Shelar flow_free(flow); 133e6445719SPravin B Shelar } 134e6445719SPravin B Shelar 135b637e498SPravin B Shelar static void __table_instance_destroy(struct table_instance *ti) 136e6445719SPravin B Shelar { 137ee9c5e67SKent Overstreet kvfree(ti->buckets); 138b637e498SPravin B Shelar kfree(ti); 139e6445719SPravin B Shelar } 140e6445719SPravin B Shelar 141b637e498SPravin B Shelar static struct table_instance *table_instance_alloc(int new_size) 142e6445719SPravin B Shelar { 143b637e498SPravin B Shelar struct table_instance *ti = kmalloc(sizeof(*ti), GFP_KERNEL); 144ee9c5e67SKent Overstreet int i; 145e6445719SPravin B Shelar 146b637e498SPravin B Shelar if (!ti) 147e6445719SPravin B Shelar return NULL; 148e6445719SPravin B Shelar 149ee9c5e67SKent Overstreet ti->buckets = kvmalloc_array(new_size, sizeof(struct hlist_head), 150ee9c5e67SKent Overstreet GFP_KERNEL); 151b637e498SPravin B Shelar if (!ti->buckets) { 152b637e498SPravin B Shelar kfree(ti); 153e6445719SPravin B Shelar return NULL; 154e6445719SPravin B Shelar } 155ee9c5e67SKent Overstreet 156ee9c5e67SKent Overstreet for (i = 0; i < new_size; i++) 157ee9c5e67SKent Overstreet INIT_HLIST_HEAD(&ti->buckets[i]); 158ee9c5e67SKent Overstreet 159b637e498SPravin B Shelar ti->n_buckets = new_size; 160b637e498SPravin B Shelar ti->node_ver = 0; 161b637e498SPravin B Shelar ti->keep_flows = false; 162b637e498SPravin B Shelar get_random_bytes(&ti->hash_seed, sizeof(u32)); 163b637e498SPravin B Shelar 164b637e498SPravin B Shelar return ti; 165b637e498SPravin B Shelar } 166b637e498SPravin B Shelar 167b637e498SPravin B Shelar int ovs_flow_tbl_init(struct flow_table *table) 168b637e498SPravin B Shelar { 16974ed7ab9SJoe Stringer struct table_instance *ti, *ufid_ti; 170b637e498SPravin B Shelar 171b637e498SPravin B Shelar ti = table_instance_alloc(TBL_MIN_BUCKETS); 172b637e498SPravin B Shelar 173b637e498SPravin B Shelar if (!ti) 174b637e498SPravin B Shelar return -ENOMEM; 175b637e498SPravin B Shelar 17674ed7ab9SJoe Stringer ufid_ti = table_instance_alloc(TBL_MIN_BUCKETS); 17774ed7ab9SJoe Stringer if (!ufid_ti) 17874ed7ab9SJoe Stringer goto free_ti; 17974ed7ab9SJoe Stringer 180b637e498SPravin B Shelar rcu_assign_pointer(table->ti, ti); 18174ed7ab9SJoe Stringer rcu_assign_pointer(table->ufid_ti, ufid_ti); 182b637e498SPravin B Shelar INIT_LIST_HEAD(&table->mask_list); 183b637e498SPravin B Shelar table->last_rehash = jiffies; 184e6445719SPravin B Shelar table->count = 0; 18574ed7ab9SJoe Stringer table->ufid_count = 0; 186b637e498SPravin B Shelar return 0; 18774ed7ab9SJoe Stringer 18874ed7ab9SJoe Stringer free_ti: 18974ed7ab9SJoe Stringer __table_instance_destroy(ti); 19074ed7ab9SJoe Stringer return -ENOMEM; 191e6445719SPravin B Shelar } 192e6445719SPravin B Shelar 193e6445719SPravin B Shelar static void flow_tbl_destroy_rcu_cb(struct rcu_head *rcu) 194e6445719SPravin B Shelar { 195b637e498SPravin B Shelar struct table_instance *ti = container_of(rcu, struct table_instance, rcu); 196e6445719SPravin B Shelar 197b637e498SPravin B Shelar __table_instance_destroy(ti); 198b637e498SPravin B Shelar } 199b637e498SPravin B Shelar 20074ed7ab9SJoe Stringer static void table_instance_destroy(struct table_instance *ti, 20174ed7ab9SJoe Stringer struct table_instance *ufid_ti, 20274ed7ab9SJoe Stringer bool deferred) 203b637e498SPravin B Shelar { 204e80857ccSAndy Zhou int i; 205e80857ccSAndy Zhou 206b637e498SPravin B Shelar if (!ti) 207b637e498SPravin B Shelar return; 208b637e498SPravin B Shelar 20974ed7ab9SJoe Stringer BUG_ON(!ufid_ti); 210e80857ccSAndy Zhou if (ti->keep_flows) 211e80857ccSAndy Zhou goto skip_flows; 212e80857ccSAndy Zhou 213e80857ccSAndy Zhou for (i = 0; i < ti->n_buckets; i++) { 214e80857ccSAndy Zhou struct sw_flow *flow; 215ee9c5e67SKent Overstreet struct hlist_head *head = &ti->buckets[i]; 216e80857ccSAndy Zhou struct hlist_node *n; 217e80857ccSAndy Zhou int ver = ti->node_ver; 21874ed7ab9SJoe Stringer int ufid_ver = ufid_ti->node_ver; 219e80857ccSAndy Zhou 22074ed7ab9SJoe Stringer hlist_for_each_entry_safe(flow, n, head, flow_table.node[ver]) { 22174ed7ab9SJoe Stringer hlist_del_rcu(&flow->flow_table.node[ver]); 22274ed7ab9SJoe Stringer if (ovs_identifier_is_ufid(&flow->id)) 22374ed7ab9SJoe Stringer hlist_del_rcu(&flow->ufid_table.node[ufid_ver]); 224e80857ccSAndy Zhou ovs_flow_free(flow, deferred); 225e80857ccSAndy Zhou } 226e80857ccSAndy Zhou } 227e80857ccSAndy Zhou 228e80857ccSAndy Zhou skip_flows: 22974ed7ab9SJoe Stringer if (deferred) { 230b637e498SPravin B Shelar call_rcu(&ti->rcu, flow_tbl_destroy_rcu_cb); 23174ed7ab9SJoe Stringer call_rcu(&ufid_ti->rcu, flow_tbl_destroy_rcu_cb); 23274ed7ab9SJoe Stringer } else { 233b637e498SPravin B Shelar __table_instance_destroy(ti); 23474ed7ab9SJoe Stringer __table_instance_destroy(ufid_ti); 23574ed7ab9SJoe Stringer } 236e6445719SPravin B Shelar } 237e6445719SPravin B Shelar 2389b996e54SPravin B Shelar /* No need for locking this function is called from RCU callback or 2399b996e54SPravin B Shelar * error path. 2409b996e54SPravin B Shelar */ 2419b996e54SPravin B Shelar void ovs_flow_tbl_destroy(struct flow_table *table) 242e6445719SPravin B Shelar { 2439b996e54SPravin B Shelar struct table_instance *ti = rcu_dereference_raw(table->ti); 24474ed7ab9SJoe Stringer struct table_instance *ufid_ti = rcu_dereference_raw(table->ufid_ti); 245e6445719SPravin B Shelar 24674ed7ab9SJoe Stringer table_instance_destroy(ti, ufid_ti, false); 247e6445719SPravin B Shelar } 248e6445719SPravin B Shelar 249b637e498SPravin B Shelar struct sw_flow *ovs_flow_tbl_dump_next(struct table_instance *ti, 250e6445719SPravin B Shelar u32 *bucket, u32 *last) 251e6445719SPravin B Shelar { 252e6445719SPravin B Shelar struct sw_flow *flow; 253e6445719SPravin B Shelar struct hlist_head *head; 254e6445719SPravin B Shelar int ver; 255e6445719SPravin B Shelar int i; 256e6445719SPravin B Shelar 257b637e498SPravin B Shelar ver = ti->node_ver; 258b637e498SPravin B Shelar while (*bucket < ti->n_buckets) { 259e6445719SPravin B Shelar i = 0; 260ee9c5e67SKent Overstreet head = &ti->buckets[*bucket]; 26174ed7ab9SJoe Stringer hlist_for_each_entry_rcu(flow, head, flow_table.node[ver]) { 262e6445719SPravin B Shelar if (i < *last) { 263e6445719SPravin B Shelar i++; 264e6445719SPravin B Shelar continue; 265e6445719SPravin B Shelar } 266e6445719SPravin B Shelar *last = i + 1; 267e6445719SPravin B Shelar return flow; 268e6445719SPravin B Shelar } 269e6445719SPravin B Shelar (*bucket)++; 270e6445719SPravin B Shelar *last = 0; 271e6445719SPravin B Shelar } 272e6445719SPravin B Shelar 273e6445719SPravin B Shelar return NULL; 274e6445719SPravin B Shelar } 275e6445719SPravin B Shelar 276b637e498SPravin B Shelar static struct hlist_head *find_bucket(struct table_instance *ti, u32 hash) 277e6445719SPravin B Shelar { 278b637e498SPravin B Shelar hash = jhash_1word(hash, ti->hash_seed); 279ee9c5e67SKent Overstreet return &ti->buckets[hash & (ti->n_buckets - 1)]; 280e6445719SPravin B Shelar } 281e6445719SPravin B Shelar 28274ed7ab9SJoe Stringer static void table_instance_insert(struct table_instance *ti, 28374ed7ab9SJoe Stringer struct sw_flow *flow) 284e6445719SPravin B Shelar { 285e6445719SPravin B Shelar struct hlist_head *head; 286e6445719SPravin B Shelar 28774ed7ab9SJoe Stringer head = find_bucket(ti, flow->flow_table.hash); 28874ed7ab9SJoe Stringer hlist_add_head_rcu(&flow->flow_table.node[ti->node_ver], head); 28974ed7ab9SJoe Stringer } 29074ed7ab9SJoe Stringer 29174ed7ab9SJoe Stringer static void ufid_table_instance_insert(struct table_instance *ti, 29274ed7ab9SJoe Stringer struct sw_flow *flow) 29374ed7ab9SJoe Stringer { 29474ed7ab9SJoe Stringer struct hlist_head *head; 29574ed7ab9SJoe Stringer 29674ed7ab9SJoe Stringer head = find_bucket(ti, flow->ufid_table.hash); 29774ed7ab9SJoe Stringer hlist_add_head_rcu(&flow->ufid_table.node[ti->node_ver], head); 298e6445719SPravin B Shelar } 299e6445719SPravin B Shelar 300b637e498SPravin B Shelar static void flow_table_copy_flows(struct table_instance *old, 30174ed7ab9SJoe Stringer struct table_instance *new, bool ufid) 302e6445719SPravin B Shelar { 303e6445719SPravin B Shelar int old_ver; 304e6445719SPravin B Shelar int i; 305e6445719SPravin B Shelar 306e6445719SPravin B Shelar old_ver = old->node_ver; 307e6445719SPravin B Shelar new->node_ver = !old_ver; 308e6445719SPravin B Shelar 309e6445719SPravin B Shelar /* Insert in new table. */ 310e6445719SPravin B Shelar for (i = 0; i < old->n_buckets; i++) { 311e6445719SPravin B Shelar struct sw_flow *flow; 312ee9c5e67SKent Overstreet struct hlist_head *head = &old->buckets[i]; 313e6445719SPravin B Shelar 31474ed7ab9SJoe Stringer if (ufid) 31574ed7ab9SJoe Stringer hlist_for_each_entry(flow, head, 31674ed7ab9SJoe Stringer ufid_table.node[old_ver]) 31774ed7ab9SJoe Stringer ufid_table_instance_insert(new, flow); 31874ed7ab9SJoe Stringer else 31974ed7ab9SJoe Stringer hlist_for_each_entry(flow, head, 32074ed7ab9SJoe Stringer flow_table.node[old_ver]) 321b637e498SPravin B Shelar table_instance_insert(new, flow); 322e6445719SPravin B Shelar } 323e6445719SPravin B Shelar 324e6445719SPravin B Shelar old->keep_flows = true; 325e6445719SPravin B Shelar } 326e6445719SPravin B Shelar 327b637e498SPravin B Shelar static struct table_instance *table_instance_rehash(struct table_instance *ti, 32874ed7ab9SJoe Stringer int n_buckets, bool ufid) 329e6445719SPravin B Shelar { 330b637e498SPravin B Shelar struct table_instance *new_ti; 331e6445719SPravin B Shelar 332b637e498SPravin B Shelar new_ti = table_instance_alloc(n_buckets); 333b637e498SPravin B Shelar if (!new_ti) 334618ed0c8SPravin B Shelar return NULL; 335e6445719SPravin B Shelar 33674ed7ab9SJoe Stringer flow_table_copy_flows(ti, new_ti, ufid); 337e6445719SPravin B Shelar 338b637e498SPravin B Shelar return new_ti; 339e6445719SPravin B Shelar } 340e6445719SPravin B Shelar 341b637e498SPravin B Shelar int ovs_flow_tbl_flush(struct flow_table *flow_table) 342e6445719SPravin B Shelar { 34374ed7ab9SJoe Stringer struct table_instance *old_ti, *new_ti; 34474ed7ab9SJoe Stringer struct table_instance *old_ufid_ti, *new_ufid_ti; 345e6445719SPravin B Shelar 346b637e498SPravin B Shelar new_ti = table_instance_alloc(TBL_MIN_BUCKETS); 347b637e498SPravin B Shelar if (!new_ti) 348b637e498SPravin B Shelar return -ENOMEM; 34974ed7ab9SJoe Stringer new_ufid_ti = table_instance_alloc(TBL_MIN_BUCKETS); 35074ed7ab9SJoe Stringer if (!new_ufid_ti) 35174ed7ab9SJoe Stringer goto err_free_ti; 35274ed7ab9SJoe Stringer 35374ed7ab9SJoe Stringer old_ti = ovsl_dereference(flow_table->ti); 35474ed7ab9SJoe Stringer old_ufid_ti = ovsl_dereference(flow_table->ufid_ti); 355b637e498SPravin B Shelar 356b637e498SPravin B Shelar rcu_assign_pointer(flow_table->ti, new_ti); 35774ed7ab9SJoe Stringer rcu_assign_pointer(flow_table->ufid_ti, new_ufid_ti); 358b637e498SPravin B Shelar flow_table->last_rehash = jiffies; 359b637e498SPravin B Shelar flow_table->count = 0; 36074ed7ab9SJoe Stringer flow_table->ufid_count = 0; 361b637e498SPravin B Shelar 36274ed7ab9SJoe Stringer table_instance_destroy(old_ti, old_ufid_ti, true); 363b637e498SPravin B Shelar return 0; 36474ed7ab9SJoe Stringer 36574ed7ab9SJoe Stringer err_free_ti: 36674ed7ab9SJoe Stringer __table_instance_destroy(new_ti); 36774ed7ab9SJoe Stringer return -ENOMEM; 368e6445719SPravin B Shelar } 369e6445719SPravin B Shelar 370272c2cf8SJoe Stringer static u32 flow_hash(const struct sw_flow_key *key, 371272c2cf8SJoe Stringer const struct sw_flow_key_range *range) 372e6445719SPravin B Shelar { 373272c2cf8SJoe Stringer int key_start = range->start; 374272c2cf8SJoe Stringer int key_end = range->end; 3757085130bSDaniele Di Proietto const u32 *hash_key = (const u32 *)((const u8 *)key + key_start); 376e6445719SPravin B Shelar int hash_u32s = (key_end - key_start) >> 2; 377e6445719SPravin B Shelar 378e6445719SPravin B Shelar /* Make sure number of hash bytes are multiple of u32. */ 379e6445719SPravin B Shelar BUILD_BUG_ON(sizeof(long) % sizeof(u32)); 380e6445719SPravin B Shelar 38187545899SDaniel Borkmann return jhash2(hash_key, hash_u32s, 0); 382e6445719SPravin B Shelar } 383e6445719SPravin B Shelar 384e6445719SPravin B Shelar static int flow_key_start(const struct sw_flow_key *key) 385e6445719SPravin B Shelar { 38600a93babSJiri Benc if (key->tun_proto) 387e6445719SPravin B Shelar return 0; 388e6445719SPravin B Shelar else 389e6445719SPravin B Shelar return rounddown(offsetof(struct sw_flow_key, phy), 390e6445719SPravin B Shelar sizeof(long)); 391e6445719SPravin B Shelar } 392e6445719SPravin B Shelar 393e6445719SPravin B Shelar static bool cmp_key(const struct sw_flow_key *key1, 394e6445719SPravin B Shelar const struct sw_flow_key *key2, 395e6445719SPravin B Shelar int key_start, int key_end) 396e6445719SPravin B Shelar { 3977085130bSDaniele Di Proietto const long *cp1 = (const long *)((const u8 *)key1 + key_start); 3987085130bSDaniele Di Proietto const long *cp2 = (const long *)((const u8 *)key2 + key_start); 399e6445719SPravin B Shelar long diffs = 0; 400e6445719SPravin B Shelar int i; 401e6445719SPravin B Shelar 402e6445719SPravin B Shelar for (i = key_start; i < key_end; i += sizeof(long)) 403e6445719SPravin B Shelar diffs |= *cp1++ ^ *cp2++; 404e6445719SPravin B Shelar 405e6445719SPravin B Shelar return diffs == 0; 406e6445719SPravin B Shelar } 407e6445719SPravin B Shelar 408e6445719SPravin B Shelar static bool flow_cmp_masked_key(const struct sw_flow *flow, 409e6445719SPravin B Shelar const struct sw_flow_key *key, 410272c2cf8SJoe Stringer const struct sw_flow_key_range *range) 411e6445719SPravin B Shelar { 412272c2cf8SJoe Stringer return cmp_key(&flow->key, key, range->start, range->end); 413e6445719SPravin B Shelar } 414e6445719SPravin B Shelar 41574ed7ab9SJoe Stringer static bool ovs_flow_cmp_unmasked_key(const struct sw_flow *flow, 41612eb18f7SThomas Graf const struct sw_flow_match *match) 417e6445719SPravin B Shelar { 418e6445719SPravin B Shelar struct sw_flow_key *key = match->key; 419e6445719SPravin B Shelar int key_start = flow_key_start(key); 420e6445719SPravin B Shelar int key_end = match->range.end; 421e6445719SPravin B Shelar 42274ed7ab9SJoe Stringer BUG_ON(ovs_identifier_is_ufid(&flow->id)); 42374ed7ab9SJoe Stringer return cmp_key(flow->id.unmasked_key, key, key_start, key_end); 424e6445719SPravin B Shelar } 425e6445719SPravin B Shelar 426b637e498SPravin B Shelar static struct sw_flow *masked_flow_lookup(struct table_instance *ti, 427e6445719SPravin B Shelar const struct sw_flow_key *unmasked, 42812eb18f7SThomas Graf const struct sw_flow_mask *mask) 429e6445719SPravin B Shelar { 430e6445719SPravin B Shelar struct sw_flow *flow; 431e6445719SPravin B Shelar struct hlist_head *head; 432e6445719SPravin B Shelar u32 hash; 433e6445719SPravin B Shelar struct sw_flow_key masked_key; 434e6445719SPravin B Shelar 435ae5f2fb1SJesse Gross ovs_flow_mask_key(&masked_key, unmasked, false, mask); 436272c2cf8SJoe Stringer hash = flow_hash(&masked_key, &mask->range); 437b637e498SPravin B Shelar head = find_bucket(ti, hash); 43874ed7ab9SJoe Stringer hlist_for_each_entry_rcu(flow, head, flow_table.node[ti->node_ver]) { 43974ed7ab9SJoe Stringer if (flow->mask == mask && flow->flow_table.hash == hash && 440272c2cf8SJoe Stringer flow_cmp_masked_key(flow, &masked_key, &mask->range)) 441e6445719SPravin B Shelar return flow; 442e6445719SPravin B Shelar } 443e6445719SPravin B Shelar return NULL; 444e6445719SPravin B Shelar } 445e6445719SPravin B Shelar 4465bb50632SAndy Zhou struct sw_flow *ovs_flow_tbl_lookup_stats(struct flow_table *tbl, 4471bd7116fSAndy Zhou const struct sw_flow_key *key, 4481bd7116fSAndy Zhou u32 *n_mask_hit) 449e6445719SPravin B Shelar { 450663efa36SJesse Gross struct table_instance *ti = rcu_dereference_ovsl(tbl->ti); 451e6445719SPravin B Shelar struct sw_flow_mask *mask; 452b637e498SPravin B Shelar struct sw_flow *flow; 453e6445719SPravin B Shelar 4541bd7116fSAndy Zhou *n_mask_hit = 0; 455b637e498SPravin B Shelar list_for_each_entry_rcu(mask, &tbl->mask_list, list) { 4561bd7116fSAndy Zhou (*n_mask_hit)++; 457b637e498SPravin B Shelar flow = masked_flow_lookup(ti, key, mask); 458e6445719SPravin B Shelar if (flow) /* Found */ 459b637e498SPravin B Shelar return flow; 460b637e498SPravin B Shelar } 461b637e498SPravin B Shelar return NULL; 462e6445719SPravin B Shelar } 463e6445719SPravin B Shelar 4645bb50632SAndy Zhou struct sw_flow *ovs_flow_tbl_lookup(struct flow_table *tbl, 4655bb50632SAndy Zhou const struct sw_flow_key *key) 4665bb50632SAndy Zhou { 4675bb50632SAndy Zhou u32 __always_unused n_mask_hit; 4685bb50632SAndy Zhou 4695bb50632SAndy Zhou return ovs_flow_tbl_lookup_stats(tbl, key, &n_mask_hit); 4705bb50632SAndy Zhou } 4715bb50632SAndy Zhou 4724a46b24eSAlex Wang struct sw_flow *ovs_flow_tbl_lookup_exact(struct flow_table *tbl, 47312eb18f7SThomas Graf const struct sw_flow_match *match) 4744a46b24eSAlex Wang { 4754a46b24eSAlex Wang struct table_instance *ti = rcu_dereference_ovsl(tbl->ti); 4764a46b24eSAlex Wang struct sw_flow_mask *mask; 4774a46b24eSAlex Wang struct sw_flow *flow; 4784a46b24eSAlex Wang 4794a46b24eSAlex Wang /* Always called under ovs-mutex. */ 4804a46b24eSAlex Wang list_for_each_entry(mask, &tbl->mask_list, list) { 4814a46b24eSAlex Wang flow = masked_flow_lookup(ti, match->key, mask); 48274ed7ab9SJoe Stringer if (flow && ovs_identifier_is_key(&flow->id) && 48374ed7ab9SJoe Stringer ovs_flow_cmp_unmasked_key(flow, match)) 48474ed7ab9SJoe Stringer return flow; 48574ed7ab9SJoe Stringer } 48674ed7ab9SJoe Stringer return NULL; 48774ed7ab9SJoe Stringer } 48874ed7ab9SJoe Stringer 48974ed7ab9SJoe Stringer static u32 ufid_hash(const struct sw_flow_id *sfid) 49074ed7ab9SJoe Stringer { 49174ed7ab9SJoe Stringer return jhash(sfid->ufid, sfid->ufid_len, 0); 49274ed7ab9SJoe Stringer } 49374ed7ab9SJoe Stringer 49474ed7ab9SJoe Stringer static bool ovs_flow_cmp_ufid(const struct sw_flow *flow, 49574ed7ab9SJoe Stringer const struct sw_flow_id *sfid) 49674ed7ab9SJoe Stringer { 49774ed7ab9SJoe Stringer if (flow->id.ufid_len != sfid->ufid_len) 49874ed7ab9SJoe Stringer return false; 49974ed7ab9SJoe Stringer 50074ed7ab9SJoe Stringer return !memcmp(flow->id.ufid, sfid->ufid, sfid->ufid_len); 50174ed7ab9SJoe Stringer } 50274ed7ab9SJoe Stringer 50374ed7ab9SJoe Stringer bool ovs_flow_cmp(const struct sw_flow *flow, const struct sw_flow_match *match) 50474ed7ab9SJoe Stringer { 50574ed7ab9SJoe Stringer if (ovs_identifier_is_ufid(&flow->id)) 50674ed7ab9SJoe Stringer return flow_cmp_masked_key(flow, match->key, &match->range); 50774ed7ab9SJoe Stringer 50874ed7ab9SJoe Stringer return ovs_flow_cmp_unmasked_key(flow, match); 50974ed7ab9SJoe Stringer } 51074ed7ab9SJoe Stringer 51174ed7ab9SJoe Stringer struct sw_flow *ovs_flow_tbl_lookup_ufid(struct flow_table *tbl, 51274ed7ab9SJoe Stringer const struct sw_flow_id *ufid) 51374ed7ab9SJoe Stringer { 51474ed7ab9SJoe Stringer struct table_instance *ti = rcu_dereference_ovsl(tbl->ufid_ti); 51574ed7ab9SJoe Stringer struct sw_flow *flow; 51674ed7ab9SJoe Stringer struct hlist_head *head; 51774ed7ab9SJoe Stringer u32 hash; 51874ed7ab9SJoe Stringer 51974ed7ab9SJoe Stringer hash = ufid_hash(ufid); 52074ed7ab9SJoe Stringer head = find_bucket(ti, hash); 52174ed7ab9SJoe Stringer hlist_for_each_entry_rcu(flow, head, ufid_table.node[ti->node_ver]) { 52274ed7ab9SJoe Stringer if (flow->ufid_table.hash == hash && 52374ed7ab9SJoe Stringer ovs_flow_cmp_ufid(flow, ufid)) 5244a46b24eSAlex Wang return flow; 5254a46b24eSAlex Wang } 5264a46b24eSAlex Wang return NULL; 5274a46b24eSAlex Wang } 5284a46b24eSAlex Wang 5291bd7116fSAndy Zhou int ovs_flow_tbl_num_masks(const struct flow_table *table) 5301bd7116fSAndy Zhou { 5311bd7116fSAndy Zhou struct sw_flow_mask *mask; 5321bd7116fSAndy Zhou int num = 0; 5331bd7116fSAndy Zhou 5341bd7116fSAndy Zhou list_for_each_entry(mask, &table->mask_list, list) 5351bd7116fSAndy Zhou num++; 5361bd7116fSAndy Zhou 5371bd7116fSAndy Zhou return num; 5381bd7116fSAndy Zhou } 5391bd7116fSAndy Zhou 54074ed7ab9SJoe Stringer static struct table_instance *table_instance_expand(struct table_instance *ti, 54174ed7ab9SJoe Stringer bool ufid) 542b637e498SPravin B Shelar { 54374ed7ab9SJoe Stringer return table_instance_rehash(ti, ti->n_buckets * 2, ufid); 544e6445719SPravin B Shelar } 545e6445719SPravin B Shelar 54656c19868SJarno Rajahalme /* Remove 'mask' from the mask list, if it is not needed any more. */ 54756c19868SJarno Rajahalme static void flow_mask_remove(struct flow_table *tbl, struct sw_flow_mask *mask) 54856c19868SJarno Rajahalme { 54956c19868SJarno Rajahalme if (mask) { 55056c19868SJarno Rajahalme /* ovs-lock is required to protect mask-refcount and 55156c19868SJarno Rajahalme * mask list. 55256c19868SJarno Rajahalme */ 55356c19868SJarno Rajahalme ASSERT_OVSL(); 55456c19868SJarno Rajahalme BUG_ON(!mask->ref_count); 55556c19868SJarno Rajahalme mask->ref_count--; 55656c19868SJarno Rajahalme 55756c19868SJarno Rajahalme if (!mask->ref_count) { 55856c19868SJarno Rajahalme list_del_rcu(&mask->list); 55956c19868SJarno Rajahalme kfree_rcu(mask, rcu); 56056c19868SJarno Rajahalme } 56156c19868SJarno Rajahalme } 56256c19868SJarno Rajahalme } 56356c19868SJarno Rajahalme 56456c19868SJarno Rajahalme /* Must be called with OVS mutex held. */ 565e6445719SPravin B Shelar void ovs_flow_tbl_remove(struct flow_table *table, struct sw_flow *flow) 566e6445719SPravin B Shelar { 567b637e498SPravin B Shelar struct table_instance *ti = ovsl_dereference(table->ti); 56874ed7ab9SJoe Stringer struct table_instance *ufid_ti = ovsl_dereference(table->ufid_ti); 569b637e498SPravin B Shelar 570e6445719SPravin B Shelar BUG_ON(table->count == 0); 57174ed7ab9SJoe Stringer hlist_del_rcu(&flow->flow_table.node[ti->node_ver]); 572e6445719SPravin B Shelar table->count--; 57374ed7ab9SJoe Stringer if (ovs_identifier_is_ufid(&flow->id)) { 57474ed7ab9SJoe Stringer hlist_del_rcu(&flow->ufid_table.node[ufid_ti->node_ver]); 57574ed7ab9SJoe Stringer table->ufid_count--; 57674ed7ab9SJoe Stringer } 57756c19868SJarno Rajahalme 57856c19868SJarno Rajahalme /* RCU delete the mask. 'flow->mask' is not NULLed, as it should be 57956c19868SJarno Rajahalme * accessible as long as the RCU read lock is held. 58056c19868SJarno Rajahalme */ 58156c19868SJarno Rajahalme flow_mask_remove(table, flow->mask); 582e6445719SPravin B Shelar } 583e6445719SPravin B Shelar 584618ed0c8SPravin B Shelar static struct sw_flow_mask *mask_alloc(void) 585e6445719SPravin B Shelar { 586e6445719SPravin B Shelar struct sw_flow_mask *mask; 587e6445719SPravin B Shelar 588e6445719SPravin B Shelar mask = kmalloc(sizeof(*mask), GFP_KERNEL); 589e6445719SPravin B Shelar if (mask) 590e80857ccSAndy Zhou mask->ref_count = 1; 591e6445719SPravin B Shelar 592e6445719SPravin B Shelar return mask; 593e6445719SPravin B Shelar } 594e6445719SPravin B Shelar 595e6445719SPravin B Shelar static bool mask_equal(const struct sw_flow_mask *a, 596e6445719SPravin B Shelar const struct sw_flow_mask *b) 597e6445719SPravin B Shelar { 5987085130bSDaniele Di Proietto const u8 *a_ = (const u8 *)&a->key + a->range.start; 5997085130bSDaniele Di Proietto const u8 *b_ = (const u8 *)&b->key + b->range.start; 600e6445719SPravin B Shelar 601e6445719SPravin B Shelar return (a->range.end == b->range.end) 602e6445719SPravin B Shelar && (a->range.start == b->range.start) 603e6445719SPravin B Shelar && (memcmp(a_, b_, range_n_bytes(&a->range)) == 0); 604e6445719SPravin B Shelar } 605e6445719SPravin B Shelar 606618ed0c8SPravin B Shelar static struct sw_flow_mask *flow_mask_find(const struct flow_table *tbl, 607e6445719SPravin B Shelar const struct sw_flow_mask *mask) 608e6445719SPravin B Shelar { 609e6445719SPravin B Shelar struct list_head *ml; 610e6445719SPravin B Shelar 611b637e498SPravin B Shelar list_for_each(ml, &tbl->mask_list) { 612e6445719SPravin B Shelar struct sw_flow_mask *m; 613e6445719SPravin B Shelar m = container_of(ml, struct sw_flow_mask, list); 614e6445719SPravin B Shelar if (mask_equal(mask, m)) 615e6445719SPravin B Shelar return m; 616e6445719SPravin B Shelar } 617e6445719SPravin B Shelar 618e6445719SPravin B Shelar return NULL; 619e6445719SPravin B Shelar } 620e6445719SPravin B Shelar 621d1211908SBen Pfaff /* Add 'mask' into the mask list, if it is not already there. */ 622618ed0c8SPravin B Shelar static int flow_mask_insert(struct flow_table *tbl, struct sw_flow *flow, 62312eb18f7SThomas Graf const struct sw_flow_mask *new) 624e6445719SPravin B Shelar { 625618ed0c8SPravin B Shelar struct sw_flow_mask *mask; 626618ed0c8SPravin B Shelar mask = flow_mask_find(tbl, new); 627618ed0c8SPravin B Shelar if (!mask) { 628618ed0c8SPravin B Shelar /* Allocate a new mask if none exsits. */ 629618ed0c8SPravin B Shelar mask = mask_alloc(); 630618ed0c8SPravin B Shelar if (!mask) 631618ed0c8SPravin B Shelar return -ENOMEM; 632618ed0c8SPravin B Shelar mask->key = new->key; 633618ed0c8SPravin B Shelar mask->range = new->range; 634b637e498SPravin B Shelar list_add_rcu(&mask->list, &tbl->mask_list); 635e80857ccSAndy Zhou } else { 636e80857ccSAndy Zhou BUG_ON(!mask->ref_count); 637e80857ccSAndy Zhou mask->ref_count++; 638e6445719SPravin B Shelar } 639e6445719SPravin B Shelar 640618ed0c8SPravin B Shelar flow->mask = mask; 641618ed0c8SPravin B Shelar return 0; 642618ed0c8SPravin B Shelar } 643618ed0c8SPravin B Shelar 64456c19868SJarno Rajahalme /* Must be called with OVS mutex held. */ 645d29ab6f8SJoe Stringer static void flow_key_insert(struct flow_table *table, struct sw_flow *flow) 646618ed0c8SPravin B Shelar { 647618ed0c8SPravin B Shelar struct table_instance *new_ti = NULL; 648618ed0c8SPravin B Shelar struct table_instance *ti; 649618ed0c8SPravin B Shelar 65074ed7ab9SJoe Stringer flow->flow_table.hash = flow_hash(&flow->key, &flow->mask->range); 651618ed0c8SPravin B Shelar ti = ovsl_dereference(table->ti); 652618ed0c8SPravin B Shelar table_instance_insert(ti, flow); 653618ed0c8SPravin B Shelar table->count++; 654618ed0c8SPravin B Shelar 655618ed0c8SPravin B Shelar /* Expand table, if necessary, to make room. */ 656618ed0c8SPravin B Shelar if (table->count > ti->n_buckets) 65774ed7ab9SJoe Stringer new_ti = table_instance_expand(ti, false); 658618ed0c8SPravin B Shelar else if (time_after(jiffies, table->last_rehash + REHASH_INTERVAL)) 65974ed7ab9SJoe Stringer new_ti = table_instance_rehash(ti, ti->n_buckets, false); 660618ed0c8SPravin B Shelar 661618ed0c8SPravin B Shelar if (new_ti) { 662618ed0c8SPravin B Shelar rcu_assign_pointer(table->ti, new_ti); 66374ed7ab9SJoe Stringer call_rcu(&ti->rcu, flow_tbl_destroy_rcu_cb); 664618ed0c8SPravin B Shelar table->last_rehash = jiffies; 665618ed0c8SPravin B Shelar } 666d29ab6f8SJoe Stringer } 667d29ab6f8SJoe Stringer 668d29ab6f8SJoe Stringer /* Must be called with OVS mutex held. */ 66974ed7ab9SJoe Stringer static void flow_ufid_insert(struct flow_table *table, struct sw_flow *flow) 67074ed7ab9SJoe Stringer { 67174ed7ab9SJoe Stringer struct table_instance *ti; 67274ed7ab9SJoe Stringer 67374ed7ab9SJoe Stringer flow->ufid_table.hash = ufid_hash(&flow->id); 67474ed7ab9SJoe Stringer ti = ovsl_dereference(table->ufid_ti); 67574ed7ab9SJoe Stringer ufid_table_instance_insert(ti, flow); 67674ed7ab9SJoe Stringer table->ufid_count++; 67774ed7ab9SJoe Stringer 67874ed7ab9SJoe Stringer /* Expand table, if necessary, to make room. */ 67974ed7ab9SJoe Stringer if (table->ufid_count > ti->n_buckets) { 68074ed7ab9SJoe Stringer struct table_instance *new_ti; 68174ed7ab9SJoe Stringer 68274ed7ab9SJoe Stringer new_ti = table_instance_expand(ti, true); 68374ed7ab9SJoe Stringer if (new_ti) { 68474ed7ab9SJoe Stringer rcu_assign_pointer(table->ufid_ti, new_ti); 68574ed7ab9SJoe Stringer call_rcu(&ti->rcu, flow_tbl_destroy_rcu_cb); 68674ed7ab9SJoe Stringer } 68774ed7ab9SJoe Stringer } 68874ed7ab9SJoe Stringer } 68974ed7ab9SJoe Stringer 69074ed7ab9SJoe Stringer /* Must be called with OVS mutex held. */ 691d29ab6f8SJoe Stringer int ovs_flow_tbl_insert(struct flow_table *table, struct sw_flow *flow, 692d29ab6f8SJoe Stringer const struct sw_flow_mask *mask) 693d29ab6f8SJoe Stringer { 694d29ab6f8SJoe Stringer int err; 695d29ab6f8SJoe Stringer 696d29ab6f8SJoe Stringer err = flow_mask_insert(table, flow, mask); 697d29ab6f8SJoe Stringer if (err) 698d29ab6f8SJoe Stringer return err; 699d29ab6f8SJoe Stringer flow_key_insert(table, flow); 70074ed7ab9SJoe Stringer if (ovs_identifier_is_ufid(&flow->id)) 70174ed7ab9SJoe Stringer flow_ufid_insert(table, flow); 702d29ab6f8SJoe Stringer 703618ed0c8SPravin B Shelar return 0; 704618ed0c8SPravin B Shelar } 705618ed0c8SPravin B Shelar 706e6445719SPravin B Shelar /* Initializes the flow module. 707e6445719SPravin B Shelar * Returns zero if successful or a negative error code. */ 708e6445719SPravin B Shelar int ovs_flow_init(void) 709e6445719SPravin B Shelar { 710e6445719SPravin B Shelar BUILD_BUG_ON(__alignof__(struct sw_flow_key) % __alignof__(long)); 711e6445719SPravin B Shelar BUILD_BUG_ON(sizeof(struct sw_flow_key) % sizeof(long)); 712e6445719SPravin B Shelar 71363e7959cSJarno Rajahalme flow_cache = kmem_cache_create("sw_flow", sizeof(struct sw_flow) 714db74a333SThadeu Lima de Souza Cascardo + (nr_cpu_ids 715*aef833c5SPablo Neira Ayuso * sizeof(struct sw_flow_stats *)), 71663e7959cSJarno Rajahalme 0, 0, NULL); 717e6445719SPravin B Shelar if (flow_cache == NULL) 718e6445719SPravin B Shelar return -ENOMEM; 719e6445719SPravin B Shelar 72063e7959cSJarno Rajahalme flow_stats_cache 721*aef833c5SPablo Neira Ayuso = kmem_cache_create("sw_flow_stats", sizeof(struct sw_flow_stats), 72263e7959cSJarno Rajahalme 0, SLAB_HWCACHE_ALIGN, NULL); 72363e7959cSJarno Rajahalme if (flow_stats_cache == NULL) { 72463e7959cSJarno Rajahalme kmem_cache_destroy(flow_cache); 72563e7959cSJarno Rajahalme flow_cache = NULL; 72663e7959cSJarno Rajahalme return -ENOMEM; 72763e7959cSJarno Rajahalme } 72863e7959cSJarno Rajahalme 729e6445719SPravin B Shelar return 0; 730e6445719SPravin B Shelar } 731e6445719SPravin B Shelar 732e6445719SPravin B Shelar /* Uninitializes the flow module. */ 733e6445719SPravin B Shelar void ovs_flow_exit(void) 734e6445719SPravin B Shelar { 73563e7959cSJarno Rajahalme kmem_cache_destroy(flow_stats_cache); 736e6445719SPravin B Shelar kmem_cache_destroy(flow_cache); 737e6445719SPravin B Shelar } 738