diff options
Diffstat (limited to 'drivers/net/veth.c')
-rw-r--r-- | drivers/net/veth.c | 60 |
1 files changed, 16 insertions, 44 deletions
diff --git a/drivers/net/veth.c b/drivers/net/veth.c index 852d0e7c4e6..124fe75b8a8 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c | |||
@@ -239,6 +239,16 @@ static int veth_open(struct net_device *dev) | |||
239 | return 0; | 239 | return 0; |
240 | } | 240 | } |
241 | 241 | ||
242 | static int veth_close(struct net_device *dev) | ||
243 | { | ||
244 | struct veth_priv *priv = netdev_priv(dev); | ||
245 | |||
246 | netif_carrier_off(dev); | ||
247 | netif_carrier_off(priv->peer); | ||
248 | |||
249 | return 0; | ||
250 | } | ||
251 | |||
242 | static int veth_dev_init(struct net_device *dev) | 252 | static int veth_dev_init(struct net_device *dev) |
243 | { | 253 | { |
244 | struct veth_net_stats *stats; | 254 | struct veth_net_stats *stats; |
@@ -263,10 +273,12 @@ static void veth_dev_free(struct net_device *dev) | |||
263 | } | 273 | } |
264 | 274 | ||
265 | static const struct net_device_ops veth_netdev_ops = { | 275 | static const struct net_device_ops veth_netdev_ops = { |
266 | .ndo_init = veth_dev_init, | 276 | .ndo_init = veth_dev_init, |
267 | .ndo_open = veth_open, | 277 | .ndo_open = veth_open, |
268 | .ndo_start_xmit = veth_xmit, | 278 | .ndo_stop = veth_close, |
269 | .ndo_get_stats = veth_get_stats, | 279 | .ndo_start_xmit = veth_xmit, |
280 | .ndo_get_stats = veth_get_stats, | ||
281 | .ndo_set_mac_address = eth_mac_addr, | ||
270 | }; | 282 | }; |
271 | 283 | ||
272 | static void veth_setup(struct net_device *dev) | 284 | static void veth_setup(struct net_device *dev) |
@@ -279,44 +291,6 @@ static void veth_setup(struct net_device *dev) | |||
279 | dev->destructor = veth_dev_free; | 291 | dev->destructor = veth_dev_free; |
280 | } | 292 | } |
281 | 293 | ||
282 | static void veth_change_state(struct net_device *dev) | ||
283 | { | ||
284 | struct net_device *peer; | ||
285 | struct veth_priv *priv; | ||
286 | |||
287 | priv = netdev_priv(dev); | ||
288 | peer = priv->peer; | ||
289 | |||
290 | if (netif_carrier_ok(peer)) { | ||
291 | if (!netif_carrier_ok(dev)) | ||
292 | netif_carrier_on(dev); | ||
293 | } else { | ||
294 | if (netif_carrier_ok(dev)) | ||
295 | netif_carrier_off(dev); | ||
296 | } | ||
297 | } | ||
298 | |||
299 | static int veth_device_event(struct notifier_block *unused, | ||
300 | unsigned long event, void *ptr) | ||
301 | { | ||
302 | struct net_device *dev = ptr; | ||
303 | |||
304 | if (dev->netdev_ops->ndo_open != veth_open) | ||
305 | goto out; | ||
306 | |||
307 | switch (event) { | ||
308 | case NETDEV_CHANGE: | ||
309 | veth_change_state(dev); | ||
310 | break; | ||
311 | } | ||
312 | out: | ||
313 | return NOTIFY_DONE; | ||
314 | } | ||
315 | |||
316 | static struct notifier_block veth_notifier_block __read_mostly = { | ||
317 | .notifier_call = veth_device_event, | ||
318 | }; | ||
319 | |||
320 | /* | 294 | /* |
321 | * netlink interface | 295 | * netlink interface |
322 | */ | 296 | */ |
@@ -467,14 +441,12 @@ static struct rtnl_link_ops veth_link_ops = { | |||
467 | 441 | ||
468 | static __init int veth_init(void) | 442 | static __init int veth_init(void) |
469 | { | 443 | { |
470 | register_netdevice_notifier(&veth_notifier_block); | ||
471 | return rtnl_link_register(&veth_link_ops); | 444 | return rtnl_link_register(&veth_link_ops); |
472 | } | 445 | } |
473 | 446 | ||
474 | static __exit void veth_exit(void) | 447 | static __exit void veth_exit(void) |
475 | { | 448 | { |
476 | rtnl_link_unregister(&veth_link_ops); | 449 | rtnl_link_unregister(&veth_link_ops); |
477 | unregister_netdevice_notifier(&veth_notifier_block); | ||
478 | } | 450 | } |
479 | 451 | ||
480 | module_init(veth_init); | 452 | module_init(veth_init); |