Skip to content

Commit 01048d9

Browse files
Jiri Pirkodavem330
authored andcommitted
team: allow to specify one option instance to be send to userspace
No need to walk through option instance list and look for ->changed == true when called knows exactly what one option instance changed. Also use lists to pass option instances needed to be present in netlink message. Signed-off-by: Jiri Pirko <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 3221c64 commit 01048d9

File tree

1 file changed

+124
-86
lines changed

1 file changed

+124
-86
lines changed

drivers/net/team/team.c

Lines changed: 124 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ static void team_refresh_port_linkup(struct team_port *port)
8989

9090
struct team_option_inst { /* One for each option instance */
9191
struct list_head list;
92+
struct list_head tmp_list;
9293
struct team_option *option;
9394
struct team_option_inst_info info;
9495
bool changed;
@@ -319,6 +320,8 @@ static void __team_options_unregister(struct team *team,
319320
}
320321

321322
static void __team_options_change_check(struct team *team);
323+
static void __team_option_inst_change(struct team *team,
324+
struct team_option_inst *opt_inst);
322325

323326
int team_options_register(struct team *team,
324327
const struct team_option *option,
@@ -383,8 +386,7 @@ static int team_option_set(struct team *team,
383386
if (err)
384387
return err;
385388

386-
opt_inst->changed = true;
387-
__team_options_change_check(team);
389+
__team_option_inst_change(team, opt_inst);
388390
return err;
389391
}
390392

@@ -1565,9 +1567,95 @@ static int team_nl_send_generic(struct genl_info *info, struct team *team,
15651567
return err;
15661568
}
15671569

1570+
static int team_nl_fill_one_option_get(struct sk_buff *skb, struct team *team,
1571+
struct team_option_inst *opt_inst)
1572+
{
1573+
struct nlattr *option_item;
1574+
struct team_option *option = opt_inst->option;
1575+
struct team_option_inst_info *opt_inst_info;
1576+
struct team_gsetter_ctx ctx;
1577+
int err;
1578+
1579+
option_item = nla_nest_start(skb, TEAM_ATTR_ITEM_OPTION);
1580+
if (!option_item)
1581+
goto nla_put_failure;
1582+
if (nla_put_string(skb, TEAM_ATTR_OPTION_NAME, option->name))
1583+
goto nla_put_failure;
1584+
if (opt_inst->changed) {
1585+
if (nla_put_flag(skb, TEAM_ATTR_OPTION_CHANGED))
1586+
goto nla_put_failure;
1587+
opt_inst->changed = false;
1588+
}
1589+
if (opt_inst->removed && nla_put_flag(skb, TEAM_ATTR_OPTION_REMOVED))
1590+
goto nla_put_failure;
1591+
1592+
opt_inst_info = &opt_inst->info;
1593+
if (opt_inst_info->port &&
1594+
nla_put_u32(skb, TEAM_ATTR_OPTION_PORT_IFINDEX,
1595+
opt_inst_info->port->dev->ifindex))
1596+
goto nla_put_failure;
1597+
if (opt_inst->option->array_size &&
1598+
nla_put_u32(skb, TEAM_ATTR_OPTION_ARRAY_INDEX,
1599+
opt_inst_info->array_index))
1600+
goto nla_put_failure;
1601+
ctx.info = opt_inst_info;
1602+
1603+
switch (option->type) {
1604+
case TEAM_OPTION_TYPE_U32:
1605+
if (nla_put_u8(skb, TEAM_ATTR_OPTION_TYPE, NLA_U32))
1606+
goto nla_put_failure;
1607+
err = team_option_get(team, opt_inst, &ctx);
1608+
if (err)
1609+
goto errout;
1610+
if (nla_put_u32(skb, TEAM_ATTR_OPTION_DATA, ctx.data.u32_val))
1611+
goto nla_put_failure;
1612+
break;
1613+
case TEAM_OPTION_TYPE_STRING:
1614+
if (nla_put_u8(skb, TEAM_ATTR_OPTION_TYPE, NLA_STRING))
1615+
goto nla_put_failure;
1616+
err = team_option_get(team, opt_inst, &ctx);
1617+
if (err)
1618+
goto errout;
1619+
if (nla_put_string(skb, TEAM_ATTR_OPTION_DATA,
1620+
ctx.data.str_val))
1621+
goto nla_put_failure;
1622+
break;
1623+
case TEAM_OPTION_TYPE_BINARY:
1624+
if (nla_put_u8(skb, TEAM_ATTR_OPTION_TYPE, NLA_BINARY))
1625+
goto nla_put_failure;
1626+
err = team_option_get(team, opt_inst, &ctx);
1627+
if (err)
1628+
goto errout;
1629+
if (nla_put(skb, TEAM_ATTR_OPTION_DATA, ctx.data.bin_val.len,
1630+
ctx.data.bin_val.ptr))
1631+
goto nla_put_failure;
1632+
break;
1633+
case TEAM_OPTION_TYPE_BOOL:
1634+
if (nla_put_u8(skb, TEAM_ATTR_OPTION_TYPE, NLA_FLAG))
1635+
goto nla_put_failure;
1636+
err = team_option_get(team, opt_inst, &ctx);
1637+
if (err)
1638+
goto errout;
1639+
if (ctx.data.bool_val &&
1640+
nla_put_flag(skb, TEAM_ATTR_OPTION_DATA))
1641+
goto nla_put_failure;
1642+
break;
1643+
default:
1644+
BUG();
1645+
}
1646+
nla_nest_end(skb, option_item);
1647+
return 0;
1648+
1649+
nla_put_failure:
1650+
err = -EMSGSIZE;
1651+
errout:
1652+
return err;
1653+
}
1654+
15681655
static int team_nl_fill_options_get(struct sk_buff *skb,
15691656
u32 pid, u32 seq, int flags,
1570-
struct team *team, bool fillall)
1657+
struct team *team,
1658+
struct list_head *sel_opt_inst_list)
15711659
{
15721660
struct nlattr *option_list;
15731661
void *hdr;
@@ -1585,85 +1673,10 @@ static int team_nl_fill_options_get(struct sk_buff *skb,
15851673
if (!option_list)
15861674
goto nla_put_failure;
15871675

1588-
list_for_each_entry(opt_inst, &team->option_inst_list, list) {
1589-
struct nlattr *option_item;
1590-
struct team_option *option = opt_inst->option;
1591-
struct team_option_inst_info *opt_inst_info;
1592-
struct team_gsetter_ctx ctx;
1593-
1594-
/* Include only changed options if fill all mode is not on */
1595-
if (!fillall && !opt_inst->changed)
1596-
continue;
1597-
option_item = nla_nest_start(skb, TEAM_ATTR_ITEM_OPTION);
1598-
if (!option_item)
1599-
goto nla_put_failure;
1600-
if (nla_put_string(skb, TEAM_ATTR_OPTION_NAME, option->name))
1601-
goto nla_put_failure;
1602-
if (opt_inst->changed) {
1603-
if (nla_put_flag(skb, TEAM_ATTR_OPTION_CHANGED))
1604-
goto nla_put_failure;
1605-
opt_inst->changed = false;
1606-
}
1607-
if (opt_inst->removed &&
1608-
nla_put_flag(skb, TEAM_ATTR_OPTION_REMOVED))
1609-
goto nla_put_failure;
1610-
1611-
opt_inst_info = &opt_inst->info;
1612-
if (opt_inst_info->port &&
1613-
nla_put_u32(skb, TEAM_ATTR_OPTION_PORT_IFINDEX,
1614-
opt_inst_info->port->dev->ifindex))
1615-
goto nla_put_failure;
1616-
if (opt_inst->option->array_size &&
1617-
nla_put_u32(skb, TEAM_ATTR_OPTION_ARRAY_INDEX,
1618-
opt_inst_info->array_index))
1619-
goto nla_put_failure;
1620-
ctx.info = opt_inst_info;
1621-
1622-
switch (option->type) {
1623-
case TEAM_OPTION_TYPE_U32:
1624-
if (nla_put_u8(skb, TEAM_ATTR_OPTION_TYPE, NLA_U32))
1625-
goto nla_put_failure;
1626-
err = team_option_get(team, opt_inst, &ctx);
1627-
if (err)
1628-
goto errout;
1629-
if (nla_put_u32(skb, TEAM_ATTR_OPTION_DATA,
1630-
ctx.data.u32_val))
1631-
goto nla_put_failure;
1632-
break;
1633-
case TEAM_OPTION_TYPE_STRING:
1634-
if (nla_put_u8(skb, TEAM_ATTR_OPTION_TYPE, NLA_STRING))
1635-
goto nla_put_failure;
1636-
err = team_option_get(team, opt_inst, &ctx);
1637-
if (err)
1638-
goto errout;
1639-
if (nla_put_string(skb, TEAM_ATTR_OPTION_DATA,
1640-
ctx.data.str_val))
1641-
goto nla_put_failure;
1642-
break;
1643-
case TEAM_OPTION_TYPE_BINARY:
1644-
if (nla_put_u8(skb, TEAM_ATTR_OPTION_TYPE, NLA_BINARY))
1645-
goto nla_put_failure;
1646-
err = team_option_get(team, opt_inst, &ctx);
1647-
if (err)
1648-
goto errout;
1649-
if (nla_put(skb, TEAM_ATTR_OPTION_DATA,
1650-
ctx.data.bin_val.len, ctx.data.bin_val.ptr))
1651-
goto nla_put_failure;
1652-
break;
1653-
case TEAM_OPTION_TYPE_BOOL:
1654-
if (nla_put_u8(skb, TEAM_ATTR_OPTION_TYPE, NLA_FLAG))
1655-
goto nla_put_failure;
1656-
err = team_option_get(team, opt_inst, &ctx);
1657-
if (err)
1658-
goto errout;
1659-
if (ctx.data.bool_val &&
1660-
nla_put_flag(skb, TEAM_ATTR_OPTION_DATA))
1661-
goto nla_put_failure;
1662-
break;
1663-
default:
1664-
BUG();
1665-
}
1666-
nla_nest_end(skb, option_item);
1676+
list_for_each_entry(opt_inst, sel_opt_inst_list, tmp_list) {
1677+
err = team_nl_fill_one_option_get(skb, team, opt_inst);
1678+
if (err)
1679+
goto errout;
16671680
}
16681681

16691682
nla_nest_end(skb, option_list);
@@ -1680,9 +1693,14 @@ static int team_nl_fill_options_get_all(struct sk_buff *skb,
16801693
struct genl_info *info, int flags,
16811694
struct team *team)
16821695
{
1696+
struct team_option_inst *opt_inst;
1697+
LIST_HEAD(sel_opt_inst_list);
1698+
1699+
list_for_each_entry(opt_inst, &team->option_inst_list, list)
1700+
list_add_tail(&opt_inst->tmp_list, &sel_opt_inst_list);
16831701
return team_nl_fill_options_get(skb, info->snd_pid,
16841702
info->snd_seq, NLM_F_ACK,
1685-
team, true);
1703+
team, &sel_opt_inst_list);
16861704
}
16871705

16881706
static int team_nl_cmd_options_get(struct sk_buff *skb, struct genl_info *info)
@@ -1941,7 +1959,8 @@ static struct genl_multicast_group team_change_event_mcgrp = {
19411959
.name = TEAM_GENL_CHANGE_EVENT_MC_GRP_NAME,
19421960
};
19431961

1944-
static int team_nl_send_event_options_get(struct team *team)
1962+
static int team_nl_send_event_options_get(struct team *team,
1963+
struct list_head *sel_opt_inst_list)
19451964
{
19461965
struct sk_buff *skb;
19471966
int err;
@@ -1951,7 +1970,7 @@ static int team_nl_send_event_options_get(struct team *team)
19511970
if (!skb)
19521971
return -ENOMEM;
19531972

1954-
err = team_nl_fill_options_get(skb, 0, 0, 0, team, false);
1973+
err = team_nl_fill_options_get(skb, 0, 0, 0, team, sel_opt_inst_list);
19551974
if (err < 0)
19561975
goto err_fill;
19571976

@@ -2021,12 +2040,31 @@ static void team_nl_fini(void)
20212040
static void __team_options_change_check(struct team *team)
20222041
{
20232042
int err;
2043+
struct team_option_inst *opt_inst;
2044+
LIST_HEAD(sel_opt_inst_list);
20242045

2025-
err = team_nl_send_event_options_get(team);
2046+
list_for_each_entry(opt_inst, &team->option_inst_list, list) {
2047+
if (opt_inst->changed)
2048+
list_add_tail(&opt_inst->tmp_list, &sel_opt_inst_list);
2049+
}
2050+
err = team_nl_send_event_options_get(team, &sel_opt_inst_list);
20262051
if (err)
20272052
netdev_warn(team->dev, "Failed to send options change via netlink\n");
20282053
}
20292054

2055+
static void __team_option_inst_change(struct team *team,
2056+
struct team_option_inst *sel_opt_inst)
2057+
{
2058+
int err;
2059+
LIST_HEAD(sel_opt_inst_list);
2060+
2061+
sel_opt_inst->changed = true;
2062+
list_add(&sel_opt_inst->tmp_list, &sel_opt_inst_list);
2063+
err = team_nl_send_event_options_get(team, &sel_opt_inst_list);
2064+
if (err)
2065+
netdev_warn(team->dev, "Failed to send option change via netlink\n");
2066+
}
2067+
20302068
/* rtnl lock is held */
20312069
static void __team_port_change_check(struct team_port *port, bool linkup)
20322070
{

0 commit comments

Comments
 (0)