1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#ifndef FLOW_H
20#define FLOW_H 1
21
22#include <linux/kernel.h>
23#include <linux/netlink.h>
24#include <linux/openvswitch.h>
25#include <linux/spinlock.h>
26#include <linux/types.h>
27#include <linux/rcupdate.h>
28#include <linux/if_ether.h>
29#include <linux/in6.h>
30#include <linux/jiffies.h>
31#include <linux/time.h>
32#include <linux/flex_array.h>
33#include <net/inet_ecn.h>
34
35struct sk_buff;
36
37struct sw_flow_actions {
38 struct rcu_head rcu;
39 u32 actions_len;
40 struct nlattr actions[];
41};
42
43struct sw_flow_key {
44 struct {
45 u32 priority;
46 u16 in_port;
47 } phy;
48 struct {
49 u8 src[ETH_ALEN];
50 u8 dst[ETH_ALEN];
51 __be16 tci;
52 __be16 type;
53 } eth;
54 struct {
55 u8 proto;
56 u8 tos;
57 u8 ttl;
58 u8 frag;
59 } ip;
60 union {
61 struct {
62 struct {
63 __be32 src;
64 __be32 dst;
65 } addr;
66 union {
67 struct {
68 __be16 src;
69 __be16 dst;
70 } tp;
71 struct {
72 u8 sha[ETH_ALEN];
73 u8 tha[ETH_ALEN];
74 } arp;
75 };
76 } ipv4;
77 struct {
78 struct {
79 struct in6_addr src;
80 struct in6_addr dst;
81 } addr;
82 __be32 label;
83 struct {
84 __be16 src;
85 __be16 dst;
86 } tp;
87 struct {
88 struct in6_addr target;
89 u8 sll[ETH_ALEN];
90 u8 tll[ETH_ALEN];
91 } nd;
92 } ipv6;
93 };
94};
95
96struct sw_flow {
97 struct rcu_head rcu;
98 struct hlist_node hash_node[2];
99 u32 hash;
100
101 struct sw_flow_key key;
102 struct sw_flow_actions __rcu *sf_acts;
103
104 spinlock_t lock;
105 unsigned long used;
106 u64 packet_count;
107 u64 byte_count;
108 u8 tcp_flags;
109};
110
111struct arp_eth_header {
112 __be16 ar_hrd;
113 __be16 ar_pro;
114 unsigned char ar_hln;
115 unsigned char ar_pln;
116 __be16 ar_op;
117
118
119 unsigned char ar_sha[ETH_ALEN];
120 unsigned char ar_sip[4];
121 unsigned char ar_tha[ETH_ALEN];
122 unsigned char ar_tip[4];
123} __packed;
124
125int ovs_flow_init(void);
126void ovs_flow_exit(void);
127
128struct sw_flow *ovs_flow_alloc(void);
129void ovs_flow_deferred_free(struct sw_flow *);
130void ovs_flow_free(struct sw_flow *flow);
131
132struct sw_flow_actions *ovs_flow_actions_alloc(const struct nlattr *);
133void ovs_flow_deferred_free_acts(struct sw_flow_actions *);
134
135int ovs_flow_extract(struct sk_buff *, u16 in_port, struct sw_flow_key *,
136 int *key_lenp);
137void ovs_flow_used(struct sw_flow *, struct sk_buff *);
138u64 ovs_flow_used_time(unsigned long flow_jiffies);
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156#define FLOW_BUFSIZE 132
157
158int ovs_flow_to_nlattrs(const struct sw_flow_key *, struct sk_buff *);
159int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
160 const struct nlattr *);
161int ovs_flow_metadata_from_nlattrs(u32 *priority, u16 *in_port,
162 const struct nlattr *);
163
164#define TBL_MIN_BUCKETS 1024
165
166struct flow_table {
167 struct flex_array *buckets;
168 unsigned int count, n_buckets;
169 struct rcu_head rcu;
170 int node_ver;
171 u32 hash_seed;
172 bool keep_flows;
173};
174
175static inline int ovs_flow_tbl_count(struct flow_table *table)
176{
177 return table->count;
178}
179
180static inline int ovs_flow_tbl_need_to_expand(struct flow_table *table)
181{
182 return (table->count > table->n_buckets);
183}
184
185struct sw_flow *ovs_flow_tbl_lookup(struct flow_table *table,
186 struct sw_flow_key *key, int len);
187void ovs_flow_tbl_destroy(struct flow_table *table);
188void ovs_flow_tbl_deferred_destroy(struct flow_table *table);
189struct flow_table *ovs_flow_tbl_alloc(int new_size);
190struct flow_table *ovs_flow_tbl_expand(struct flow_table *table);
191struct flow_table *ovs_flow_tbl_rehash(struct flow_table *table);
192void ovs_flow_tbl_insert(struct flow_table *table, struct sw_flow *flow);
193void ovs_flow_tbl_remove(struct flow_table *table, struct sw_flow *flow);
194u32 ovs_flow_hash(const struct sw_flow_key *key, int key_len);
195
196struct sw_flow *ovs_flow_tbl_next(struct flow_table *table, u32 *bucket, u32 *idx);
197extern const int ovs_key_lens[OVS_KEY_ATTR_MAX + 1];
198
199#endif
200