diff options
author | Moni Shoua <monis@mellanox.com> | 2015-02-03 09:48:31 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-02-04 19:14:24 -0500 |
commit | 69e6113343cfe983511904ffca0d7a1466460b67 (patch) | |
tree | af67707b31a322a8a418081cd491900ec8109c84 /drivers/net/bonding | |
parent | 69a2338e05995b10225b2a131f7540d1305980e4 (diff) |
net/bonding: Notify state change on slaves
Use notifier chain to dispatch an event upon a change in slave state.
Event is dispatched with slave specific info.
Signed-off-by: Moni Shoua <monis@mellanox.com>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bonding')
-rw-r--r-- | drivers/net/bonding/bond_main.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 92fe3a1bf52b..679ef00d6b16 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -1196,6 +1196,47 @@ static void bond_fill_ifslave(struct slave *slave, struct ifslave *info) | |||
1196 | info->link_failure_count = slave->link_failure_count; | 1196 | info->link_failure_count = slave->link_failure_count; |
1197 | } | 1197 | } |
1198 | 1198 | ||
1199 | static void bond_netdev_notify(struct slave *slave, struct net_device *dev) | ||
1200 | { | ||
1201 | struct bonding *bond = slave->bond; | ||
1202 | struct netdev_bonding_info bonding_info; | ||
1203 | |||
1204 | rtnl_lock(); | ||
1205 | /* make sure that slave is still valid */ | ||
1206 | if (dev->priv_flags & IFF_BONDING) { | ||
1207 | bond_fill_ifslave(slave, &bonding_info.slave); | ||
1208 | bond_fill_ifbond(bond, &bonding_info.master); | ||
1209 | netdev_bonding_info_change(slave->dev, &bonding_info); | ||
1210 | } | ||
1211 | rtnl_unlock(); | ||
1212 | } | ||
1213 | |||
1214 | static void bond_netdev_notify_work(struct work_struct *_work) | ||
1215 | { | ||
1216 | struct netdev_notify_work *w = | ||
1217 | container_of(_work, struct netdev_notify_work, work.work); | ||
1218 | |||
1219 | bond_netdev_notify(w->slave, w->dev); | ||
1220 | dev_put(w->dev); | ||
1221 | } | ||
1222 | |||
1223 | void bond_queue_slave_event(struct slave *slave) | ||
1224 | { | ||
1225 | struct netdev_notify_work *nnw = kzalloc(sizeof(*nnw), GFP_ATOMIC); | ||
1226 | |||
1227 | if (!nnw) | ||
1228 | return; | ||
1229 | |||
1230 | INIT_DELAYED_WORK(&nnw->work, bond_netdev_notify_work); | ||
1231 | nnw->slave = slave; | ||
1232 | nnw->dev = slave->dev; | ||
1233 | |||
1234 | if (queue_delayed_work(slave->bond->wq, &nnw->work, 0)) | ||
1235 | dev_hold(slave->dev); | ||
1236 | else | ||
1237 | kfree(nnw); | ||
1238 | } | ||
1239 | |||
1199 | /* enslave device <slave> to bond device <master> */ | 1240 | /* enslave device <slave> to bond device <master> */ |
1200 | int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | 1241 | int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) |
1201 | { | 1242 | { |
@@ -1590,6 +1631,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1590 | new_slave->link != BOND_LINK_DOWN ? "an up" : "a down"); | 1631 | new_slave->link != BOND_LINK_DOWN ? "an up" : "a down"); |
1591 | 1632 | ||
1592 | /* enslave is successful */ | 1633 | /* enslave is successful */ |
1634 | bond_queue_slave_event(new_slave); | ||
1593 | return 0; | 1635 | return 0; |
1594 | 1636 | ||
1595 | /* Undo stages on error */ | 1637 | /* Undo stages on error */ |