From: Jesse Gross Date: Wed, 3 Feb 2010 22:39:29 +0000 (-0500) Subject: gre: Simplify net namespace operations. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8fb56e55f65c207ef4034cef123a9eea4aeb974b;p=openvswitch gre: Simplify net namespace operations. Ports commit cfb8fb "net: Simplify ip_gre pernet operations." from the mainline kernel. --- diff --git a/datapath/linux-2.6/compat-2.6/include/net/net_namespace.h b/datapath/linux-2.6/compat-2.6/include/net/net_namespace.h index 9b66c91c..92a4e021 100644 --- a/datapath/linux-2.6/compat-2.6/include/net/net_namespace.h +++ b/datapath/linux-2.6/compat-2.6/include/net/net_namespace.h @@ -2,25 +2,28 @@ #define __NET_NAMESPACE_WRAPPER_H 1 #include -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,24) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) #include_next #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33) struct net; -struct pernet_operations { +struct extended_pernet_operations { struct list_head list; int (*init)(struct net *net); void (*exit)(struct net *net); + int *id; + size_t size; }; -#endif /* linux kernel < 2.6.24 */ +#define pernet_operations extended_pernet_operations + +#define register_pernet_device rpl_register_pernet_device +int rpl_register_pernet_device(struct extended_pernet_operations *ops); -extern int register_pernet_gen_device(int *id, struct pernet_operations *); -extern void unregister_pernet_gen_device(int id, struct pernet_operations *); +#define unregister_pernet_device rpl_unregister_pernet_device +void rpl_unregister_pernet_device(struct extended_pernet_operations *ops); -#endif /* linux kernel < 2.6.26 */ +#endif /* linux kernel < 2.6.33 */ #endif diff --git a/datapath/linux-2.6/compat-2.6/include/net/netns/generic.h b/datapath/linux-2.6/compat-2.6/include/net/netns/generic.h index f70bc87e..7aedf31f 100644 --- a/datapath/linux-2.6/compat-2.6/include/net/netns/generic.h +++ b/datapath/linux-2.6/compat-2.6/include/net/netns/generic.h @@ -2,15 +2,18 @@ #define __NET_NETNS_GENERIC_WRAPPER_H 1 #include -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) +#include_next +#endif -struct net; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33) -extern void *net_generic(struct net *net, int id); -extern int net_assign_generic(struct net *net, int id, void *data); +#define net_assign_generic rpl_net_assign_generic +int rpl_net_assign_generic(struct net *net, int id, void *data); -#else -#include_next -#endif /* linux kernel < 2.6.26 */ +#define net_generic rpl_net_generic +void *rpl_net_generic(struct net *net, int id); + +#endif /* linux kernel < 2.6.33 */ #endif diff --git a/datapath/linux-2.6/compat-2.6/ip_gre.c b/datapath/linux-2.6/compat-2.6/ip_gre.c index 9a7ea96f..ec0f0c5e 100644 --- a/datapath/linux-2.6/compat-2.6/ip_gre.c +++ b/datapath/linux-2.6/compat-2.6/ip_gre.c @@ -1465,17 +1465,8 @@ static void ipgre_destroy_tunnels(struct ipgre_net *ign, struct list_head *head) static int ipgre_init_net(struct net *net) { + struct ipgre_net *ign = net_generic(net, ipgre_net_id); int err; - struct ipgre_net *ign; - - err = -ENOMEM; - ign = kzalloc(sizeof(struct ipgre_net), GFP_KERNEL); - if (ign == NULL) - goto err_alloc; - - err = net_assign_generic(net, ipgre_net_id, ign); - if (err < 0) - goto err_assign; ign->fb_tunnel_dev = alloc_netdev(sizeof(struct ip_tunnel), GRE_IOCTL_DEVICE, ipgre_tunnel_setup); @@ -1502,10 +1493,6 @@ static int ipgre_init_net(struct net *net) err_reg_dev: free_netdev(ign->fb_tunnel_dev); err_alloc_dev: - /* nothing */ -err_assign: - kfree(ign); -err_alloc: return err; } @@ -1519,12 +1506,13 @@ static void ipgre_exit_net(struct net *net) ipgre_destroy_tunnels(ign, &list); unregister_netdevice_many(&list); rtnl_unlock(); - kfree(ign); } static struct pernet_operations ipgre_net_ops = { .init = ipgre_init_net, .exit = ipgre_exit_net, + .id = &ipgre_net_id, + .size = sizeof(struct ipgre_net), }; static int ipgre_tap_init(struct net_device *dev) @@ -1866,7 +1854,7 @@ static int __init ipgre_init(void) return -EAGAIN; } - err = register_pernet_gen_device(&ipgre_net_id, &ipgre_net_ops); + err = register_pernet_device(&ipgre_net_ops); if (err < 0) goto gen_device_failed; @@ -1887,7 +1875,7 @@ out: tap_ops_failed: rtnl_link_unregister(&ipgre_link_ops); rtnl_link_failed: - unregister_pernet_gen_device(ipgre_net_id, &ipgre_net_ops); + unregister_pernet_device(&ipgre_net_ops); #endif gen_device_failed: inet_del_protocol(&ipgre_protocol, IPPROTO_GRE); @@ -1901,7 +1889,7 @@ static void __exit ipgre_fini(void) rtnl_link_unregister(&ipgre_tap_ops); rtnl_link_unregister(&ipgre_link_ops); #endif - unregister_pernet_gen_device(ipgre_net_id, &ipgre_net_ops); + unregister_pernet_device(&ipgre_net_ops); if (inet_del_protocol(&ipgre_protocol, IPPROTO_GRE) < 0) printk(KERN_INFO "ipgre close: can't remove protocol\n"); } diff --git a/datapath/linux-2.6/compat-2.6/net_namespace-ip_gre.c b/datapath/linux-2.6/compat-2.6/net_namespace-ip_gre.c index 323b6446..a7a211cd 100644 --- a/datapath/linux-2.6/compat-2.6/net_namespace-ip_gre.c +++ b/datapath/linux-2.6/compat-2.6/net_namespace-ip_gre.c @@ -1,49 +1,117 @@ #include -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33) #include #include #include +#undef pernet_operations +#undef register_pernet_device +#undef unregister_pernet_device +#undef net_assign_generic +#undef net_generic + /* This trivial implementation assumes that there is only a single pernet - * generic device registered and that the caller is well behaved. It only - * weakly attempts to check that these conditions are true. */ + * device registered and that the caller is well behaved. It only weakly + * attempts to check that these conditions are true. */ -static bool device_registered; +static struct extended_pernet_operations *dev_ops; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) static void *ng_data; +#else +static struct pernet_operations new_ops; +#endif -int register_pernet_gen_device(int *id, struct pernet_operations *ops) +static int device_init_net(struct net *net) { - BUG_ON(device_registered); + int err; + if (dev_ops->id && dev_ops->size) { + void *data = kzalloc(dev_ops->size, GFP_KERNEL); + if (!data) + return -ENOMEM; + + err = rpl_net_assign_generic(net, *dev_ops->id, data); + if (err) { + kfree(data); + return err; + } + } + if (dev_ops->init) + return dev_ops->init(net); + return 0; +} - *id = 1; - device_registered = true; +static void device_exit_net(struct net *net) +{ + if (dev_ops->id && dev_ops->size) { + int id = *dev_ops->id; + kfree(rpl_net_generic(net, id)); + } - if (ops->init == NULL) - return 0; - return ops->init(NULL); + if (dev_ops->exit) + return dev_ops->exit(net); } -void unregister_pernet_gen_device(int id, struct pernet_operations *ops) +int rpl_register_pernet_device(struct extended_pernet_operations *ops) { - device_registered = false; - if (ops->exit) - ops->exit(NULL); + BUG_ON(dev_ops); + dev_ops = ops; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) + if (dev_ops->id) + *dev_ops->id = 1; + + return device_init_net(NULL); +#else + memcpy(&new_ops, dev_ops, sizeof new_ops); + new_ops.init = device_init_net; + new_ops.exit = device_exit_net; + + if (ops->id) + return register_pernet_gen_device(dev_ops->id, &new_ops); + else + return register_pernet_device(&new_ops); +#endif } -int net_assign_generic(struct net *net, int id, void *data) +void rpl_unregister_pernet_device(struct extended_pernet_operations *ops) { + BUG_ON(!dev_ops); + BUG_ON(dev_ops != ops); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) + device_exit_net(NULL); +#else + if (ops->id) + unregister_pernet_gen_device(*dev_ops->id, &new_ops); + else + unregister_pernet_device(&new_ops); +#endif + + dev_ops = NULL; +} + +int rpl_net_assign_generic(struct net *net, int id, void *data) +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) BUG_ON(id != 1); ng_data = data; return 0; +#else + return net_assign_generic(net, id, data); +#endif } -void *net_generic(struct net *net, int id) +void *rpl_net_generic(struct net *net, int id) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) BUG_ON(id != 1); return ng_data; +#else + return net_generic(net, id); +#endif } -#endif /* kernel < 2.6.26 */ +#endif /* kernel < 2.6.33 */