From: Tobias Waldekranz <tobias@waldekranz.com>
To: Nikolay Aleksandrov <razor@blackwall.org>,
davem@davemloft.net, kuba@kernel.org
Cc: Ivan Vecera <ivecera@redhat.com>, Andrew Lunn <andrew@lunn.ch>,
Florian Fainelli <f.fainelli@gmail.com>,
Jiri Pirko <jiri@resnulli.us>,
bridge@lists.linux-foundation.org,
Ido Schimmel <idosch@nvidia.com>, Petr Machata <petrm@nvidia.com>,
Russell King <linux@armlinux.org.uk>,
linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
Cooper Lees <me@cooperlees.com>, Roopa Prabhu <roopa@nvidia.com>,
Matt Johnston <matt@codeconstruct.com.au>,
Vladimir Oltean <olteanv@gmail.com>,
Vivien Didelot <vivien.didelot@gmail.com>
Subject: Re: [Bridge] [PATCH v3 net-next 03/14] net: bridge: mst: Support setting and reporting MST port states
Date: Mon, 14 Mar 2022 13:38:34 +0100 [thread overview]
Message-ID: <8735jkn1yt.fsf@waldekranz.com> (raw)
In-Reply-To: <d16cb4b7-a1bf-2e96-0b59-2c4c37b2fdd3@blackwall.org>
On Mon, Mar 14, 2022 at 12:37, Nikolay Aleksandrov <razor@blackwall.org> wrote:
> On 14/03/2022 11:52, Tobias Waldekranz wrote:
>> Make it possible to change the port state in a given MSTI by extending
>> the bridge port netlink interface (RTM_SETLINK on PF_BRIDGE).The
>> proposed iproute2 interface would be:
>>
>> bridge mst set dev <PORT> msti <MSTI> state <STATE>
>>
>> Current states in all applicable MSTIs can also be dumped via a
>> corresponding RTM_GETLINK. The proposed iproute interface looks like
>> this:
>>
>> $ bridge mst
>> port msti
>> vb1 0
>> state forwarding
>> 100
>> state disabled
>> vb2 0
>> state forwarding
>> 100
>> state forwarding
>>
>> The preexisting per-VLAN states are still valid in the MST
>> mode (although they are read-only), and can be queried as usual if one
>> is interested in knowing a particular VLAN's state without having to
>> care about the VID to MSTI mapping (in this example VLAN 20 and 30 are
>> bound to MSTI 100):
>>
>> $ bridge -d vlan
>> port vlan-id
>> vb1 10
>> state forwarding mcast_router 1
>> 20
>> state disabled mcast_router 1
>> 30
>> state disabled mcast_router 1
>> 40
>> state forwarding mcast_router 1
>> vb2 10
>> state forwarding mcast_router 1
>> 20
>> state forwarding mcast_router 1
>> 30
>> state forwarding mcast_router 1
>> 40
>> state forwarding mcast_router 1
>>
>> Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
>> ---
>
> Hi Tobias,
> A few comments below..
>
>> include/uapi/linux/if_bridge.h | 17 ++++++
>> include/uapi/linux/rtnetlink.h | 1 +
>> net/bridge/br_mst.c | 105 +++++++++++++++++++++++++++++++++
>> net/bridge/br_netlink.c | 32 +++++++++-
>> net/bridge/br_private.h | 15 +++++
>> 5 files changed, 169 insertions(+), 1 deletion(-)
>>
>> diff --git a/include/uapi/linux/if_bridge.h b/include/uapi/linux/if_bridge.h
>> index f60244b747ae..879dfaef8da0 100644
>> --- a/include/uapi/linux/if_bridge.h
>> +++ b/include/uapi/linux/if_bridge.h
>> @@ -122,6 +122,7 @@ enum {
>> IFLA_BRIDGE_VLAN_TUNNEL_INFO,
>> IFLA_BRIDGE_MRP,
>> IFLA_BRIDGE_CFM,
>> + IFLA_BRIDGE_MST,
>> __IFLA_BRIDGE_MAX,
>> };
>> #define IFLA_BRIDGE_MAX (__IFLA_BRIDGE_MAX - 1)
>> @@ -453,6 +454,21 @@ enum {
>>
>> #define IFLA_BRIDGE_CFM_CC_PEER_STATUS_MAX (__IFLA_BRIDGE_CFM_CC_PEER_STATUS_MAX - 1)
>>
>> +enum {
>> + IFLA_BRIDGE_MST_UNSPEC,
>> + IFLA_BRIDGE_MST_ENTRY,
>> + __IFLA_BRIDGE_MST_MAX,
>> +};
>> +#define IFLA_BRIDGE_MST_MAX (__IFLA_BRIDGE_MST_MAX - 1)
>> +
>> +enum {
>> + IFLA_BRIDGE_MST_ENTRY_UNSPEC,
>> + IFLA_BRIDGE_MST_ENTRY_MSTI,
>> + IFLA_BRIDGE_MST_ENTRY_STATE,
>> + __IFLA_BRIDGE_MST_ENTRY_MAX,
>> +};
>> +#define IFLA_BRIDGE_MST_ENTRY_MAX (__IFLA_BRIDGE_MST_ENTRY_MAX - 1)
>> +
>> struct bridge_stp_xstats {
>> __u64 transition_blk;
>> __u64 transition_fwd;
>> @@ -786,4 +802,5 @@ enum {
>> __BRIDGE_QUERIER_MAX
>> };
>> #define BRIDGE_QUERIER_MAX (__BRIDGE_QUERIER_MAX - 1)
>> +
>
> stray new line
Well that's embarrassing :)
>> #endif /* _UAPI_LINUX_IF_BRIDGE_H */
>> diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h
>> index 51530aade46e..83849a37db5b 100644
>> --- a/include/uapi/linux/rtnetlink.h
>> +++ b/include/uapi/linux/rtnetlink.h
>> @@ -817,6 +817,7 @@ enum {
>> #define RTEXT_FILTER_MRP (1 << 4)
>> #define RTEXT_FILTER_CFM_CONFIG (1 << 5)
>> #define RTEXT_FILTER_CFM_STATUS (1 << 6)
>> +#define RTEXT_FILTER_MST (1 << 7)
>>
>> /* End of information exported to user level */
>>
>> diff --git a/net/bridge/br_mst.c b/net/bridge/br_mst.c
>> index 78ef5fea4d2b..df65aa7701c1 100644
>> --- a/net/bridge/br_mst.c
>> +++ b/net/bridge/br_mst.c
>> @@ -124,3 +124,108 @@ int br_mst_set_enabled(struct net_bridge *br, bool on,
>> br_opt_toggle(br, BROPT_MST_ENABLED, on);
>> return 0;
>> }
>> +
>> +int br_mst_fill_info(struct sk_buff *skb, struct net_bridge_vlan_group *vg)
>
> const vg
>
>> +{
>> + struct net_bridge_vlan *v;
>
> const v
>
>> + struct nlattr *nest;
>> + unsigned long *seen;
>> + int err = 0;
>> +
>> + seen = bitmap_zalloc(VLAN_N_VID, 0);
>> + if (!seen)
>> + return -ENOMEM;
>> +
>> + list_for_each_entry(v, &vg->vlan_list, vlist) {
>> + if (test_bit(v->brvlan->msti, seen))
>> + continue;
>> +
>> + nest = nla_nest_start_noflag(skb, IFLA_BRIDGE_MST_ENTRY);
>> + if (!nest ||
>> + nla_put_u16(skb, IFLA_BRIDGE_MST_ENTRY_MSTI, v->brvlan->msti) ||
>> + nla_put_u8(skb, IFLA_BRIDGE_MST_ENTRY_STATE, v->state)) {
>> + err = -EMSGSIZE;
>> + break;
>> + }
>> + nla_nest_end(skb, nest);
>> +
>> + set_bit(v->brvlan->msti, seen);
>
> __set_bit()
>
>> + }
>> +
>> + kfree(seen);
>> + return err;
>> +}
>> +
>> +static const struct nla_policy br_mst_nl_policy[IFLA_BRIDGE_MST_ENTRY_MAX + 1] = {
>> + [IFLA_BRIDGE_MST_ENTRY_MSTI] = NLA_POLICY_RANGE(NLA_U16,
>> + 1, /* 0 reserved for CST */
>> + VLAN_N_VID - 1),
>> + [IFLA_BRIDGE_MST_ENTRY_STATE] = NLA_POLICY_RANGE(NLA_U8,
>> + BR_STATE_DISABLED,
>> + BR_STATE_BLOCKING),
>> +};
>> +
>> +static int br_mst_parse_one(struct net_bridge_port *p,
>> + const struct nlattr *attr,
>> + struct netlink_ext_ack *extack)
>> +{
>
> I'd either set the state after parsing, so this function just does what it
> says (parse) or I'd rename it.
>
>> + struct nlattr *tb[IFLA_BRIDGE_MST_ENTRY_MAX + 1];
>> + u16 msti;
>> + u8 state;
>> + int err;
>> +
>> + err = nla_parse_nested(tb, IFLA_BRIDGE_MST_ENTRY_MAX, attr,
>> + br_mst_nl_policy, extack);
>> + if (err)
>> + return err;
>> +
>> + if (!tb[IFLA_BRIDGE_MST_ENTRY_MSTI]) {
>> + NL_SET_ERR_MSG_MOD(extack, "MSTI not specified");
>> + return -EINVAL;
>> + }
>> +
>> + if (!tb[IFLA_BRIDGE_MST_ENTRY_STATE]) {
>> + NL_SET_ERR_MSG_MOD(extack, "State not specified");
>> + return -EINVAL;
>> + }
>> +
>> + msti = nla_get_u16(tb[IFLA_BRIDGE_MST_ENTRY_MSTI]);
>> + state = nla_get_u8(tb[IFLA_BRIDGE_MST_ENTRY_STATE]);
>> +
>> + br_mst_set_state(p, msti, state);
>> + return 0;
>> +}
>> +
>> +int br_mst_parse(struct net_bridge_port *p, struct nlattr *mst_attr,
>> + struct netlink_ext_ack *extack)
>
> This doesn't just parse though, it also sets the state. Please rename it to
> something more appropriate.
>
> const mst_attr
>
>> +{
>> + struct nlattr *attr;
>> + int err, msts = 0;
>> + int rem;
>> +
>> + if (!br_opt_get(p->br, BROPT_MST_ENABLED)) {
>> + NL_SET_ERR_MSG_MOD(extack, "Can't modify MST state when MST is disabled");
>> + return -EBUSY;
>> + }
>> +
>> + nla_for_each_nested(attr, mst_attr, rem) {
>> + switch (nla_type(attr)) {
>> + case IFLA_BRIDGE_MST_ENTRY:
>> + err = br_mst_parse_one(p, attr, extack);
>> + break;
>> + default:
>> + continue;
>> + }
>> +
>> + msts++;
>> + if (err)
>> + break;
>> + }
>> +
>> + if (!msts) {
>> + NL_SET_ERR_MSG_MOD(extack, "Found no MST entries to process");
>> + err = -EINVAL;
>> + }
>> +
>> + return err;
>> +}
>> diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
>> index 7d4432ca9a20..d2b4550f30d6 100644
>> --- a/net/bridge/br_netlink.c
>> +++ b/net/bridge/br_netlink.c
>> @@ -485,7 +485,8 @@ static int br_fill_ifinfo(struct sk_buff *skb,
>> RTEXT_FILTER_BRVLAN_COMPRESSED |
>> RTEXT_FILTER_MRP |
>> RTEXT_FILTER_CFM_CONFIG |
>> - RTEXT_FILTER_CFM_STATUS)) {
>> + RTEXT_FILTER_CFM_STATUS |
>> + RTEXT_FILTER_MST)) {
>> af = nla_nest_start_noflag(skb, IFLA_AF_SPEC);
>> if (!af)
>> goto nla_put_failure;
>> @@ -564,7 +565,28 @@ static int br_fill_ifinfo(struct sk_buff *skb,
>> nla_nest_end(skb, cfm_nest);
>> }
>>
>> + if ((filter_mask & RTEXT_FILTER_MST) &&
>> + br_opt_get(br, BROPT_MST_ENABLED) && port) {
>> + struct net_bridge_vlan_group *vg = nbp_vlan_group(port);
>
> const vg
>
>> + struct nlattr *mst_nest;
>> + int err;
>> +
>> + if (!vg || !vg->num_vlans)
>> + goto done;
>> +
>> + mst_nest = nla_nest_start(skb, IFLA_BRIDGE_MST);
>> + if (!mst_nest)
>> + goto nla_put_failure;
>> +
>> + err = br_mst_fill_info(skb, vg);
>> + if (err)
>> + goto nla_put_failure;
>> +
>> + nla_nest_end(skb, mst_nest);
>> + }
>> +
>
> I think you should also update br_get_link_af_size_filtered() to account for the
> new dump attributes based on the filter. I'd adjust vinfo_sz based on the filter
> flag.
>
>> done:
>> +
>> if (af)
>> nla_nest_end(skb, af);
>> nlmsg_end(skb, nlh);
>> @@ -803,6 +825,14 @@ static int br_afspec(struct net_bridge *br,
>> if (err)
>> return err;
>> break;
>> + case IFLA_BRIDGE_MST:
>> + if (cmd != RTM_SETLINK || !p)
>> + return -EINVAL;
>
> These are two different errors, please set extack appropriately
> for each error.
Thanks for the review, all of the above will be fixed in v4.
next prev parent reply other threads:[~2022-03-14 12:38 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-14 9:52 [Bridge] [PATCH v3 net-next 00/14] net: bridge: Multiple Spanning Trees Tobias Waldekranz
2022-03-14 9:52 ` [Bridge] [PATCH v3 net-next 01/14] net: bridge: mst: Multiple Spanning Tree (MST) mode Tobias Waldekranz
2022-03-14 10:37 ` Nikolay Aleksandrov
2022-03-14 11:09 ` Nikolay Aleksandrov
2022-03-14 16:43 ` kernel test robot
2022-03-14 9:52 ` [Bridge] [PATCH v3 net-next 02/14] net: bridge: mst: Allow changing a VLAN's MSTI Tobias Waldekranz
2022-03-14 10:45 ` Nikolay Aleksandrov
2022-03-14 9:52 ` [Bridge] [PATCH v3 net-next 03/14] net: bridge: mst: Support setting and reporting MST port states Tobias Waldekranz
2022-03-14 10:37 ` Nikolay Aleksandrov
2022-03-14 12:38 ` Tobias Waldekranz [this message]
2022-03-14 14:58 ` Vladimir Oltean
2022-03-14 15:42 ` Tobias Waldekranz
2022-03-14 9:52 ` [Bridge] [PATCH v3 net-next 04/14] net: bridge: mst: Notify switchdev drivers of MST mode changes Tobias Waldekranz
2022-03-14 9:52 ` [Bridge] [PATCH v3 net-next 05/14] net: bridge: mst: Notify switchdev drivers of VLAN MSTI migrations Tobias Waldekranz
2022-03-14 9:52 ` [Bridge] [PATCH v3 net-next 06/14] net: bridge: mst: Notify switchdev drivers of MST state changes Tobias Waldekranz
2022-03-14 9:52 ` [Bridge] [PATCH v3 net-next 07/14] net: bridge: mst: Add helper to map an MSTI to a VID set Tobias Waldekranz
2022-03-14 10:42 ` Nikolay Aleksandrov
2022-03-14 9:52 ` [Bridge] [PATCH v3 net-next 08/14] net: bridge: mst: Add helper to check if MST is enabled Tobias Waldekranz
2022-03-14 10:43 ` Nikolay Aleksandrov
2022-03-14 9:52 ` [Bridge] [PATCH v3 net-next 09/14] net: dsa: Validate hardware support for MST Tobias Waldekranz
2022-03-14 16:56 ` Vladimir Oltean
2022-03-14 17:55 ` Vladimir Oltean
2022-03-14 20:01 ` Tobias Waldekranz
2022-03-14 20:20 ` Vladimir Oltean
2022-03-14 22:13 ` Tobias Waldekranz
2022-03-14 17:51 ` Vladimir Oltean
2022-03-14 9:52 ` [Bridge] [PATCH v3 net-next 10/14] net: dsa: Pass VLAN MSTI migration notifications to driver Tobias Waldekranz
2022-03-14 17:07 ` Vladimir Oltean
2022-03-14 9:52 ` [Bridge] [PATCH v3 net-next 11/14] net: dsa: Handle MST state changes Tobias Waldekranz
2022-03-14 17:14 ` Vladimir Oltean
2022-03-14 9:52 ` [Bridge] [PATCH v3 net-next 12/14] net: dsa: mv88e6xxx: Disentangle STU from VTU Tobias Waldekranz
2022-03-14 9:52 ` [Bridge] [PATCH v3 net-next 13/14] net: dsa: mv88e6xxx: Export STU as devlink region Tobias Waldekranz
2022-03-14 9:52 ` [Bridge] [PATCH v3 net-next 14/14] net: dsa: mv88e6xxx: MST Offloading Tobias Waldekranz
2022-03-14 16:27 ` Vladimir Oltean
2022-03-14 21:57 ` Tobias Waldekranz
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=8735jkn1yt.fsf@waldekranz.com \
--to=tobias@waldekranz.com \
--cc=andrew@lunn.ch \
--cc=bridge@lists.linux-foundation.org \
--cc=davem@davemloft.net \
--cc=f.fainelli@gmail.com \
--cc=idosch@nvidia.com \
--cc=ivecera@redhat.com \
--cc=jiri@resnulli.us \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@armlinux.org.uk \
--cc=matt@codeconstruct.com.au \
--cc=me@cooperlees.com \
--cc=netdev@vger.kernel.org \
--cc=olteanv@gmail.com \
--cc=petrm@nvidia.com \
--cc=razor@blackwall.org \
--cc=roopa@nvidia.com \
--cc=vivien.didelot@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.