Stephen Hemminger
2017-Sep-20 23:21 UTC
[Bridge] [PATCH net-next v2] bridge: also trigger RTM_NEWLINK when interface is released from bridge
On Wed, 20 Sep 2017 15:57:16 -0600 David Ahern <dsahern at gmail.com> wrote:> On 9/20/17 3:09 PM, David Miller wrote: > > From: Vincent Bernat <vincent at bernat.im> > > Date: Sat, 16 Sep 2017 16:18:33 +0200 > > > > David, I am CC:'ing you because you've done work in this area over the > > past year. I'm applying this patch, it's been sitting since the 16th > > and likes entirely correct to me. But if you have objections just let > > me know. > > > >> Currently, when an interface is released from a bridge via > >> ioctl(), we get a RTM_DELLINK event through netlink: > >> > >> Deleted 2: dummy0: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 master bridge0 state UNKNOWN > >> link/ether 6e:23:c2:54:3a:b3 > >> > >> Userspace has to interpret that as a removal from the bridge, not as a > >> complete removal of the interface. When an bridged interface is > >> completely removed, we get two events: > >> > >> Deleted 2: dummy0: <BROADCAST,NOARP> mtu 1500 master bridge0 state DOWN > >> link/ether 6e:23:c2:54:3a:b3 > >> Deleted 2: dummy0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group default > >> link/ether 6e:23:c2:54:3a:b3 brd ff:ff:ff:ff:ff:ff > >> > >> In constrast, when an interface is released from a bond, we get a > >> RTM_NEWLINK with only the new characteristics (no master): > >> > >> 3: dummy1: <BROADCAST,NOARP,SLAVE,UP,LOWER_UP> mtu 1500 qdisc noqueue master bond0 state UNKNOWN group default > >> link/ether ae:dc:7a:8c:9a:3c brd ff:ff:ff:ff:ff:ff > >> 3: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default > >> link/ether ae:dc:7a:8c:9a:3c brd ff:ff:ff:ff:ff:ff > >> 4: bond0: <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default > >> link/ether ae:dc:7a:8c:9a:3c brd ff:ff:ff:ff:ff:ff > >> 3: dummy1: <BROADCAST,NOARP> mtu 1500 qdisc noqueue state DOWN group default > >> link/ether ae:dc:7a:8c:9a:3c brd ff:ff:ff:ff:ff:ff > >> 3: dummy1: <BROADCAST,NOARP> mtu 1500 qdisc noqueue state DOWN group default > >> link/ether ca:c8:7b:66:f8:25 brd ff:ff:ff:ff:ff:ff > >> 4: bond0: <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default > >> link/ether ae:dc:7a:8c:9a:3c brd ff:ff:ff:ff:ff:ff > >> > >> Userland may be confused by the fact we say a link is deleted while > >> its characteristics are only modified. A first solution would have > >> been to turn the RTM_DELLINK event in del_nbp() into a RTM_NEWLINK > >> event. However, maybe some piece of userland is relying on this > >> RTM_DELLINK to detect when a bridged interface is released. Instead, > >> we also emit a RTM_NEWLINK event once the interface is > >> released (without master info). > >> > >> Deleted 2: dummy0: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 master bridge0 state UNKNOWN > >> link/ether 8a:bb:e7:94:b1:f8 > >> 2: dummy0: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default > >> link/ether 8a:bb:e7:94:b1:f8 brd ff:ff:ff:ff:ff:ff > >> > >> This is done only when using ioctl(). When using Netlink, such an > >> event is already automatically emitted in do_setlink(). > > The DELLINK is for AF_BRIDGE family (ifi_family). Adding family to > print_linkinfo and running the monitor I get: > > > [LINK]family 0: 35: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc > noqueue master br0 state UNKNOWN group default > link/ether d6:c3:73:86:3c:73 brd ff:ff:ff:ff:ff:ff > > [LINK]family 7: 35: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 > master br0 state UNKNOWN > link/ether d6:c3:73:86:3c:73 > > [LINK]Deleted family 7: 35: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu > 1500 master br0 state UNKNOWN > link/ether d6:c3:73:86:3c:73 > > [LINK]family 0: 35: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc > noqueue state UNKNOWN group default > link/ether d6:c3:73:86:3c:73 brd ff:ff:ff:ff:ff:ff > > And that seems correct. So I think the RTM_NEWLINK added by this patch > should not be needed.Agreed, thanks for tracing this. The one concern is that ports added or removed through ioctl should cause same events as doing the same thing via netlink. Some users use brctl (ioctl) and others use newer bridge (netlink) API.
Vincent Bernat
2017-Sep-21 10:04 UTC
[Bridge] [PATCH net-next v2] bridge: also trigger RTM_NEWLINK when interface is released from bridge
? 20 septembre 2017 16:21 -0700, Stephen Hemminger <stephen at networkplumber.org>?:> The one concern is that ports added or removed through ioctl should > cause same events as doing the same thing via netlink. Some users use > brctl (ioctl) and others use newer bridge (netlink) API.I'll make a third iteration to have the same notifications when using ioctl() with details in the commit message. -- When in doubt, tell the truth. -- Mark Twain
Vincent Bernat
2017-Sep-21 10:05 UTC
[Bridge] [net-next v3] bridge: trigger RTM_NEWLINK when interface is modified by bridge ioctl
Currently, there is a difference in netlink events received when an interface is modified through bridge ioctl() or through netlink. This patch generates additional events when an interface is added to or removed from a bridge via ioctl(). When adding then removing an interface from a bridge with netlink, we get: 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue master bridge0 state UNKNOWN group default link/ether 9e:da:60:ee:cf:c8 brd ff:ff:ff:ff:ff:ff 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 master bridge0 state UNKNOWN link/ether 9e:da:60:ee:cf:c8 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 master bridge0 state UNKNOWN link/ether 9e:da:60:ee:cf:c8 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 master bridge0 state UNKNOWN link/ether 9e:da:60:ee:cf:c8 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 master bridge0 state UNKNOWN link/ether 9e:da:60:ee:cf:c8 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue master bridge0 state UNKNOWN group default link/ether 9e:da:60:ee:cf:c8 brd ff:ff:ff:ff:ff:ff 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue master bridge0 state UNKNOWN group default link/ether 9e:da:60:ee:cf:c8 brd ff:ff:ff:ff:ff:ff 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 master bridge0 state UNKNOWN link/ether 9e:da:60:ee:cf:c8 Deleted 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 master bridge0 state UNKNOWN link/ether 9e:da:60:ee:cf:c8 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default link/ether 9e:da:60:ee:cf:c8 brd ff:ff:ff:ff:ff:ff When using ioctl(): 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue master bridge0 state UNKNOWN group default link/ether 9e:da:60:ee:cf:c8 brd ff:ff:ff:ff:ff:ff 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 master bridge0 state UNKNOWN link/ether 9e:da:60:ee:cf:c8 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 master bridge0 state UNKNOWN link/ether 9e:da:60:ee:cf:c8 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 master bridge0 state UNKNOWN link/ether 9e:da:60:ee:cf:c8 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue master bridge0 state UNKNOWN group default link/ether 9e:da:60:ee:cf:c8 brd ff:ff:ff:ff:ff:ff 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue master bridge0 state UNKNOWN group default link/ether 9e:da:60:ee:cf:c8 brd ff:ff:ff:ff:ff:ff 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 master bridge0 state UNKNOWN link/ether 9e:da:60:ee:cf:c8 Deleted 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 master bridge0 state UNKNOWN link/ether 9e:da:60:ee:cf:c8 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default link/ether 9e:da:60:ee:cf:c8 brd ff:ff:ff:ff:ff:ff Without this patch, the last netlink notification is not sent. Signed-off-by: Vincent Bernat <vincent at bernat.im> --- net/bridge/br_ioctl.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/bridge/br_ioctl.c b/net/bridge/br_ioctl.c index 7970f8540cbb..66cd98772051 100644 --- a/net/bridge/br_ioctl.c +++ b/net/bridge/br_ioctl.c @@ -102,6 +102,9 @@ static int add_del_if(struct net_bridge *br, int ifindex, int isadd) else ret = br_del_if(br, dev); + if (!ret) + rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_MASTER, GFP_KERNEL); + return ret; } -- 2.14.1
Roopa Prabhu
2017-Sep-21 15:09 UTC
[Bridge] [PATCH net-next v2] bridge: also trigger RTM_NEWLINK when interface is released from bridge
On Thu, Sep 21, 2017 at 3:04 AM, Vincent Bernat <vincent at bernat.im> wrote:> ? 20 septembre 2017 16:21 -0700, Stephen Hemminger <stephen at networkplumber.org> : > >> The one concern is that ports added or removed through ioctl should >> cause same events as doing the same thing via netlink. Some users use >> brctl (ioctl) and others use newer bridge (netlink) API. > > I'll make a third iteration to have the same notifications when using > ioctl() with details in the commit message. > --as long as the ioctl path for bridge port removal is generating a: RTM_DELLINK with AF_BRIDGE and RTM_NEWLINK with AF_UNSPEC with 'master' removed we should be good. These are the most important ones. are there other specific bridge-events missing ?. you might want to run `bridge monitor link` also. and un-slaving of a port also triggers fdb events which are visible under `bridge monitor fdb`
Stephen Hemminger
2017-Sep-21 15:15 UTC
[Bridge] [net-next v3] bridge: trigger RTM_NEWLINK when interface is modified by bridge ioctl
On Thu, 21 Sep 2017 12:05:25 +0200 Vincent Bernat <vincent at bernat.im> wrote:> Currently, there is a difference in netlink events received when an > interface is modified through bridge ioctl() or through netlink. This > patch generates additional events when an interface is added to or > removed from a bridge via ioctl(). > > When adding then removing an interface from a bridge with netlink, we > get: > > 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue master bridge0 state UNKNOWN group default > link/ether 9e:da:60:ee:cf:c8 brd ff:ff:ff:ff:ff:ff > 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 master bridge0 state UNKNOWN > link/ether 9e:da:60:ee:cf:c8 > 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 master bridge0 state UNKNOWN > link/ether 9e:da:60:ee:cf:c8 > 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 master bridge0 state UNKNOWN > link/ether 9e:da:60:ee:cf:c8 > 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 master bridge0 state UNKNOWN > link/ether 9e:da:60:ee:cf:c8 > 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue master bridge0 state UNKNOWN group default > link/ether 9e:da:60:ee:cf:c8 brd ff:ff:ff:ff:ff:ff > > 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue master bridge0 state UNKNOWN group default > link/ether 9e:da:60:ee:cf:c8 brd ff:ff:ff:ff:ff:ff > 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 master bridge0 state UNKNOWN > link/ether 9e:da:60:ee:cf:c8 > Deleted 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 master bridge0 state UNKNOWN > link/ether 9e:da:60:ee:cf:c8 > 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default > link/ether 9e:da:60:ee:cf:c8 brd ff:ff:ff:ff:ff:ff > > When using ioctl(): > > 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue master bridge0 state UNKNOWN group default > link/ether 9e:da:60:ee:cf:c8 brd ff:ff:ff:ff:ff:ff > 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 master bridge0 state UNKNOWN > link/ether 9e:da:60:ee:cf:c8 > 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 master bridge0 state UNKNOWN > link/ether 9e:da:60:ee:cf:c8 > 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 master bridge0 state UNKNOWN > link/ether 9e:da:60:ee:cf:c8 > 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue master bridge0 state UNKNOWN group default > link/ether 9e:da:60:ee:cf:c8 brd ff:ff:ff:ff:ff:ff > > 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue master bridge0 state UNKNOWN group default > link/ether 9e:da:60:ee:cf:c8 brd ff:ff:ff:ff:ff:ff > 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 master bridge0 state UNKNOWN > link/ether 9e:da:60:ee:cf:c8 > Deleted 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 master bridge0 state UNKNOWN > link/ether 9e:da:60:ee:cf:c8 > 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default > link/ether 9e:da:60:ee:cf:c8 brd ff:ff:ff:ff:ff:ff > > Without this patch, the last netlink notification is not sent. > > Signed-off-by: Vincent Bernat <vincent at bernat.im>This makes sense, you should probably add a Fixes: tag to help maintainers of long term stable kernels. Reviewed-by: Stephen Hemminger <stephen at networkplumber.org>
David Ahern
2017-Sep-21 16:43 UTC
[Bridge] [net-next v3] bridge: trigger RTM_NEWLINK when interface is modified by bridge ioctl
On 9/21/17 4:05 AM, Vincent Bernat wrote:> Currently, there is a difference in netlink events received when an > interface is modified through bridge ioctl() or through netlink. This > patch generates additional events when an interface is added to or > removed from a bridge via ioctl(). > > When adding then removing an interface from a bridge with netlink, we > get: > > 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue master bridge0 state UNKNOWN group default > link/ether 9e:da:60:ee:cf:c8 brd ff:ff:ff:ff:ff:ff > 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 master bridge0 state UNKNOWN > link/ether 9e:da:60:ee:cf:c8 > 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 master bridge0 state UNKNOWN > link/ether 9e:da:60:ee:cf:c8 > 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 master bridge0 state UNKNOWN > link/ether 9e:da:60:ee:cf:c8 > 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 master bridge0 state UNKNOWN > link/ether 9e:da:60:ee:cf:c8 > 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue master bridge0 state UNKNOWN group default > link/ether 9e:da:60:ee:cf:c8 brd ff:ff:ff:ff:ff:ff > > 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue master bridge0 state UNKNOWN group default > link/ether 9e:da:60:ee:cf:c8 brd ff:ff:ff:ff:ff:ff > 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 master bridge0 state UNKNOWN > link/ether 9e:da:60:ee:cf:c8 > Deleted 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 master bridge0 state UNKNOWN > link/ether 9e:da:60:ee:cf:c8 > 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default > link/ether 9e:da:60:ee:cf:c8 brd ff:ff:ff:ff:ff:ff > > When using ioctl(): > > 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue master bridge0 state UNKNOWN group default > link/ether 9e:da:60:ee:cf:c8 brd ff:ff:ff:ff:ff:ff > 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 master bridge0 state UNKNOWN > link/ether 9e:da:60:ee:cf:c8 > 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 master bridge0 state UNKNOWN > link/ether 9e:da:60:ee:cf:c8 > 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 master bridge0 state UNKNOWN > link/ether 9e:da:60:ee:cf:c8 > 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue master bridge0 state UNKNOWN group default > link/ether 9e:da:60:ee:cf:c8 brd ff:ff:ff:ff:ff:ff > > 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue master bridge0 state UNKNOWN group default > link/ether 9e:da:60:ee:cf:c8 brd ff:ff:ff:ff:ff:ff > 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 master bridge0 state UNKNOWN > link/ether 9e:da:60:ee:cf:c8 > Deleted 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 master bridge0 state UNKNOWN > link/ether 9e:da:60:ee:cf:c8 > 5: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default > link/ether 9e:da:60:ee:cf:c8 brd ff:ff:ff:ff:ff:ff > > Without this patch, the last netlink notification is not sent. > > Signed-off-by: Vincent Bernat <vincent at bernat.im> > --- > net/bridge/br_ioctl.c | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/net/bridge/br_ioctl.c b/net/bridge/br_ioctl.c > index 7970f8540cbb..66cd98772051 100644 > --- a/net/bridge/br_ioctl.c > +++ b/net/bridge/br_ioctl.c > @@ -102,6 +102,9 @@ static int add_del_if(struct net_bridge *br, int ifindex, int isadd) > else > ret = br_del_if(br, dev); > > + if (!ret) > + rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_MASTER, GFP_KERNEL); > + > return ret; > } > >Agreed that this is needed for userspace to know about the master change when done through ioctl. The bridge code is emitting a lot of what appears to be redundant messages for both paths (netlink and ioctl). Reviewed-by: David Ahern <dsahern at gmail.com>
David Miller
2017-Sep-21 22:45 UTC
[Bridge] [net-next v3] bridge: trigger RTM_NEWLINK when interface is modified by bridge ioctl
From: Vincent Bernat <vincent at bernat.im> Date: Thu, 21 Sep 2017 12:05:25 +0200> Currently, there is a difference in netlink events received when an > interface is modified through bridge ioctl() or through netlink. This > patch generates additional events when an interface is added to or > removed from a bridge via ioctl()....> Signed-off-by: Vincent Bernat <vincent at bernat.im>Applied.