提交 c2892f02 编写于 作者: A Alexey Dobriyan 提交者: David S. Miller

gre: fix netns vs proto registration ordering

GRE protocol receive hook can be called right after protocol addition is done.
If netns stuff is not yet initialized, we're going to oops in
net_generic().

This is remotely oopsable if ip_gre is compiled as module and packet
comes at unfortunate moment of module loading.
Signed-off-by: NAlexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 749f621e
...@@ -1665,14 +1665,15 @@ static int __init ipgre_init(void) ...@@ -1665,14 +1665,15 @@ static int __init ipgre_init(void)
printk(KERN_INFO "GRE over IPv4 tunneling driver\n"); printk(KERN_INFO "GRE over IPv4 tunneling driver\n");
if (inet_add_protocol(&ipgre_protocol, IPPROTO_GRE) < 0) {
printk(KERN_INFO "ipgre init: can't add protocol\n");
return -EAGAIN;
}
err = register_pernet_device(&ipgre_net_ops); err = register_pernet_device(&ipgre_net_ops);
if (err < 0) if (err < 0)
goto gen_device_failed; return err;
err = inet_add_protocol(&ipgre_protocol, IPPROTO_GRE);
if (err < 0) {
printk(KERN_INFO "ipgre init: can't add protocol\n");
goto add_proto_failed;
}
err = rtnl_link_register(&ipgre_link_ops); err = rtnl_link_register(&ipgre_link_ops);
if (err < 0) if (err < 0)
...@@ -1688,9 +1689,9 @@ static int __init ipgre_init(void) ...@@ -1688,9 +1689,9 @@ static int __init ipgre_init(void)
tap_ops_failed: tap_ops_failed:
rtnl_link_unregister(&ipgre_link_ops); rtnl_link_unregister(&ipgre_link_ops);
rtnl_link_failed: rtnl_link_failed:
unregister_pernet_device(&ipgre_net_ops);
gen_device_failed:
inet_del_protocol(&ipgre_protocol, IPPROTO_GRE); inet_del_protocol(&ipgre_protocol, IPPROTO_GRE);
add_proto_failed:
unregister_pernet_device(&ipgre_net_ops);
goto out; goto out;
} }
...@@ -1698,9 +1699,9 @@ static void __exit ipgre_fini(void) ...@@ -1698,9 +1699,9 @@ static void __exit ipgre_fini(void)
{ {
rtnl_link_unregister(&ipgre_tap_ops); rtnl_link_unregister(&ipgre_tap_ops);
rtnl_link_unregister(&ipgre_link_ops); rtnl_link_unregister(&ipgre_link_ops);
unregister_pernet_device(&ipgre_net_ops);
if (inet_del_protocol(&ipgre_protocol, IPPROTO_GRE) < 0) if (inet_del_protocol(&ipgre_protocol, IPPROTO_GRE) < 0)
printk(KERN_INFO "ipgre close: can't remove protocol\n"); printk(KERN_INFO "ipgre close: can't remove protocol\n");
unregister_pernet_device(&ipgre_net_ops);
} }
module_init(ipgre_init); module_init(ipgre_init);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册