aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/tun.c
diff options
context:
space:
mode:
authorNeil Horman <nhorman@tuxdriver.com>2011-06-15 01:25:01 -0400
committerDavid S. Miller <davem@conan.davemloft.net>2011-06-16 23:53:10 -0400
commitbebd097a0af8bd6c51f50a65f3a435019b0e906a (patch)
tree22215109ca9499577da0690f84c7b691ee8e6df7 /drivers/net/tun.c
parentae6e86b7fb15520ac64513ad643de63e0b077aa5 (diff)
tun: teach the tun/tap driver to support netpoll
Commit 8d8fc29d02a33e4bd5f4fa47823c1fd386346093 changed the behavior of slave devices in regards to netpoll. Specifically it created a mutually exclusive relationship between being a slave and a netpoll-capable device. This creates problems for KVM because guests relied on needing netconsole active on a slave device to a bridge. Ideally libvirtd could just attach netconsole to the bridge device instead, but thats currently infeasible, because while the bridge device supports netpoll, it requires that all slave interface also support it, but the tun/tap driver currently does not. The most direct solution is to teach tun/tap to support netpoll, which is implemented by the patch below. I've not tested this yet, but its pretty straightforward. Signed-off-by: Neil Horman <nhorman@tuxdriver.com> Reported-by: Rik van Riel <riel@redhat.com> CC: Rik van Riel <riel@redhat.com> CC: Maxim Krasnyansky <maxk@qualcomm.com> CC: Cong Wang <amwang@redhat.com> CC: "David S. Miller" <davem@davemloft.net> Reviewed-by: Rik van Riel <riel@redhat.com> Tested-by: Rik van Riel <riel@redhat.com> Reviewed-by: WANG Cong <amwang@redhat.com> Signed-off-by: David S. Miller <davem@conan.davemloft.net>
Diffstat (limited to 'drivers/net/tun.c')
-rw-r--r--drivers/net/tun.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 74e94054ab1a..5235f48be1be 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -460,7 +460,23 @@ static u32 tun_net_fix_features(struct net_device *dev, u32 features)
460 460
461 return (features & tun->set_features) | (features & ~TUN_USER_FEATURES); 461 return (features & tun->set_features) | (features & ~TUN_USER_FEATURES);
462} 462}
463 463#ifdef CONFIG_NET_POLL_CONTROLLER
464static void tun_poll_controller(struct net_device *dev)
465{
466 /*
467 * Tun only receives frames when:
468 * 1) the char device endpoint gets data from user space
469 * 2) the tun socket gets a sendmsg call from user space
470 * Since both of those are syncronous operations, we are guaranteed
471 * never to have pending data when we poll for it
472 * so theres nothing to do here but return.
473 * We need this though so netpoll recognizes us as an interface that
474 * supports polling, which enables bridge devices in virt setups to
475 * still use netconsole
476 */
477 return;
478}
479#endif
464static const struct net_device_ops tun_netdev_ops = { 480static const struct net_device_ops tun_netdev_ops = {
465 .ndo_uninit = tun_net_uninit, 481 .ndo_uninit = tun_net_uninit,
466 .ndo_open = tun_net_open, 482 .ndo_open = tun_net_open,
@@ -468,6 +484,9 @@ static const struct net_device_ops tun_netdev_ops = {
468 .ndo_start_xmit = tun_net_xmit, 484 .ndo_start_xmit = tun_net_xmit,
469 .ndo_change_mtu = tun_net_change_mtu, 485 .ndo_change_mtu = tun_net_change_mtu,
470 .ndo_fix_features = tun_net_fix_features, 486 .ndo_fix_features = tun_net_fix_features,
487#ifdef CONFIG_NET_POLL_CONTROLLER
488 .ndo_poll_controller = tun_poll_controller,
489#endif
471}; 490};
472 491
473static const struct net_device_ops tap_netdev_ops = { 492static const struct net_device_ops tap_netdev_ops = {
@@ -480,6 +499,9 @@ static const struct net_device_ops tap_netdev_ops = {
480 .ndo_set_multicast_list = tun_net_mclist, 499 .ndo_set_multicast_list = tun_net_mclist,
481 .ndo_set_mac_address = eth_mac_addr, 500 .ndo_set_mac_address = eth_mac_addr,
482 .ndo_validate_addr = eth_validate_addr, 501 .ndo_validate_addr = eth_validate_addr,
502#ifdef CONFIG_NET_POLL_CONTROLLER
503 .ndo_poll_controller = tun_poll_controller,
504#endif
483}; 505};
484 506
485/* Initialize net device. */ 507/* Initialize net device. */