mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-21 01:32:47 +07:00
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 list_head list;
|
||||||
struct team_option *option;
|
struct team_option *option;
|
||||||
struct team_port *port; /* != NULL if per-port */
|
struct team_port *port; /* != NULL if per-port */
|
||||||
|
u32 array_index;
|
||||||
bool changed;
|
bool changed;
|
||||||
bool removed;
|
bool removed;
|
||||||
};
|
};
|
||||||
@ -106,22 +107,6 @@ static struct team_option *__team_find_option(struct team *team,
|
|||||||
return NULL;
|
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)
|
static void __team_option_inst_del(struct team_option_inst *opt_inst)
|
||||||
{
|
{
|
||||||
list_del(&opt_inst->list);
|
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,
|
static int __team_option_inst_add_option(struct team *team,
|
||||||
struct team_option *option)
|
struct team_option *option)
|
||||||
{
|
{
|
||||||
struct team_port *port;
|
struct team_port *port;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (!option->per_port)
|
if (!option->per_port) {
|
||||||
return __team_option_inst_add(team, option, 0);
|
err = __team_option_inst_add(team, option, 0);
|
||||||
|
if (err)
|
||||||
|
goto inst_del_option;
|
||||||
|
}
|
||||||
|
|
||||||
list_for_each_entry(port, &team->port_list, list) {
|
list_for_each_entry(port, &team->port_list, list) {
|
||||||
err = __team_option_inst_add(team, option, port);
|
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))
|
opt_inst->port->dev->ifindex))
|
||||||
goto nla_put_failure;
|
goto nla_put_failure;
|
||||||
ctx.port = opt_inst->port;
|
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) {
|
switch (option->type) {
|
||||||
case TEAM_OPTION_TYPE_U32:
|
case TEAM_OPTION_TYPE_U32:
|
||||||
if (nla_put_u8(skb, TEAM_ATTR_OPTION_TYPE, NLA_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) {
|
nla_for_each_nested(nl_option, info->attrs[TEAM_ATTR_LIST_OPTION], i) {
|
||||||
struct nlattr *opt_attrs[TEAM_ATTR_OPTION_MAX + 1];
|
struct nlattr *opt_attrs[TEAM_ATTR_OPTION_MAX + 1];
|
||||||
struct nlattr *attr_port_ifindex;
|
struct nlattr *attr;
|
||||||
struct nlattr *attr_data;
|
struct nlattr *attr_data;
|
||||||
enum team_option_type opt_type;
|
enum team_option_type opt_type;
|
||||||
int opt_port_ifindex = 0; /* != 0 for per-port options */
|
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;
|
struct team_option_inst *opt_inst;
|
||||||
char *opt_name;
|
char *opt_name;
|
||||||
bool opt_found = false;
|
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]);
|
opt_name = nla_data(opt_attrs[TEAM_ATTR_OPTION_NAME]);
|
||||||
attr_port_ifindex = opt_attrs[TEAM_ATTR_OPTION_PORT_IFINDEX];
|
attr = opt_attrs[TEAM_ATTR_OPTION_PORT_IFINDEX];
|
||||||
if (attr_port_ifindex)
|
if (attr)
|
||||||
opt_port_ifindex = nla_get_u32(attr_port_ifindex);
|
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) {
|
list_for_each_entry(opt_inst, &team->option_inst_list, list) {
|
||||||
struct team_option *option = opt_inst->option;
|
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;
|
opt_inst->port->dev->ifindex : 0;
|
||||||
if (option->type != opt_type ||
|
if (option->type != opt_type ||
|
||||||
strcmp(option->name, opt_name) ||
|
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;
|
continue;
|
||||||
opt_found = true;
|
opt_found = true;
|
||||||
ctx.port = opt_inst->port;
|
ctx.port = opt_inst->port;
|
||||||
|
ctx.array_index = opt_inst->array_index;
|
||||||
switch (opt_type) {
|
switch (opt_type) {
|
||||||
case TEAM_OPTION_TYPE_U32:
|
case TEAM_OPTION_TYPE_U32:
|
||||||
ctx.data.u32_val = nla_get_u32(attr_data);
|
ctx.data.u32_val = nla_get_u32(attr_data);
|
||||||
|
@ -93,6 +93,7 @@ struct team_gsetter_ctx {
|
|||||||
} bin_val;
|
} bin_val;
|
||||||
bool bool_val;
|
bool bool_val;
|
||||||
} data;
|
} data;
|
||||||
|
u32 array_index;
|
||||||
struct team_port *port;
|
struct team_port *port;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -100,6 +101,7 @@ struct team_option {
|
|||||||
struct list_head list;
|
struct list_head list;
|
||||||
const char *name;
|
const char *name;
|
||||||
bool per_port;
|
bool per_port;
|
||||||
|
unsigned int array_size; /* != 0 means the option is array */
|
||||||
enum team_option_type type;
|
enum team_option_type type;
|
||||||
int (*getter)(struct team *team, struct team_gsetter_ctx *ctx);
|
int (*getter)(struct team *team, struct team_gsetter_ctx *ctx);
|
||||||
int (*setter)(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_DATA, /* dynamic */
|
||||||
TEAM_ATTR_OPTION_REMOVED, /* flag */
|
TEAM_ATTR_OPTION_REMOVED, /* flag */
|
||||||
TEAM_ATTR_OPTION_PORT_IFINDEX, /* u32 */ /* for per-port options */
|
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 = __TEAM_ATTR_OPTION_MAX - 1,
|
TEAM_ATTR_OPTION_MAX = __TEAM_ATTR_OPTION_MAX - 1,
|
||||||
|
Loading…
Reference in New Issue
Block a user