aboutsummaryrefslogtreecommitdiffstats
path: root/net/openvswitch/flow.h
diff options
context:
space:
mode:
authorAndy Zhou <azhou@nicira.com>2013-08-07 23:01:00 -0400
committerJesse Gross <jesse@nicira.com>2013-08-23 19:43:07 -0400
commit03f0d916aa0317592dda11bd17c7357858719b6c (patch)
tree436f94d9c4846cadfa73ee0822f44a6383f3a2f3 /net/openvswitch/flow.h
parent3fa34de67861abfc4846ccec886ca549d46ae56c (diff)
openvswitch: Mega flow implementation
Add wildcarded flow support in kernel datapath. Wildcarded flow can improve OVS flow set up performance by avoid sending matching new flows to the user space program. The exact performance boost will largely dependent on wildcarded flow hit rate. In case all new flows hits wildcard flows, the flow set up rate is within 5% of that of linux bridge module. Pravin has made significant contributions to this patch. Including API clean ups and bug fixes. Signed-off-by: Pravin B Shelar <pshelar@nicira.com> Signed-off-by: Andy Zhou <azhou@nicira.com> Signed-off-by: Jesse Gross <jesse@nicira.com>
Diffstat (limited to 'net/openvswitch/flow.h')
-rw-r--r--net/openvswitch/flow.h96
1 files changed, 77 insertions, 19 deletions
diff --git a/net/openvswitch/flow.h b/net/openvswitch/flow.h
index 66ef7220293e..9674e45f6969 100644
--- a/net/openvswitch/flow.h
+++ b/net/openvswitch/flow.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2007-2011 Nicira, Inc. 2 * Copyright (c) 2007-2013 Nicira, Inc.
3 * 3 *
4 * This program is free software; you can redistribute it and/or 4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of version 2 of the GNU General Public 5 * modify it under the terms of version 2 of the GNU General Public
@@ -33,6 +33,8 @@
33#include <net/inet_ecn.h> 33#include <net/inet_ecn.h>
34 34
35struct sk_buff; 35struct sk_buff;
36struct sw_flow_mask;
37struct flow_table;
36 38
37struct sw_flow_actions { 39struct sw_flow_actions {
38 struct rcu_head rcu; 40 struct rcu_head rcu;
@@ -131,6 +133,8 @@ struct sw_flow {
131 u32 hash; 133 u32 hash;
132 134
133 struct sw_flow_key key; 135 struct sw_flow_key key;
136 struct sw_flow_key unmasked_key;
137 struct sw_flow_mask *mask;
134 struct sw_flow_actions __rcu *sf_acts; 138 struct sw_flow_actions __rcu *sf_acts;
135 139
136 spinlock_t lock; /* Lock for values below. */ 140 spinlock_t lock; /* Lock for values below. */
@@ -140,6 +144,25 @@ struct sw_flow {
140 u8 tcp_flags; /* Union of seen TCP flags. */ 144 u8 tcp_flags; /* Union of seen TCP flags. */
141}; 145};
142 146
147struct sw_flow_key_range {
148 size_t start;
149 size_t end;
150};
151
152static inline u16 ovs_sw_flow_key_range_actual_size(const struct sw_flow_key_range *range)
153{
154 return range->end - range->start;
155}
156
157struct sw_flow_match {
158 struct sw_flow_key *key;
159 struct sw_flow_key_range range;
160 struct sw_flow_mask *mask;
161};
162
163void ovs_match_init(struct sw_flow_match *match,
164 struct sw_flow_key *key, struct sw_flow_mask *mask);
165
143struct arp_eth_header { 166struct arp_eth_header {
144 __be16 ar_hrd; /* format of hardware address */ 167 __be16 ar_hrd; /* format of hardware address */
145 __be16 ar_pro; /* format of protocol address */ 168 __be16 ar_pro; /* format of protocol address */
@@ -159,21 +182,21 @@ void ovs_flow_exit(void);
159 182
160struct sw_flow *ovs_flow_alloc(void); 183struct sw_flow *ovs_flow_alloc(void);
161void ovs_flow_deferred_free(struct sw_flow *); 184void ovs_flow_deferred_free(struct sw_flow *);
162void ovs_flow_free(struct sw_flow *flow); 185void ovs_flow_free(struct sw_flow *, bool deferred);
163 186
164struct sw_flow_actions *ovs_flow_actions_alloc(int actions_len); 187struct sw_flow_actions *ovs_flow_actions_alloc(int actions_len);
165void ovs_flow_deferred_free_acts(struct sw_flow_actions *); 188void ovs_flow_deferred_free_acts(struct sw_flow_actions *);
166 189
167int ovs_flow_extract(struct sk_buff *, u16 in_port, struct sw_flow_key *, 190int ovs_flow_extract(struct sk_buff *, u16 in_port, struct sw_flow_key *);
168 int *key_lenp);
169void ovs_flow_used(struct sw_flow *, struct sk_buff *); 191void ovs_flow_used(struct sw_flow *, struct sk_buff *);
170u64 ovs_flow_used_time(unsigned long flow_jiffies); 192u64 ovs_flow_used_time(unsigned long flow_jiffies);
171 193int ovs_flow_to_nlattrs(const struct sw_flow_key *,
172int ovs_flow_to_nlattrs(const struct sw_flow_key *, struct sk_buff *); 194 const struct sw_flow_key *, struct sk_buff *);
173int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp, 195int ovs_match_from_nlattrs(struct sw_flow_match *match,
196 const struct nlattr *,
174 const struct nlattr *); 197 const struct nlattr *);
175int ovs_flow_metadata_from_nlattrs(struct sw_flow *flow, int key_len, 198int ovs_flow_metadata_from_nlattrs(struct sw_flow *flow,
176 const struct nlattr *attr); 199 const struct nlattr *attr);
177 200
178#define MAX_ACTIONS_BUFSIZE (32 * 1024) 201#define MAX_ACTIONS_BUFSIZE (32 * 1024)
179#define TBL_MIN_BUCKETS 1024 202#define TBL_MIN_BUCKETS 1024
@@ -182,6 +205,7 @@ struct flow_table {
182 struct flex_array *buckets; 205 struct flex_array *buckets;
183 unsigned int count, n_buckets; 206 unsigned int count, n_buckets;
184 struct rcu_head rcu; 207 struct rcu_head rcu;
208 struct list_head *mask_list;
185 int node_ver; 209 int node_ver;
186 u32 hash_seed; 210 u32 hash_seed;
187 bool keep_flows; 211 bool keep_flows;
@@ -197,22 +221,56 @@ static inline int ovs_flow_tbl_need_to_expand(struct flow_table *table)
197 return (table->count > table->n_buckets); 221 return (table->count > table->n_buckets);
198} 222}
199 223
200struct sw_flow *ovs_flow_tbl_lookup(struct flow_table *table, 224struct sw_flow *ovs_flow_lookup(struct flow_table *,
201 struct sw_flow_key *key, int len); 225 const struct sw_flow_key *);
202void ovs_flow_tbl_destroy(struct flow_table *table); 226struct sw_flow *ovs_flow_lookup_unmasked_key(struct flow_table *table,
203void ovs_flow_tbl_deferred_destroy(struct flow_table *table); 227 struct sw_flow_match *match);
228
229void ovs_flow_tbl_destroy(struct flow_table *table, bool deferred);
204struct flow_table *ovs_flow_tbl_alloc(int new_size); 230struct flow_table *ovs_flow_tbl_alloc(int new_size);
205struct flow_table *ovs_flow_tbl_expand(struct flow_table *table); 231struct flow_table *ovs_flow_tbl_expand(struct flow_table *table);
206struct flow_table *ovs_flow_tbl_rehash(struct flow_table *table); 232struct flow_table *ovs_flow_tbl_rehash(struct flow_table *table);
207void ovs_flow_tbl_insert(struct flow_table *table, struct sw_flow *flow,
208 struct sw_flow_key *key, int key_len);
209void ovs_flow_tbl_remove(struct flow_table *table, struct sw_flow *flow);
210 233
211struct sw_flow *ovs_flow_tbl_next(struct flow_table *table, u32 *bucket, u32 *idx); 234void ovs_flow_insert(struct flow_table *table, struct sw_flow *flow);
235void ovs_flow_remove(struct flow_table *table, struct sw_flow *flow);
236
237struct sw_flow *ovs_flow_dump_next(struct flow_table *table, u32 *bucket, u32 *idx);
212extern const int ovs_key_lens[OVS_KEY_ATTR_MAX + 1]; 238extern const int ovs_key_lens[OVS_KEY_ATTR_MAX + 1];
213int ovs_ipv4_tun_from_nlattr(const struct nlattr *attr, 239int ovs_ipv4_tun_from_nlattr(const struct nlattr *attr,
214 struct ovs_key_ipv4_tunnel *tun_key); 240 struct sw_flow_match *match, bool is_mask);
215int ovs_ipv4_tun_to_nlattr(struct sk_buff *skb, 241int ovs_ipv4_tun_to_nlattr(struct sk_buff *skb,
216 const struct ovs_key_ipv4_tunnel *tun_key); 242 const struct ovs_key_ipv4_tunnel *tun_key,
243 const struct ovs_key_ipv4_tunnel *output);
244
245bool ovs_flow_cmp_unmasked_key(const struct sw_flow *flow,
246 const struct sw_flow_key *key, int key_len);
247
248struct sw_flow_mask {
249 int ref_count;
250 struct rcu_head rcu;
251 struct list_head list;
252 struct sw_flow_key_range range;
253 struct sw_flow_key key;
254};
255
256static inline u16
257ovs_sw_flow_mask_actual_size(const struct sw_flow_mask *mask)
258{
259 return ovs_sw_flow_key_range_actual_size(&mask->range);
260}
261
262static inline u16
263ovs_sw_flow_mask_size_roundup(const struct sw_flow_mask *mask)
264{
265 return roundup(ovs_sw_flow_mask_actual_size(mask), sizeof(u32));
266}
217 267
268struct sw_flow_mask *ovs_sw_flow_mask_alloc(void);
269void ovs_sw_flow_mask_add_ref(struct sw_flow_mask *);
270void ovs_sw_flow_mask_del_ref(struct sw_flow_mask *, bool deferred);
271void ovs_sw_flow_mask_insert(struct flow_table *, struct sw_flow_mask *);
272struct sw_flow_mask *ovs_sw_flow_mask_find(const struct flow_table *,
273 const struct sw_flow_mask *);
274void ovs_flow_key_mask(struct sw_flow_key *dst, const struct sw_flow_key *src,
275 const struct sw_flow_mask *mask);
218#endif /* flow.h */ 276#endif /* flow.h */