mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-03 07:38:10 +00:00
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: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
024f35c552
3 changed files with 75 additions and 62 deletions
|
@ -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 = {
|
||||||
|
|
||||||
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[] = {
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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,
|
||||||
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 = {
|
||||||
|
|
||||||
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[] = {
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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,
|
||||||
|
|
||||||
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)
|
||||||
}
|
}
|
||||||
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)
|
||||||
}
|
}
|
||||||
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)
|
||||||
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;
|
||||||
|
|
Loading…
Reference in a new issue