@@ -89,6 +89,7 @@ static void team_refresh_port_linkup(struct team_port *port)
89
89
90
90
struct team_option_inst { /* One for each option instance */
91
91
struct list_head list ;
92
+ struct list_head tmp_list ;
92
93
struct team_option * option ;
93
94
struct team_option_inst_info info ;
94
95
bool changed ;
@@ -319,6 +320,8 @@ static void __team_options_unregister(struct team *team,
319
320
}
320
321
321
322
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 );
322
325
323
326
int team_options_register (struct team * team ,
324
327
const struct team_option * option ,
@@ -383,8 +386,7 @@ static int team_option_set(struct team *team,
383
386
if (err )
384
387
return err ;
385
388
386
- opt_inst -> changed = true;
387
- __team_options_change_check (team );
389
+ __team_option_inst_change (team , opt_inst );
388
390
return err ;
389
391
}
390
392
@@ -1565,9 +1567,95 @@ static int team_nl_send_generic(struct genl_info *info, struct team *team,
1565
1567
return err ;
1566
1568
}
1567
1569
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
+
1568
1655
static int team_nl_fill_options_get (struct sk_buff * skb ,
1569
1656
u32 pid , u32 seq , int flags ,
1570
- struct team * team , bool fillall )
1657
+ struct team * team ,
1658
+ struct list_head * sel_opt_inst_list )
1571
1659
{
1572
1660
struct nlattr * option_list ;
1573
1661
void * hdr ;
@@ -1585,85 +1673,10 @@ static int team_nl_fill_options_get(struct sk_buff *skb,
1585
1673
if (!option_list )
1586
1674
goto nla_put_failure ;
1587
1675
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 ;
1667
1680
}
1668
1681
1669
1682
nla_nest_end (skb , option_list );
@@ -1680,9 +1693,14 @@ static int team_nl_fill_options_get_all(struct sk_buff *skb,
1680
1693
struct genl_info * info , int flags ,
1681
1694
struct team * team )
1682
1695
{
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 );
1683
1701
return team_nl_fill_options_get (skb , info -> snd_pid ,
1684
1702
info -> snd_seq , NLM_F_ACK ,
1685
- team , true );
1703
+ team , & sel_opt_inst_list );
1686
1704
}
1687
1705
1688
1706
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 = {
1941
1959
.name = TEAM_GENL_CHANGE_EVENT_MC_GRP_NAME ,
1942
1960
};
1943
1961
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 )
1945
1964
{
1946
1965
struct sk_buff * skb ;
1947
1966
int err ;
@@ -1951,7 +1970,7 @@ static int team_nl_send_event_options_get(struct team *team)
1951
1970
if (!skb )
1952
1971
return - ENOMEM ;
1953
1972
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 );
1955
1974
if (err < 0 )
1956
1975
goto err_fill ;
1957
1976
@@ -2021,12 +2040,31 @@ static void team_nl_fini(void)
2021
2040
static void __team_options_change_check (struct team * team )
2022
2041
{
2023
2042
int err ;
2043
+ struct team_option_inst * opt_inst ;
2044
+ LIST_HEAD (sel_opt_inst_list );
2024
2045
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 );
2026
2051
if (err )
2027
2052
netdev_warn (team -> dev , "Failed to send options change via netlink\n" );
2028
2053
}
2029
2054
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
+
2030
2068
/* rtnl lock is held */
2031
2069
static void __team_port_change_check (struct team_port * port , bool linkup )
2032
2070
{
0 commit comments