summaryrefslogtreecommitdiffstats
path: root/net/openvswitch/datapath.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/openvswitch/datapath.c')
-rw-r--r--net/openvswitch/datapath.c21
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,
1148 return dp ? dp : ERR_PTR(-ENODEV); 1148 return dp ? dp : ERR_PTR(-ENODEV);
1149} 1149}
1150 1150
1151static void ovs_dp_reset_user_features(struct sk_buff *skb, struct genl_info *info)
1152{
1153 struct datapath *dp;
1154
1155 dp = lookup_datapath(sock_net(skb->sk), info->userhdr, info->attrs);
1156 if (!dp)
1157 return;
1158
1159 WARN(dp->user_features, "Dropping previously announced user features\n");
1160 dp->user_features = 0;
1161}
1162
1151static void ovs_dp_change(struct datapath *dp, struct nlattr **a) 1163static void ovs_dp_change(struct datapath *dp, struct nlattr **a)
1152{ 1164{
1153 if (a[OVS_DP_ATTR_USER_FEATURES]) 1165 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)
1220 if (err == -EBUSY) 1232 if (err == -EBUSY)
1221 err = -EEXIST; 1233 err = -EEXIST;
1222 1234
1235 if (err == -EEXIST) {
1236 /* An outdated user space instance that does not understand
1237 * the concept of user_features has attempted to create a new
1238 * datapath and is likely to reuse it. Drop all user features.
1239 */
1240 if (info->genlhdr->version < OVS_DP_VER_FEATURES)
1241 ovs_dp_reset_user_features(skb, info);
1242 }
1243
1223 goto err_destroy_ports_array; 1244 goto err_destroy_ports_array;
1224 } 1245 }
1225 1246