From 45f7bf0ddba8e1b81db65fab30eca50da83e6be5 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 14 Apr 2011 22:50:55 +0200 Subject: Implement interface configuration and deletion --- quicktun.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 9 deletions(-) (limited to 'quicktun.c') diff --git a/quicktun.c b/quicktun.c index b0b1e32..d16a62f 100644 --- a/quicktun.c +++ b/quicktun.c @@ -35,6 +35,7 @@ struct quicktun_struct { static void quicktun_net_uninit(struct net_device *dev) { + pr_info("quicktun_net_uninit"); } static netdev_tx_t quicktun_net_xmit(struct sk_buff *skb, struct net_device *dev) @@ -106,18 +107,18 @@ quicktun_net_change_mtu(struct net_device *dev, int new_mtu) } -static const struct net_device_ops quicktun_tun_netdev_ops = { +static const struct net_device_ops quicktun_ethernet_netdev_ops = { .ndo_uninit = quicktun_net_uninit, .ndo_start_xmit = quicktun_net_xmit, .ndo_change_mtu = quicktun_net_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, }; -static const struct net_device_ops quicktun_tap_netdev_ops = { +static const struct net_device_ops quicktun_ip_netdev_ops = { .ndo_uninit = quicktun_net_uninit, .ndo_start_xmit = quicktun_net_xmit, .ndo_change_mtu = quicktun_net_change_mtu, - .ndo_set_mac_address = eth_mac_addr, - .ndo_validate_addr = eth_validate_addr, }; @@ -153,6 +154,7 @@ static const struct ethtool_ops quicktun_ethtool_ops = { static void quicktun_free_netdev(struct net_device *dev) { + pr_info("Quicktun: free_netdev"); } static void quicktun_setup(struct net_device *dev) @@ -176,7 +178,7 @@ static void quicktun_net_init(struct net_device *dev) switch (tun->flags & QUICKTUN_MODE_MASK) { case QUICKTUN_MODE_ETHERNET: - dev->netdev_ops = &quicktun_tap_netdev_ops; + dev->netdev_ops = &quicktun_ethernet_netdev_ops; ether_setup(dev); @@ -184,7 +186,7 @@ static void quicktun_net_init(struct net_device *dev) break; case QUICKTUN_MODE_IP: - dev->netdev_ops = &quicktun_tun_netdev_ops; + dev->netdev_ops = &quicktun_ip_netdev_ops; dev->hard_header_len = 0; dev->addr_len = 0; @@ -309,9 +311,49 @@ static int quicktun_cmd_create_device(struct sk_buff *skb, struct genl_info *inf return err; } -static int quicktun_cmd_destroy_device(struct sk_buff *skb, struct genl_info *info) +static int quicktun_cmd_delete_device(struct sk_buff *skb, struct genl_info *info) { + int err; + struct net *net = genl_info_net(info); + struct net_device *dev; + struct quicktun_struct *tun; + struct socket *sock; + char *name; + + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + if (!info->attrs[QUICKTUN_A_IFNAME]) + return -EINVAL; + + name = nla_data(info->attrs[QUICKTUN_A_IFNAME]); + + dev = dev_get_by_name(net, name); + if (!dev) + return -EINVAL; + + if (dev->netdev_ops != &quicktun_ethernet_netdev_ops && dev->netdev_ops != &quicktun_ip_netdev_ops) { + err = -EINVAL; + goto err; + } + + tun = netdev_priv(dev); + sock = tun->sock; + + rtnl_lock(); + dev_put(dev); + unregister_netdevice(dev); + rtnl_unlock(); + + pr_info("quicktun: release sock"); + sock_release(sock); + return 0; + +err: + dev_put(dev); + + return err; } @@ -341,8 +383,8 @@ static struct genl_ops quicktun_nl_ops[] = { .policy = quicktun_nl_policy, }, { - .cmd = QUICKTUN_CMD_DESTROY_DEVICE, - .doit = quicktun_cmd_destroy_device, + .cmd = QUICKTUN_CMD_DELETE_DEVICE, + .doit = quicktun_cmd_delete_device, .policy = quicktun_nl_policy, }, }; -- cgit v1.2.3