aboutsummaryrefslogtreecommitdiffstats
path: root/net/openvswitch/flow.c
diff options
context:
space:
mode:
authorPravin B Shelar <pshelar@nicira.com>2013-06-17 20:50:28 -0400
committerDavid S. Miller <davem@davemloft.net>2013-06-19 21:07:41 -0400
commita3e82996a8874c4cfe8c7f1be4d552018d8cba7e (patch)
treef476c0df25d3076a67594bc15e0cd5190ce18351 /net/openvswitch/flow.c
parentffe3f4321745e743dd179ec2b12180c01ba0d3aa (diff)
openvswitch: Optimize flow key match for non tunnel flows.
Following patch adds start offset for sw_flow-key, so that we can skip tunneling information in key for non-tunnel flows. Signed-off-by: Pravin B Shelar <pshelar@nicira.com> Acked-by: Jesse Gross <jesse@nicira.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/openvswitch/flow.c')
-rw-r--r--net/openvswitch/flow.c49
1 files changed, 37 insertions, 12 deletions
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c
index 976a8b766a6a..5c519b121e1b 100644
--- a/net/openvswitch/flow.c
+++ b/net/openvswitch/flow.c
@@ -353,6 +353,14 @@ struct sw_flow *ovs_flow_tbl_next(struct flow_table *table, u32 *bucket, u32 *la
353 return NULL; 353 return NULL;
354} 354}
355 355
356static void __flow_tbl_insert(struct flow_table *table, struct sw_flow *flow)
357{
358 struct hlist_head *head;
359 head = find_bucket(table, flow->hash);
360 hlist_add_head_rcu(&flow->hash_node[table->node_ver], head);
361 table->count++;
362}
363
356static void flow_table_copy_flows(struct flow_table *old, struct flow_table *new) 364static void flow_table_copy_flows(struct flow_table *old, struct flow_table *new)
357{ 365{
358 int old_ver; 366 int old_ver;
@@ -369,7 +377,7 @@ static void flow_table_copy_flows(struct flow_table *old, struct flow_table *new
369 head = flex_array_get(old->buckets, i); 377 head = flex_array_get(old->buckets, i);
370 378
371 hlist_for_each_entry(flow, head, hash_node[old_ver]) 379 hlist_for_each_entry(flow, head, hash_node[old_ver])
372 ovs_flow_tbl_insert(new, flow); 380 __flow_tbl_insert(new, flow);
373 } 381 }
374 old->keep_flows = true; 382 old->keep_flows = true;
375} 383}
@@ -763,9 +771,18 @@ out:
763 return error; 771 return error;
764} 772}
765 773
766u32 ovs_flow_hash(const struct sw_flow_key *key, int key_len) 774static u32 ovs_flow_hash(const struct sw_flow_key *key, int key_start, int key_len)
775{
776 return jhash2((u32 *)((u8 *)key + key_start),
777 DIV_ROUND_UP(key_len - key_start, sizeof(u32)), 0);
778}
779
780static int flow_key_start(struct sw_flow_key *key)
767{ 781{
768 return jhash2((u32 *)key, DIV_ROUND_UP(key_len, sizeof(u32)), 0); 782 if (key->tun_key.ipv4_dst)
783 return 0;
784 else
785 return offsetof(struct sw_flow_key, phy);
769} 786}
770 787
771struct sw_flow *ovs_flow_tbl_lookup(struct flow_table *table, 788struct sw_flow *ovs_flow_tbl_lookup(struct flow_table *table,
@@ -773,28 +790,31 @@ struct sw_flow *ovs_flow_tbl_lookup(struct flow_table *table,
773{ 790{
774 struct sw_flow *flow; 791 struct sw_flow *flow;
775 struct hlist_head *head; 792 struct hlist_head *head;
793 u8 *_key;
794 int key_start;
776 u32 hash; 795 u32 hash;
777 796
778 hash = ovs_flow_hash(key, key_len); 797 key_start = flow_key_start(key);
798 hash = ovs_flow_hash(key, key_start, key_len);
779 799
800 _key = (u8 *) key + key_start;
780 head = find_bucket(table, hash); 801 head = find_bucket(table, hash);
781 hlist_for_each_entry_rcu(flow, head, hash_node[table->node_ver]) { 802 hlist_for_each_entry_rcu(flow, head, hash_node[table->node_ver]) {
782 803
783 if (flow->hash == hash && 804 if (flow->hash == hash &&
784 !memcmp(&flow->key, key, key_len)) { 805 !memcmp((u8 *)&flow->key + key_start, _key, key_len - key_start)) {
785 return flow; 806 return flow;
786 } 807 }
787 } 808 }
788 return NULL; 809 return NULL;
789} 810}
790 811
791void ovs_flow_tbl_insert(struct flow_table *table, struct sw_flow *flow) 812void ovs_flow_tbl_insert(struct flow_table *table, struct sw_flow *flow,
813 struct sw_flow_key *key, int key_len)
792{ 814{
793 struct hlist_head *head; 815 flow->hash = ovs_flow_hash(key, flow_key_start(key), key_len);
794 816 memcpy(&flow->key, key, sizeof(flow->key));
795 head = find_bucket(table, flow->hash); 817 __flow_tbl_insert(table, flow);
796 hlist_add_head_rcu(&flow->hash_node[table->node_ver], head);
797 table->count++;
798} 818}
799 819
800void ovs_flow_tbl_remove(struct flow_table *table, struct sw_flow *flow) 820void ovs_flow_tbl_remove(struct flow_table *table, struct sw_flow *flow)
@@ -1235,6 +1255,7 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
1235/** 1255/**
1236 * ovs_flow_metadata_from_nlattrs - parses Netlink attributes into a flow key. 1256 * ovs_flow_metadata_from_nlattrs - parses Netlink attributes into a flow key.
1237 * @flow: Receives extracted in_port, priority, tun_key and skb_mark. 1257 * @flow: Receives extracted in_port, priority, tun_key and skb_mark.
1258 * @key_len: Length of key in @flow. Used for calculating flow hash.
1238 * @attr: Netlink attribute holding nested %OVS_KEY_ATTR_* Netlink attribute 1259 * @attr: Netlink attribute holding nested %OVS_KEY_ATTR_* Netlink attribute
1239 * sequence. 1260 * sequence.
1240 * 1261 *
@@ -1243,7 +1264,7 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
1243 * get the metadata, that is, the parts of the flow key that cannot be 1264 * get the metadata, that is, the parts of the flow key that cannot be
1244 * extracted from the packet itself. 1265 * extracted from the packet itself.
1245 */ 1266 */
1246int ovs_flow_metadata_from_nlattrs(struct sw_flow *flow, 1267int ovs_flow_metadata_from_nlattrs(struct sw_flow *flow, int key_len,
1247 const struct nlattr *attr) 1268 const struct nlattr *attr)
1248{ 1269{
1249 struct ovs_key_ipv4_tunnel *tun_key = &flow->key.tun_key; 1270 struct ovs_key_ipv4_tunnel *tun_key = &flow->key.tun_key;
@@ -1289,6 +1310,10 @@ int ovs_flow_metadata_from_nlattrs(struct sw_flow *flow,
1289 } 1310 }
1290 if (rem) 1311 if (rem)
1291 return -EINVAL; 1312 return -EINVAL;
1313
1314 flow->hash = ovs_flow_hash(&flow->key,
1315 flow_key_start(&flow->key), key_len);
1316
1292 return 0; 1317 return 0;
1293} 1318}
1294 1319