summaryrefslogtreecommitdiffstats
path: root/quicktun.c
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2011-04-14 22:50:55 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2011-04-14 22:50:55 +0200
commit45f7bf0ddba8e1b81db65fab30eca50da83e6be5 (patch)
tree3ad123b8177cb6e9ce2ff93ff612766a8ecba360 /quicktun.c
parentb476556d447c07244e71ff15d832efb19109ae29 (diff)
downloadmodquicktun-45f7bf0ddba8e1b81db65fab30eca50da83e6be5.tar
modquicktun-45f7bf0ddba8e1b81db65fab30eca50da83e6be5.zip
Implement interface configuration and deletion
Diffstat (limited to 'quicktun.c')
-rw-r--r--quicktun.c60
1 files changed, 51 insertions, 9 deletions
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,
},
};