diff options
author | Thomas Graf <tgraf@suug.ch> | 2013-12-13 15:22:19 +0100 |
---|---|---|
committer | Jesse Gross <jesse@nicira.com> | 2014-01-06 15:53:00 -0800 |
commit | 44da5ae5fbea4686f667dc854e5ea16814e44c59 (patch) | |
tree | 66c2cb74f950abe16d4b811068bfefb045037e05 /net/openvswitch | |
parent | 43d4be9cb55f3bac5253e9289996fd9d735531db (diff) |
openvswitch: Drop user features if old user space attempted to create datapath
Drop user features if an outdated user space instance that does not
understand the concept of user_features attempted to create a new
datapath.
Signed-off-by: Thomas Graf <tgraf@suug.ch>
Signed-off-by: Jesse Gross <jesse@nicira.com>
Diffstat (limited to 'net/openvswitch')
-rw-r--r-- | net/openvswitch/datapath.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index 6a9b0cb8a1db..497b2fd36df4 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c @@ -1148,6 +1148,18 @@ static struct datapath *lookup_datapath(struct net *net, return dp ? dp : ERR_PTR(-ENODEV); } +static void ovs_dp_reset_user_features(struct sk_buff *skb, struct genl_info *info) +{ + struct datapath *dp; + + dp = lookup_datapath(sock_net(skb->sk), info->userhdr, info->attrs); + if (!dp) + return; + + WARN(dp->user_features, "Dropping previously announced user features\n"); + dp->user_features = 0; +} + static void ovs_dp_change(struct datapath *dp, struct nlattr **a) { if (a[OVS_DP_ATTR_USER_FEATURES]) @@ -1220,6 +1232,15 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info) if (err == -EBUSY) err = -EEXIST; + if (err == -EEXIST) { + /* An outdated user space instance that does not understand + * the concept of user_features has attempted to create a new + * datapath and is likely to reuse it. Drop all user features. + */ + if (info->genlhdr->version < OVS_DP_VER_FEATURES) + ovs_dp_reset_user_features(skb, info); + } + goto err_destroy_ports_array; } |