All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Michael S. Tsirkin" <mst@redhat.com>
To: Vlad Yasevich <vyasevic@redhat.com>
Cc: john.r.fastabend@intel.com, netdev@vger.kernel.org,
	shemminger@vyatta.com, bridge@lists.linux-foundation.org,
	jhs@mojatatu.com
Subject: Re: [PATCH 2/7] bridge: Keep track of ports capable of flooding.
Date: Wed, 26 Feb 2014 17:41:22 +0200	[thread overview]
Message-ID: <20140226154122.GC15330@redhat.com> (raw)
In-Reply-To: <1393427905-6811-3-git-send-email-vyasevic@redhat.com>

On Wed, Feb 26, 2014 at 10:18:20AM -0500, Vlad Yasevich wrote:
> Keep track of bridge ports that have unicast flooding turned on.
> This will later be used by the algorithm to automatically manage
> address programming and promisc mode.
> 
> Signed-off-by: Vlad Yasevich <vyasevic@redhat.com>
> ---
>  net/bridge/br_if.c       | 60 ++++++++++++++++++++++++++++++++++++++++++++++--
>  net/bridge/br_netlink.c  |  3 +++
>  net/bridge/br_private.h  |  4 ++++
>  net/bridge/br_sysfs_if.c |  6 ++++-
>  4 files changed, 70 insertions(+), 3 deletions(-)
> 
> diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
> index 54d207d..f072b34 100644
> --- a/net/bridge/br_if.c
> +++ b/net/bridge/br_if.c
> @@ -27,6 +27,9 @@
>  
>  #include "br_private.h"
>  
> +static void br_add_flood_port(struct net_bridge_port *p, struct net_bridge *br);
> +static void br_del_flood_port(struct net_bridge_port *p, struct net_bridge *br);
> +

same nitpick about forward declarations of static
functions.
maybe they are ok for bridge, but that's my $.02


>  /*
>   * Determine initial path cost based on speed.
>   * using recommendations from 802.1d standard
> @@ -141,11 +144,14 @@ static void del_nbp(struct net_bridge_port *p)
>  
>  	br_ifinfo_notify(RTM_DELLINK, p);
>  
> +	list_del_rcu(&p->list);
> +
> +	if (p->flags & BR_FLOOD)
> +		br_del_flood_port(p, br);
> +
>  	nbp_vlan_flush(p);
>  	br_fdb_delete_by_port(br, p, 1);
>  
> -	list_del_rcu(&p->list);
> -
>  	dev->priv_flags &= ~IFF_BRIDGE_PORT;
>  
>  	netdev_rx_handler_unregister(dev);

ok so it doesn't matter in which order we do
list_del_rcu and nbp_vlan_flush then?

> @@ -383,6 +389,9 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
>  	dev_disable_lro(dev);
>  
>  	list_add_rcu(&p->list, &br->port_list);
> +
> +	if (p->flags & BR_FLOOD)
> +		br_add_flood_port(p, br);
>  
>  	netdev_update_features(br->dev);
>  
> @@ -455,3 +464,50 @@ int br_del_if(struct net_bridge *br, struct net_device *dev)
>  
>  	return 0;
>  }
> +
> +static void br_add_flood_port(struct net_bridge_port *p, struct net_bridge *br)
> +{
> +	/* Increment the number of  flooding ports, and if we
> +	 * only have 1 flooding port cache if for future use.
> +	 */
> +	br->n_flood_ports++;
> +	if (br->n_flood_ports == 1)
> +		br->c_flood_port = p;
> +}
> +
> +static void br_del_flood_port(struct net_bridge_port *p, struct net_bridge *br)
> +{
> +	struct net_bridge_port *port;
> +
> +	/* Decrement the  number of flood port.
> +	 * If we are deleting the current flood port, clear
> +	 * the cached port.  If we are down to 1 flood port,
> +	 * set it if it is not set.
> +	 */
> +	br->n_flood_ports--;
> +	if (p == br->c_flood_port)
> +		br->c_flood_port = NULL;
> +
> +	if (br->n_flood_ports == 1) {
> +		list_for_each_entry(port, &p->br->port_list, list) {
> +			if (port->flags & BR_FLOOD) {
> +				br->c_flood_port = port;
> +				break;
> +			}
> +		}
> +	}
> +}
> +
> +void br_port_flags_change(struct net_bridge_port *p, unsigned long mask)
> +{
> +	struct net_bridge *br = p->br;
> +
> +	/* We are only interested FLOOD flag */
> +	if (!(mask & BR_FLOOD))
> +		return;
> +
> +	if (p->flags & BR_FLOOD)
> +		br_add_flood_port(p, br);
> +	else
> +		br_del_flood_port(p, br);
> +}
> diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
> index e74b6d53..01382b9 100644
> --- a/net/bridge/br_netlink.c
> +++ b/net/bridge/br_netlink.c
> @@ -328,6 +328,7 @@ static void br_set_port_flag(struct net_bridge_port *p, struct nlattr *tb[],
>  static int br_setport(struct net_bridge_port *p, struct nlattr *tb[])
>  {
>  	int err;
> +	unsigned long old_flags = p->flags;
>  
>  	br_set_port_flag(p, tb, IFLA_BRPORT_MODE, BR_HAIRPIN_MODE);
>  	br_set_port_flag(p, tb, IFLA_BRPORT_GUARD, BR_BPDU_GUARD);
> @@ -353,6 +354,8 @@ static int br_setport(struct net_bridge_port *p, struct nlattr *tb[])
>  		if (err)
>  			return err;
>  	}
> +
> +	br_port_flags_change(p, old_flags ^ p->flags);
>  	return 0;
>  }
>  
> diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
> index 3ba11bc..26a3987 100644
> --- a/net/bridge/br_private.h
> +++ b/net/bridge/br_private.h
> @@ -290,6 +290,8 @@ struct net_bridge
>  	struct timer_list		topology_change_timer;
>  	struct timer_list		gc_timer;
>  	struct kobject			*ifobj;
> +	struct net_bridge_port		*c_flood_port;
> +	u32				n_flood_ports;

