aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/tun.c
diff options
context:
space:
mode:
authorPavel Emelyanov <xemul@openvz.org>2008-04-16 03:40:46 -0400
committerDavid S. Miller <davem@davemloft.net>2008-04-16 03:40:46 -0400
commit79d1760491a25bfc70aeac363142cadd3f1cda71 (patch)
tree8c5a2d8f2d1b0f09097013abad7b8c2dc2852494 /drivers/net/tun.c
parent17515408a15fa51c553e67c415502e785145cd7f (diff)
[TUN]: Introduce the tun_net structure and init/exit net ops.
This is the first step in making tuntap devices work in net namespaces. The structure mentioned is pointed by generic net pointer with tun_net_id id, and tun driver fills one on its load. It will contain only the tun devices list. So declare this structure and introduce net init and exit hooks. Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/tun.c')
-rw-r--r--drivers/net/tun.c53
1 files changed, 52 insertions, 1 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 5b5d87585d91..f359d6082c38 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -63,6 +63,7 @@
63#include <linux/if_tun.h> 63#include <linux/if_tun.h>
64#include <linux/crc32.h> 64#include <linux/crc32.h>
65#include <net/net_namespace.h> 65#include <net/net_namespace.h>
66#include <net/netns/generic.h>
66 67
67#include <asm/system.h> 68#include <asm/system.h>
68#include <asm/uaccess.h> 69#include <asm/uaccess.h>
@@ -106,6 +107,11 @@ struct tun_struct {
106 107
107/* Network device part of the driver */ 108/* Network device part of the driver */
108 109
110static unsigned int tun_net_id;
111struct tun_net {
112 struct list_head dev_list;
113};
114
109static LIST_HEAD(tun_dev_list); 115static LIST_HEAD(tun_dev_list);
110static const struct ethtool_ops tun_ethtool_ops; 116static const struct ethtool_ops tun_ethtool_ops;
111 117
@@ -909,6 +915,37 @@ static const struct ethtool_ops tun_ethtool_ops = {
909 .set_rx_csum = tun_set_rx_csum 915 .set_rx_csum = tun_set_rx_csum
910}; 916};
911 917
918static int tun_init_net(struct net *net)
919{
920 struct tun_net *tn;
921
922 tn = kmalloc(sizeof(*tn), GFP_KERNEL);
923 if (tn == NULL)
924 return -ENOMEM;
925
926 INIT_LIST_HEAD(&tn->dev_list);
927
928 if (net_assign_generic(net, tun_net_id, tn)) {
929 kfree(tn);
930 return -ENOMEM;
931 }
932
933 return 0;
934}
935
936static void tun_exit_net(struct net *net)
937{
938 struct tun_net *tn;
939
940 tn = net_generic(net, tun_net_id);
941 kfree(tn);
942}
943
944static struct pernet_operations tun_net_ops = {
945 .init = tun_init_net,
946 .exit = tun_exit_net,
947};
948
912static int __init tun_init(void) 949static int __init tun_init(void)
913{ 950{
914 int ret = 0; 951 int ret = 0;
@@ -916,9 +953,22 @@ static int __init tun_init(void)
916 printk(KERN_INFO "tun: %s, %s\n", DRV_DESCRIPTION, DRV_VERSION); 953 printk(KERN_INFO "tun: %s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
917 printk(KERN_INFO "tun: %s\n", DRV_COPYRIGHT); 954 printk(KERN_INFO "tun: %s\n", DRV_COPYRIGHT);
918 955
956 ret = register_pernet_gen_device(&tun_net_id, &tun_net_ops);
957 if (ret) {
958 printk(KERN_ERR "tun: Can't register pernet ops\n");
959 goto err_pernet;
960 }
961
919 ret = misc_register(&tun_miscdev); 962 ret = misc_register(&tun_miscdev);
920 if (ret) 963 if (ret) {
921 printk(KERN_ERR "tun: Can't register misc device %d\n", TUN_MINOR); 964 printk(KERN_ERR "tun: Can't register misc device %d\n", TUN_MINOR);
965 goto err_misc;
966 }
967 return 0;
968
969err_misc:
970 unregister_pernet_gen_device(tun_net_id, &tun_net_ops);
971err_pernet:
922 return ret; 972 return ret;
923} 973}
924 974
@@ -935,6 +985,7 @@ static void tun_cleanup(void)
935 } 985 }
936 rtnl_unlock(); 986 rtnl_unlock();
937 987
988 unregister_pernet_gen_device(tun_net_id, &tun_net_ops);
938} 989}
939 990
940module_init(tun_init); 991module_init(tun_init);