All of lore.kernel.org
 help / color / mirror / Atom feed
From: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
To: Horatiu Vultur <horatiu.vultur@microchip.com>,
	davem@davemloft.net, jiri@resnulli.us, ivecera@redhat.com,
	kuba@kernel.org, roopa@cumulusnetworks.com, olteanv@gmail.com,
	andrew@lunn.ch, linux-kernel@vger.kernel.org,
	netdev@vger.kernel.org, bridge@lists.linux-foundation.org,
	UNGLinuxDriver@microchip.com
Subject: Re: [RFC net-next v5 9/9] bridge: mrp: Integrate MRP into the bridge
Date: Sat, 18 Apr 2020 11:25:46 +0300	[thread overview]
Message-ID: <48c8e196-5808-d7c8-25c3-dff8f56dea5b@cumulusnetworks.com> (raw)
In-Reply-To: <20200414112618.3644-10-horatiu.vultur@microchip.com>

On 14/04/2020 14:26, Horatiu Vultur wrote:
> To integrate MRP into the bridge, the bridge needs to do the following:
> - add new flag(BR_MPP_AWARE) to the net bridge ports, this bit will be set when
>   the port is added to an MRP instance. In this way it knows if the frame was
>   received on MRP ring port
> - detect if the MRP frame was received on MRP ring port in that case it would be
>   processed otherwise just forward it as usual.
> - enable parsing of MRP
> - before whenever the bridge was set up, it would set all the ports in
>   forwarding state. Add an extra check to not set ports in forwarding state if
>   the port is an MRP ring port. The reason of this change is that if the MRP
>   instance initially sets the port in blocked state by setting the bridge up it
>   would overwrite this setting.
> 
> Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
> ---
>  include/linux/if_bridge.h |  1 +
>  net/bridge/br_device.c    |  3 +++
>  net/bridge/br_if.c        |  2 ++
>  net/bridge/br_input.c     |  3 +++
>  net/bridge/br_netlink.c   |  5 +++++
>  net/bridge/br_private.h   | 35 +++++++++++++++++++++++++++++++++++
>  net/bridge/br_stp.c       |  6 ++++++
>  net/bridge/br_stp_if.c    |  5 +++++
>  8 files changed, 60 insertions(+)
> 
> diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h
> index 9e57c4411734..10baa9efdae8 100644
> --- a/include/linux/if_bridge.h
> +++ b/include/linux/if_bridge.h
> @@ -47,6 +47,7 @@ struct br_ip_list {
>  #define BR_BCAST_FLOOD		BIT(14)
>  #define BR_NEIGH_SUPPRESS	BIT(15)
>  #define BR_ISOLATED		BIT(16)
> +#define BR_MRP_AWARE		BIT(17)
>  
>  #define BR_DEFAULT_AGEING_TIME	(300 * HZ)
>  
> diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
> index 0e3dbc5f3c34..8ec1362588af 100644
> --- a/net/bridge/br_device.c
> +++ b/net/bridge/br_device.c
> @@ -463,6 +463,9 @@ void br_dev_setup(struct net_device *dev)
>  	spin_lock_init(&br->lock);
>  	INIT_LIST_HEAD(&br->port_list);
>  	INIT_HLIST_HEAD(&br->fdb_list);
> +#if IS_ENABLED(CONFIG_BRIDGE_MRP)
> +	INIT_LIST_HEAD(&br->mrp_list);
> +#endif
>  	spin_lock_init(&br->hash_lock);
>  
>  	br->bridge_id.prio[0] = 0x80;
> diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
> index 4fe30b182ee7..ca685c0cdf95 100644
> --- a/net/bridge/br_if.c
> +++ b/net/bridge/br_if.c
> @@ -333,6 +333,8 @@ static void del_nbp(struct net_bridge_port *p)
>  	br_stp_disable_port(p);
>  	spin_unlock_bh(&br->lock);
>  
> +	br_mrp_port_del(br, p);
> +
>  	br_ifinfo_notify(RTM_DELLINK, NULL, p);
>  
>  	list_del_rcu(&p->list);
> diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
> index fcc260840028..d5c34f36f0f4 100644
> --- a/net/bridge/br_input.c
> +++ b/net/bridge/br_input.c
> @@ -342,6 +342,9 @@ rx_handler_result_t br_handle_frame(struct sk_buff **pskb)
>  		}
>  	}
>  
> +	if (unlikely(br_mrp_process(p, skb)))
> +		return RX_HANDLER_PASS;
> +
>  forward:
>  	switch (p->state) {
>  	case BR_STATE_FORWARDING:
> diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
> index 43dab4066f91..8826fcd1eb76 100644
> --- a/net/bridge/br_netlink.c
> +++ b/net/bridge/br_netlink.c
> @@ -669,6 +669,11 @@ static int br_afspec(struct net_bridge *br,
>  			if (err)
>  				return err;
>  			break;
> +		case IFLA_BRIDGE_MRP:
> +			err = br_mrp_parse(br, p, attr, cmd, extack);
> +			if (err)
> +				return err;
> +			break;
>  		}
>  	}
>  
> diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
> index 1f97703a52ff..5835828320b6 100644
> --- a/net/bridge/br_private.h
> +++ b/net/bridge/br_private.h
> @@ -428,6 +428,10 @@ struct net_bridge {
>  	int offload_fwd_mark;
>  #endif
>  	struct hlist_head		fdb_list;
> +
> +#if IS_ENABLED(CONFIG_BRIDGE_MRP)
> +	struct list_head		__rcu mrp_list;
> +#endif
>  };
>  
>  struct br_input_skb_cb {
> @@ -1304,6 +1308,37 @@ unsigned long br_timer_value(const struct timer_list *timer);
>  extern int (*br_fdb_test_addr_hook)(struct net_device *dev, unsigned char *addr);
>  #endif
>  
> +/* br_mrp.c */
> +#if IS_ENABLED(CONFIG_BRIDGE_MRP)
> +int br_mrp_parse(struct net_bridge *br, struct net_bridge_port *p,
> +		 struct nlattr *attr, int cmd, struct netlink_ext_ack *extack);
> +int br_mrp_process(struct net_bridge_port *p, struct sk_buff *skb);
> +bool br_mrp_enabled(struct net_bridge *br);
> +void br_mrp_port_del(struct net_bridge *br, struct net_bridge_port *p);
> +#else
> +static inline int br_mrp_parse(struct net_bridge *br, struct net_bridge_port *p,
> +			       struct nlattr *attr, int cmd,
> +			       struct netlink_ext_ack *extack)
> +{
> +	return -EOPNOTSUPP;
> +}
> +
> +static inline int br_mrp_process(struct net_bridge_port *p, struct sk_buff *skb)
> +{
> +	return 0;
> +}
> +
> +static inline bool br_mrp_enabled(struct net_bridge *br)
> +{
> +	return 0;
> +}
> +
> +static inline void br_mrp_port_del(struct net_bridge *br,
> +				   struct net_bridge_port *p)
> +{
> +}
> +#endif
> +
>  /* br_netlink.c */
>  extern struct rtnl_link_ops br_link_ops;
>  int br_netlink_init(void);
> diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c
> index 1f14b8455345..3e88be7aa269 100644
> --- a/net/bridge/br_stp.c
> +++ b/net/bridge/br_stp.c
> @@ -36,6 +36,12 @@ void br_set_state(struct net_bridge_port *p, unsigned int state)
>  	};
>  	int err;
>  
> +	/* Don't change the state of the ports if they are driven by a different
> +	 * protocol.
> +	 */
> +	if (p->flags & BR_MRP_AWARE)
> +		return;
> +
>  	p->state = state;
>  	err = switchdev_port_attr_set(p->dev, &attr);
>  	if (err && err != -EOPNOTSUPP)
> diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c
> index d174d3a566aa..542b212d5033 100644
> --- a/net/bridge/br_stp_if.c
> +++ b/net/bridge/br_stp_if.c
> @@ -200,6 +200,11 @@ void br_stp_set_enabled(struct net_bridge *br, unsigned long val)
>  {
>  	ASSERT_RTNL();
>  
> +	if (br_mrp_enabled(br)) {
> +		br_warn(br, "STP can't be enabled if MRP is already enabled\n");

It'd be nice if this can be returned in an extack if this function is called from netlink.
In addition this must return an error - otherwise writing to the sysfs file would be successful
while nothing will have changed, so the user will think it worked. Check out set_stp_state().
You can drop the br_warn, just make sure to return proper extack error from netlink (it is
the preferred interface over sysfs, so simply returning an error for sysfs would be enough).

> +		return;
> +	}
> +
>  	if (val) {
>  		if (br->stp_enabled == BR_NO_STP)
>  			br_stp_start(br);
> 


WARNING: multiple messages have this Message-ID (diff)
From: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
To: Horatiu Vultur <horatiu.vultur@microchip.com>,
	davem@davemloft.net, jiri@resnulli.us, ivecera@redhat.com,
	kuba@kernel.org, roopa@cumulusnetworks.com, olteanv@gmail.com,
	andrew@lunn.ch, linux-kernel@vger.kernel.org,
	netdev@vger.kernel.org, bridge@lists.linux-foundation.org,
	UNGLinuxDriver@microchip.com
Subject: Re: [Bridge] [RFC net-next v5 9/9] bridge: mrp: Integrate MRP into the bridge
Date: Sat, 18 Apr 2020 11:25:46 +0300	[thread overview]
Message-ID: <48c8e196-5808-d7c8-25c3-dff8f56dea5b@cumulusnetworks.com> (raw)
In-Reply-To: <20200414112618.3644-10-horatiu.vultur@microchip.com>

On 14/04/2020 14:26, Horatiu Vultur wrote:
> To integrate MRP into the bridge, the bridge needs to do the following:
> - add new flag(BR_MPP_AWARE) to the net bridge ports, this bit will be set when
>   the port is added to an MRP instance. In this way it knows if the frame was
>   received on MRP ring port
> - detect if the MRP frame was received on MRP ring port in that case it would be
>   processed otherwise just forward it as usual.
> - enable parsing of MRP
> - before whenever the bridge was set up, it would set all the ports in
>   forwarding state. Add an extra check to not set ports in forwarding state if
>   the port is an MRP ring port. The reason of this change is that if the MRP
>   instance initially sets the port in blocked state by setting the bridge up it
>   would overwrite this setting.
> 
> Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
> ---
>  include/linux/if_bridge.h |  1 +
>  net/bridge/br_device.c    |  3 +++
>  net/bridge/br_if.c        |  2 ++
>  net/bridge/br_input.c     |  3 +++
>  net/bridge/br_netlink.c   |  5 +++++
>  net/bridge/br_private.h   | 35 +++++++++++++++++++++++++++++++++++
>  net/bridge/br_stp.c       |  6 ++++++
>  net/bridge/br_stp_if.c    |  5 +++++
>  8 files changed, 60 insertions(+)
> 
> diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h
> index 9e57c4411734..10baa9efdae8 100644
> --- a/include/linux/if_bridge.h
> +++ b/include/linux/if_bridge.h
> @@ -47,6 +47,7 @@ struct br_ip_list {
>  #define BR_BCAST_FLOOD		BIT(14)
>  #define BR_NEIGH_SUPPRESS	BIT(15)
>  #define BR_ISOLATED		BIT(16)
> +#define BR_MRP_AWARE		BIT(17)
>  
>  #define BR_DEFAULT_AGEING_TIME	(300 * HZ)
>  
> diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
> index 0e3dbc5f3c34..8ec1362588af 100644
> --- a/net/bridge/br_device.c
> +++ b/net/bridge/br_device.c
> @@ -463,6 +463,9 @@ void br_dev_setup(struct net_device *dev)
>  	spin_lock_init(&br->lock);
>  	INIT_LIST_HEAD(&br->port_list);
>  	INIT_HLIST_HEAD(&br->fdb_list);
> +#if IS_ENABLED(CONFIG_BRIDGE_MRP)
> +	INIT_LIST_HEAD(&br->mrp_list);
> +#endif
>  	spin_lock_init(&br->hash_lock);
>  
>  	br->bridge_id.prio[0] = 0x80;
> diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
> index 4fe30b182ee7..ca685c0cdf95 100644
> --- a/net/bridge/br_if.c
> +++ b/net/bridge/br_if.c
> @@ -333,6 +333,8 @@ static void del_nbp(struct net_bridge_port *p)
>  	br_stp_disable_port(p);
>  	spin_unlock_bh(&br->lock);
>  
> +	br_mrp_port_del(br, p);
> +
>  	br_ifinfo_notify(RTM_DELLINK, NULL, p);
>  
>  	list_del_rcu(&p->list);
> diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
> index fcc260840028..d5c34f36f0f4 100644
> --- a/net/bridge/br_input.c
> +++ b/net/bridge/br_input.c
> @@ -342,6 +342,9 @@ rx_handler_result_t br_handle_frame(struct sk_buff **pskb)
>  		}
>  	}
>  
> +	if (unlikely(br_mrp_process(p, skb)))
> +		return RX_HANDLER_PASS;
> +
>  forward:
>  	switch (p->state) {
>  	case BR_STATE_FORWARDING:
> diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
> index 43dab4066f91..8826fcd1eb76 100644
> --- a/net/bridge/br_netlink.c
> +++ b/net/bridge/br_netlink.c
> @@ -669,6 +669,11 @@ static int br_afspec(struct net_bridge *br,
>  			if (err)
>  				return err;
>  			break;
> +		case IFLA_BRIDGE_MRP:
> +			err = br_mrp_parse(br, p, attr, cmd, extack);
> +			if (err)
> +				return err;
> +			break;
>  		}
>  	}
>  
> diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
> index 1f97703a52ff..5835828320b6 100644
> --- a/net/bridge/br_private.h
> +++ b/net/bridge/br_private.h
> @@ -428,6 +428,10 @@ struct net_bridge {
>  	int offload_fwd_mark;
>  #endif
>  	struct hlist_head		fdb_list;
> +
> +#if IS_ENABLED(CONFIG_BRIDGE_MRP)
> +	struct list_head		__rcu mrp_list;
> +#endif
>  };
>  
>  struct br_input_skb_cb {
> @@ -1304,6 +1308,37 @@ unsigned long br_timer_value(const struct timer_list *timer);
>  extern int (*br_fdb_test_addr_hook)(struct net_device *dev, unsigned char *addr);
>  #endif
>  
> +/* br_mrp.c */
> +#if IS_ENABLED(CONFIG_BRIDGE_MRP)
> +int br_mrp_parse(struct net_bridge *br, struct net_bridge_port *p,
> +		 struct nlattr *attr, int cmd, struct netlink_ext_ack *extack);
> +int br_mrp_process(struct net_bridge_port *p, struct sk_buff *skb);
> +bool br_mrp_enabled(struct net_bridge *br);
> +void br_mrp_port_del(struct net_bridge *br, struct net_bridge_port *p);
> +#else
> +static inline int br_mrp_parse(struct net_bridge *br, struct net_bridge_port *p,
> +			       struct nlattr *attr, int cmd,
> +			       struct netlink_ext_ack *extack)
> +{
> +	return -EOPNOTSUPP;
> +}
> +
> +static inline int br_mrp_process(struct net_bridge_port *p, struct sk_buff *skb)
> +{
> +	return 0;
> +}
> +
> +static inline bool br_mrp_enabled(struct net_bridge *br)
> +{
> +	return 0;
> +}
> +
> +static inline void br_mrp_port_del(struct net_bridge *br,
> +				   struct net_bridge_port *p)
> +{
> +}
> +#endif
> +
>  /* br_netlink.c */
>  extern struct rtnl_link_ops br_link_ops;
>  int br_netlink_init(void);
> diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c
> index 1f14b8455345..3e88be7aa269 100644
> --- a/net/bridge/br_stp.c
> +++ b/net/bridge/br_stp.c
> @@ -36,6 +36,12 @@ void br_set_state(struct net_bridge_port *p, unsigned int state)
>  	};
>  	int err;
>  
> +	/* Don't change the state of the ports if they are driven by a different
> +	 * protocol.
> +	 */
> +	if (p->flags & BR_MRP_AWARE)
> +		return;
> +
>  	p->state = state;
>  	err = switchdev_port_attr_set(p->dev, &attr);
>  	if (err && err != -EOPNOTSUPP)
> diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c
> index d174d3a566aa..542b212d5033 100644
> --- a/net/bridge/br_stp_if.c
> +++ b/net/bridge/br_stp_if.c
> @@ -200,6 +200,11 @@ void br_stp_set_enabled(struct net_bridge *br, unsigned long val)
>  {
>  	ASSERT_RTNL();
>  
> +	if (br_mrp_enabled(br)) {
> +		br_warn(br, "STP can't be enabled if MRP is already enabled\n");

It'd be nice if this can be returned in an extack if this function is called from netlink.
In addition this must return an error - otherwise writing to the sysfs file would be successful
while nothing will have changed, so the user will think it worked. Check out set_stp_state().
You can drop the br_warn, just make sure to return proper extack error from netlink (it is
the preferred interface over sysfs, so simply returning an error for sysfs would be enough).

> +		return;
> +	}
> +
>  	if (val) {
>  		if (br->stp_enabled == BR_NO_STP)
>  			br_stp_start(br);
> 


  reply	other threads:[~2020-04-18  8:25 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-14 11:26 [RFC net-next v5 0/9] net: bridge: mrp: Add support for Media Redundancy Protocol(MRP) Horatiu Vultur
2020-04-14 11:26 ` [Bridge] " Horatiu Vultur
2020-04-14 11:26 ` [RFC net-next v5 1/9] bridge: uapi: mrp: Add mrp attributes Horatiu Vultur
2020-04-14 11:26   ` [Bridge] " Horatiu Vultur
2020-04-14 11:26 ` [RFC net-next v5 2/9] bridge: mrp: Update Kconfig and Makefile Horatiu Vultur
2020-04-14 11:26   ` [Bridge] " Horatiu Vultur
2020-04-18  8:49   ` Nikolay Aleksandrov
2020-04-18  8:49     ` [Bridge] " Nikolay Aleksandrov
2020-04-14 11:26 ` [RFC net-next v5 3/9] bridge: mrp: Expose function br_mrp_port_open Horatiu Vultur
2020-04-14 11:26   ` [Bridge] " Horatiu Vultur
2020-04-18  8:11   ` Nikolay Aleksandrov
2020-04-18  8:11     ` [Bridge] " Nikolay Aleksandrov
2020-04-18 15:29     ` Horatiu Vultur
2020-04-18 15:29       ` [Bridge] " Horatiu Vultur
2020-04-14 11:26 ` [RFC net-next v5 4/9] bridge: mrp: Add MRP interface Horatiu Vultur
2020-04-14 11:26   ` [Bridge] " Horatiu Vultur
2020-04-14 11:26 ` [RFC net-next v5 5/9] switchdev: mrp: Extend switchdev API to offload MRP Horatiu Vultur
2020-04-14 11:26   ` [Bridge] " Horatiu Vultur
2020-04-14 11:26 ` [RFC net-next v5 6/9] bridge: switchdev: mrp: Implement MRP API for switchdev Horatiu Vultur
2020-04-14 11:26   ` [Bridge] " Horatiu Vultur
2020-04-14 11:26 ` [RFC net-next v5 7/9] bridge: mrp: Connect MRP API with the switchev API Horatiu Vultur
2020-04-14 11:26   ` [Bridge] " Horatiu Vultur
2020-04-18  8:46   ` Nikolay Aleksandrov
2020-04-18  8:46     ` [Bridge] " Nikolay Aleksandrov
2020-04-18 14:57     ` Horatiu Vultur
2020-04-18 14:57       ` [Bridge] " Horatiu Vultur
2020-04-18  8:50   ` Nikolay Aleksandrov
2020-04-18  8:50     ` [Bridge] " Nikolay Aleksandrov
2020-04-14 11:26 ` [RFC net-next v5 8/9] bridge: mrp: Implement netlink interface to configure MRP Horatiu Vultur
2020-04-14 11:26   ` [Bridge] " Horatiu Vultur
2020-04-18  8:21   ` Nikolay Aleksandrov
2020-04-18  8:21     ` [Bridge] " Nikolay Aleksandrov
2020-04-18 14:48     ` Horatiu Vultur
2020-04-18 14:48       ` [Bridge] " Horatiu Vultur
2020-04-18  8:34   ` Nikolay Aleksandrov
2020-04-18  8:34     ` [Bridge] " Nikolay Aleksandrov
2020-04-18 14:51     ` Horatiu Vultur
2020-04-18 14:51       ` [Bridge] " Horatiu Vultur
2020-04-14 11:26 ` [RFC net-next v5 9/9] bridge: mrp: Integrate MRP into the bridge Horatiu Vultur
2020-04-14 11:26   ` [Bridge] " Horatiu Vultur
2020-04-18  8:25   ` Nikolay Aleksandrov [this message]
2020-04-18  8:25     ` Nikolay Aleksandrov
2020-04-18 14:44     ` Horatiu Vultur
2020-04-18 14:44       ` [Bridge] " Horatiu Vultur
2020-04-18  9:01 ` [RFC net-next v5 0/9] net: bridge: mrp: Add support for Media Redundancy Protocol(MRP) Nikolay Aleksandrov
2020-04-18  9:01   ` [Bridge] " Nikolay Aleksandrov
2020-04-18 15:03   ` Horatiu Vultur
2020-04-18 15:03     ` [Bridge] " Horatiu Vultur

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=48c8e196-5808-d7c8-25c3-dff8f56dea5b@cumulusnetworks.com \
    --to=nikolay@cumulusnetworks.com \
    --cc=UNGLinuxDriver@microchip.com \
    --cc=andrew@lunn.ch \
    --cc=bridge@lists.linux-foundation.org \
    --cc=davem@davemloft.net \
    --cc=horatiu.vultur@microchip.com \
    --cc=ivecera@redhat.com \
    --cc=jiri@resnulli.us \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=olteanv@gmail.com \
    --cc=roopa@cumulusnetworks.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.