1*e6445719SPravin B Shelar /* 2*e6445719SPravin B Shelar * Copyright (c) 2007-2013 Nicira, Inc. 3*e6445719SPravin B Shelar * 4*e6445719SPravin B Shelar * This program is free software; you can redistribute it and/or 5*e6445719SPravin B Shelar * modify it under the terms of version 2 of the GNU General Public 6*e6445719SPravin B Shelar * License as published by the Free Software Foundation. 7*e6445719SPravin B Shelar * 8*e6445719SPravin B Shelar * This program is distributed in the hope that it will be useful, but 9*e6445719SPravin B Shelar * WITHOUT ANY WARRANTY; without even the implied warranty of 10*e6445719SPravin B Shelar * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11*e6445719SPravin B Shelar * General Public License for more details. 12*e6445719SPravin B Shelar * 13*e6445719SPravin B Shelar * You should have received a copy of the GNU General Public License 14*e6445719SPravin B Shelar * along with this program; if not, write to the Free Software 15*e6445719SPravin B Shelar * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 16*e6445719SPravin B Shelar * 02110-1301, USA 17*e6445719SPravin B Shelar */ 18*e6445719SPravin B Shelar 19*e6445719SPravin B Shelar #include "flow.h" 20*e6445719SPravin B Shelar #include "datapath.h" 21*e6445719SPravin B Shelar #include <linux/uaccess.h> 22*e6445719SPravin B Shelar #include <linux/netdevice.h> 23*e6445719SPravin B Shelar #include <linux/etherdevice.h> 24*e6445719SPravin B Shelar #include <linux/if_ether.h> 25*e6445719SPravin B Shelar #include <linux/if_vlan.h> 26*e6445719SPravin B Shelar #include <net/llc_pdu.h> 27*e6445719SPravin B Shelar #include <linux/kernel.h> 28*e6445719SPravin B Shelar #include <linux/jhash.h> 29*e6445719SPravin B Shelar #include <linux/jiffies.h> 30*e6445719SPravin B Shelar #include <linux/llc.h> 31*e6445719SPravin B Shelar #include <linux/module.h> 32*e6445719SPravin B Shelar #include <linux/in.h> 33*e6445719SPravin B Shelar #include <linux/rcupdate.h> 34*e6445719SPravin B Shelar #include <linux/if_arp.h> 35*e6445719SPravin B Shelar #include <linux/ip.h> 36*e6445719SPravin B Shelar #include <linux/ipv6.h> 37*e6445719SPravin B Shelar #include <linux/sctp.h> 38*e6445719SPravin B Shelar #include <linux/tcp.h> 39*e6445719SPravin B Shelar #include <linux/udp.h> 40*e6445719SPravin B Shelar #include <linux/icmp.h> 41*e6445719SPravin B Shelar #include <linux/icmpv6.h> 42*e6445719SPravin B Shelar #include <linux/rculist.h> 43*e6445719SPravin B Shelar #include <net/ip.h> 44*e6445719SPravin B Shelar #include <net/ipv6.h> 45*e6445719SPravin B Shelar #include <net/ndisc.h> 46*e6445719SPravin B Shelar 47*e6445719SPravin B Shelar static struct kmem_cache *flow_cache; 48*e6445719SPravin B Shelar 49*e6445719SPravin B Shelar static u16 range_n_bytes(const struct sw_flow_key_range *range) 50*e6445719SPravin B Shelar { 51*e6445719SPravin B Shelar return range->end - range->start; 52*e6445719SPravin B Shelar } 53*e6445719SPravin B Shelar 54*e6445719SPravin B Shelar void ovs_flow_mask_key(struct sw_flow_key *dst, const struct sw_flow_key *src, 55*e6445719SPravin B Shelar const struct sw_flow_mask *mask) 56*e6445719SPravin B Shelar { 57*e6445719SPravin B Shelar const long *m = (long *)((u8 *)&mask->key + mask->range.start); 58*e6445719SPravin B Shelar const long *s = (long *)((u8 *)src + mask->range.start); 59*e6445719SPravin B Shelar long *d = (long *)((u8 *)dst + mask->range.start); 60*e6445719SPravin B Shelar int i; 61*e6445719SPravin B Shelar 62*e6445719SPravin B Shelar /* The memory outside of the 'mask->range' are not set since 63*e6445719SPravin B Shelar * further operations on 'dst' only uses contents within 64*e6445719SPravin B Shelar * 'mask->range'. 65*e6445719SPravin B Shelar */ 66*e6445719SPravin B Shelar for (i = 0; i < range_n_bytes(&mask->range); i += sizeof(long)) 67*e6445719SPravin B Shelar *d++ = *s++ & *m++; 68*e6445719SPravin B Shelar } 69*e6445719SPravin B Shelar 70*e6445719SPravin B Shelar struct sw_flow *ovs_flow_alloc(void) 71*e6445719SPravin B Shelar { 72*e6445719SPravin B Shelar struct sw_flow *flow; 73*e6445719SPravin B Shelar 74*e6445719SPravin B Shelar flow = kmem_cache_alloc(flow_cache, GFP_KERNEL); 75*e6445719SPravin B Shelar if (!flow) 76*e6445719SPravin B Shelar return ERR_PTR(-ENOMEM); 77*e6445719SPravin B Shelar 78*e6445719SPravin B Shelar spin_lock_init(&flow->lock); 79*e6445719SPravin B Shelar flow->sf_acts = NULL; 80*e6445719SPravin B Shelar flow->mask = NULL; 81*e6445719SPravin B Shelar 82*e6445719SPravin B Shelar return flow; 83*e6445719SPravin B Shelar } 84*e6445719SPravin B Shelar 85*e6445719SPravin B Shelar static struct flex_array *alloc_buckets(unsigned int n_buckets) 86*e6445719SPravin B Shelar { 87*e6445719SPravin B Shelar struct flex_array *buckets; 88*e6445719SPravin B Shelar int i, err; 89*e6445719SPravin B Shelar 90*e6445719SPravin B Shelar buckets = flex_array_alloc(sizeof(struct hlist_head), 91*e6445719SPravin B Shelar n_buckets, GFP_KERNEL); 92*e6445719SPravin B Shelar if (!buckets) 93*e6445719SPravin B Shelar return NULL; 94*e6445719SPravin B Shelar 95*e6445719SPravin B Shelar err = flex_array_prealloc(buckets, 0, n_buckets, GFP_KERNEL); 96*e6445719SPravin B Shelar if (err) { 97*e6445719SPravin B Shelar flex_array_free(buckets); 98*e6445719SPravin B Shelar return NULL; 99*e6445719SPravin B Shelar } 100*e6445719SPravin B Shelar 101*e6445719SPravin B Shelar for (i = 0; i < n_buckets; i++) 102*e6445719SPravin B Shelar INIT_HLIST_HEAD((struct hlist_head *) 103*e6445719SPravin B Shelar flex_array_get(buckets, i)); 104*e6445719SPravin B Shelar 105*e6445719SPravin B Shelar return buckets; 106*e6445719SPravin B Shelar } 107*e6445719SPravin B Shelar 108*e6445719SPravin B Shelar static void flow_free(struct sw_flow *flow) 109*e6445719SPravin B Shelar { 110*e6445719SPravin B Shelar kfree((struct sf_flow_acts __force *)flow->sf_acts); 111*e6445719SPravin B Shelar kmem_cache_free(flow_cache, flow); 112*e6445719SPravin B Shelar } 113*e6445719SPravin B Shelar 114*e6445719SPravin B Shelar static void rcu_free_flow_callback(struct rcu_head *rcu) 115*e6445719SPravin B Shelar { 116*e6445719SPravin B Shelar struct sw_flow *flow = container_of(rcu, struct sw_flow, rcu); 117*e6445719SPravin B Shelar 118*e6445719SPravin B Shelar flow_free(flow); 119*e6445719SPravin B Shelar } 120*e6445719SPravin B Shelar 121*e6445719SPravin B Shelar void ovs_flow_free(struct sw_flow *flow, bool deferred) 122*e6445719SPravin B Shelar { 123*e6445719SPravin B Shelar if (!flow) 124*e6445719SPravin B Shelar return; 125*e6445719SPravin B Shelar 126*e6445719SPravin B Shelar ovs_sw_flow_mask_del_ref(flow->mask, deferred); 127*e6445719SPravin B Shelar 128*e6445719SPravin B Shelar if (deferred) 129*e6445719SPravin B Shelar call_rcu(&flow->rcu, rcu_free_flow_callback); 130*e6445719SPravin B Shelar else 131*e6445719SPravin B Shelar flow_free(flow); 132*e6445719SPravin B Shelar } 133*e6445719SPravin B Shelar 134*e6445719SPravin B Shelar static void free_buckets(struct flex_array *buckets) 135*e6445719SPravin B Shelar { 136*e6445719SPravin B Shelar flex_array_free(buckets); 137*e6445719SPravin B Shelar } 138*e6445719SPravin B Shelar 139*e6445719SPravin B Shelar static void __flow_tbl_destroy(struct flow_table *table) 140*e6445719SPravin B Shelar { 141*e6445719SPravin B Shelar int i; 142*e6445719SPravin B Shelar 143*e6445719SPravin B Shelar if (table->keep_flows) 144*e6445719SPravin B Shelar goto skip_flows; 145*e6445719SPravin B Shelar 146*e6445719SPravin B Shelar for (i = 0; i < table->n_buckets; i++) { 147*e6445719SPravin B Shelar struct sw_flow *flow; 148*e6445719SPravin B Shelar struct hlist_head *head = flex_array_get(table->buckets, i); 149*e6445719SPravin B Shelar struct hlist_node *n; 150*e6445719SPravin B Shelar int ver = table->node_ver; 151*e6445719SPravin B Shelar 152*e6445719SPravin B Shelar hlist_for_each_entry_safe(flow, n, head, hash_node[ver]) { 153*e6445719SPravin B Shelar hlist_del(&flow->hash_node[ver]); 154*e6445719SPravin B Shelar ovs_flow_free(flow, false); 155*e6445719SPravin B Shelar } 156*e6445719SPravin B Shelar } 157*e6445719SPravin B Shelar 158*e6445719SPravin B Shelar BUG_ON(!list_empty(table->mask_list)); 159*e6445719SPravin B Shelar kfree(table->mask_list); 160*e6445719SPravin B Shelar 161*e6445719SPravin B Shelar skip_flows: 162*e6445719SPravin B Shelar free_buckets(table->buckets); 163*e6445719SPravin B Shelar kfree(table); 164*e6445719SPravin B Shelar } 165*e6445719SPravin B Shelar 166*e6445719SPravin B Shelar static struct flow_table *__flow_tbl_alloc(int new_size) 167*e6445719SPravin B Shelar { 168*e6445719SPravin B Shelar struct flow_table *table = kmalloc(sizeof(*table), GFP_KERNEL); 169*e6445719SPravin B Shelar 170*e6445719SPravin B Shelar if (!table) 171*e6445719SPravin B Shelar return NULL; 172*e6445719SPravin B Shelar 173*e6445719SPravin B Shelar table->buckets = alloc_buckets(new_size); 174*e6445719SPravin B Shelar 175*e6445719SPravin B Shelar if (!table->buckets) { 176*e6445719SPravin B Shelar kfree(table); 177*e6445719SPravin B Shelar return NULL; 178*e6445719SPravin B Shelar } 179*e6445719SPravin B Shelar table->n_buckets = new_size; 180*e6445719SPravin B Shelar table->count = 0; 181*e6445719SPravin B Shelar table->node_ver = 0; 182*e6445719SPravin B Shelar table->keep_flows = false; 183*e6445719SPravin B Shelar get_random_bytes(&table->hash_seed, sizeof(u32)); 184*e6445719SPravin B Shelar table->mask_list = NULL; 185*e6445719SPravin B Shelar 186*e6445719SPravin B Shelar return table; 187*e6445719SPravin B Shelar } 188*e6445719SPravin B Shelar 189*e6445719SPravin B Shelar struct flow_table *ovs_flow_tbl_alloc(int new_size) 190*e6445719SPravin B Shelar { 191*e6445719SPravin B Shelar struct flow_table *table = __flow_tbl_alloc(new_size); 192*e6445719SPravin B Shelar 193*e6445719SPravin B Shelar if (!table) 194*e6445719SPravin B Shelar return NULL; 195*e6445719SPravin B Shelar 196*e6445719SPravin B Shelar table->mask_list = kmalloc(sizeof(struct list_head), GFP_KERNEL); 197*e6445719SPravin B Shelar if (!table->mask_list) { 198*e6445719SPravin B Shelar table->keep_flows = true; 199*e6445719SPravin B Shelar __flow_tbl_destroy(table); 200*e6445719SPravin B Shelar return NULL; 201*e6445719SPravin B Shelar } 202*e6445719SPravin B Shelar INIT_LIST_HEAD(table->mask_list); 203*e6445719SPravin B Shelar 204*e6445719SPravin B Shelar return table; 205*e6445719SPravin B Shelar } 206*e6445719SPravin B Shelar 207*e6445719SPravin B Shelar static void flow_tbl_destroy_rcu_cb(struct rcu_head *rcu) 208*e6445719SPravin B Shelar { 209*e6445719SPravin B Shelar struct flow_table *table = container_of(rcu, struct flow_table, rcu); 210*e6445719SPravin B Shelar 211*e6445719SPravin B Shelar __flow_tbl_destroy(table); 212*e6445719SPravin B Shelar } 213*e6445719SPravin B Shelar 214*e6445719SPravin B Shelar void ovs_flow_tbl_destroy(struct flow_table *table, bool deferred) 215*e6445719SPravin B Shelar { 216*e6445719SPravin B Shelar if (!table) 217*e6445719SPravin B Shelar return; 218*e6445719SPravin B Shelar 219*e6445719SPravin B Shelar if (deferred) 220*e6445719SPravin B Shelar call_rcu(&table->rcu, flow_tbl_destroy_rcu_cb); 221*e6445719SPravin B Shelar else 222*e6445719SPravin B Shelar __flow_tbl_destroy(table); 223*e6445719SPravin B Shelar } 224*e6445719SPravin B Shelar 225*e6445719SPravin B Shelar struct sw_flow *ovs_flow_tbl_dump_next(struct flow_table *table, 226*e6445719SPravin B Shelar u32 *bucket, u32 *last) 227*e6445719SPravin B Shelar { 228*e6445719SPravin B Shelar struct sw_flow *flow; 229*e6445719SPravin B Shelar struct hlist_head *head; 230*e6445719SPravin B Shelar int ver; 231*e6445719SPravin B Shelar int i; 232*e6445719SPravin B Shelar 233*e6445719SPravin B Shelar ver = table->node_ver; 234*e6445719SPravin B Shelar while (*bucket < table->n_buckets) { 235*e6445719SPravin B Shelar i = 0; 236*e6445719SPravin B Shelar head = flex_array_get(table->buckets, *bucket); 237*e6445719SPravin B Shelar hlist_for_each_entry_rcu(flow, head, hash_node[ver]) { 238*e6445719SPravin B Shelar if (i < *last) { 239*e6445719SPravin B Shelar i++; 240*e6445719SPravin B Shelar continue; 241*e6445719SPravin B Shelar } 242*e6445719SPravin B Shelar *last = i + 1; 243*e6445719SPravin B Shelar return flow; 244*e6445719SPravin B Shelar } 245*e6445719SPravin B Shelar (*bucket)++; 246*e6445719SPravin B Shelar *last = 0; 247*e6445719SPravin B Shelar } 248*e6445719SPravin B Shelar 249*e6445719SPravin B Shelar return NULL; 250*e6445719SPravin B Shelar } 251*e6445719SPravin B Shelar 252*e6445719SPravin B Shelar static struct hlist_head *find_bucket(struct flow_table *table, u32 hash) 253*e6445719SPravin B Shelar { 254*e6445719SPravin B Shelar hash = jhash_1word(hash, table->hash_seed); 255*e6445719SPravin B Shelar return flex_array_get(table->buckets, 256*e6445719SPravin B Shelar (hash & (table->n_buckets - 1))); 257*e6445719SPravin B Shelar } 258*e6445719SPravin B Shelar 259*e6445719SPravin B Shelar static void __tbl_insert(struct flow_table *table, struct sw_flow *flow) 260*e6445719SPravin B Shelar { 261*e6445719SPravin B Shelar struct hlist_head *head; 262*e6445719SPravin B Shelar 263*e6445719SPravin B Shelar head = find_bucket(table, flow->hash); 264*e6445719SPravin B Shelar hlist_add_head_rcu(&flow->hash_node[table->node_ver], head); 265*e6445719SPravin B Shelar 266*e6445719SPravin B Shelar table->count++; 267*e6445719SPravin B Shelar } 268*e6445719SPravin B Shelar 269*e6445719SPravin B Shelar static void flow_table_copy_flows(struct flow_table *old, 270*e6445719SPravin B Shelar struct flow_table *new) 271*e6445719SPravin B Shelar { 272*e6445719SPravin B Shelar int old_ver; 273*e6445719SPravin B Shelar int i; 274*e6445719SPravin B Shelar 275*e6445719SPravin B Shelar old_ver = old->node_ver; 276*e6445719SPravin B Shelar new->node_ver = !old_ver; 277*e6445719SPravin B Shelar 278*e6445719SPravin B Shelar /* Insert in new table. */ 279*e6445719SPravin B Shelar for (i = 0; i < old->n_buckets; i++) { 280*e6445719SPravin B Shelar struct sw_flow *flow; 281*e6445719SPravin B Shelar struct hlist_head *head; 282*e6445719SPravin B Shelar 283*e6445719SPravin B Shelar head = flex_array_get(old->buckets, i); 284*e6445719SPravin B Shelar 285*e6445719SPravin B Shelar hlist_for_each_entry(flow, head, hash_node[old_ver]) 286*e6445719SPravin B Shelar __tbl_insert(new, flow); 287*e6445719SPravin B Shelar } 288*e6445719SPravin B Shelar 289*e6445719SPravin B Shelar new->mask_list = old->mask_list; 290*e6445719SPravin B Shelar old->keep_flows = true; 291*e6445719SPravin B Shelar } 292*e6445719SPravin B Shelar 293*e6445719SPravin B Shelar static struct flow_table *__flow_tbl_rehash(struct flow_table *table, 294*e6445719SPravin B Shelar int n_buckets) 295*e6445719SPravin B Shelar { 296*e6445719SPravin B Shelar struct flow_table *new_table; 297*e6445719SPravin B Shelar 298*e6445719SPravin B Shelar new_table = __flow_tbl_alloc(n_buckets); 299*e6445719SPravin B Shelar if (!new_table) 300*e6445719SPravin B Shelar return ERR_PTR(-ENOMEM); 301*e6445719SPravin B Shelar 302*e6445719SPravin B Shelar flow_table_copy_flows(table, new_table); 303*e6445719SPravin B Shelar 304*e6445719SPravin B Shelar return new_table; 305*e6445719SPravin B Shelar } 306*e6445719SPravin B Shelar 307*e6445719SPravin B Shelar struct flow_table *ovs_flow_tbl_rehash(struct flow_table *table) 308*e6445719SPravin B Shelar { 309*e6445719SPravin B Shelar return __flow_tbl_rehash(table, table->n_buckets); 310*e6445719SPravin B Shelar } 311*e6445719SPravin B Shelar 312*e6445719SPravin B Shelar struct flow_table *ovs_flow_tbl_expand(struct flow_table *table) 313*e6445719SPravin B Shelar { 314*e6445719SPravin B Shelar return __flow_tbl_rehash(table, table->n_buckets * 2); 315*e6445719SPravin B Shelar } 316*e6445719SPravin B Shelar 317*e6445719SPravin B Shelar static u32 flow_hash(const struct sw_flow_key *key, int key_start, 318*e6445719SPravin B Shelar int key_end) 319*e6445719SPravin B Shelar { 320*e6445719SPravin B Shelar u32 *hash_key = (u32 *)((u8 *)key + key_start); 321*e6445719SPravin B Shelar int hash_u32s = (key_end - key_start) >> 2; 322*e6445719SPravin B Shelar 323*e6445719SPravin B Shelar /* Make sure number of hash bytes are multiple of u32. */ 324*e6445719SPravin B Shelar BUILD_BUG_ON(sizeof(long) % sizeof(u32)); 325*e6445719SPravin B Shelar 326*e6445719SPravin B Shelar return jhash2(hash_key, hash_u32s, 0); 327*e6445719SPravin B Shelar } 328*e6445719SPravin B Shelar 329*e6445719SPravin B Shelar static int flow_key_start(const struct sw_flow_key *key) 330*e6445719SPravin B Shelar { 331*e6445719SPravin B Shelar if (key->tun_key.ipv4_dst) 332*e6445719SPravin B Shelar return 0; 333*e6445719SPravin B Shelar else 334*e6445719SPravin B Shelar return rounddown(offsetof(struct sw_flow_key, phy), 335*e6445719SPravin B Shelar sizeof(long)); 336*e6445719SPravin B Shelar } 337*e6445719SPravin B Shelar 338*e6445719SPravin B Shelar static bool cmp_key(const struct sw_flow_key *key1, 339*e6445719SPravin B Shelar const struct sw_flow_key *key2, 340*e6445719SPravin B Shelar int key_start, int key_end) 341*e6445719SPravin B Shelar { 342*e6445719SPravin B Shelar const long *cp1 = (long *)((u8 *)key1 + key_start); 343*e6445719SPravin B Shelar const long *cp2 = (long *)((u8 *)key2 + key_start); 344*e6445719SPravin B Shelar long diffs = 0; 345*e6445719SPravin B Shelar int i; 346*e6445719SPravin B Shelar 347*e6445719SPravin B Shelar for (i = key_start; i < key_end; i += sizeof(long)) 348*e6445719SPravin B Shelar diffs |= *cp1++ ^ *cp2++; 349*e6445719SPravin B Shelar 350*e6445719SPravin B Shelar return diffs == 0; 351*e6445719SPravin B Shelar } 352*e6445719SPravin B Shelar 353*e6445719SPravin B Shelar static bool flow_cmp_masked_key(const struct sw_flow *flow, 354*e6445719SPravin B Shelar const struct sw_flow_key *key, 355*e6445719SPravin B Shelar int key_start, int key_end) 356*e6445719SPravin B Shelar { 357*e6445719SPravin B Shelar return cmp_key(&flow->key, key, key_start, key_end); 358*e6445719SPravin B Shelar } 359*e6445719SPravin B Shelar 360*e6445719SPravin B Shelar bool ovs_flow_cmp_unmasked_key(const struct sw_flow *flow, 361*e6445719SPravin B Shelar struct sw_flow_match *match) 362*e6445719SPravin B Shelar { 363*e6445719SPravin B Shelar struct sw_flow_key *key = match->key; 364*e6445719SPravin B Shelar int key_start = flow_key_start(key); 365*e6445719SPravin B Shelar int key_end = match->range.end; 366*e6445719SPravin B Shelar 367*e6445719SPravin B Shelar return cmp_key(&flow->unmasked_key, key, key_start, key_end); 368*e6445719SPravin B Shelar } 369*e6445719SPravin B Shelar 370*e6445719SPravin B Shelar static struct sw_flow *masked_flow_lookup(struct flow_table *table, 371*e6445719SPravin B Shelar const struct sw_flow_key *unmasked, 372*e6445719SPravin B Shelar struct sw_flow_mask *mask) 373*e6445719SPravin B Shelar { 374*e6445719SPravin B Shelar struct sw_flow *flow; 375*e6445719SPravin B Shelar struct hlist_head *head; 376*e6445719SPravin B Shelar int key_start = mask->range.start; 377*e6445719SPravin B Shelar int key_end = mask->range.end; 378*e6445719SPravin B Shelar u32 hash; 379*e6445719SPravin B Shelar struct sw_flow_key masked_key; 380*e6445719SPravin B Shelar 381*e6445719SPravin B Shelar ovs_flow_mask_key(&masked_key, unmasked, mask); 382*e6445719SPravin B Shelar hash = flow_hash(&masked_key, key_start, key_end); 383*e6445719SPravin B Shelar head = find_bucket(table, hash); 384*e6445719SPravin B Shelar hlist_for_each_entry_rcu(flow, head, hash_node[table->node_ver]) { 385*e6445719SPravin B Shelar if (flow->mask == mask && 386*e6445719SPravin B Shelar flow_cmp_masked_key(flow, &masked_key, 387*e6445719SPravin B Shelar key_start, key_end)) 388*e6445719SPravin B Shelar return flow; 389*e6445719SPravin B Shelar } 390*e6445719SPravin B Shelar return NULL; 391*e6445719SPravin B Shelar } 392*e6445719SPravin B Shelar 393*e6445719SPravin B Shelar struct sw_flow *ovs_flow_tbl_lookup(struct flow_table *tbl, 394*e6445719SPravin B Shelar const struct sw_flow_key *key) 395*e6445719SPravin B Shelar { 396*e6445719SPravin B Shelar struct sw_flow *flow = NULL; 397*e6445719SPravin B Shelar struct sw_flow_mask *mask; 398*e6445719SPravin B Shelar 399*e6445719SPravin B Shelar list_for_each_entry_rcu(mask, tbl->mask_list, list) { 400*e6445719SPravin B Shelar flow = masked_flow_lookup(tbl, key, mask); 401*e6445719SPravin B Shelar if (flow) /* Found */ 402*e6445719SPravin B Shelar break; 403*e6445719SPravin B Shelar } 404*e6445719SPravin B Shelar 405*e6445719SPravin B Shelar return flow; 406*e6445719SPravin B Shelar } 407*e6445719SPravin B Shelar 408*e6445719SPravin B Shelar void ovs_flow_tbl_insert(struct flow_table *table, struct sw_flow *flow) 409*e6445719SPravin B Shelar { 410*e6445719SPravin B Shelar flow->hash = flow_hash(&flow->key, flow->mask->range.start, 411*e6445719SPravin B Shelar flow->mask->range.end); 412*e6445719SPravin B Shelar __tbl_insert(table, flow); 413*e6445719SPravin B Shelar } 414*e6445719SPravin B Shelar 415*e6445719SPravin B Shelar void ovs_flow_tbl_remove(struct flow_table *table, struct sw_flow *flow) 416*e6445719SPravin B Shelar { 417*e6445719SPravin B Shelar BUG_ON(table->count == 0); 418*e6445719SPravin B Shelar hlist_del_rcu(&flow->hash_node[table->node_ver]); 419*e6445719SPravin B Shelar table->count--; 420*e6445719SPravin B Shelar } 421*e6445719SPravin B Shelar 422*e6445719SPravin B Shelar struct sw_flow_mask *ovs_sw_flow_mask_alloc(void) 423*e6445719SPravin B Shelar { 424*e6445719SPravin B Shelar struct sw_flow_mask *mask; 425*e6445719SPravin B Shelar 426*e6445719SPravin B Shelar mask = kmalloc(sizeof(*mask), GFP_KERNEL); 427*e6445719SPravin B Shelar if (mask) 428*e6445719SPravin B Shelar mask->ref_count = 0; 429*e6445719SPravin B Shelar 430*e6445719SPravin B Shelar return mask; 431*e6445719SPravin B Shelar } 432*e6445719SPravin B Shelar 433*e6445719SPravin B Shelar void ovs_sw_flow_mask_add_ref(struct sw_flow_mask *mask) 434*e6445719SPravin B Shelar { 435*e6445719SPravin B Shelar mask->ref_count++; 436*e6445719SPravin B Shelar } 437*e6445719SPravin B Shelar 438*e6445719SPravin B Shelar static void rcu_free_sw_flow_mask_cb(struct rcu_head *rcu) 439*e6445719SPravin B Shelar { 440*e6445719SPravin B Shelar struct sw_flow_mask *mask = container_of(rcu, struct sw_flow_mask, rcu); 441*e6445719SPravin B Shelar 442*e6445719SPravin B Shelar kfree(mask); 443*e6445719SPravin B Shelar } 444*e6445719SPravin B Shelar 445*e6445719SPravin B Shelar void ovs_sw_flow_mask_del_ref(struct sw_flow_mask *mask, bool deferred) 446*e6445719SPravin B Shelar { 447*e6445719SPravin B Shelar if (!mask) 448*e6445719SPravin B Shelar return; 449*e6445719SPravin B Shelar 450*e6445719SPravin B Shelar BUG_ON(!mask->ref_count); 451*e6445719SPravin B Shelar mask->ref_count--; 452*e6445719SPravin B Shelar 453*e6445719SPravin B Shelar if (!mask->ref_count) { 454*e6445719SPravin B Shelar list_del_rcu(&mask->list); 455*e6445719SPravin B Shelar if (deferred) 456*e6445719SPravin B Shelar call_rcu(&mask->rcu, rcu_free_sw_flow_mask_cb); 457*e6445719SPravin B Shelar else 458*e6445719SPravin B Shelar kfree(mask); 459*e6445719SPravin B Shelar } 460*e6445719SPravin B Shelar } 461*e6445719SPravin B Shelar 462*e6445719SPravin B Shelar static bool mask_equal(const struct sw_flow_mask *a, 463*e6445719SPravin B Shelar const struct sw_flow_mask *b) 464*e6445719SPravin B Shelar { 465*e6445719SPravin B Shelar u8 *a_ = (u8 *)&a->key + a->range.start; 466*e6445719SPravin B Shelar u8 *b_ = (u8 *)&b->key + b->range.start; 467*e6445719SPravin B Shelar 468*e6445719SPravin B Shelar return (a->range.end == b->range.end) 469*e6445719SPravin B Shelar && (a->range.start == b->range.start) 470*e6445719SPravin B Shelar && (memcmp(a_, b_, range_n_bytes(&a->range)) == 0); 471*e6445719SPravin B Shelar } 472*e6445719SPravin B Shelar 473*e6445719SPravin B Shelar struct sw_flow_mask *ovs_sw_flow_mask_find(const struct flow_table *tbl, 474*e6445719SPravin B Shelar const struct sw_flow_mask *mask) 475*e6445719SPravin B Shelar { 476*e6445719SPravin B Shelar struct list_head *ml; 477*e6445719SPravin B Shelar 478*e6445719SPravin B Shelar list_for_each(ml, tbl->mask_list) { 479*e6445719SPravin B Shelar struct sw_flow_mask *m; 480*e6445719SPravin B Shelar m = container_of(ml, struct sw_flow_mask, list); 481*e6445719SPravin B Shelar if (mask_equal(mask, m)) 482*e6445719SPravin B Shelar return m; 483*e6445719SPravin B Shelar } 484*e6445719SPravin B Shelar 485*e6445719SPravin B Shelar return NULL; 486*e6445719SPravin B Shelar } 487*e6445719SPravin B Shelar 488*e6445719SPravin B Shelar /** 489*e6445719SPravin B Shelar * add a new mask into the mask list. 490*e6445719SPravin B Shelar * The caller needs to make sure that 'mask' is not the same 491*e6445719SPravin B Shelar * as any masks that are already on the list. 492*e6445719SPravin B Shelar */ 493*e6445719SPravin B Shelar void ovs_sw_flow_mask_insert(struct flow_table *tbl, struct sw_flow_mask *mask) 494*e6445719SPravin B Shelar { 495*e6445719SPravin B Shelar list_add_rcu(&mask->list, tbl->mask_list); 496*e6445719SPravin B Shelar } 497*e6445719SPravin B Shelar 498*e6445719SPravin B Shelar /* Initializes the flow module. 499*e6445719SPravin B Shelar * Returns zero if successful or a negative error code. */ 500*e6445719SPravin B Shelar int ovs_flow_init(void) 501*e6445719SPravin B Shelar { 502*e6445719SPravin B Shelar BUILD_BUG_ON(__alignof__(struct sw_flow_key) % __alignof__(long)); 503*e6445719SPravin B Shelar BUILD_BUG_ON(sizeof(struct sw_flow_key) % sizeof(long)); 504*e6445719SPravin B Shelar 505*e6445719SPravin B Shelar flow_cache = kmem_cache_create("sw_flow", sizeof(struct sw_flow), 0, 506*e6445719SPravin B Shelar 0, NULL); 507*e6445719SPravin B Shelar if (flow_cache == NULL) 508*e6445719SPravin B Shelar return -ENOMEM; 509*e6445719SPravin B Shelar 510*e6445719SPravin B Shelar return 0; 511*e6445719SPravin B Shelar } 512*e6445719SPravin B Shelar 513*e6445719SPravin B Shelar /* Uninitializes the flow module. */ 514*e6445719SPravin B Shelar void ovs_flow_exit(void) 515*e6445719SPravin B Shelar { 516*e6445719SPravin B Shelar kmem_cache_destroy(flow_cache); 517*e6445719SPravin B Shelar } 518