mirror of https://gitee.com/openkylin/linux.git
team: introduce array options
Signed-off-by: Jiri Pirko <jpirko@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
f82b959d26
commit
b13033262d
|
@ -90,6 +90,7 @@ struct team_option_inst { /* One for each option instance */
|
|||
struct list_head list;
|
||||
struct team_option *option;
|
||||
struct team_port *port; /* != NULL if per-port */
|
||||
u32 array_index;
|
||||
bool changed;
|
||||
bool removed;
|
||||
};
|
||||
|
@ -106,22 +107,6 @@ static struct team_option *__team_find_option(struct team *team,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int __team_option_inst_add(struct team *team, struct team_option *option,
|
||||
struct team_port *port)
|
||||
{
|
||||
struct team_option_inst *opt_inst;
|
||||
|
||||
opt_inst = kmalloc(sizeof(*opt_inst), GFP_KERNEL);
|
||||
if (!opt_inst)
|
||||
return -ENOMEM;
|
||||
opt_inst->option = option;
|
||||
opt_inst->port = port;
|
||||
opt_inst->changed = true;
|
||||
opt_inst->removed = false;
|
||||
list_add_tail(&opt_inst->list, &team->option_inst_list);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __team_option_inst_del(struct team_option_inst *opt_inst)
|
||||
{
|
||||
list_del(&opt_inst->list);
|
||||
|
@ -139,14 +124,42 @@ static void __team_option_inst_del_option(struct team *team,
|
|||
}
|
||||
}
|
||||
|
||||
static int __team_option_inst_add(struct team *team, struct team_option *option,
|
||||
struct team_port *port)
|
||||
{
|
||||
struct team_option_inst *opt_inst;
|
||||
unsigned int array_size;
|
||||
unsigned int i;
|
||||
|
||||
array_size = option->array_size;
|
||||
if (!array_size)
|
||||
array_size = 1; /* No array but still need one instance */
|
||||
|
||||
for (i = 0; i < array_size; i++) {
|
||||
opt_inst = kmalloc(sizeof(*opt_inst), GFP_KERNEL);
|
||||
if (!opt_inst)
|
||||
return -ENOMEM;
|
||||
opt_inst->option = option;
|
||||
opt_inst->port = port;
|
||||
opt_inst->array_index = i;
|
||||
opt_inst->changed = true;
|
||||
opt_inst->removed = false;
|
||||
list_add_tail(&opt_inst->list, &team->option_inst_list);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __team_option_inst_add_option(struct team *team,
|
||||
struct team_option *option)
|
||||
{
|
||||
struct team_port *port;
|
||||
int err;
|
||||
|
||||
if (!option->per_port)
|
||||
return __team_option_inst_add(team, option, 0);
|
||||
if (!option->per_port) {
|
||||
err = __team_option_inst_add(team, option, 0);
|
||||
if (err)
|
||||
goto inst_del_option;
|
||||
}
|
||||
|
||||
list_for_each_entry(port, &team->port_list, list) {
|
||||
err = __team_option_inst_add(team, option, port);
|
||||
|
@ -1567,6 +1580,11 @@ static int team_nl_fill_options_get(struct sk_buff *skb,
|
|||
opt_inst->port->dev->ifindex))
|
||||
goto nla_put_failure;
|
||||
ctx.port = opt_inst->port;
|
||||
if (opt_inst->option->array_size &&
|
||||
nla_put_u32(skb, TEAM_ATTR_OPTION_ARRAY_INDEX,
|
||||
opt_inst->array_index))
|
||||
goto nla_put_failure;
|
||||
ctx.array_index = opt_inst->array_index;
|
||||
switch (option->type) {
|
||||
case TEAM_OPTION_TYPE_U32:
|
||||
if (nla_put_u8(skb, TEAM_ATTR_OPTION_TYPE, NLA_U32))
|
||||
|
@ -1668,10 +1686,12 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info)
|
|||
|
||||
nla_for_each_nested(nl_option, info->attrs[TEAM_ATTR_LIST_OPTION], i) {
|
||||
struct nlattr *opt_attrs[TEAM_ATTR_OPTION_MAX + 1];
|
||||
struct nlattr *attr_port_ifindex;
|
||||
struct nlattr *attr;
|
||||
struct nlattr *attr_data;
|
||||
enum team_option_type opt_type;
|
||||
int opt_port_ifindex = 0; /* != 0 for per-port options */
|
||||
u32 opt_array_index = 0;
|
||||
bool opt_is_array = false;
|
||||
struct team_option_inst *opt_inst;
|
||||
char *opt_name;
|
||||
bool opt_found = false;
|
||||
|
@ -1713,9 +1733,15 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info)
|
|||
}
|
||||
|
||||
opt_name = nla_data(opt_attrs[TEAM_ATTR_OPTION_NAME]);
|
||||
attr_port_ifindex = opt_attrs[TEAM_ATTR_OPTION_PORT_IFINDEX];
|
||||
if (attr_port_ifindex)
|
||||
opt_port_ifindex = nla_get_u32(attr_port_ifindex);
|
||||
attr = opt_attrs[TEAM_ATTR_OPTION_PORT_IFINDEX];
|
||||
if (attr)
|
||||
opt_port_ifindex = nla_get_u32(attr);
|
||||
|
||||
attr = opt_attrs[TEAM_ATTR_OPTION_ARRAY_INDEX];
|
||||
if (attr) {
|
||||
opt_is_array = true;
|
||||
opt_array_index = nla_get_u32(attr);
|
||||
}
|
||||
|
||||
list_for_each_entry(opt_inst, &team->option_inst_list, list) {
|
||||
struct team_option *option = opt_inst->option;
|
||||
|
@ -1726,10 +1752,13 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info)
|
|||
opt_inst->port->dev->ifindex : 0;
|
||||
if (option->type != opt_type ||
|
||||
strcmp(option->name, opt_name) ||
|
||||
tmp_ifindex != opt_port_ifindex)
|
||||
tmp_ifindex != opt_port_ifindex ||
|
||||
(option->array_size && !opt_is_array) ||
|
||||
opt_inst->array_index != opt_array_index)
|
||||
continue;
|
||||
opt_found = true;
|
||||
ctx.port = opt_inst->port;
|
||||
ctx.array_index = opt_inst->array_index;
|
||||
switch (opt_type) {
|
||||
case TEAM_OPTION_TYPE_U32:
|
||||
ctx.data.u32_val = nla_get_u32(attr_data);
|
||||
|
|
|
@ -93,6 +93,7 @@ struct team_gsetter_ctx {
|
|||
} bin_val;
|
||||
bool bool_val;
|
||||
} data;
|
||||
u32 array_index;
|
||||
struct team_port *port;
|
||||
};
|
||||
|
||||
|
@ -100,6 +101,7 @@ struct team_option {
|
|||
struct list_head list;
|
||||
const char *name;
|
||||
bool per_port;
|
||||
unsigned int array_size; /* != 0 means the option is array */
|
||||
enum team_option_type type;
|
||||
int (*getter)(struct team *team, struct team_gsetter_ctx *ctx);
|
||||
int (*setter)(struct team *team, struct team_gsetter_ctx *ctx);
|
||||
|
@ -242,6 +244,7 @@ enum {
|
|||
TEAM_ATTR_OPTION_DATA, /* dynamic */
|
||||
TEAM_ATTR_OPTION_REMOVED, /* flag */
|
||||
TEAM_ATTR_OPTION_PORT_IFINDEX, /* u32 */ /* for per-port options */
|
||||
TEAM_ATTR_OPTION_ARRAY_INDEX, /* u32 */ /* for array options */
|
||||
|
||||
__TEAM_ATTR_OPTION_MAX,
|
||||
TEAM_ATTR_OPTION_MAX = __TEAM_ATTR_OPTION_MAX - 1,
|
||||
|
|
Loading…
Reference in New Issue