|
@@ -261,6 +261,17 @@ static void __team_option_inst_mark_removed_port(struct team *team,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static bool __team_option_inst_tmp_find(const struct list_head *opts,
|
|
|
+ const struct team_option_inst *needle)
|
|
|
+{
|
|
|
+ struct team_option_inst *opt_inst;
|
|
|
+
|
|
|
+ list_for_each_entry(opt_inst, opts, tmp_list)
|
|
|
+ if (opt_inst == needle)
|
|
|
+ return true;
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
static int __team_options_register(struct team *team,
|
|
|
const struct team_option *option,
|
|
|
size_t option_count)
|
|
@@ -2568,6 +2579,14 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info)
|
|
|
if (err)
|
|
|
goto team_put;
|
|
|
opt_inst->changed = true;
|
|
|
+
|
|
|
+ /* dumb/evil user-space can send us duplicate opt,
|
|
|
+ * keep only the last one
|
|
|
+ */
|
|
|
+ if (__team_option_inst_tmp_find(&opt_inst_list,
|
|
|
+ opt_inst))
|
|
|
+ continue;
|
|
|
+
|
|
|
list_add(&opt_inst->tmp_list, &opt_inst_list);
|
|
|
}
|
|
|
if (!opt_found) {
|