From 3c7eacfc8a9a4c2bd48e0093c4f43cf69afd5210 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Fri, 14 Feb 2014 11:42:36 +0100 Subject: ovs: fix dp check in ovs_dp_reset_user_features This fixes crash when userspace does "ovs-dpctl add-dp dev" where dev is existing non-dp netdevice. Introduced by: commit 44da5ae5fbea4686f667dc854e5ea16814e44c59 "openvswitch: Drop user features if old user space attempted to create datapath" Signed-off-by: Jiri Pirko Signed-off-by: Jesse Gross --- net/openvswitch/datapath.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index e9a48baf8551..e42340d3f820 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c @@ -1174,7 +1174,7 @@ static void ovs_dp_reset_user_features(struct sk_buff *skb, struct genl_info *in struct datapath *dp; dp = lookup_datapath(sock_net(skb->sk), info->userhdr, info->attrs); - if (!dp) + if (IS_ERR(dp)) return; WARN(dp->user_features, "Dropping previously announced user features\n"); -- cgit v1.2.1 From 04382a3303c22b0c536fbd0c94c1f012f2b8ed60 Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Sat, 15 Feb 2014 17:37:45 -0800 Subject: openvswitch: Read tcp flags only then the tranport header is present. Only the first IP fragment can have a TCP header, check for this. Signed-off-by: Jarno Rajahalme Signed-off-by: Jesse Gross --- net/openvswitch/flow.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c index 16f4b46161d4..d71e60fa28cb 100644 --- a/net/openvswitch/flow.c +++ b/net/openvswitch/flow.c @@ -73,6 +73,7 @@ void ovs_flow_stats_update(struct sw_flow *flow, struct sk_buff *skb) if ((flow->key.eth.type == htons(ETH_P_IP) || flow->key.eth.type == htons(ETH_P_IPV6)) && + flow->key.ip.frag != OVS_FRAG_TYPE_LATER && flow->key.ip.proto == IPPROTO_TCP && likely(skb->len >= skb_transport_offset(skb) + sizeof(struct tcphdr))) { tcp_flags = TCP_FLAGS_BE16(tcp_hdr(skb)); -- cgit v1.2.1 From 42ee19e2939277a5277c307e517ce2d7ba5f0703 Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Sat, 15 Feb 2014 17:42:29 -0800 Subject: openvswitch: Fix race. ovs_vport_cmd_dump() did rcu_read_lock() only after getting the datapath, which could have been deleted in between. Resolved by taking rcu_read_lock() before the get_dp() call. Signed-off-by: Jarno Rajahalme Signed-off-by: Pravin B Shelar --- net/openvswitch/datapath.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index e42340d3f820..8601b320b443 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c @@ -1762,11 +1762,12 @@ static int ovs_vport_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb) int bucket = cb->args[0], skip = cb->args[1]; int i, j = 0; + rcu_read_lock(); dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex); - if (!dp) + if (!dp) { + rcu_read_unlock(); return -ENODEV; - - rcu_read_lock(); + } for (i = bucket; i < DP_VPORT_HASH_BUCKETS; i++) { struct vport *vport; -- cgit v1.2.1 From f9b8c4c8baded129535d82d74df8e87a7a369f54 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Thu, 20 Mar 2014 10:45:21 -0700 Subject: openvswitch: Correctly report flow used times for first 5 minutes after boot. The kernel starts out its "jiffies" timer as 5 minutes below zero, as shown in include/linux/jiffies.h: /* * Have the 32 bit jiffies value wrap 5 minutes after boot * so jiffies wrap bugs show up earlier. */ #define INITIAL_JIFFIES ((unsigned long)(unsigned int) (-300*HZ)) The loop in ovs_flow_stats_get() starts out with 'used' set to 0, then takes any "later" time. This means that for the first five minutes after boot, flows will always be reported as never used, since 0 is greater than any time already seen. Signed-off-by: Ben Pfaff Acked-by: Pravin B Shelar Signed-off-by: Jesse Gross --- net/openvswitch/flow.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c index d71e60fa28cb..dda451f4429c 100644 --- a/net/openvswitch/flow.c +++ b/net/openvswitch/flow.c @@ -92,7 +92,7 @@ static void stats_read(struct flow_stats *stats, unsigned long *used, __be16 *tcp_flags) { spin_lock(&stats->lock); - if (time_after(stats->used, *used)) + if (!*used || time_after(stats->used, *used)) *used = stats->used; *tcp_flags |= stats->tcp_flags; ovs_stats->n_packets += stats->packet_count; -- cgit v1.2.1