diff options
Diffstat (limited to 'drivers/net/veth.c')
| -rw-r--r-- | drivers/net/veth.c | 51 |
1 files changed, 11 insertions, 40 deletions
diff --git a/drivers/net/veth.c b/drivers/net/veth.c index 108bbbeacfb6..124fe75b8a8a 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; |
| @@ -265,6 +275,7 @@ static void veth_dev_free(struct net_device *dev) | |||
| 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, |
| 278 | .ndo_stop = veth_close, | ||
| 268 | .ndo_start_xmit = veth_xmit, | 279 | .ndo_start_xmit = veth_xmit, |
| 269 | .ndo_get_stats = veth_get_stats, | 280 | .ndo_get_stats = veth_get_stats, |
| 270 | .ndo_set_mac_address = eth_mac_addr, | 281 | .ndo_set_mac_address = eth_mac_addr, |
| @@ -280,44 +291,6 @@ static void veth_setup(struct net_device *dev) | |||
| 280 | dev->destructor = veth_dev_free; | 291 | dev->destructor = veth_dev_free; |
| 281 | } | 292 | } |
| 282 | 293 | ||
| 283 | static void veth_change_state(struct net_device *dev) | ||
| 284 | { | ||
| 285 | struct net_device *peer; | ||
| 286 | struct veth_priv *priv; | ||
| 287 | |||
| 288 | priv = netdev_priv(dev); | ||
| 289 | peer = priv->peer; | ||
| 290 | |||
| 291 | if (netif_carrier_ok(peer)) { | ||
| 292 | if (!netif_carrier_ok(dev)) | ||
| 293 | netif_carrier_on(dev); | ||
| 294 | } else { | ||
| 295 | if (netif_carrier_ok(dev)) | ||
| 296 | netif_carrier_off(dev); | ||
| 297 | } | ||
| 298 | } | ||
| 299 | |||
| 300 | static int veth_device_event(struct notifier_block *unused, | ||
| 301 | unsigned long event, void *ptr) | ||
| 302 | { | ||
| 303 | struct net_device *dev = ptr; | ||
| 304 | |||
| 305 | if (dev->netdev_ops->ndo_open != veth_open) | ||
| 306 | goto out; | ||
| 307 | |||
| 308 | switch (event) { | ||
| 309 | case NETDEV_CHANGE: | ||
| 310 | veth_change_state(dev); | ||
| 311 | break; | ||
| 312 | } | ||
| 313 | out: | ||
| 314 | return NOTIFY_DONE; | ||
| 315 | } | ||
| 316 | |||
| 317 | static struct notifier_block veth_notifier_block __read_mostly = { | ||
| 318 | .notifier_call = veth_device_event, | ||
| 319 | }; | ||
| 320 | |||
| 321 | /* | 294 | /* |
| 322 | * netlink interface | 295 | * netlink interface |
| 323 | */ | 296 | */ |
| @@ -468,14 +441,12 @@ static struct rtnl_link_ops veth_link_ops = { | |||
| 468 | 441 | ||
| 469 | static __init int veth_init(void) | 442 | static __init int veth_init(void) |
| 470 | { | 443 | { |
| 471 | register_netdevice_notifier(&veth_notifier_block); | ||
| 472 | return rtnl_link_register(&veth_link_ops); | 444 | return rtnl_link_register(&veth_link_ops); |
| 473 | } | 445 | } |
| 474 | 446 | ||
| 475 | static __exit void veth_exit(void) | 447 | static __exit void veth_exit(void) |
| 476 | { | 448 | { |
| 477 | rtnl_link_unregister(&veth_link_ops); | 449 | rtnl_link_unregister(&veth_link_ops); |
| 478 | unregister_netdevice_notifier(&veth_notifier_block); | ||
| 479 | } | 450 | } |
| 480 | 451 | ||
| 481 | module_init(veth_init); | 452 | module_init(veth_init); |
