Commit 024f35c5 authored by David S. Miller's avatar David S. Miller

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec

Steffen Klassert says:

====================
pull request (net): ipsec 2015-12-22

Just one patch to fix dst_entries_init with multiple namespaces.
From Dan Streetman.

Please pull or let me know if there are problems.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents e459dfee a8a572a6
...@@ -259,7 +259,7 @@ static void xfrm4_dst_ifdown(struct dst_entry *dst, struct net_device *dev, ...@@ -259,7 +259,7 @@ static void xfrm4_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
xfrm_dst_ifdown(dst, dev); xfrm_dst_ifdown(dst, dev);
} }
static struct dst_ops xfrm4_dst_ops = { static struct dst_ops xfrm4_dst_ops_template = {
.family = AF_INET, .family = AF_INET,
.gc = xfrm4_garbage_collect, .gc = xfrm4_garbage_collect,
.update_pmtu = xfrm4_update_pmtu, .update_pmtu = xfrm4_update_pmtu,
...@@ -273,7 +273,7 @@ static struct dst_ops xfrm4_dst_ops = { ...@@ -273,7 +273,7 @@ static struct dst_ops xfrm4_dst_ops = {
static struct xfrm_policy_afinfo xfrm4_policy_afinfo = { static struct xfrm_policy_afinfo xfrm4_policy_afinfo = {
.family = AF_INET, .family = AF_INET,
.dst_ops = &xfrm4_dst_ops, .dst_ops = &xfrm4_dst_ops_template,
.dst_lookup = xfrm4_dst_lookup, .dst_lookup = xfrm4_dst_lookup,
.get_saddr = xfrm4_get_saddr, .get_saddr = xfrm4_get_saddr,
.decode_session = _decode_session4, .decode_session = _decode_session4,
...@@ -295,7 +295,7 @@ static struct ctl_table xfrm4_policy_table[] = { ...@@ -295,7 +295,7 @@ static struct ctl_table xfrm4_policy_table[] = {
{ } { }
}; };
static int __net_init xfrm4_net_init(struct net *net) static int __net_init xfrm4_net_sysctl_init(struct net *net)
{ {
struct ctl_table *table; struct ctl_table *table;
struct ctl_table_header *hdr; struct ctl_table_header *hdr;
...@@ -323,7 +323,7 @@ static int __net_init xfrm4_net_init(struct net *net) ...@@ -323,7 +323,7 @@ static int __net_init xfrm4_net_init(struct net *net)
return -ENOMEM; return -ENOMEM;
} }
static void __net_exit xfrm4_net_exit(struct net *net) static void __net_exit xfrm4_net_sysctl_exit(struct net *net)
{ {
struct ctl_table *table; struct ctl_table *table;
...@@ -335,12 +335,44 @@ static void __net_exit xfrm4_net_exit(struct net *net) ...@@ -335,12 +335,44 @@ static void __net_exit xfrm4_net_exit(struct net *net)
if (!net_eq(net, &init_net)) if (!net_eq(net, &init_net))
kfree(table); kfree(table);
} }
#else /* CONFIG_SYSCTL */
static int inline xfrm4_net_sysctl_init(struct net *net)
{
return 0;
}
static void inline xfrm4_net_sysctl_exit(struct net *net)
{
}
#endif
static int __net_init xfrm4_net_init(struct net *net)
{
int ret;
memcpy(&net->xfrm.xfrm4_dst_ops, &xfrm4_dst_ops_template,
sizeof(xfrm4_dst_ops_template));
ret = dst_entries_init(&net->xfrm.xfrm4_dst_ops);
if (ret)
return ret;
ret = xfrm4_net_sysctl_init(net);
if (ret)
dst_entries_destroy(&net->xfrm.xfrm4_dst_ops);
return ret;
}
static void __net_exit xfrm4_net_exit(struct net *net)
{
xfrm4_net_sysctl_exit(net);
dst_entries_destroy(&net->xfrm.xfrm4_dst_ops);
}
static struct pernet_operations __net_initdata xfrm4_net_ops = { static struct pernet_operations __net_initdata xfrm4_net_ops = {
.init = xfrm4_net_init, .init = xfrm4_net_init,
.exit = xfrm4_net_exit, .exit = xfrm4_net_exit,
}; };
#endif
static void __init xfrm4_policy_init(void) static void __init xfrm4_policy_init(void)
{ {
...@@ -349,13 +381,9 @@ static void __init xfrm4_policy_init(void) ...@@ -349,13 +381,9 @@ static void __init xfrm4_policy_init(void)
void __init xfrm4_init(void) void __init xfrm4_init(void)
{ {
dst_entries_init(&xfrm4_dst_ops);
xfrm4_state_init(); xfrm4_state_init();
xfrm4_policy_init(); xfrm4_policy_init();
xfrm4_protocol_init(); xfrm4_protocol_init();
#ifdef CONFIG_SYSCTL
register_pernet_subsys(&xfrm4_net_ops); register_pernet_subsys(&xfrm4_net_ops);
#endif
} }
...@@ -279,7 +279,7 @@ static void xfrm6_dst_ifdown(struct dst_entry *dst, struct net_device *dev, ...@@ -279,7 +279,7 @@ static void xfrm6_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
xfrm_dst_ifdown(dst, dev); xfrm_dst_ifdown(dst, dev);
} }
static struct dst_ops xfrm6_dst_ops = { static struct dst_ops xfrm6_dst_ops_template = {
.family = AF_INET6, .family = AF_INET6,
.gc = xfrm6_garbage_collect, .gc = xfrm6_garbage_collect,
.update_pmtu = xfrm6_update_pmtu, .update_pmtu = xfrm6_update_pmtu,
...@@ -293,7 +293,7 @@ static struct dst_ops xfrm6_dst_ops = { ...@@ -293,7 +293,7 @@ static struct dst_ops xfrm6_dst_ops = {
static struct xfrm_policy_afinfo xfrm6_policy_afinfo = { static struct xfrm_policy_afinfo xfrm6_policy_afinfo = {
.family = AF_INET6, .family = AF_INET6,
.dst_ops = &xfrm6_dst_ops, .dst_ops = &xfrm6_dst_ops_template,
.dst_lookup = xfrm6_dst_lookup, .dst_lookup = xfrm6_dst_lookup,
.get_saddr = xfrm6_get_saddr, .get_saddr = xfrm6_get_saddr,
.decode_session = _decode_session6, .decode_session = _decode_session6,
...@@ -325,7 +325,7 @@ static struct ctl_table xfrm6_policy_table[] = { ...@@ -325,7 +325,7 @@ static struct ctl_table xfrm6_policy_table[] = {
{ } { }
}; };
static int __net_init xfrm6_net_init(struct net *net) static int __net_init xfrm6_net_sysctl_init(struct net *net)
{ {
struct ctl_table *table; struct ctl_table *table;
struct ctl_table_header *hdr; struct ctl_table_header *hdr;
...@@ -353,7 +353,7 @@ static int __net_init xfrm6_net_init(struct net *net) ...@@ -353,7 +353,7 @@ static int __net_init xfrm6_net_init(struct net *net)
return -ENOMEM; return -ENOMEM;
} }
static void __net_exit xfrm6_net_exit(struct net *net) static void __net_exit xfrm6_net_sysctl_exit(struct net *net)
{ {
struct ctl_table *table; struct ctl_table *table;
...@@ -365,24 +365,52 @@ static void __net_exit xfrm6_net_exit(struct net *net) ...@@ -365,24 +365,52 @@ static void __net_exit xfrm6_net_exit(struct net *net)
if (!net_eq(net, &init_net)) if (!net_eq(net, &init_net))
kfree(table); kfree(table);
} }
#else /* CONFIG_SYSCTL */
static int inline xfrm6_net_sysctl_init(struct net *net)
{
return 0;
}
static void inline xfrm6_net_sysctl_exit(struct net *net)
{
}
#endif
static int __net_init xfrm6_net_init(struct net *net)
{
int ret;
memcpy(&net->xfrm.xfrm6_dst_ops, &xfrm6_dst_ops_template,
sizeof(xfrm6_dst_ops_template));
ret = dst_entries_init(&net->xfrm.xfrm6_dst_ops);
if (ret)
return ret;
ret = xfrm6_net_sysctl_init(net);
if (ret)
dst_entries_destroy(&net->xfrm.xfrm6_dst_ops);
return ret;
}
static void __net_exit xfrm6_net_exit(struct net *net)
{
xfrm6_net_sysctl_exit(net);
dst_entries_destroy(&net->xfrm.xfrm6_dst_ops);
}
static struct pernet_operations xfrm6_net_ops = { static struct pernet_operations xfrm6_net_ops = {
.init = xfrm6_net_init, .init = xfrm6_net_init,
.exit = xfrm6_net_exit, .exit = xfrm6_net_exit,
}; };
#endif
int __init xfrm6_init(void) int __init xfrm6_init(void)
{ {
int ret; int ret;
dst_entries_init(&xfrm6_dst_ops);
ret = xfrm6_policy_init(); ret = xfrm6_policy_init();
if (ret) { if (ret)
dst_entries_destroy(&xfrm6_dst_ops);
goto out; goto out;
}
ret = xfrm6_state_init(); ret = xfrm6_state_init();
if (ret) if (ret)
goto out_policy; goto out_policy;
...@@ -391,9 +419,7 @@ int __init xfrm6_init(void) ...@@ -391,9 +419,7 @@ int __init xfrm6_init(void)
if (ret) if (ret)
goto out_state; goto out_state;
#ifdef CONFIG_SYSCTL
register_pernet_subsys(&xfrm6_net_ops); register_pernet_subsys(&xfrm6_net_ops);
#endif
out: out:
return ret; return ret;
out_state: out_state:
...@@ -405,11 +431,8 @@ int __init xfrm6_init(void) ...@@ -405,11 +431,8 @@ int __init xfrm6_init(void)
void xfrm6_fini(void) void xfrm6_fini(void)
{ {
#ifdef CONFIG_SYSCTL
unregister_pernet_subsys(&xfrm6_net_ops); unregister_pernet_subsys(&xfrm6_net_ops);
#endif
xfrm6_protocol_fini(); xfrm6_protocol_fini();
xfrm6_policy_fini(); xfrm6_policy_fini();
xfrm6_state_fini(); xfrm6_state_fini();
dst_entries_destroy(&xfrm6_dst_ops);
} }
...@@ -2826,7 +2826,6 @@ static struct neighbour *xfrm_neigh_lookup(const struct dst_entry *dst, ...@@ -2826,7 +2826,6 @@ static struct neighbour *xfrm_neigh_lookup(const struct dst_entry *dst,
int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
{ {
struct net *net;
int err = 0; int err = 0;
if (unlikely(afinfo == NULL)) if (unlikely(afinfo == NULL))
return -EINVAL; return -EINVAL;
...@@ -2857,26 +2856,6 @@ int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) ...@@ -2857,26 +2856,6 @@ int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
} }
spin_unlock(&xfrm_policy_afinfo_lock); spin_unlock(&xfrm_policy_afinfo_lock);
rtnl_lock();
for_each_net(net) {
struct dst_ops *xfrm_dst_ops;
switch (afinfo->family) {
case AF_INET:
xfrm_dst_ops = &net->xfrm.xfrm4_dst_ops;
break;
#if IS_ENABLED(CONFIG_IPV6)
case AF_INET6:
xfrm_dst_ops = &net->xfrm.xfrm6_dst_ops;
break;
#endif
default:
BUG();
}
*xfrm_dst_ops = *afinfo->dst_ops;
}
rtnl_unlock();
return err; return err;
} }
EXPORT_SYMBOL(xfrm_policy_register_afinfo); EXPORT_SYMBOL(xfrm_policy_register_afinfo);
...@@ -2912,22 +2891,6 @@ int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo) ...@@ -2912,22 +2891,6 @@ int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo)
} }
EXPORT_SYMBOL(xfrm_policy_unregister_afinfo); EXPORT_SYMBOL(xfrm_policy_unregister_afinfo);
static void __net_init xfrm_dst_ops_init(struct net *net)
{
struct xfrm_policy_afinfo *afinfo;
rcu_read_lock();
afinfo = rcu_dereference(xfrm_policy_afinfo[AF_INET]);
if (afinfo)
net->xfrm.xfrm4_dst_ops = *afinfo->dst_ops;
#if IS_ENABLED(CONFIG_IPV6)
afinfo = rcu_dereference(xfrm_policy_afinfo[AF_INET6]);
if (afinfo)
net->xfrm.xfrm6_dst_ops = *afinfo->dst_ops;
#endif
rcu_read_unlock();
}
static int xfrm_dev_event(struct notifier_block *this, unsigned long event, void *ptr) static int xfrm_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
{ {
struct net_device *dev = netdev_notifier_info_to_dev(ptr); struct net_device *dev = netdev_notifier_info_to_dev(ptr);
...@@ -3076,7 +3039,6 @@ static int __net_init xfrm_net_init(struct net *net) ...@@ -3076,7 +3039,6 @@ static int __net_init xfrm_net_init(struct net *net)
rv = xfrm_policy_init(net); rv = xfrm_policy_init(net);
if (rv < 0) if (rv < 0)
goto out_policy; goto out_policy;
xfrm_dst_ops_init(net);
rv = xfrm_sysctl_init(net); rv = xfrm_sysctl_init(net);
if (rv < 0) if (rv < 0)
goto out_sysctl; goto out_sysctl;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment