提交 77f98598 编写于 作者: S stephen hemminger 提交者: David S. Miller

bridge: fix ordering of NEWLINK and NEWNEIGH events

When port is added to a bridge, the old code would send the new neighbor
netlink message before the subsequent new link message. This bug makes
it difficult to use the monitoring API in an application.

This code changes the ordering to add the forwarding entry
after the port is setup. One of the error checks (for invalid address)
is moved earlier in the process to avoid having to do unwind.
Signed-off-by: NStephen Hemminger <shemminger@vyatta.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 3de09455
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/netpoll.h> #include <linux/netpoll.h>
#include <linux/ethtool.h> #include <linux/ethtool.h>
#include <linux/if_arp.h> #include <linux/if_arp.h>
...@@ -322,7 +323,8 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) ...@@ -322,7 +323,8 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
/* Don't allow bridging non-ethernet like devices */ /* Don't allow bridging non-ethernet like devices */
if ((dev->flags & IFF_LOOPBACK) || if ((dev->flags & IFF_LOOPBACK) ||
dev->type != ARPHRD_ETHER || dev->addr_len != ETH_ALEN) dev->type != ARPHRD_ETHER || dev->addr_len != ETH_ALEN ||
!is_valid_ether_addr(dev->dev_addr))
return -EINVAL; return -EINVAL;
/* No bridging of bridges */ /* No bridging of bridges */
...@@ -349,10 +351,6 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) ...@@ -349,10 +351,6 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
err = kobject_init_and_add(&p->kobj, &brport_ktype, &(dev->dev.kobj), err = kobject_init_and_add(&p->kobj, &brport_ktype, &(dev->dev.kobj),
SYSFS_BRIDGE_PORT_ATTR); SYSFS_BRIDGE_PORT_ATTR);
if (err)
goto err0;
err = br_fdb_insert(br, p, dev->dev_addr);
if (err) if (err)
goto err1; goto err1;
...@@ -394,6 +392,9 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) ...@@ -394,6 +392,9 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
dev_set_mtu(br->dev, br_min_mtu(br)); dev_set_mtu(br->dev, br_min_mtu(br));
if (br_fdb_insert(br, p, dev->dev_addr))
netdev_err(dev, "failed insert local address bridge forwarding table\n");
kobject_uevent(&p->kobj, KOBJ_ADD); kobject_uevent(&p->kobj, KOBJ_ADD);
return 0; return 0;
...@@ -403,11 +404,9 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) ...@@ -403,11 +404,9 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
err3: err3:
sysfs_remove_link(br->ifobj, p->dev->name); sysfs_remove_link(br->ifobj, p->dev->name);
err2: err2:
br_fdb_delete_by_port(br, p, 1);
err1:
kobject_put(&p->kobj); kobject_put(&p->kobj);
p = NULL; /* kobject_put frees */ p = NULL; /* kobject_put frees */
err0: err1:
dev_set_promiscuity(dev, -1); dev_set_promiscuity(dev, -1);
put_back: put_back:
dev_put(dev); dev_put(dev);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册