any hints on locking for these fields?
are these all under rtnl?

>  #ifdef CONFIG_BRIDGE_VLAN_FILTERING
>  	u8				vlan_enabled;
>  	struct net_port_vlans __rcu	*vlan_info;
> @@ -415,6 +417,8 @@ int br_del_if(struct net_bridge *br, struct net_device *dev);
>  int br_min_mtu(const struct net_bridge *br);
>  netdev_features_t br_features_recompute(struct net_bridge *br,
>  					netdev_features_t features);
> +void br_port_flags_change(struct net_bridge_port *port,
> +			  unsigned long mask);
>  
>  /* br_input.c */
>  int br_handle_frame_finish(struct sk_buff *skb);
> diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c
> index 7f66aa4..9ff6691 100644
> --- a/net/bridge/br_sysfs_if.c
> +++ b/net/bridge/br_sysfs_if.c
> @@ -51,7 +51,10 @@ static BRPORT_ATTR(_name, S_IRUGO | S_IWUSR,			\
>  static int store_flag(struct net_bridge_port *p, unsigned long v,
>  		     unsigned long mask)
>  {
> -	unsigned long flags = p->flags;
> +	unsigned long flags;
> +	unsigned long old_flags;
> +
> +	old_flags = flags = p->flags;
>  
>  	if (v)
>  		flags |= mask;
> @@ -60,6 +63,7 @@ static int store_flag(struct net_bridge_port *p, unsigned long v,
>  
>  	if (flags != p->flags) {
>  		p->flags = flags;
> +		br_port_flags_change(p, old_flags ^ flags);
>  		br_ifinfo_notify(RTM_NEWLINK, p);
>  	}
>  	return 0;
> -- 
> 1.8.5.3

WARNING: multiple messages have this Message-ID (diff)
From: "Michael S. Tsirkin" <mst@redhat.com>
To: Vlad Yasevich <vyasevic@redhat.com>
Cc: john.r.fastabend@intel.com, netdev@vger.kernel.org,
	shemminger@vyatta.com, bridge@lists.linux-foundation.org,
	jhs@mojatatu.com
Subject: Re: [Bridge] [PATCH 2/7] bridge: Keep track of ports capable of flooding.
Date: Wed, 26 Feb 2014 17:41:22 +0200	[thread overview]
Message-ID: <20140226154122.GC15330@redhat.com> (raw)
In-Reply-To: <1393427905-6811-3-git-send-email-vyasevic@redhat.com>

On Wed, Feb 26, 2014 at 10:18:20AM -0500, Vlad Yasevich wrote:
> Keep track of bridge ports that have unicast flooding turned on.
> This will later be used by the algorithm to automatically manage
> address programming and promisc mode.
> 
> Signed-off-by: Vlad Yasevich <vyasevic@redhat.com>
> ---
>  net/bridge/br_if.c       | 60 ++++++++++++++++++++++++++++++++++++++++++++++--
>  net/bridge/br_netlink.c  |  3 +++
>  net/bridge/br_private.h  |  4 ++++
>  net/bridge/br_sysfs_if.c |  6 ++++-
>  4 files changed, 70 insertions(+), 3 deletions(-)
> 
> diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
> index 54d207d..f072b34 100644
> --- a/net/bridge/br_if.c
> +++ b/net/bridge/br_if.c
> @@ -27,6 +27,9 @@
>  
>  #include "br_private.h"
>  
> +static void br_add_flood_port(struct net_bridge_port *p, struct net_bridge *br);
> +static void br_del_flood_port(struct net_bridge_port *p, struct net_bridge *br);
> +

same nitpick about forward declarations of static
functions.
maybe they are ok for bridge, but that's my $.02


>  /*
>   * Determine initial path cost based on speed.
>   * using recommendations from 802.1d standard
> @@ -141,11 +144,14 @@ static void del_nbp(struct net_bridge_port *p)
>  
>  	br_ifinfo_notify(RTM_DELLINK, p);
>  
> +	list_del_rcu(&p->list);
> +
> +	if (p->flags & BR_FLOOD)
> +		br_del_flood_port(p, br);
> +
>  	nbp_vlan_flush(p);
>  	br_fdb_delete_by_port(br, p, 1);
>  
> -	list_del_rcu(&p->list);
> -
>  	dev->priv_flags &= ~IFF_BRIDGE_PORT;
>  
>  	netdev_rx_handler_unregister(dev);

ok so it doesn't matter in which order we do
list_del_rcu and nbp_vlan_flush then?

> @@ -383,6 +389,9 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
>  	dev_disable_lro(dev);
>  
>  	list_add_rcu(&p->list, &br->port_list);
> +
> +	if (p->flags & BR_FLOOD)
> +		br_add_flood_port(p, br);
>  
>  	netdev_update_features(br->dev);
>  
> @@ -455,3 +464,50 @@ int br_del_if(struct net_bridge *br, struct net_device *dev)
>  
>  	return 0;
>  }
> +
> +static void br_add_flood_port(struct net_bridge_port *p, struct net_bridge *br)
> +{
> +	/* Increment the number of  flooding ports, and if we
> +	 * only have 1 flooding port cache if for future use.
> +	 */
> +	br->n_flood_ports++;
> +	if (br->n_flood_ports == 1)
> +		br->c_flood_port = p;
> +}
> +
> +static void br_del_flood_port(struct net_bridge_port *p, struct net_bridge *br)
> +{
> +	struct net_bridge_port *port;
> +
> +	/* Decrement the  number of flood port.
> +	 * If we are deleting the current flood port, clear
> +	 * the cached port.  If we are down to 1 flood port,
> +	 * set it if it is not set.
> +	 */
> +	br->n_flood_ports--;
> +	if (p == br->c_flood_port)
> +		br->c_flood_port = NULL;
> +
> +	if (br->n_flood_ports == 1) {
> +		list_for_each_entry(port, &p->br->port_list, list) {
> +			if (port->flags & BR_FLOOD) {
> +				br->c_flood_port = port;
> +				break;
> +			}
> +		}
> +	}
> +}
> +
> +void br_port_flags_change(struct net_bridge_port *p, unsigned long mask)
> +{
> +	struct net_bridge *br = p->br;
> +
> +	/* We are only interested FLOOD flag */
> +	if (!(mask & BR_FLOOD))
> +		return;
> +
> +	if (p->flags & BR_FLOOD)
> +		br_add_flood_port(p, br);
> +	else
> +		br_del_flood_port(p, br);
> +}
> diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
> index e74b6d53..01382b9 100644
> --- a/net/bridge/br_netlink.c
> +++ b/net/bridge/br_netlink.c
> @@ -328,6 +328,7 @@ static void br_set_port_flag(struct net_bridge_port *p, struct nlattr *tb[],
>  static int br_setport(struct net_bridge_port *p, struct nlattr *tb[])
>  {
>  	int err;
> +	unsigned long old_flags = p->flags;
>  
>  	br_set_port_flag(p, tb, IFLA_BRPORT_MODE, BR_HAIRPIN_MODE);
>  	br_set_port_flag(p, tb, IFLA_BRPORT_GUARD, BR_BPDU_GUARD);
> @@ -353,6 +354,8 @@ static int br_setport(struct net_bridge_port *p, struct nlattr *tb[])
>  		if (err)
>  			return err;
>  	}
> +
> +	br_port_flags_change(p, old_flags ^ p->flags);
>  	return 0;
>  }
>  
> diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
> index 3ba11bc..26a3987 100644
> --- a/net/bridge/br_private.h
> +++ b/net/bridge/br_private.h
> @@ -290,6 +290,8 @@ struct net_bridge
>  	struct timer_list		topology_change_timer;
>  	struct timer_list		gc_timer;
>  	struct kobject			*ifobj;
> +	struct net_bridge_port		*c_flood_port;
> +	u32				n_flood_ports;

any hints on locking for these fields?
are these all under rtnl?

>  #ifdef CONFIG_BRIDGE_VLAN_FILTERING
>  	u8				vlan_enabled;
>  	struct net_port_vlans __rcu	*vlan_info;
> @@ -415,6 +417,8 @@ int br_del_if(struct net_bridge *br, struct net_device *dev);
>  int br_min_mtu(const struct net_bridge *br);
>  netdev_features_t br_features_recompute(struct net_bridge *br,
>  					netdev_features_t features);
> +void br_port_flags_change(struct net_bridge_port *port,
> +			  unsigned long mask);
>  
>  /* br_input.c */
>  int br_handle_frame_finish(struct sk_buff *skb);
> diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c
> index 7f66aa4..9ff6691 100644
> --- a/net/bridge/br_sysfs_if.c
> +++ b/net/bridge/br_sysfs_if.c
> @@ -51,7 +51,10 @@ static BRPORT_ATTR(_name, S_IRUGO | S_IWUSR,			\
>  static int store_flag(struct net_bridge_port *p, unsigned long v,
>  		     unsigned long mask)
>  {
> -	unsigned long flags = p->flags;
> +	unsigned long flags;
> +	unsigned long old_flags;
> +
> +	old_flags = flags = p->flags;
>  
>  	if (v)
>  		flags |= mask;
> @@ -60,6 +63,7 @@ static int store_flag(struct net_bridge_port *p, unsigned long v,
>  
>  	if (flags != p->flags) {
>  		p->flags = flags;
> +		br_port_flags_change(p, old_flags ^ flags);
>  		br_ifinfo_notify(RTM_NEWLINK, p);
>  	}
>  	return 0;
> -- 
> 1.8.5.3

  reply	other threads:[~2014-02-26 15:41 UTC|newest]

Thread overview: 91+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-02-26 15:18 [PATCH RFC 0/7] Non-promisc bidge ports support Vlad Yasevich
2014-02-26 15:18 ` [Bridge] " Vlad Yasevich
2014-02-26 15:18 ` [PATCH 1/7] bridge: Turn flag change macro into a function Vlad Yasevich
2014-02-26 15:18   ` [Bridge] " Vlad Yasevich
2014-02-26 15:29   ` Michael S. Tsirkin
2014-02-26 15:29     ` [Bridge] " Michael S. Tsirkin
2014-02-26 15:36     ` Vlad Yasevich
2014-02-26 15:36       ` [Bridge] " Vlad Yasevich
2014-02-26 15:18 ` [PATCH 2/7] bridge: Keep track of ports capable of flooding Vlad Yasevich
2014-02-26 15:18   ` [Bridge] " Vlad Yasevich
2014-02-26 15:41   ` Michael S. Tsirkin [this message]
2014-02-26 15:41     ` Michael S. Tsirkin
2014-02-26 15:41     ` Vlad Yasevich
2014-02-26 15:41       ` [Bridge] " Vlad Yasevich
2014-02-26 15:53       ` Michael S. Tsirkin
2014-02-26 15:53         ` [Bridge] " Michael S. Tsirkin
2014-02-27 11:59   ` Toshiaki Makita
2014-02-27 11:59     ` [Bridge] " Toshiaki Makita
2014-02-27 12:54     ` Vlad Yasevich
2014-02-27 12:54       ` [Bridge] " Vlad Yasevich
2014-02-26 15:18 ` [PATCH 3/7] bridge: Add addresses from static fdbs to bridge address list Vlad Yasevich
2014-02-26 15:18   ` [Bridge] " Vlad Yasevich
2014-02-26 15:46   ` Michael S. Tsirkin
2014-02-26 15:46     ` [Bridge] " Michael S. Tsirkin
2014-02-26 15:43     ` Vlad Yasevich
2014-02-26 15:43       ` [Bridge] " Vlad Yasevich
2014-02-26 16:23   ` Michael S. Tsirkin
2014-02-26 16:23     ` [Bridge] " Michael S. Tsirkin
2014-02-26 17:25     ` Vlad Yasevich
2014-02-26 17:25       ` [Bridge] " Vlad Yasevich
2014-02-26 17:33       ` Michael S. Tsirkin
2014-02-26 17:33         ` [Bridge] " Michael S. Tsirkin
2014-02-26 16:57   ` Stephen Hemminger
2014-02-26 16:57     ` [Bridge] " Stephen Hemminger
2014-02-26 17:35     ` Vlad Yasevich
2014-02-26 17:35       ` [Bridge] " Vlad Yasevich
2014-02-27  7:53       ` Michael S. Tsirkin
2014-02-27  7:53         ` [Bridge] " Michael S. Tsirkin
2014-02-27 13:08         ` Vlad Yasevich
2014-02-27 13:08           ` [Bridge] " Vlad Yasevich
2014-02-27 13:38           ` Michael S. Tsirkin
2014-02-27 13:38             ` [Bridge] " Michael S. Tsirkin
2014-02-26 15:18 ` [PATCH 4/7] bridge: Automatically manage port promiscuous mode Vlad Yasevich
2014-02-26 15:18   ` [Bridge] " Vlad Yasevich
2014-02-26 15:51   ` Michael S. Tsirkin
2014-02-26 15:51     ` [Bridge] " Michael S. Tsirkin
2014-02-26 16:02     ` Vlad Yasevich
2014-02-26 16:02       ` [Bridge] " Vlad Yasevich
2014-02-26 16:58   ` Stephen Hemminger
2014-02-26 16:58     ` [Bridge] " Stephen Hemminger
2014-02-26 17:32     ` Michael S. Tsirkin
2014-02-26 17:32       ` [Bridge] " Michael S. Tsirkin
2014-02-26 15:18 ` [PATCH 5/7] bridge: Correctly manage promiscuity when user requested it Vlad Yasevich
2014-02-26 15:18   ` [Bridge] " Vlad Yasevich
2014-02-26 15:18 ` [PATCH 6/7] bridge: Manage promisc mode when vlans are configured on top of a bridge Vlad Yasevich
2014-02-26 15:18   ` [Bridge] " Vlad Yasevich
2014-02-26 16:00   ` Michael S. Tsirkin
2014-02-26 16:00     ` [Bridge] " Michael S. Tsirkin
2014-02-26 16:05     ` Vlad Yasevich
2014-02-26 16:05       ` [Bridge] " Vlad Yasevich
2014-02-26 16:25       ` Michael S. Tsirkin
2014-02-26 16:25         ` [Bridge] " Michael S. Tsirkin
2014-02-27 12:06   ` Toshiaki Makita
2014-02-27 12:06     ` [Bridge] " Toshiaki Makita
2014-02-27 13:17     ` Vlad Yasevich
2014-02-27 13:17       ` [Bridge] " Vlad Yasevich
2014-02-28 19:34       ` Vlad Yasevich
2014-02-28 19:34         ` [Bridge] " Vlad Yasevich
2014-03-01 14:57         ` Toshiaki Makita
2014-03-01 14:57           ` [Bridge] " Toshiaki Makita
2014-03-03 12:12           ` Vlad Yasevich
2014-03-03 12:12             ` [Bridge] " Vlad Yasevich
2014-02-26 15:18 ` [PATCH 7/7] bridge: Support promisc management when all ports are non-flooding Vlad Yasevich
2014-02-26 15:18   ` [Bridge] " Vlad Yasevich
2014-02-26 15:57   ` Michael S. Tsirkin
2014-02-26 15:57     ` [Bridge] " Michael S. Tsirkin
2014-02-27  3:46     ` Vlad Yasevich
2014-02-27  3:46       ` [Bridge] " Vlad Yasevich
2014-02-27  7:29       ` Michael S. Tsirkin
2014-02-27  7:29         ` [Bridge] " Michael S. Tsirkin
2014-02-26 16:01   ` Michael S. Tsirkin
2014-02-26 16:01     ` [Bridge] " Michael S. Tsirkin
2014-02-26 16:34 ` [PATCH RFC 0/7] Non-promisc bidge ports support Michael S. Tsirkin
2014-02-26 16:34   ` [Bridge] " Michael S. Tsirkin
2014-02-26 23:59 ` Jamal Hadi Salim
2014-02-26 23:59   ` [Bridge] " Jamal Hadi Salim
2014-02-27  3:37   ` Vlad Yasevich
2014-02-27  3:37     ` [Bridge] " Vlad Yasevich
2014-02-27  8:54     ` Amidu Sila
2014-02-27  7:20   ` Michael S. Tsirkin
2014-02-27  7:20     ` [Bridge] " Michael S. Tsirkin

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=20140226154122.GC15330@redhat.com \
    --to=mst@redhat.com \
    --cc=bridge@lists.linux-foundation.org \
    --cc=jhs@mojatatu.com \
    --cc=john.r.fastabend@intel.com \
    --cc=netdev@vger.kernel.org \
    --cc=shemminger@vyatta.com \
    --cc=vyasevic@redhat.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.