1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
2 | /* |
3 | * Copyright (c) 2007-2013 Nicira, Inc. |
4 | */ |
5 | |
6 | #ifndef FLOW_TABLE_H |
7 | #define FLOW_TABLE_H 1 |
8 | |
9 | #include <linux/kernel.h> |
10 | #include <linux/netlink.h> |
11 | #include <linux/openvswitch.h> |
12 | #include <linux/spinlock.h> |
13 | #include <linux/types.h> |
14 | #include <linux/rcupdate.h> |
15 | #include <linux/if_ether.h> |
16 | #include <linux/in6.h> |
17 | #include <linux/jiffies.h> |
18 | #include <linux/time.h> |
19 | |
20 | #include <net/inet_ecn.h> |
21 | #include <net/ip_tunnels.h> |
22 | |
23 | #include "flow.h" |
24 | |
25 | struct mask_cache_entry { |
26 | u32 skb_hash; |
27 | u32 mask_index; |
28 | }; |
29 | |
30 | struct mask_cache { |
31 | struct rcu_head rcu; |
32 | u32 cache_size; /* Must be ^2 value. */ |
33 | struct mask_cache_entry __percpu *mask_cache; |
34 | }; |
35 | |
36 | struct mask_count { |
37 | int index; |
38 | u64 counter; |
39 | }; |
40 | |
41 | struct mask_array_stats { |
42 | struct u64_stats_sync syncp; |
43 | u64 usage_cntrs[]; |
44 | }; |
45 | |
46 | struct mask_array { |
47 | struct rcu_head rcu; |
48 | int count, max; |
49 | struct mask_array_stats __percpu *masks_usage_stats; |
50 | u64 *masks_usage_zero_cntr; |
51 | struct sw_flow_mask __rcu *masks[] __counted_by(max); |
52 | }; |
53 | |
54 | struct table_instance { |
55 | struct hlist_head *buckets; |
56 | unsigned int n_buckets; |
57 | struct rcu_head rcu; |
58 | int node_ver; |
59 | u32 hash_seed; |
60 | }; |
61 | |
62 | struct flow_table { |
63 | struct table_instance __rcu *ti; |
64 | struct table_instance __rcu *ufid_ti; |
65 | struct mask_cache __rcu *mask_cache; |
66 | struct mask_array __rcu *mask_array; |
67 | unsigned long last_rehash; |
68 | unsigned int count; |
69 | unsigned int ufid_count; |
70 | }; |
71 | |
72 | extern struct kmem_cache *flow_stats_cache; |
73 | |
74 | int ovs_flow_init(void); |
75 | void ovs_flow_exit(void); |
76 | |
77 | struct sw_flow *ovs_flow_alloc(void); |
78 | void ovs_flow_free(struct sw_flow *, bool deferred); |
79 | |
80 | int ovs_flow_tbl_init(struct flow_table *); |
81 | int ovs_flow_tbl_count(const struct flow_table *table); |
82 | void ovs_flow_tbl_destroy(struct flow_table *table); |
83 | int ovs_flow_tbl_flush(struct flow_table *flow_table); |
84 | |
85 | int ovs_flow_tbl_insert(struct flow_table *table, struct sw_flow *flow, |
86 | const struct sw_flow_mask *mask); |
87 | void ovs_flow_tbl_remove(struct flow_table *table, struct sw_flow *flow); |
88 | int ovs_flow_tbl_num_masks(const struct flow_table *table); |
89 | u32 ovs_flow_tbl_masks_cache_size(const struct flow_table *table); |
90 | int ovs_flow_tbl_masks_cache_resize(struct flow_table *table, u32 size); |
91 | struct sw_flow *ovs_flow_tbl_dump_next(struct table_instance *table, |
92 | u32 *bucket, u32 *idx); |
93 | struct sw_flow *ovs_flow_tbl_lookup_stats(struct flow_table *, |
94 | const struct sw_flow_key *, |
95 | u32 skb_hash, |
96 | u32 *n_mask_hit, |
97 | u32 *n_cache_hit); |
98 | struct sw_flow *ovs_flow_tbl_lookup(struct flow_table *, |
99 | const struct sw_flow_key *); |
100 | struct sw_flow *ovs_flow_tbl_lookup_exact(struct flow_table *tbl, |
101 | const struct sw_flow_match *match); |
102 | struct sw_flow *ovs_flow_tbl_lookup_ufid(struct flow_table *, |
103 | const struct sw_flow_id *); |
104 | |
105 | bool ovs_flow_cmp(const struct sw_flow *, const struct sw_flow_match *); |
106 | |
107 | void ovs_flow_mask_key(struct sw_flow_key *dst, const struct sw_flow_key *src, |
108 | bool full, const struct sw_flow_mask *mask); |
109 | |
110 | void ovs_flow_masks_rebalance(struct flow_table *table); |
111 | void table_instance_flow_flush(struct flow_table *table, |
112 | struct table_instance *ti, |
113 | struct table_instance *ufid_ti); |
114 | |
115 | #endif /* flow_table.h */ |
116 | |