diff options
author | Ben Pfaff <blp@nicira.com> | 2014-05-06 19:48:38 -0400 |
---|---|---|
committer | Pravin B Shelar <pshelar@nicira.com> | 2014-06-29 17:10:51 -0400 |
commit | ad55200734c65a3ec5d0c39d6ea904008baea536 (patch) | |
tree | 22c1e9d24400afb53d774a7b20f4746b0053c18a /net/openvswitch | |
parent | e0bb8c44ed5cfcc56b571758ed966ee48779024c (diff) |
openvswitch: Fix tracking of flags seen in TCP flows.
Flow statistics need to take into account the TCP flags from the packet
currently being processed (in 'key'), not the TCP flags matched by the
flow found in the kernel flow table (in 'flow').
This bug made the Open vSwitch userspace fin_timeout action have no effect
in many cases.
This bug is introduced by commit 88d73f6c411ac2f0578 (openvswitch: Use
TCP flags in the flow key for stats.)
Reported-by: Len Gao <leng@vmware.com>
Signed-off-by: Ben Pfaff <blp@nicira.com>
Acked-by: Jarno Rajahalme <jrajahalme@nicira.com>
Acked-by: Jesse Gross <jesse@nicira.com>
Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
Diffstat (limited to 'net/openvswitch')
-rw-r--r-- | net/openvswitch/datapath.c | 4 | ||||
-rw-r--r-- | net/openvswitch/flow.c | 4 | ||||
-rw-r--r-- | net/openvswitch/flow.h | 5 |
3 files changed, 7 insertions, 6 deletions
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index 0d407bca81e3..a863678c50ac 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2007-2013 Nicira, Inc. | 2 | * Copyright (c) 2007-2014 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 |
@@ -276,7 +276,7 @@ void ovs_dp_process_received_packet(struct vport *p, struct sk_buff *skb) | |||
276 | OVS_CB(skb)->flow = flow; | 276 | OVS_CB(skb)->flow = flow; |
277 | OVS_CB(skb)->pkt_key = &key; | 277 | OVS_CB(skb)->pkt_key = &key; |
278 | 278 | ||
279 | ovs_flow_stats_update(OVS_CB(skb)->flow, skb); | 279 | ovs_flow_stats_update(OVS_CB(skb)->flow, key.tp.flags, skb); |
280 | ovs_execute_actions(dp, skb); | 280 | ovs_execute_actions(dp, skb); |
281 | stats_counter = &stats->n_hit; | 281 | stats_counter = &stats->n_hit; |
282 | 282 | ||
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c index 334751cb1528..d07ab538fc9d 100644 --- a/net/openvswitch/flow.c +++ b/net/openvswitch/flow.c | |||
@@ -61,10 +61,10 @@ u64 ovs_flow_used_time(unsigned long flow_jiffies) | |||
61 | 61 | ||
62 | #define TCP_FLAGS_BE16(tp) (*(__be16 *)&tcp_flag_word(tp) & htons(0x0FFF)) | 62 | #define TCP_FLAGS_BE16(tp) (*(__be16 *)&tcp_flag_word(tp) & htons(0x0FFF)) |
63 | 63 | ||
64 | void ovs_flow_stats_update(struct sw_flow *flow, struct sk_buff *skb) | 64 | void ovs_flow_stats_update(struct sw_flow *flow, __be16 tcp_flags, |
65 | struct sk_buff *skb) | ||
65 | { | 66 | { |
66 | struct flow_stats *stats; | 67 | struct flow_stats *stats; |
67 | __be16 tcp_flags = flow->key.tp.flags; | ||
68 | int node = numa_node_id(); | 68 | int node = numa_node_id(); |
69 | 69 | ||
70 | stats = rcu_dereference(flow->stats[node]); | 70 | stats = rcu_dereference(flow->stats[node]); |
diff --git a/net/openvswitch/flow.h b/net/openvswitch/flow.h index ac395d2cd821..5e5aaed3a85b 100644 --- a/net/openvswitch/flow.h +++ b/net/openvswitch/flow.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2007-2013 Nicira, Inc. | 2 | * Copyright (c) 2007-2014 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 |
@@ -180,7 +180,8 @@ struct arp_eth_header { | |||
180 | unsigned char ar_tip[4]; /* target IP address */ | 180 | unsigned char ar_tip[4]; /* target IP address */ |
181 | } __packed; | 181 | } __packed; |
182 | 182 | ||
183 | void ovs_flow_stats_update(struct sw_flow *, struct sk_buff *); | 183 | void ovs_flow_stats_update(struct sw_flow *, __be16 tcp_flags, |
184 | struct sk_buff *); | ||
184 | void ovs_flow_stats_get(const struct sw_flow *, struct ovs_flow_stats *, | 185 | void ovs_flow_stats_get(const struct sw_flow *, struct ovs_flow_stats *, |
185 | unsigned long *used, __be16 *tcp_flags); | 186 | unsigned long *used, __be16 *tcp_flags); |
186 | void ovs_flow_stats_clear(struct sw_flow *); | 187 | void ovs_flow_stats_clear(struct sw_flow *); |