From 5e5f3f0f801321078c897a5de0b4b4304f234da0 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Mon, 3 Mar 2008 21:44:34 +0900 Subject: [IPV6] ADDRCONF: Convert ipv6_get_saddr() to ipv6_dev_get_saddr(). Since most users of ipv6_get_saddr() pass non-NULL as dst argument, use ipv6_dev_get_saddr() directly. Signed-off-by: YOSHIFUJI Hideaki --- net/ipv6/fib6_rules.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'net/ipv6/fib6_rules.c') diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index 695c0ca8a417..157db3a1ce00 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c @@ -85,8 +85,8 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp, if ((rule->flags & FIB_RULE_FIND_SADDR) && r->src.plen && !(flags & RT6_LOOKUP_F_HAS_SADDR)) { struct in6_addr saddr; - if (ipv6_get_saddr(&rt->u.dst, &flp->fl6_dst, - &saddr)) + if (ipv6_dev_get_saddr(ip6_dst_idev(&rt->u.dst)->dev, + &flp->fl6_dst, &saddr)) goto again; if (!ipv6_prefix_equal(&saddr, &r->src.addr, r->src.plen)) -- cgit v1.2.3 From 58f09b78b730cf0d936597272bf35b3d615e967c Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Mon, 3 Mar 2008 23:25:27 -0800 Subject: [NETNS][IPV6] ip6_fib - make it per network namespace The fib table for ipv6 are moved to the network namespace structure. All references to them are made relatively to the network namespace. All external calls to the ip6_fib functions taking the network namespace parameter are made using the init_net variable, so the ip6_fib engine is ready for the namespaces but the callers not yet. Signed-off-by: Daniel Lezcano Signed-off-by: Benjamin Thery Signed-off-by: David S. Miller --- include/net/ip6_fib.h | 9 +-- include/net/netns/ipv6.h | 5 ++ net/ipv6/fib6_rules.c | 8 +-- net/ipv6/ip6_fib.c | 161 +++++++++++++++++++++++++++-------------------- net/ipv6/route.c | 22 ++++--- 5 files changed, 119 insertions(+), 86 deletions(-) (limited to 'net/ipv6/fib6_rules.c') diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h index 953d6040ff50..4d4c8aca8fb9 100644 --- a/include/net/ip6_fib.h +++ b/include/net/ip6_fib.h @@ -181,10 +181,11 @@ typedef struct rt6_info *(*pol_lookup_t)(struct fib6_table *, * exported functions */ -extern struct fib6_table * fib6_get_table(u32 id); -extern struct fib6_table * fib6_new_table(u32 id); -extern struct dst_entry * fib6_rule_lookup(struct flowi *fl, int flags, - pol_lookup_t lookup); +extern struct fib6_table *fib6_get_table(struct net *net, u32 id); +extern struct fib6_table *fib6_new_table(struct net *net, u32 id); +extern struct dst_entry *fib6_rule_lookup(struct net *net, + struct flowi *fl, int flags, + pol_lookup_t lookup); extern struct fib6_node *fib6_lookup(struct fib6_node *root, struct in6_addr *daddr, diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h index 82623d3a8e35..b0653261c5a3 100644 --- a/include/net/netns/ipv6.h +++ b/include/net/netns/ipv6.h @@ -35,6 +35,11 @@ struct netns_ipv6 { struct xt_table *ip6table_filter; struct xt_table *ip6table_mangle; struct xt_table *ip6table_raw; +#endif + struct hlist_head *fib_table_hash; + struct fib6_table *fib6_main_tbl; +#ifdef CONFIG_IPV6_MULTIPLE_TABLES + struct fib6_table *fib6_local_tbl; #endif struct sock **icmp_sk; }; diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index 157db3a1ce00..03ad23a5fd3c 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c @@ -31,8 +31,8 @@ struct fib6_rule static struct fib_rules_ops fib6_rules_ops; -struct dst_entry *fib6_rule_lookup(struct flowi *fl, int flags, - pol_lookup_t lookup) +struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi *fl, + int flags, pol_lookup_t lookup) { struct fib_lookup_arg arg = { .lookup_ptr = lookup, @@ -71,7 +71,7 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp, goto discard_pkt; } - table = fib6_get_table(rule->table); + table = fib6_get_table(&init_net, rule->table); if (table) rt = lookup(table, flp, flags); @@ -151,7 +151,7 @@ static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb, if (rule->table == RT6_TABLE_UNSPEC) goto errout; - if (fib6_new_table(rule->table) == NULL) { + if (fib6_new_table(&init_net, rule->table) == NULL) { err = -ENOBUFS; goto errout; } diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 04d774963f3c..7b549f0bc428 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -166,16 +166,13 @@ static __inline__ void rt6_release(struct rt6_info *rt) dst_free(&rt->u.dst); } -static struct fib6_table *fib6_main_tbl; - #ifdef CONFIG_IPV6_MULTIPLE_TABLES #define FIB_TABLE_HASHSZ 256 #else #define FIB_TABLE_HASHSZ 1 #endif -static struct hlist_head *fib_table_hash; -static void fib6_link_table(struct fib6_table *tb) +static void fib6_link_table(struct net *net, struct fib6_table *tb) { unsigned int h; @@ -191,13 +188,11 @@ static void fib6_link_table(struct fib6_table *tb) * No protection necessary, this is the only list mutatation * operation, tables never disappear once they exist. */ - hlist_add_head_rcu(&tb->tb6_hlist, &fib_table_hash[h]); + hlist_add_head_rcu(&tb->tb6_hlist, &net->ipv6.fib_table_hash[h]); } #ifdef CONFIG_IPV6_MULTIPLE_TABLES -static struct fib6_table *fib6_local_tbl; - static struct fib6_table *fib6_alloc_table(u32 id) { struct fib6_table *table; @@ -212,26 +207,27 @@ static struct fib6_table *fib6_alloc_table(u32 id) return table; } -struct fib6_table *fib6_new_table(u32 id) +struct fib6_table *fib6_new_table(struct net *net, u32 id) { struct fib6_table *tb; if (id == 0) id = RT6_TABLE_MAIN; - tb = fib6_get_table(id); + tb = fib6_get_table(net, id); if (tb) return tb; tb = fib6_alloc_table(id); if (tb != NULL) - fib6_link_table(tb); + fib6_link_table(net, tb); return tb; } -struct fib6_table *fib6_get_table(u32 id) +struct fib6_table *fib6_get_table(struct net *net, u32 id) { struct fib6_table *tb; + struct hlist_head *head; struct hlist_node *node; unsigned int h; @@ -239,7 +235,8 @@ struct fib6_table *fib6_get_table(u32 id) id = RT6_TABLE_MAIN; h = id & (FIB_TABLE_HASHSZ - 1); rcu_read_lock(); - hlist_for_each_entry_rcu(tb, node, &fib_table_hash[h], tb6_hlist) { + head = &net->ipv6.fib_table_hash[h]; + hlist_for_each_entry_rcu(tb, node, head, tb6_hlist) { if (tb->tb6_id == id) { rcu_read_unlock(); return tb; @@ -250,33 +247,32 @@ struct fib6_table *fib6_get_table(u32 id) return NULL; } -static void __init fib6_tables_init(void) +static void fib6_tables_init(struct net *net) { - fib6_link_table(fib6_main_tbl); - fib6_link_table(fib6_local_tbl); + fib6_link_table(net, net->ipv6.fib6_main_tbl); + fib6_link_table(net, net->ipv6.fib6_local_tbl); } - #else -struct fib6_table *fib6_new_table(u32 id) +struct fib6_table *fib6_new_table(struct net *net, u32 id) { - return fib6_get_table(id); + return fib6_get_table(net, id); } -struct fib6_table *fib6_get_table(u32 id) +struct fib6_table *fib6_get_table(struct net *net, u32 id) { - return fib6_main_tbl; + return net->ipv6.fib6_main_tbl; } -struct dst_entry *fib6_rule_lookup(struct flowi *fl, int flags, - pol_lookup_t lookup) +struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi *fl, + int flags, pol_lookup_t lookup) { - return (struct dst_entry *) lookup(fib6_main_tbl, fl, flags); + return (struct dst_entry *) lookup(net->ipv6.fib6_main_tbl, fl, flags); } -static void __init fib6_tables_init(void) +static void fib6_tables_init(struct net *net) { - fib6_link_table(fib6_main_tbl); + fib6_link_table(net, net->ipv6.fib6_main_tbl); } #endif @@ -357,11 +353,9 @@ static int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb) struct fib6_walker_t *w; struct fib6_table *tb; struct hlist_node *node; + struct hlist_head *head; int res = 0; - if (net != &init_net) - return 0; - s_h = cb->args[0]; s_e = cb->args[1]; @@ -390,7 +384,8 @@ static int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb) for (h = s_h; h < FIB_TABLE_HASHSZ; h++, s_e = 0) { e = 0; - hlist_for_each_entry(tb, node, &fib_table_hash[h], tb6_hlist) { + head = &net->ipv6.fib_table_hash[h]; + hlist_for_each_entry(tb, node, head, tb6_hlist) { if (e < s_e) goto next; res = fib6_dump_table(tb, skb, cb); @@ -1360,12 +1355,13 @@ void fib6_clean_all(int (*func)(struct rt6_info *, void *arg), { struct fib6_table *table; struct hlist_node *node; + struct hlist_head *head; unsigned int h; rcu_read_lock(); for (h = 0; h < FIB_TABLE_HASHSZ; h++) { - hlist_for_each_entry_rcu(table, node, &fib_table_hash[h], - tb6_hlist) { + head = &init_net.ipv6.fib_table_hash[h]; + hlist_for_each_entry_rcu(table, node, head, tb6_hlist) { write_lock_bh(&table->tb6_lock); fib6_clean_tree(&table->tb6_root, func, prune, arg); write_unlock_bh(&table->tb6_lock); @@ -1466,55 +1462,88 @@ void fib6_run_gc(unsigned long dummy) spin_unlock_bh(&fib6_gc_lock); } -int __init fib6_init(void) +static int fib6_net_init(struct net *net) { - int ret = -ENOMEM; - fib6_node_kmem = kmem_cache_create("fib6_nodes", - sizeof(struct fib6_node), - 0, SLAB_HWCACHE_ALIGN, - NULL); - if (!fib6_node_kmem) - goto out; + int ret; - fib_table_hash = kzalloc(sizeof(*fib_table_hash)*FIB_TABLE_HASHSZ, - GFP_KERNEL); - if (!fib_table_hash) - goto out_kmem_cache_create; + ret = -ENOMEM; + net->ipv6.fib_table_hash = + kzalloc(sizeof(*net->ipv6.fib_table_hash)*FIB_TABLE_HASHSZ, + GFP_KERNEL); + if (!net->ipv6.fib_table_hash) + goto out; - fib6_main_tbl = kzalloc(sizeof(*fib6_main_tbl), GFP_KERNEL); - if (!fib6_main_tbl) + net->ipv6.fib6_main_tbl = kzalloc(sizeof(*net->ipv6.fib6_main_tbl), + GFP_KERNEL); + if (!net->ipv6.fib6_main_tbl) goto out_fib_table_hash; - fib6_main_tbl->tb6_id = RT6_TABLE_MAIN; - fib6_main_tbl->tb6_root.leaf = &ip6_null_entry; - fib6_main_tbl->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO; + net->ipv6.fib6_main_tbl->tb6_id = RT6_TABLE_MAIN; + net->ipv6.fib6_main_tbl->tb6_root.leaf = &ip6_null_entry; + net->ipv6.fib6_main_tbl->tb6_root.fn_flags = + RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO; #ifdef CONFIG_IPV6_MULTIPLE_TABLES - fib6_local_tbl = kzalloc(sizeof(*fib6_local_tbl), GFP_KERNEL); - if (!fib6_local_tbl) + net->ipv6.fib6_local_tbl = kzalloc(sizeof(*net->ipv6.fib6_local_tbl), + GFP_KERNEL); + if (!net->ipv6.fib6_local_tbl) goto out_fib6_main_tbl; - - fib6_local_tbl->tb6_id = RT6_TABLE_LOCAL; - fib6_local_tbl->tb6_root.leaf = &ip6_null_entry; - fib6_local_tbl->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO; + net->ipv6.fib6_local_tbl->tb6_id = RT6_TABLE_LOCAL; + net->ipv6.fib6_local_tbl->tb6_root.leaf = &ip6_null_entry; + net->ipv6.fib6_local_tbl->tb6_root.fn_flags = + RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO; #endif + fib6_tables_init(net); - fib6_tables_init(); - - ret = __rtnl_register(PF_INET6, RTM_GETROUTE, NULL, inet6_dump_fib); - if (ret) - goto out_fib6_local_tbl; + ret = 0; out: return ret; -out_fib6_local_tbl: #ifdef CONFIG_IPV6_MULTIPLE_TABLES - kfree(fib6_local_tbl); out_fib6_main_tbl: + kfree(net->ipv6.fib6_main_tbl); #endif - kfree(fib6_main_tbl); out_fib_table_hash: - kfree(fib_table_hash); + kfree(net->ipv6.fib_table_hash); + goto out; + } + +static void fib6_net_exit(struct net *net) +{ +#ifdef CONFIG_IPV6_MULTIPLE_TABLES + kfree(net->ipv6.fib6_local_tbl); +#endif + kfree(net->ipv6.fib6_main_tbl); + kfree(net->ipv6.fib_table_hash); +} + +static struct pernet_operations fib6_net_ops = { + .init = fib6_net_init, + .exit = fib6_net_exit, +}; + +int __init fib6_init(void) +{ + int ret = -ENOMEM; + fib6_node_kmem = kmem_cache_create("fib6_nodes", + sizeof(struct fib6_node), + 0, SLAB_HWCACHE_ALIGN, + NULL); + if (!fib6_node_kmem) + goto out; + + ret = register_pernet_subsys(&fib6_net_ops); + if (ret) + goto out_kmem_cache_create; + + ret = __rtnl_register(PF_INET6, RTM_GETROUTE, NULL, inet6_dump_fib); + if (ret) + goto out_unregister_subsys; +out: + return ret; + +out_unregister_subsys: + unregister_pernet_subsys(&fib6_net_ops); out_kmem_cache_create: kmem_cache_destroy(fib6_node_kmem); goto out; @@ -1523,10 +1552,6 @@ out_kmem_cache_create: void fib6_gc_cleanup(void) { del_timer(&ip6_fib_timer); -#ifdef CONFIG_IPV6_MULTIPLE_TABLES - kfree(fib6_local_tbl); -#endif - kfree(fib6_main_tbl); - kfree(fib_table_hash); + unregister_pernet_subsys(&fib6_net_ops); kmem_cache_destroy(fib6_node_kmem); } diff --git a/net/ipv6/route.c b/net/ipv6/route.c index cd717450fb10..09206f7ba525 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -571,7 +571,7 @@ struct rt6_info *rt6_lookup(struct in6_addr *daddr, struct in6_addr *saddr, flags |= RT6_LOOKUP_F_HAS_SADDR; } - dst = fib6_rule_lookup(&fl, flags, ip6_pol_route_lookup); + dst = fib6_rule_lookup(&init_net, &fl, flags, ip6_pol_route_lookup); if (dst->error == 0) return (struct rt6_info *) dst; @@ -758,7 +758,7 @@ void ip6_route_input(struct sk_buff *skb) if (rt6_need_strict(&iph->daddr)) flags |= RT6_LOOKUP_F_IFACE; - skb->dst = fib6_rule_lookup(&fl, flags, ip6_pol_route_input); + skb->dst = fib6_rule_lookup(&init_net, &fl, flags, ip6_pol_route_input); } static struct rt6_info *ip6_pol_route_output(struct fib6_table *table, @@ -777,7 +777,7 @@ struct dst_entry * ip6_route_output(struct sock *sk, struct flowi *fl) if (!ipv6_addr_any(&fl->fl6_src)) flags |= RT6_LOOKUP_F_HAS_SADDR; - return fib6_rule_lookup(fl, flags, ip6_pol_route_output); + return fib6_rule_lookup(&init_net, fl, flags, ip6_pol_route_output); } EXPORT_SYMBOL(ip6_route_output); @@ -1069,7 +1069,7 @@ int ip6_route_add(struct fib6_config *cfg) if (cfg->fc_metric == 0) cfg->fc_metric = IP6_RT_PRIO_USER; - table = fib6_new_table(cfg->fc_table); + table = fib6_new_table(&init_net, cfg->fc_table); if (table == NULL) { err = -ENOBUFS; goto out; @@ -1275,7 +1275,7 @@ static int ip6_route_del(struct fib6_config *cfg) struct rt6_info *rt; int err = -ESRCH; - table = fib6_get_table(cfg->fc_table); + table = fib6_get_table(&init_net, cfg->fc_table); if (table == NULL) return err; @@ -1390,7 +1390,9 @@ static struct rt6_info *ip6_route_redirect(struct in6_addr *dest, if (rt6_need_strict(dest)) flags |= RT6_LOOKUP_F_IFACE; - return (struct rt6_info *)fib6_rule_lookup((struct flowi *)&rdfl, flags, __ip6_route_redirect); + return (struct rt6_info *)fib6_rule_lookup(&init_net, + (struct flowi *)&rdfl, + flags, __ip6_route_redirect); } void rt6_redirect(struct in6_addr *dest, struct in6_addr *src, @@ -1589,7 +1591,7 @@ static struct rt6_info *rt6_get_route_info(struct in6_addr *prefix, int prefixle struct rt6_info *rt = NULL; struct fib6_table *table; - table = fib6_get_table(RT6_TABLE_INFO); + table = fib6_get_table(&init_net, RT6_TABLE_INFO); if (table == NULL) return NULL; @@ -1644,7 +1646,7 @@ struct rt6_info *rt6_get_dflt_router(struct in6_addr *addr, struct net_device *d struct rt6_info *rt; struct fib6_table *table; - table = fib6_get_table(RT6_TABLE_DFLT); + table = fib6_get_table(&init_net, RT6_TABLE_DFLT); if (table == NULL) return NULL; @@ -1688,7 +1690,7 @@ void rt6_purge_dflt_routers(void) struct fib6_table *table; /* NOTE: Keep consistent with rt6_get_dflt_router */ - table = fib6_get_table(RT6_TABLE_DFLT); + table = fib6_get_table(&init_net, RT6_TABLE_DFLT); if (table == NULL) return; @@ -1851,7 +1853,7 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, ipv6_addr_copy(&rt->rt6i_dst.addr, addr); rt->rt6i_dst.plen = 128; - rt->rt6i_table = fib6_get_table(RT6_TABLE_LOCAL); + rt->rt6i_table = fib6_get_table(&init_net, RT6_TABLE_LOCAL); atomic_set(&rt->u.dst.__refcnt, 1); -- cgit v1.2.3 From eb5564b8532eec6b49379095df2b979aab85661f Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Mon, 3 Mar 2008 23:32:30 -0800 Subject: [NETNS][IPV6] fib6 rule - dynamic allocation of the rules struct ops The fib6_rules_ops structure is dynamically allocated, so that allows to make several instances of it per network namespace. The global static fib6_rules_ops structure is renamed to fib6_rules_ops_template in order to quickly memcopy it for the structure initialization. Signed-off-by: Daniel Lezcano Signed-off-by: Benjamin Thery Signed-off-by: David S. Miller --- net/ipv6/fib6_rules.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'net/ipv6/fib6_rules.c') diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index 03ad23a5fd3c..60af08f12547 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c @@ -29,7 +29,7 @@ struct fib6_rule u8 tclass; }; -static struct fib_rules_ops fib6_rules_ops; +static struct fib_rules_ops *fib6_rules_ops; struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi *fl, int flags, pol_lookup_t lookup) @@ -38,7 +38,7 @@ struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi *fl, .lookup_ptr = lookup, }; - fib_rules_lookup(&fib6_rules_ops, fl, flags, &arg); + fib_rules_lookup(fib6_rules_ops, fl, flags, &arg); if (arg.rule) fib_rule_put(arg.rule); @@ -234,7 +234,7 @@ static size_t fib6_rule_nlmsg_payload(struct fib_rule *rule) + nla_total_size(16); /* src */ } -static struct fib_rules_ops fib6_rules_ops = { +static struct fib_rules_ops fib6_rules_ops_template = { .family = AF_INET6, .rule_size = sizeof(struct fib6_rule), .addr_size = sizeof(struct in6_addr), @@ -247,7 +247,6 @@ static struct fib_rules_ops fib6_rules_ops = { .nlmsg_payload = fib6_rule_nlmsg_payload, .nlgroup = RTNLGRP_IPV6_RULE, .policy = fib6_rule_policy, - .rules_list = LIST_HEAD_INIT(fib6_rules_ops.rules_list), .owner = THIS_MODULE, .fro_net = &init_net, }; @@ -256,11 +255,18 @@ static int __init fib6_default_rules_init(void) { int err; - err = fib_default_rule_add(&fib6_rules_ops, 0, + fib6_rules_ops = kmemdup(&fib6_rules_ops_template, + sizeof(*fib6_rules_ops), GFP_KERNEL); + if (!fib6_rules_ops) + return -ENOMEM; + + INIT_LIST_HEAD(&fib6_rules_ops->rules_list); + + err = fib_default_rule_add(fib6_rules_ops, 0, RT6_TABLE_LOCAL, FIB_RULE_PERMANENT); if (err < 0) return err; - err = fib_default_rule_add(&fib6_rules_ops, 0x7FFE, RT6_TABLE_MAIN, 0); + err = fib_default_rule_add(fib6_rules_ops, 0x7FFE, RT6_TABLE_MAIN, 0); if (err < 0) return err; return 0; @@ -274,18 +280,20 @@ int __init fib6_rules_init(void) if (ret) goto out; - ret = fib_rules_register(&fib6_rules_ops); + ret = fib_rules_register(fib6_rules_ops); if (ret) goto out_default_rules_init; out: return ret; out_default_rules_init: - fib_rules_cleanup_ops(&fib6_rules_ops); + fib_rules_cleanup_ops(fib6_rules_ops); + kfree(fib6_rules_ops); goto out; } void fib6_rules_cleanup(void) { - fib_rules_unregister(&fib6_rules_ops); + fib_rules_unregister(fib6_rules_ops); + kfree(fib6_rules_ops); } -- cgit v1.2.3 From dcabb819a6eced95ef531b001e663d0d592c8d9f Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Mon, 3 Mar 2008 23:33:08 -0800 Subject: [NETNS][IPV6] fib6_rules - handle several network namespaces The fib6_rules_ops is moved to the network namespace structure. All references are changed to have it relatively to it. Each time a network namespace is created a new fib6_rules_ops is allocated, initialized and stored into the network namespace structure. The common part of the fib rules is namespace aware, so it is quite easy to retrieve the network namespace from the rules and use it in the different callbacks. Signed-off-by: Daniel Lezcano Signed-off-by: Benjamin Thery Signed-off-by: David S. Miller --- include/net/netns/ipv6.h | 1 + net/ipv6/fib6_rules.c | 82 +++++++++++++++++++++++++++--------------------- 2 files changed, 47 insertions(+), 36 deletions(-) (limited to 'net/ipv6/fib6_rules.c') diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h index 5279cd6a00ba..66bf9c0f745b 100644 --- a/include/net/netns/ipv6.h +++ b/include/net/netns/ipv6.h @@ -41,6 +41,7 @@ struct netns_ipv6 { struct fib6_table *fib6_main_tbl; #ifdef CONFIG_IPV6_MULTIPLE_TABLES struct fib6_table *fib6_local_tbl; + struct fib_rules_ops *fib6_rules_ops; #endif struct sock **icmp_sk; }; diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index 60af08f12547..89cb092c9732 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c @@ -29,8 +29,6 @@ struct fib6_rule u8 tclass; }; -static struct fib_rules_ops *fib6_rules_ops; - struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi *fl, int flags, pol_lookup_t lookup) { @@ -38,7 +36,7 @@ struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi *fl, .lookup_ptr = lookup, }; - fib_rules_lookup(fib6_rules_ops, fl, flags, &arg); + fib_rules_lookup(net->ipv6.fib6_rules_ops, fl, flags, &arg); if (arg.rule) fib_rule_put(arg.rule); @@ -71,7 +69,7 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp, goto discard_pkt; } - table = fib6_get_table(&init_net, rule->table); + table = fib6_get_table(rule->fr_net, rule->table); if (table) rt = lookup(table, flp, flags); @@ -145,13 +143,14 @@ static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb, struct nlattr **tb) { int err = -EINVAL; + struct net *net = skb->sk->sk_net; struct fib6_rule *rule6 = (struct fib6_rule *) rule; if (rule->action == FR_ACT_TO_TBL) { if (rule->table == RT6_TABLE_UNSPEC) goto errout; - if (fib6_new_table(&init_net, rule->table) == NULL) { + if (fib6_new_table(net, rule->table) == NULL) { err = -ENOBUFS; goto errout; } @@ -251,49 +250,60 @@ static struct fib_rules_ops fib6_rules_ops_template = { .fro_net = &init_net, }; -static int __init fib6_default_rules_init(void) +static int fib6_rules_net_init(struct net *net) { - int err; + int err = -ENOMEM; - fib6_rules_ops = kmemdup(&fib6_rules_ops_template, - sizeof(*fib6_rules_ops), GFP_KERNEL); - if (!fib6_rules_ops) - return -ENOMEM; + net->ipv6.fib6_rules_ops = kmemdup(&fib6_rules_ops_template, + sizeof(*net->ipv6.fib6_rules_ops), + GFP_KERNEL); + if (!net->ipv6.fib6_rules_ops) + goto out; - INIT_LIST_HEAD(&fib6_rules_ops->rules_list); + net->ipv6.fib6_rules_ops->fro_net = net; + INIT_LIST_HEAD(&net->ipv6.fib6_rules_ops->rules_list); - err = fib_default_rule_add(fib6_rules_ops, 0, + err = fib_default_rule_add(net->ipv6.fib6_rules_ops, 0, RT6_TABLE_LOCAL, FIB_RULE_PERMANENT); - if (err < 0) - return err; - err = fib_default_rule_add(fib6_rules_ops, 0x7FFE, RT6_TABLE_MAIN, 0); - if (err < 0) - return err; - return 0; -} - -int __init fib6_rules_init(void) -{ - int ret; + if (err) + goto out_fib6_rules_ops; - ret = fib6_default_rules_init(); - if (ret) - goto out; + err = fib_default_rule_add(net->ipv6.fib6_rules_ops, + 0x7FFE, RT6_TABLE_MAIN, 0); + if (err) + goto out_fib6_default_rule_add; - ret = fib_rules_register(fib6_rules_ops); - if (ret) - goto out_default_rules_init; + err = fib_rules_register(net->ipv6.fib6_rules_ops); + if (err) + goto out_fib6_default_rule_add; out: - return ret; + return err; -out_default_rules_init: - fib_rules_cleanup_ops(fib6_rules_ops); - kfree(fib6_rules_ops); +out_fib6_default_rule_add: + fib_rules_cleanup_ops(net->ipv6.fib6_rules_ops); +out_fib6_rules_ops: + kfree(net->ipv6.fib6_rules_ops); goto out; } +static void fib6_rules_net_exit(struct net *net) +{ + fib_rules_unregister(net->ipv6.fib6_rules_ops); + kfree(net->ipv6.fib6_rules_ops); +} + +static struct pernet_operations fib6_rules_net_ops = { + .init = fib6_rules_net_init, + .exit = fib6_rules_net_exit, +}; + +int __init fib6_rules_init(void) +{ + return register_pernet_subsys(&fib6_rules_net_ops); +} + + void fib6_rules_cleanup(void) { - fib_rules_unregister(fib6_rules_ops); - kfree(fib6_rules_ops); + return unregister_pernet_subsys(&fib6_rules_net_ops); } -- cgit v1.2.3 From bdb3289f739e94bcae8b51972ae844ec66c2f4df Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Tue, 4 Mar 2008 13:48:10 -0800 Subject: [NETNS][IPV6] rt6_info - make rt6_info accessed as a pointer This patch make mindless changes and prepares the code to use dynamic allocation for rt6_info structure. The code accesses the rt6_info structure as a pointer instead of a global static variable. Signed-off-by: Daniel Lezcano Signed-off-by: Benjamin Thery Signed-off-by: David S. Miller --- include/net/ip6_route.h | 6 ++--- net/ipv6/addrconf.c | 12 ++++----- net/ipv6/fib6_rules.c | 12 ++++----- net/ipv6/ip6_fib.c | 18 ++++++------- net/ipv6/route.c | 70 ++++++++++++++++++++++++++++++++++++++----------- 5 files changed, 78 insertions(+), 40 deletions(-) (limited to 'net/ipv6/fib6_rules.c') diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index 2bcbfb826530..e0caed25bfba 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h @@ -34,11 +34,11 @@ struct route_info { #define RT6_LOOKUP_F_REACHABLE 0x2 #define RT6_LOOKUP_F_HAS_SADDR 0x4 -extern struct rt6_info ip6_null_entry; +extern struct rt6_info *ip6_null_entry; #ifdef CONFIG_IPV6_MULTIPLE_TABLES -extern struct rt6_info ip6_prohibit_entry; -extern struct rt6_info ip6_blk_hole_entry; +extern struct rt6_info *ip6_prohibit_entry; +extern struct rt6_info *ip6_blk_hole_entry; #endif extern void ip6_route_input(struct sk_buff *skb); diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index b37ae421b61b..3192a848a53a 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -4301,13 +4301,13 @@ int __init addrconf_init(void) if (err) goto errlo; - ip6_null_entry.u.dst.dev = init_net.loopback_dev; - ip6_null_entry.rt6i_idev = in6_dev_get(init_net.loopback_dev); + ip6_null_entry->u.dst.dev = init_net.loopback_dev; + ip6_null_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); #ifdef CONFIG_IPV6_MULTIPLE_TABLES - ip6_prohibit_entry.u.dst.dev = init_net.loopback_dev; - ip6_prohibit_entry.rt6i_idev = in6_dev_get(init_net.loopback_dev); - ip6_blk_hole_entry.u.dst.dev = init_net.loopback_dev; - ip6_blk_hole_entry.rt6i_idev = in6_dev_get(init_net.loopback_dev); + ip6_prohibit_entry->u.dst.dev = init_net.loopback_dev; + ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); + ip6_blk_hole_entry->u.dst.dev = init_net.loopback_dev; + ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); #endif register_netdevice_notifier(&ipv6_dev_notf); diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index 89cb092c9732..c00055f232c4 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c @@ -43,8 +43,8 @@ struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi *fl, if (arg.result) return arg.result; - dst_hold(&ip6_null_entry.u.dst); - return &ip6_null_entry.u.dst; + dst_hold(&ip6_null_entry->u.dst); + return &ip6_null_entry->u.dst; } static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp, @@ -58,14 +58,14 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp, case FR_ACT_TO_TBL: break; case FR_ACT_UNREACHABLE: - rt = &ip6_null_entry; + rt = ip6_null_entry; goto discard_pkt; default: case FR_ACT_BLACKHOLE: - rt = &ip6_blk_hole_entry; + rt = ip6_blk_hole_entry; goto discard_pkt; case FR_ACT_PROHIBIT: - rt = &ip6_prohibit_entry; + rt = ip6_prohibit_entry; goto discard_pkt; } @@ -73,7 +73,7 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp, if (table) rt = lookup(table, flp, flags); - if (rt != &ip6_null_entry) { + if (rt != ip6_null_entry) { struct fib6_rule *r = (struct fib6_rule *)rule; /* diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 1c2566e3d392..f028f7a1a446 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -200,7 +200,7 @@ static struct fib6_table *fib6_alloc_table(u32 id) table = kzalloc(sizeof(*table), GFP_ATOMIC); if (table != NULL) { table->tb6_id = id; - table->tb6_root.leaf = &ip6_null_entry; + table->tb6_root.leaf = ip6_null_entry; table->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO; } @@ -717,8 +717,8 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nl_info *info) if (sfn == NULL) goto st_failure; - sfn->leaf = &ip6_null_entry; - atomic_inc(&ip6_null_entry.rt6i_ref); + sfn->leaf = ip6_null_entry; + atomic_inc(&ip6_null_entry->rt6i_ref); sfn->fn_flags = RTN_ROOT; sfn->fn_sernum = fib6_new_sernum(); @@ -777,7 +777,7 @@ out: #if RT6_DEBUG >= 2 if (!pn->leaf) { BUG_TRAP(pn->leaf != NULL); - pn->leaf = &ip6_null_entry; + pn->leaf = ip6_null_entry; } #endif atomic_inc(&pn->leaf->rt6i_ref); @@ -962,7 +962,7 @@ struct fib6_node * fib6_locate(struct fib6_node *root, static struct rt6_info * fib6_find_prefix(struct fib6_node *fn) { if (fn->fn_flags&RTN_ROOT) - return &ip6_null_entry; + return ip6_null_entry; while(fn) { if(fn->left) @@ -1012,7 +1012,7 @@ static struct fib6_node * fib6_repair_tree(struct fib6_node *fn) #if RT6_DEBUG >= 2 if (fn->leaf==NULL) { BUG_TRAP(fn->leaf); - fn->leaf = &ip6_null_entry; + fn->leaf = ip6_null_entry; } #endif atomic_inc(&fn->leaf->rt6i_ref); @@ -1154,7 +1154,7 @@ int fib6_del(struct rt6_info *rt, struct nl_info *info) return -ENOENT; } #endif - if (fn == NULL || rt == &ip6_null_entry) + if (fn == NULL || rt == ip6_null_entry) return -ENOENT; BUG_TRAP(fn->fn_flags&RTN_RTINFO); @@ -1501,7 +1501,7 @@ static int fib6_net_init(struct net *net) goto out_fib_table_hash; net->ipv6.fib6_main_tbl->tb6_id = RT6_TABLE_MAIN; - net->ipv6.fib6_main_tbl->tb6_root.leaf = &ip6_null_entry; + net->ipv6.fib6_main_tbl->tb6_root.leaf = ip6_null_entry; net->ipv6.fib6_main_tbl->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO; @@ -1511,7 +1511,7 @@ static int fib6_net_init(struct net *net) if (!net->ipv6.fib6_local_tbl) goto out_fib6_main_tbl; net->ipv6.fib6_local_tbl->tb6_id = RT6_TABLE_LOCAL; - net->ipv6.fib6_local_tbl->tb6_root.leaf = &ip6_null_entry; + net->ipv6.fib6_local_tbl->tb6_root.leaf = ip6_null_entry; net->ipv6.fib6_local_tbl->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO; #endif diff --git a/net/ipv6/route.c b/net/ipv6/route.c index b3ac4901af86..8f954c1e961f 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -127,7 +127,7 @@ static struct dst_ops ip6_dst_blackhole_ops = { .entries = ATOMIC_INIT(0), }; -struct rt6_info ip6_null_entry = { +static struct rt6_info ip6_null_entry_template = { .u = { .dst = { .__refcnt = ATOMIC_INIT(1), @@ -138,7 +138,6 @@ struct rt6_info ip6_null_entry = { .input = ip6_pkt_discard, .output = ip6_pkt_discard_out, .ops = &ip6_dst_ops, - .path = (struct dst_entry*)&ip6_null_entry, } }, .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP), @@ -146,12 +145,14 @@ struct rt6_info ip6_null_entry = { .rt6i_ref = ATOMIC_INIT(1), }; +struct rt6_info *ip6_null_entry; + #ifdef CONFIG_IPV6_MULTIPLE_TABLES static int ip6_pkt_prohibit(struct sk_buff *skb); static int ip6_pkt_prohibit_out(struct sk_buff *skb); -struct rt6_info ip6_prohibit_entry = { +struct rt6_info ip6_prohibit_entry_template = { .u = { .dst = { .__refcnt = ATOMIC_INIT(1), @@ -162,7 +163,6 @@ struct rt6_info ip6_prohibit_entry = { .input = ip6_pkt_prohibit, .output = ip6_pkt_prohibit_out, .ops = &ip6_dst_ops, - .path = (struct dst_entry*)&ip6_prohibit_entry, } }, .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP), @@ -170,7 +170,9 @@ struct rt6_info ip6_prohibit_entry = { .rt6i_ref = ATOMIC_INIT(1), }; -struct rt6_info ip6_blk_hole_entry = { +struct rt6_info *ip6_prohibit_entry; + +static struct rt6_info ip6_blk_hole_entry_template = { .u = { .dst = { .__refcnt = ATOMIC_INIT(1), @@ -181,7 +183,6 @@ struct rt6_info ip6_blk_hole_entry = { .input = dst_discard, .output = dst_discard, .ops = &ip6_dst_ops, - .path = (struct dst_entry*)&ip6_blk_hole_entry, } }, .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP), @@ -189,6 +190,8 @@ struct rt6_info ip6_blk_hole_entry = { .rt6i_ref = ATOMIC_INIT(1), }; +struct rt6_info *ip6_blk_hole_entry; + #endif /* allocate dst with ip6_dst_ops */ @@ -271,7 +274,7 @@ static __inline__ struct rt6_info *rt6_device_match(struct rt6_info *rt, return local; if (strict) - return &ip6_null_entry; + return ip6_null_entry; } return rt; } @@ -437,7 +440,7 @@ static struct rt6_info *rt6_select(struct fib6_node *fn, int oif, int strict) RT6_TRACE("%s() => %p\n", __FUNCTION__, match); - return (match ? match : &ip6_null_entry); + return (match ? match : ip6_null_entry); } #ifdef CONFIG_IPV6_ROUTE_INFO @@ -522,7 +525,7 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len, #define BACKTRACK(saddr) \ do { \ - if (rt == &ip6_null_entry) { \ + if (rt == ip6_null_entry) { \ struct fib6_node *pn; \ while (1) { \ if (fn->fn_flags & RTN_TL_ROOT) \ @@ -686,7 +689,7 @@ restart_2: restart: rt = rt6_select(fn, oif, strict | reachable); BACKTRACK(&fl->fl6_src); - if (rt == &ip6_null_entry || + if (rt == ip6_null_entry || rt->rt6i_flags & RTF_CACHE) goto out; @@ -704,7 +707,7 @@ restart: } dst_release(&rt->u.dst); - rt = nrt ? : &ip6_null_entry; + rt = nrt ? : ip6_null_entry; dst_hold(&rt->u.dst); if (nrt) { @@ -1257,7 +1260,7 @@ static int __ip6_del_rt(struct rt6_info *rt, struct nl_info *info) int err; struct fib6_table *table; - if (rt == &ip6_null_entry) + if (rt == ip6_null_entry) return -ENOENT; table = rt->rt6i_table; @@ -1369,7 +1372,7 @@ restart: } if (!rt) - rt = &ip6_null_entry; + rt = ip6_null_entry; BACKTRACK(&fl->fl6_src); out: dst_hold(&rt->u.dst); @@ -1415,7 +1418,7 @@ void rt6_redirect(struct in6_addr *dest, struct in6_addr *src, rt = ip6_route_redirect(dest, src, saddr, neigh->dev); - if (rt == &ip6_null_entry) { + if (rt == ip6_null_entry) { if (net_ratelimit()) printk(KERN_DEBUG "rt6_redirect: source isn't a valid nexthop " "for redirect target\n"); @@ -1886,7 +1889,7 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, static int fib6_ifdown(struct rt6_info *rt, void *arg) { if (((void*)rt->rt6i_dev == arg || arg == NULL) && - rt != &ip6_null_entry) { + rt != ip6_null_entry) { RT6_TRACE("deleted by ifdown %p\n", rt); return -1; } @@ -2565,9 +2568,30 @@ int __init ip6_route_init(void) ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops.kmem_cachep; + ret = -ENOMEM; + ip6_null_entry = kmemdup(&ip6_null_entry_template, + sizeof(*ip6_null_entry), GFP_KERNEL); + if (!ip6_null_entry) + goto out_kmem_cache; + ip6_null_entry->u.dst.path = (struct dst_entry *)ip6_null_entry; + +#ifdef CONFIG_IPV6_MULTIPLE_TABLES + ip6_prohibit_entry = kmemdup(&ip6_prohibit_entry_template, + sizeof(*ip6_prohibit_entry), GFP_KERNEL); + if (!ip6_prohibit_entry) + goto out_ip6_null_entry; + ip6_prohibit_entry->u.dst.path = (struct dst_entry *)ip6_prohibit_entry; + + ip6_blk_hole_entry = kmemdup(&ip6_blk_hole_entry_template, + sizeof(*ip6_blk_hole_entry), GFP_KERNEL); + if (!ip6_blk_hole_entry) + goto out_ip6_prohibit_entry; + ip6_blk_hole_entry->u.dst.path = (struct dst_entry *)ip6_blk_hole_entry; +#endif + ret = fib6_init(); if (ret) - goto out_kmem_cache; + goto out_ip6_blk_hole_entry; ret = xfrm6_init(); if (ret) @@ -2595,6 +2619,14 @@ xfrm6_init: xfrm6_fini(); out_fib6_init: fib6_gc_cleanup(); +out_ip6_blk_hole_entry: +#ifdef CONFIG_IPV6_MULTIPLE_TABLES + kfree(ip6_blk_hole_entry); +out_ip6_prohibit_entry: + kfree(ip6_prohibit_entry); +out_ip6_null_entry: +#endif + kfree(ip6_null_entry); out_kmem_cache: kmem_cache_destroy(ip6_dst_ops.kmem_cachep); goto out; @@ -2607,4 +2639,10 @@ void ip6_route_cleanup(void) xfrm6_fini(); fib6_gc_cleanup(); kmem_cache_destroy(ip6_dst_ops.kmem_cachep); + + kfree(ip6_null_entry); +#ifdef CONFIG_IPV6_MULTIPLE_TABLES + kfree(ip6_prohibit_entry); + kfree(ip6_blk_hole_entry); +#endif } -- cgit v1.2.3 From 8ed677896752fff056f6cf3d7ce462adc6c464f0 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Tue, 4 Mar 2008 13:48:30 -0800 Subject: [NETNS][IPV6] rt6_info - move rt6_info structure inside the namespace The rt6_info structures are moved inside the network namespace structure. All references to these structures are now relative to the initial network namespace. Signed-off-by: Daniel Lezcano Signed-off-by: Benjamin Thery Signed-off-by: David S. Miller --- include/net/ip6_fib.h | 3 +- include/net/netns/ipv6.h | 3 + net/ipv6/addrconf.c | 9 --- net/ipv6/fib6_rules.c | 17 ++-- net/ipv6/ip6_fib.c | 45 ++++++----- net/ipv6/route.c | 202 +++++++++++++++++++++++++++++++---------------- 6 files changed, 171 insertions(+), 108 deletions(-) (limited to 'net/ipv6/fib6_rules.c') diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h index fae267f65341..7c5c0f79168a 100644 --- a/include/net/ip6_fib.h +++ b/include/net/ip6_fib.h @@ -174,7 +174,8 @@ struct fib6_table { #define RT6_TABLE_LOCAL RT6_TABLE_MAIN #endif -typedef struct rt6_info *(*pol_lookup_t)(struct fib6_table *, +typedef struct rt6_info *(*pol_lookup_t)(struct net *, + struct fib6_table *, struct flowi *, int); /* diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h index c6c9afff13ef..311a942f36e9 100644 --- a/include/net/netns/ipv6.h +++ b/include/net/netns/ipv6.h @@ -36,11 +36,14 @@ struct netns_ipv6 { struct xt_table *ip6table_mangle; struct xt_table *ip6table_raw; #endif + struct rt6_info *ip6_null_entry; struct rt6_statistics *rt6_stats; struct timer_list *ip6_fib_timer; struct hlist_head *fib_table_hash; struct fib6_table *fib6_main_tbl; #ifdef CONFIG_IPV6_MULTIPLE_TABLES + struct rt6_info *ip6_prohibit_entry; + struct rt6_info *ip6_blk_hole_entry; struct fib6_table *fib6_local_tbl; struct fib_rules_ops *fib6_rules_ops; #endif diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 3192a848a53a..17b06d220e95 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -4301,15 +4301,6 @@ int __init addrconf_init(void) if (err) goto errlo; - ip6_null_entry->u.dst.dev = init_net.loopback_dev; - ip6_null_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); -#ifdef CONFIG_IPV6_MULTIPLE_TABLES - ip6_prohibit_entry->u.dst.dev = init_net.loopback_dev; - ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); - ip6_blk_hole_entry->u.dst.dev = init_net.loopback_dev; - ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); -#endif - register_netdevice_notifier(&ipv6_dev_notf); addrconf_verify(0); diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index c00055f232c4..55137408f054 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c @@ -43,8 +43,8 @@ struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi *fl, if (arg.result) return arg.result; - dst_hold(&ip6_null_entry->u.dst); - return &ip6_null_entry->u.dst; + dst_hold(&net->ipv6.ip6_null_entry->u.dst); + return &net->ipv6.ip6_null_entry->u.dst; } static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp, @@ -52,28 +52,29 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp, { struct rt6_info *rt = NULL; struct fib6_table *table; + struct net *net = rule->fr_net; pol_lookup_t lookup = arg->lookup_ptr; switch (rule->action) { case FR_ACT_TO_TBL: break; case FR_ACT_UNREACHABLE: - rt = ip6_null_entry; + rt = net->ipv6.ip6_null_entry; goto discard_pkt; default: case FR_ACT_BLACKHOLE: - rt = ip6_blk_hole_entry; + rt = net->ipv6.ip6_blk_hole_entry; goto discard_pkt; case FR_ACT_PROHIBIT: - rt = ip6_prohibit_entry; + rt = net->ipv6.ip6_prohibit_entry; goto discard_pkt; } - table = fib6_get_table(rule->fr_net, rule->table); + table = fib6_get_table(net, rule->table); if (table) - rt = lookup(table, flp, flags); + rt = lookup(net, table, flp, flags); - if (rt != ip6_null_entry) { + if (rt != net->ipv6.ip6_null_entry) { struct fib6_rule *r = (struct fib6_rule *)rule; /* diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index f028f7a1a446..b0814b0082e7 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -79,8 +79,8 @@ static DEFINE_RWLOCK(fib6_walker_lock); static void fib6_prune_clones(struct net *net, struct fib6_node *fn, struct rt6_info *rt); -static struct rt6_info * fib6_find_prefix(struct fib6_node *fn); -static struct fib6_node * fib6_repair_tree(struct fib6_node *fn); +static struct rt6_info *fib6_find_prefix(struct net *net, struct fib6_node *fn); +static struct fib6_node *fib6_repair_tree(struct net *net, struct fib6_node *fn); static int fib6_walk(struct fib6_walker_t *w); static int fib6_walk_continue(struct fib6_walker_t *w); @@ -193,14 +193,14 @@ static void fib6_link_table(struct net *net, struct fib6_table *tb) #ifdef CONFIG_IPV6_MULTIPLE_TABLES -static struct fib6_table *fib6_alloc_table(u32 id) +static struct fib6_table *fib6_alloc_table(struct net *net, u32 id) { struct fib6_table *table; table = kzalloc(sizeof(*table), GFP_ATOMIC); if (table != NULL) { table->tb6_id = id; - table->tb6_root.leaf = ip6_null_entry; + table->tb6_root.leaf = net->ipv6.ip6_null_entry; table->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO; } @@ -217,7 +217,7 @@ struct fib6_table *fib6_new_table(struct net *net, u32 id) if (tb) return tb; - tb = fib6_alloc_table(id); + tb = fib6_alloc_table(net, id); if (tb != NULL) fib6_link_table(net, tb); @@ -267,7 +267,7 @@ struct fib6_table *fib6_get_table(struct net *net, u32 id) struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi *fl, int flags, pol_lookup_t lookup) { - return (struct dst_entry *) lookup(net->ipv6.fib6_main_tbl, fl, flags); + return (struct dst_entry *) lookup(net, net->ipv6.fib6_main_tbl, fl, flags); } static void fib6_tables_init(struct net *net) @@ -717,8 +717,8 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nl_info *info) if (sfn == NULL) goto st_failure; - sfn->leaf = ip6_null_entry; - atomic_inc(&ip6_null_entry->rt6i_ref); + sfn->leaf = info->nl_net->ipv6.ip6_null_entry; + atomic_inc(&info->nl_net->ipv6.ip6_null_entry->rt6i_ref); sfn->fn_flags = RTN_ROOT; sfn->fn_sernum = fib6_new_sernum(); @@ -773,11 +773,11 @@ out: * super-tree leaf node we have to find a new one for it. */ if (pn != fn && !pn->leaf && !(pn->fn_flags & RTN_RTINFO)) { - pn->leaf = fib6_find_prefix(pn); + pn->leaf = fib6_find_prefix(info->nl_net, pn); #if RT6_DEBUG >= 2 if (!pn->leaf) { BUG_TRAP(pn->leaf != NULL); - pn->leaf = ip6_null_entry; + pn->leaf = info->nl_net->ipv6.ip6_null_entry; } #endif atomic_inc(&pn->leaf->rt6i_ref); @@ -793,7 +793,7 @@ out: */ st_failure: if (fn && !(fn->fn_flags & (RTN_RTINFO|RTN_ROOT))) - fib6_repair_tree(fn); + fib6_repair_tree(info->nl_net, fn); dst_free(&rt->u.dst); return err; #endif @@ -959,10 +959,10 @@ struct fib6_node * fib6_locate(struct fib6_node *root, * */ -static struct rt6_info * fib6_find_prefix(struct fib6_node *fn) +static struct rt6_info *fib6_find_prefix(struct net *net, struct fib6_node *fn) { if (fn->fn_flags&RTN_ROOT) - return ip6_null_entry; + return net->ipv6.ip6_null_entry; while(fn) { if(fn->left) @@ -981,7 +981,8 @@ static struct rt6_info * fib6_find_prefix(struct fib6_node *fn) * is the node we want to try and remove. */ -static struct fib6_node * fib6_repair_tree(struct fib6_node *fn) +static struct fib6_node *fib6_repair_tree(struct net *net, + struct fib6_node *fn) { int children; int nstate; @@ -1008,11 +1009,11 @@ static struct fib6_node * fib6_repair_tree(struct fib6_node *fn) || (children && fn->fn_flags&RTN_ROOT) #endif ) { - fn->leaf = fib6_find_prefix(fn); + fn->leaf = fib6_find_prefix(net, fn); #if RT6_DEBUG >= 2 if (fn->leaf==NULL) { BUG_TRAP(fn->leaf); - fn->leaf = ip6_null_entry; + fn->leaf = net->ipv6.ip6_null_entry; } #endif atomic_inc(&fn->leaf->rt6i_ref); @@ -1117,7 +1118,7 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp, if (fn->leaf == NULL) { fn->fn_flags &= ~RTN_RTINFO; net->ipv6.rt6_stats->fib_route_nodes--; - fn = fib6_repair_tree(fn); + fn = fib6_repair_tree(net, fn); } if (atomic_read(&rt->rt6i_ref) != 1) { @@ -1129,7 +1130,7 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp, */ while (fn) { if (!(fn->fn_flags&RTN_RTINFO) && fn->leaf == rt) { - fn->leaf = fib6_find_prefix(fn); + fn->leaf = fib6_find_prefix(net, fn); atomic_inc(&fn->leaf->rt6i_ref); rt6_release(rt); } @@ -1145,6 +1146,7 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp, int fib6_del(struct rt6_info *rt, struct nl_info *info) { + struct net *net = info->nl_net; struct fib6_node *fn = rt->rt6i_node; struct rt6_info **rtp; @@ -1154,7 +1156,7 @@ int fib6_del(struct rt6_info *rt, struct nl_info *info) return -ENOENT; } #endif - if (fn == NULL || rt == ip6_null_entry) + if (fn == NULL || rt == net->ipv6.ip6_null_entry) return -ENOENT; BUG_TRAP(fn->fn_flags&RTN_RTINFO); @@ -1501,7 +1503,7 @@ static int fib6_net_init(struct net *net) goto out_fib_table_hash; net->ipv6.fib6_main_tbl->tb6_id = RT6_TABLE_MAIN; - net->ipv6.fib6_main_tbl->tb6_root.leaf = ip6_null_entry; + net->ipv6.fib6_main_tbl->tb6_root.leaf = net->ipv6.ip6_null_entry; net->ipv6.fib6_main_tbl->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO; @@ -1511,7 +1513,7 @@ static int fib6_net_init(struct net *net) if (!net->ipv6.fib6_local_tbl) goto out_fib6_main_tbl; net->ipv6.fib6_local_tbl->tb6_id = RT6_TABLE_LOCAL; - net->ipv6.fib6_local_tbl->tb6_root.leaf = ip6_null_entry; + net->ipv6.fib6_local_tbl->tb6_root.leaf = net->ipv6.ip6_null_entry; net->ipv6.fib6_local_tbl->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO; #endif @@ -1536,6 +1538,7 @@ out_timer: static void fib6_net_exit(struct net *net) { + rt6_ifdown(net, NULL); del_timer(net->ipv6.ip6_fib_timer); kfree(net->ipv6.ip6_fib_timer); #ifdef CONFIG_IPV6_MULTIPLE_TABLES diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 8f954c1e961f..7ff66cebe77c 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -145,8 +145,6 @@ static struct rt6_info ip6_null_entry_template = { .rt6i_ref = ATOMIC_INIT(1), }; -struct rt6_info *ip6_null_entry; - #ifdef CONFIG_IPV6_MULTIPLE_TABLES static int ip6_pkt_prohibit(struct sk_buff *skb); @@ -170,8 +168,6 @@ struct rt6_info ip6_prohibit_entry_template = { .rt6i_ref = ATOMIC_INIT(1), }; -struct rt6_info *ip6_prohibit_entry; - static struct rt6_info ip6_blk_hole_entry_template = { .u = { .dst = { @@ -190,8 +186,6 @@ static struct rt6_info ip6_blk_hole_entry_template = { .rt6i_ref = ATOMIC_INIT(1), }; -struct rt6_info *ip6_blk_hole_entry; - #endif /* allocate dst with ip6_dst_ops */ @@ -245,7 +239,8 @@ static inline int rt6_need_strict(struct in6_addr *daddr) * Route lookup. Any table->tb6_lock is implied. */ -static __inline__ struct rt6_info *rt6_device_match(struct rt6_info *rt, +static inline struct rt6_info *rt6_device_match(struct net *net, + struct rt6_info *rt, int oif, int strict) { @@ -274,7 +269,7 @@ static __inline__ struct rt6_info *rt6_device_match(struct rt6_info *rt, return local; if (strict) - return ip6_null_entry; + return net->ipv6.ip6_null_entry; } return rt; } @@ -415,6 +410,7 @@ static struct rt6_info *find_rr_leaf(struct fib6_node *fn, static struct rt6_info *rt6_select(struct fib6_node *fn, int oif, int strict) { struct rt6_info *match, *rt0; + struct net *net; RT6_TRACE("%s(fn->leaf=%p, oif=%d)\n", __FUNCTION__, fn->leaf, oif); @@ -440,7 +436,8 @@ static struct rt6_info *rt6_select(struct fib6_node *fn, int oif, int strict) RT6_TRACE("%s() => %p\n", __FUNCTION__, match); - return (match ? match : ip6_null_entry); + net = rt0->rt6i_dev->nd_net; + return (match ? match : net->ipv6.ip6_null_entry); } #ifdef CONFIG_IPV6_ROUTE_INFO @@ -523,9 +520,9 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len, } #endif -#define BACKTRACK(saddr) \ +#define BACKTRACK(__net, saddr) \ do { \ - if (rt == ip6_null_entry) { \ + if (rt == __net->ipv6.ip6_null_entry) { \ struct fib6_node *pn; \ while (1) { \ if (fn->fn_flags & RTN_TL_ROOT) \ @@ -541,7 +538,8 @@ do { \ } \ } while(0) -static struct rt6_info *ip6_pol_route_lookup(struct fib6_table *table, +static struct rt6_info *ip6_pol_route_lookup(struct net *net, + struct fib6_table *table, struct flowi *fl, int flags) { struct fib6_node *fn; @@ -551,8 +549,8 @@ static struct rt6_info *ip6_pol_route_lookup(struct fib6_table *table, fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src); restart: rt = fn->leaf; - rt = rt6_device_match(rt, fl->oif, flags); - BACKTRACK(&fl->fl6_src); + rt = rt6_device_match(net, rt, fl->oif, flags); + BACKTRACK(net, &fl->fl6_src); out: dst_use(&rt->u.dst, jiffies); read_unlock_bh(&table->tb6_lock); @@ -668,8 +666,8 @@ static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort, struct in6_addr *d return rt; } -static struct rt6_info *ip6_pol_route(struct fib6_table *table, int oif, - struct flowi *fl, int flags) +static struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table, int oif, + struct flowi *fl, int flags) { struct fib6_node *fn; struct rt6_info *rt, *nrt; @@ -688,8 +686,9 @@ restart_2: restart: rt = rt6_select(fn, oif, strict | reachable); - BACKTRACK(&fl->fl6_src); - if (rt == ip6_null_entry || + + BACKTRACK(net, &fl->fl6_src); + if (rt == net->ipv6.ip6_null_entry || rt->rt6i_flags & RTF_CACHE) goto out; @@ -707,7 +706,7 @@ restart: } dst_release(&rt->u.dst); - rt = nrt ? : ip6_null_entry; + rt = nrt ? : net->ipv6.ip6_null_entry; dst_hold(&rt->u.dst); if (nrt) { @@ -740,10 +739,10 @@ out2: return rt; } -static struct rt6_info *ip6_pol_route_input(struct fib6_table *table, +static struct rt6_info *ip6_pol_route_input(struct net *net, struct fib6_table *table, struct flowi *fl, int flags) { - return ip6_pol_route(table, fl->iif, fl, flags); + return ip6_pol_route(net, table, fl->iif, fl, flags); } void ip6_route_input(struct sk_buff *skb) @@ -770,10 +769,10 @@ void ip6_route_input(struct sk_buff *skb) skb->dst = fib6_rule_lookup(net, &fl, flags, ip6_pol_route_input); } -static struct rt6_info *ip6_pol_route_output(struct fib6_table *table, +static struct rt6_info *ip6_pol_route_output(struct net *net, struct fib6_table *table, struct flowi *fl, int flags) { - return ip6_pol_route(table, fl->oif, fl, flags); + return ip6_pol_route(net, table, fl->oif, fl, flags); } struct dst_entry * ip6_route_output(struct sock *sk, struct flowi *fl) @@ -1259,8 +1258,9 @@ static int __ip6_del_rt(struct rt6_info *rt, struct nl_info *info) { int err; struct fib6_table *table; + struct net *net = rt->rt6i_dev->nd_net; - if (rt == ip6_null_entry) + if (rt == net->ipv6.ip6_null_entry) return -ENOENT; table = rt->rt6i_table; @@ -1329,7 +1329,8 @@ struct ip6rd_flowi { struct in6_addr gateway; }; -static struct rt6_info *__ip6_route_redirect(struct fib6_table *table, +static struct rt6_info *__ip6_route_redirect(struct net *net, + struct fib6_table *table, struct flowi *fl, int flags) { @@ -1372,8 +1373,8 @@ restart: } if (!rt) - rt = ip6_null_entry; - BACKTRACK(&fl->fl6_src); + rt = net->ipv6.ip6_null_entry; + BACKTRACK(net, &fl->fl6_src); out: dst_hold(&rt->u.dst); @@ -1415,10 +1416,11 @@ void rt6_redirect(struct in6_addr *dest, struct in6_addr *src, { struct rt6_info *rt, *nrt = NULL; struct netevent_redirect netevent; + struct net *net = neigh->dev->nd_net; rt = ip6_route_redirect(dest, src, saddr, neigh->dev); - if (rt == ip6_null_entry) { + if (rt == net->ipv6.ip6_null_entry) { if (net_ratelimit()) printk(KERN_DEBUG "rt6_redirect: source isn't a valid nexthop " "for redirect target\n"); @@ -1886,10 +1888,18 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, return rt; } +struct arg_dev_net { + struct net_device *dev; + struct net *net; +}; + static int fib6_ifdown(struct rt6_info *rt, void *arg) { - if (((void*)rt->rt6i_dev == arg || arg == NULL) && - rt != ip6_null_entry) { + struct net_device *dev = ((struct arg_dev_net *)arg)->dev; + struct net *net = ((struct arg_dev_net *)arg)->net; + + if (((void *)rt->rt6i_dev == dev || dev == NULL) && + rt != net->ipv6.ip6_null_entry) { RT6_TRACE("deleted by ifdown %p\n", rt); return -1; } @@ -1898,7 +1908,12 @@ static int fib6_ifdown(struct rt6_info *rt, void *arg) void rt6_ifdown(struct net *net, struct net_device *dev) { - fib6_clean_all(net, fib6_ifdown, 0, dev); + struct arg_dev_net adn = { + .dev = dev, + .net = net, + }; + + fib6_clean_all(net, fib6_ifdown, 0, &adn); } struct rt6_mtu_change_arg @@ -2289,6 +2304,26 @@ errout: rtnl_set_sk_err(net, RTNLGRP_IPV6_ROUTE, err); } +static int ip6_route_dev_notify(struct notifier_block *this, + unsigned long event, void *data) +{ + struct net_device *dev = (struct net_device *)data; + struct net *net = dev->nd_net; + + if (event == NETDEV_REGISTER && (dev->flags & IFF_LOOPBACK)) { + net->ipv6.ip6_null_entry->u.dst.dev = dev; + net->ipv6.ip6_null_entry->rt6i_idev = in6_dev_get(dev); +#ifdef CONFIG_IPV6_MULTIPLE_TABLES + net->ipv6.ip6_prohibit_entry->u.dst.dev = dev; + net->ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(dev); + net->ipv6.ip6_blk_hole_entry->u.dst.dev = dev; + net->ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(dev); +#endif + } + + return NOTIFY_OK; +} + /* * /proc */ @@ -2535,11 +2570,47 @@ struct ctl_table *ipv6_route_sysctl_init(struct net *net) static int ip6_route_net_init(struct net *net) { + int ret = 0; + + ret = -ENOMEM; + net->ipv6.ip6_null_entry = kmemdup(&ip6_null_entry_template, + sizeof(*net->ipv6.ip6_null_entry), + GFP_KERNEL); + if (!net->ipv6.ip6_null_entry) + goto out; + net->ipv6.ip6_null_entry->u.dst.path = + (struct dst_entry *)net->ipv6.ip6_null_entry; + +#ifdef CONFIG_IPV6_MULTIPLE_TABLES + net->ipv6.ip6_prohibit_entry = kmemdup(&ip6_prohibit_entry_template, + sizeof(*net->ipv6.ip6_prohibit_entry), + GFP_KERNEL); + if (!net->ipv6.ip6_prohibit_entry) { + kfree(net->ipv6.ip6_null_entry); + goto out; + } + net->ipv6.ip6_prohibit_entry->u.dst.path = + (struct dst_entry *)net->ipv6.ip6_prohibit_entry; + + net->ipv6.ip6_blk_hole_entry = kmemdup(&ip6_blk_hole_entry_template, + sizeof(*net->ipv6.ip6_blk_hole_entry), + GFP_KERNEL); + if (!net->ipv6.ip6_blk_hole_entry) { + kfree(net->ipv6.ip6_null_entry); + kfree(net->ipv6.ip6_prohibit_entry); + goto out; + } + net->ipv6.ip6_blk_hole_entry->u.dst.path = + (struct dst_entry *)net->ipv6.ip6_blk_hole_entry; +#endif + #ifdef CONFIG_PROC_FS proc_net_fops_create(net, "ipv6_route", 0, &ipv6_route_proc_fops); proc_net_fops_create(net, "rt6_stats", S_IRUGO, &rt6_stats_seq_fops); #endif - return 0; + ret = 0; +out: + return ret; } static void ip6_route_net_exit(struct net *net) @@ -2548,7 +2619,11 @@ static void ip6_route_net_exit(struct net *net) proc_net_remove(net, "ipv6_route"); proc_net_remove(net, "rt6_stats"); #endif - rt6_ifdown(net, NULL); + kfree(net->ipv6.ip6_null_entry); +#ifdef CONFIG_IPV6_MULTIPLE_TABLES + kfree(net->ipv6.ip6_prohibit_entry); + kfree(net->ipv6.ip6_blk_hole_entry); +#endif } static struct pernet_operations ip6_route_net_ops = { @@ -2556,6 +2631,11 @@ static struct pernet_operations ip6_route_net_ops = { .exit = ip6_route_net_exit, }; +static struct notifier_block ip6_route_dev_notifier = { + .notifier_call = ip6_route_dev_notify, + .priority = 0, +}; + int __init ip6_route_init(void) { int ret; @@ -2568,30 +2648,24 @@ int __init ip6_route_init(void) ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops.kmem_cachep; - ret = -ENOMEM; - ip6_null_entry = kmemdup(&ip6_null_entry_template, - sizeof(*ip6_null_entry), GFP_KERNEL); - if (!ip6_null_entry) + ret = register_pernet_subsys(&ip6_route_net_ops); + if (ret) goto out_kmem_cache; - ip6_null_entry->u.dst.path = (struct dst_entry *)ip6_null_entry; - -#ifdef CONFIG_IPV6_MULTIPLE_TABLES - ip6_prohibit_entry = kmemdup(&ip6_prohibit_entry_template, - sizeof(*ip6_prohibit_entry), GFP_KERNEL); - if (!ip6_prohibit_entry) - goto out_ip6_null_entry; - ip6_prohibit_entry->u.dst.path = (struct dst_entry *)ip6_prohibit_entry; - - ip6_blk_hole_entry = kmemdup(&ip6_blk_hole_entry_template, - sizeof(*ip6_blk_hole_entry), GFP_KERNEL); - if (!ip6_blk_hole_entry) - goto out_ip6_prohibit_entry; - ip6_blk_hole_entry->u.dst.path = (struct dst_entry *)ip6_blk_hole_entry; -#endif + /* Registering of the loopback is done before this portion of code, + * the loopback reference in rt6_info will not be taken, do it + * manually for init_net */ + init_net.ipv6.ip6_null_entry->u.dst.dev = init_net.loopback_dev; + init_net.ipv6.ip6_null_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); + #ifdef CONFIG_IPV6_MULTIPLE_TABLES + init_net.ipv6.ip6_prohibit_entry->u.dst.dev = init_net.loopback_dev; + init_net.ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); + init_net.ipv6.ip6_blk_hole_entry->u.dst.dev = init_net.loopback_dev; + init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); + #endif ret = fib6_init(); if (ret) - goto out_ip6_blk_hole_entry; + goto out_register_subsys; ret = xfrm6_init(); if (ret) @@ -2607,9 +2681,10 @@ int __init ip6_route_init(void) __rtnl_register(PF_INET6, RTM_GETROUTE, inet6_rtm_getroute, NULL)) goto fib6_rules_init; - ret = register_pernet_subsys(&ip6_route_net_ops); + ret = register_netdevice_notifier(&ip6_route_dev_notifier); if (ret) goto fib6_rules_init; + out: return ret; @@ -2619,14 +2694,8 @@ xfrm6_init: xfrm6_fini(); out_fib6_init: fib6_gc_cleanup(); -out_ip6_blk_hole_entry: -#ifdef CONFIG_IPV6_MULTIPLE_TABLES - kfree(ip6_blk_hole_entry); -out_ip6_prohibit_entry: - kfree(ip6_prohibit_entry); -out_ip6_null_entry: -#endif - kfree(ip6_null_entry); +out_register_subsys: + unregister_pernet_subsys(&ip6_route_net_ops); out_kmem_cache: kmem_cache_destroy(ip6_dst_ops.kmem_cachep); goto out; @@ -2634,15 +2703,10 @@ out_kmem_cache: void ip6_route_cleanup(void) { - unregister_pernet_subsys(&ip6_route_net_ops); + unregister_netdevice_notifier(&ip6_route_dev_notifier); fib6_rules_cleanup(); xfrm6_fini(); fib6_gc_cleanup(); + unregister_pernet_subsys(&ip6_route_net_ops); kmem_cache_destroy(ip6_dst_ops.kmem_cachep); - - kfree(ip6_null_entry); -#ifdef CONFIG_IPV6_MULTIPLE_TABLES - kfree(ip6_prohibit_entry); - kfree(ip6_blk_hole_entry); -#endif } -- cgit v1.2.3 From 7cbca67c073263c179f605bdbbdc565ab29d801d Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Tue, 25 Mar 2008 09:37:42 +0900 Subject: [IPV6]: Support Source Address Selection API (RFC5014). Signed-off-by: YOSHIFUJI Hideaki --- include/linux/in6.h | 11 +++++++ include/linux/ipv6.h | 6 +++- include/net/addrconf.h | 1 + include/net/ip6_route.h | 9 ++++-- net/ipv6/addrconf.c | 17 +++++++++-- net/ipv6/fib6_rules.c | 12 +++++++- net/ipv6/ip6_output.c | 4 ++- net/ipv6/ipv6_sockglue.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++ net/ipv6/ndisc.c | 4 ++- net/ipv6/route.c | 11 ++++++- net/ipv6/xfrm6_policy.c | 2 +- net/sctp/ipv6.c | 4 ++- 12 files changed, 146 insertions(+), 13 deletions(-) (limited to 'net/ipv6/fib6_rules.c') diff --git a/include/linux/in6.h b/include/linux/in6.h index 2a61c82af115..f674000c6c99 100644 --- a/include/linux/in6.h +++ b/include/linux/in6.h @@ -249,4 +249,15 @@ struct in6_flowlabel_req * IP6T_SO_GET_REVISION_TARGET 69 */ +/* RFC5014: Source address selection */ +#define IPV6_ADDR_PREFERENCES 72 + +#define IPV6_PREFER_SRC_TMP 0x0001 +#define IPV6_PREFER_SRC_PUBLIC 0x0002 +#define IPV6_PREFER_SRC_PUBTMP_DEFAULT 0x0100 +#define IPV6_PREFER_SRC_COA 0x0004 +#define IPV6_PREFER_SRC_HOME 0x0400 +#define IPV6_PREFER_SRC_CGA 0x0008 +#define IPV6_PREFER_SRC_NONCGA 0x0800 + #endif diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index 87ae4e389ce1..c9ba0da16ce9 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -322,7 +322,11 @@ struct ipv6_pinfo { __u8 recverr:1, sndflow:1, pmtudisc:2, - ipv6only:1; + ipv6only:1, + srcprefs:3; /* 001: prefer temporary address + * 010: prefer public address + * 100: prefer care-of address + */ __u8 tclass; __u32 dst_cookie; diff --git a/include/net/addrconf.h b/include/net/addrconf.h index edcb4bbaab7d..c9276c72764d 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h @@ -78,6 +78,7 @@ extern struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net, extern int ipv6_dev_get_saddr(struct net_device *dev, struct in6_addr *daddr, + unsigned int srcprefs, struct in6_addr *saddr); extern int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr, diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index 5c3b67c86aef..3ae6799c2b14 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h @@ -30,9 +30,12 @@ struct route_info { #include #include -#define RT6_LOOKUP_F_IFACE 0x1 -#define RT6_LOOKUP_F_REACHABLE 0x2 -#define RT6_LOOKUP_F_HAS_SADDR 0x4 +#define RT6_LOOKUP_F_IFACE 0x00000001 +#define RT6_LOOKUP_F_REACHABLE 0x00000002 +#define RT6_LOOKUP_F_HAS_SADDR 0x00000004 +#define RT6_LOOKUP_F_SRCPREF_TMP 0x00000008 +#define RT6_LOOKUP_F_SRCPREF_PUBLIC 0x00000010 +#define RT6_LOOKUP_F_SRCPREF_COA 0x00000020 extern struct rt6_info *ip6_null_entry; diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 787e90af166c..89954885dee1 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -909,6 +909,7 @@ struct ipv6_saddr_dst { int ifindex; int scope; int label; + unsigned int prefs; }; static inline int ipv6_saddr_preferred(int type) @@ -984,9 +985,12 @@ static int ipv6_get_saddr_eval(struct ipv6_saddr_score *score, break; #ifdef CONFIG_IPV6_MIP6 case IPV6_SADDR_RULE_HOA: + { /* Rule 4: Prefer home address */ - ret = !!(score->ifa->flags & IFA_F_HOMEADDRESS); + int prefhome = !(dst->prefs & IPV6_PREFER_SRC_COA); + ret = !(score->ifa->flags & IFA_F_HOMEADDRESS) ^ prefhome; break; + } #endif case IPV6_SADDR_RULE_OIF: /* Rule 5: Prefer outgoing interface */ @@ -1000,11 +1004,16 @@ static int ipv6_get_saddr_eval(struct ipv6_saddr_score *score, break; #ifdef CONFIG_IPV6_PRIVACY case IPV6_SADDR_RULE_PRIVACY: + { /* Rule 7: Prefer public address * Note: prefer temprary address if use_tempaddr >= 2 */ - ret = (!(score->ifa->flags & IFA_F_TEMPORARY)) ^ (score->ifa->idev->cnf.use_tempaddr >= 2); + int preftmp = dst->prefs & (IPV6_PREFER_SRC_PUBLIC|IPV6_PREFER_SRC_TMP) ? + !!(dst->prefs & IPV6_PREFER_SRC_TMP) : + score->ifa->idev->cnf.use_tempaddr >= 2; + ret = (!(score->ifa->flags & IFA_F_TEMPORARY)) ^ preftmp; break; + } #endif case IPV6_SADDR_RULE_ORCHID: /* Rule 8-: Prefer ORCHID vs ORCHID or @@ -1030,7 +1039,8 @@ out: } int ipv6_dev_get_saddr(struct net_device *dst_dev, - struct in6_addr *daddr, struct in6_addr *saddr) + struct in6_addr *daddr, unsigned int prefs, + struct in6_addr *saddr) { struct ipv6_saddr_score scores[2], *score = &scores[0], *hiscore = &scores[1]; @@ -1044,6 +1054,7 @@ int ipv6_dev_get_saddr(struct net_device *dst_dev, dst.ifindex = dst_dev ? dst_dev->ifindex : 0; dst.scope = __ipv6_addr_src_scope(dst_type); dst.label = ipv6_addr_label(daddr, dst_type, dst.ifindex); + dst.prefs = prefs; hiscore->rule = -1; hiscore->ifa = NULL; diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index 55137408f054..e7a7fe26cebf 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c @@ -84,8 +84,18 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp, if ((rule->flags & FIB_RULE_FIND_SADDR) && r->src.plen && !(flags & RT6_LOOKUP_F_HAS_SADDR)) { struct in6_addr saddr; + unsigned int srcprefs = 0; + + if (flags & RT6_LOOKUP_F_SRCPREF_TMP) + srcprefs |= IPV6_PREFER_SRC_TMP; + if (flags & RT6_LOOKUP_F_SRCPREF_PUBLIC) + srcprefs |= IPV6_PREFER_SRC_PUBLIC; + if (flags & RT6_LOOKUP_F_SRCPREF_COA) + srcprefs |= IPV6_PREFER_SRC_COA; + if (ipv6_dev_get_saddr(ip6_dst_idev(&rt->u.dst)->dev, - &flp->fl6_dst, &saddr)) + &flp->fl6_dst, srcprefs, + &saddr)) goto again; if (!ipv6_prefix_equal(&saddr, &r->src.addr, r->src.plen)) diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 2a4f08c8a02d..d34aa61353bb 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -920,7 +920,9 @@ static int ip6_dst_lookup_tail(struct sock *sk, if (ipv6_addr_any(&fl->fl6_src)) { err = ipv6_dev_get_saddr(ip6_dst_idev(*dst)->dev, - &fl->fl6_dst, &fl->fl6_src); + &fl->fl6_dst, + sk ? inet6_sk(sk)->srcprefs : 0, + &fl->fl6_src); if (err) goto out_err_release; } diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 8e29fb1d1df6..dc6695cc5767 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -617,7 +617,67 @@ done: retv = xfrm_user_policy(sk, optname, optval, optlen); break; + case IPV6_ADDR_PREFERENCES: + { + unsigned int pref = 0; + unsigned int prefmask = ~0; + + retv = -EINVAL; + + /* check PUBLIC/TMP/PUBTMP_DEFAULT conflicts */ + switch (val & (IPV6_PREFER_SRC_PUBLIC| + IPV6_PREFER_SRC_TMP| + IPV6_PREFER_SRC_PUBTMP_DEFAULT)) { + case IPV6_PREFER_SRC_PUBLIC: + pref |= IPV6_PREFER_SRC_PUBLIC; + break; + case IPV6_PREFER_SRC_TMP: + pref |= IPV6_PREFER_SRC_TMP; + break; + case IPV6_PREFER_SRC_PUBTMP_DEFAULT: + break; + case 0: + goto pref_skip_pubtmp; + default: + goto e_inval; + } + + prefmask &= ~(IPV6_PREFER_SRC_PUBLIC| + IPV6_PREFER_SRC_TMP); +pref_skip_pubtmp: + + /* check HOME/COA conflicts */ + switch (val & (IPV6_PREFER_SRC_HOME|IPV6_PREFER_SRC_COA)) { + case IPV6_PREFER_SRC_HOME: + break; + case IPV6_PREFER_SRC_COA: + pref |= IPV6_PREFER_SRC_COA; + case 0: + goto pref_skip_coa; + default: + goto e_inval; + } + + prefmask &= ~IPV6_PREFER_SRC_COA; +pref_skip_coa: + + /* check CGA/NONCGA conflicts */ + switch (val & (IPV6_PREFER_SRC_CGA|IPV6_PREFER_SRC_NONCGA)) { + case IPV6_PREFER_SRC_CGA: + case IPV6_PREFER_SRC_NONCGA: + case 0: + break; + default: + goto e_inval; + } + + np->srcprefs = (np->srcprefs & prefmask) | pref; + retv = 0; + + break; + } } + release_sock(sk); return retv; @@ -932,6 +992,24 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, val = np->sndflow; break; + case IPV6_ADDR_PREFERENCES: + val = 0; + + if (np->srcprefs & IPV6_PREFER_SRC_TMP) + val |= IPV6_PREFER_SRC_TMP; + else if (np->srcprefs & IPV6_PREFER_SRC_PUBLIC) + val |= IPV6_PREFER_SRC_PUBLIC; + else { + /* XXX: should we return system default? */ + val |= IPV6_PREFER_SRC_PUBTMP_DEFAULT; + } + + if (np->srcprefs & IPV6_PREFER_SRC_COA) + val |= IPV6_PREFER_SRC_COA; + else + val |= IPV6_PREFER_SRC_HOME; + break; + default: return -ENOPROTOOPT; } diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index e7d8e74704c1..3f68a6eae7b2 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -546,7 +546,9 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh, override = 0; in6_ifa_put(ifp); } else { - if (ipv6_dev_get_saddr(dev, daddr, &tmpaddr)) + if (ipv6_dev_get_saddr(dev, daddr, + inet6_sk(dev->nd_net->ipv6.ndisc_sk)->srcprefs, + &tmpaddr)) return; src_addr = &tmpaddr; } diff --git a/net/ipv6/route.c b/net/ipv6/route.c index aa3f08718e44..06faa46920e1 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -782,6 +782,15 @@ struct dst_entry * ip6_route_output(struct net *net, struct sock *sk, if (!ipv6_addr_any(&fl->fl6_src)) flags |= RT6_LOOKUP_F_HAS_SADDR; + else if (sk) { + unsigned int prefs = inet6_sk(sk)->srcprefs; + if (prefs & IPV6_PREFER_SRC_TMP) + flags |= RT6_LOOKUP_F_SRCPREF_TMP; + if (prefs & IPV6_PREFER_SRC_PUBLIC) + flags |= RT6_LOOKUP_F_SRCPREF_PUBLIC; + if (prefs & IPV6_PREFER_SRC_COA) + flags |= RT6_LOOKUP_F_SRCPREF_COA; + } return fib6_rule_lookup(net, fl, flags, ip6_pol_route_output); } @@ -2162,7 +2171,7 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt, else if (dst) { struct in6_addr saddr_buf; if (ipv6_dev_get_saddr(ip6_dst_idev(&rt->u.dst)->dev, - dst, &saddr_buf) == 0) + dst, 0, &saddr_buf) == 0) NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf); } diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index e96dafdc7032..d92d1fceb8cf 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c @@ -58,7 +58,7 @@ static int xfrm6_get_saddr(xfrm_address_t *saddr, xfrm_address_t *daddr) return -EHOSTUNREACH; ipv6_dev_get_saddr(ip6_dst_idev(dst)->dev, - (struct in6_addr *)&daddr->a6, + (struct in6_addr *)&daddr->a6, 0, (struct in6_addr *)&saddr->a6); dst_release(dst); return 0; diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index 46c5b3c5cb99..dc71d0d83753 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c @@ -316,7 +316,9 @@ static void sctp_v6_get_saddr(struct sctp_association *asoc, if (!asoc) { ipv6_dev_get_saddr(dst ? ip6_dst_idev(dst)->dev : NULL, - &daddr->v6.sin6_addr, &saddr->v6.sin6_addr); + &daddr->v6.sin6_addr, + inet6_sk(asoc->base.sk)->srcprefs, + &saddr->v6.sin6_addr); SCTP_DEBUG_PRINTK("saddr from ipv6_get_saddr: " NIP6_FMT "\n", NIP6(saddr->v6.sin6_addr)); return; -- cgit v1.2.3 From 3b1e0a655f8eba44ab1ee2a1068d169ccfb853b9 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Wed, 26 Mar 2008 02:26:21 +0900 Subject: [NET] NETNS: Omit sock->sk_net without CONFIG_NET_NS. Introduce per-sock inlines: sock_net(), sock_net_set() and per-inet_timewait_sock inlines: twsk_net(), twsk_net_set(). Without CONFIG_NET_NS, no namespace other than &init_net exists. Let's explicitly define them to help compiler optimizations. Signed-off-by: YOSHIFUJI Hideaki --- include/linux/ipv6.h | 4 ++-- include/net/inet_hashtables.h | 8 ++++---- include/net/inet_timewait_sock.h | 18 ++++++++++++++++++ include/net/route.h | 4 ++-- include/net/sock.h | 24 ++++++++++++++++++++++-- net/atm/svc.c | 2 +- net/ax25/af_ax25.c | 2 +- net/bluetooth/l2cap.c | 2 +- net/bluetooth/rfcomm/sock.c | 2 +- net/bluetooth/sco.c | 2 +- net/bridge/br_netlink.c | 4 ++-- net/core/fib_rules.c | 6 +++--- net/core/neighbour.c | 10 +++++----- net/core/rtnetlink.c | 12 ++++++------ net/core/sock.c | 10 +++++----- net/decnet/af_decnet.c | 2 +- net/decnet/dn_dev.c | 6 +++--- net/decnet/dn_fib.c | 4 ++-- net/decnet/dn_route.c | 4 ++-- net/decnet/dn_table.c | 2 +- net/ipv4/af_inet.c | 6 +++--- net/ipv4/devinet.c | 6 +++--- net/ipv4/fib_frontend.c | 8 ++++---- net/ipv4/fib_rules.c | 2 +- net/ipv4/igmp.c | 14 +++++++------- net/ipv4/inet_connection_sock.c | 4 ++-- net/ipv4/inet_hashtables.c | 8 ++++---- net/ipv4/inet_timewait_sock.c | 2 +- net/ipv4/ip_input.c | 2 +- net/ipv4/ip_output.c | 4 ++-- net/ipv4/ip_sockglue.c | 6 +++--- net/ipv4/ipmr.c | 4 ++-- net/ipv4/netfilter/arp_tables.c | 16 ++++++++-------- net/ipv4/netfilter/ip_tables.c | 16 ++++++++-------- net/ipv4/raw.c | 12 ++++++------ net/ipv4/route.c | 4 ++-- net/ipv4/tcp_ipv4.c | 14 +++++++------- net/ipv4/udp.c | 16 ++++++++-------- net/ipv6/addrconf.c | 10 +++++----- net/ipv6/addrlabel.c | 6 +++--- net/ipv6/af_inet6.c | 4 ++-- net/ipv6/fib6_rules.c | 2 +- net/ipv6/icmp.c | 2 +- net/ipv6/inet6_hashtables.c | 4 ++-- net/ipv6/ip6_fib.c | 2 +- net/ipv6/ip6_output.c | 2 +- net/ipv6/ipv6_sockglue.c | 2 +- net/ipv6/mcast.c | 12 ++++++------ net/ipv6/netfilter/ip6_tables.c | 16 ++++++++-------- net/ipv6/raw.c | 6 +++--- net/ipv6/route.c | 4 ++-- net/ipv6/tcp_ipv6.c | 2 +- net/ipv6/udp.c | 4 ++-- net/irda/af_irda.c | 2 +- net/llc/llc_conn.c | 2 +- net/netfilter/nf_sockopt.c | 2 +- net/netlink/af_netlink.c | 30 +++++++++++++++--------------- net/netrom/af_netrom.c | 2 +- net/packet/af_packet.c | 28 ++++++++++++++-------------- net/rose/af_rose.c | 2 +- net/sched/act_api.c | 4 ++-- net/sched/cls_api.c | 4 ++-- net/sched/sch_api.c | 10 +++++----- net/sctp/ipv6.c | 2 +- net/sctp/protocol.c | 2 +- net/socket.c | 4 ++-- net/tipc/socket.c | 2 +- net/unix/af_unix.c | 20 ++++++++++---------- net/x25/af_x25.c | 2 +- 69 files changed, 253 insertions(+), 215 deletions(-) (limited to 'net/ipv6/fib6_rules.c') diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index c9ba0da16ce9..b90d3d461d4e 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -481,7 +481,7 @@ static inline struct raw6_sock *raw6_sk(const struct sock *sk) #endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ #define INET6_MATCH(__sk, __net, __hash, __saddr, __daddr, __ports, __dif)\ - (((__sk)->sk_hash == (__hash)) && ((__sk)->sk_net == (__net)) && \ + (((__sk)->sk_hash == (__hash)) && sock_net((__sk)) == (__net) && \ ((*((__portpair *)&(inet_sk(__sk)->dport))) == (__ports)) && \ ((__sk)->sk_family == AF_INET6) && \ ipv6_addr_equal(&inet6_sk(__sk)->daddr, (__saddr)) && \ @@ -489,7 +489,7 @@ static inline struct raw6_sock *raw6_sk(const struct sock *sk) (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif)))) #define INET6_TW_MATCH(__sk, __net, __hash, __saddr, __daddr, __ports, __dif) \ - (((__sk)->sk_hash == (__hash)) && ((__sk)->sk_net == (__net)) && \ + (((__sk)->sk_hash == (__hash)) && sock_net((__sk)) == (__net) && \ (*((__portpair *)&(inet_twsk(__sk)->tw_dport)) == (__ports)) && \ ((__sk)->sk_family == PF_INET6) && \ (ipv6_addr_equal(&inet6_twsk(__sk)->tw_v6_daddr, (__saddr))) && \ diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h index d99c1ba2ece0..5525227c5e92 100644 --- a/include/net/inet_hashtables.h +++ b/include/net/inet_hashtables.h @@ -314,25 +314,25 @@ typedef __u64 __bitwise __addrpair; ((__force __u64)(__be32)(__saddr))); #endif /* __BIG_ENDIAN */ #define INET_MATCH(__sk, __net, __hash, __cookie, __saddr, __daddr, __ports, __dif)\ - (((__sk)->sk_hash == (__hash)) && ((__sk)->sk_net == (__net)) && \ + (((__sk)->sk_hash == (__hash)) && sock_net((__sk)) == (__net) && \ ((*((__addrpair *)&(inet_sk(__sk)->daddr))) == (__cookie)) && \ ((*((__portpair *)&(inet_sk(__sk)->dport))) == (__ports)) && \ (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif)))) #define INET_TW_MATCH(__sk, __net, __hash, __cookie, __saddr, __daddr, __ports, __dif)\ - (((__sk)->sk_hash == (__hash)) && ((__sk)->sk_net == (__net)) && \ + (((__sk)->sk_hash == (__hash)) && sock_net((__sk)) == (__net) && \ ((*((__addrpair *)&(inet_twsk(__sk)->tw_daddr))) == (__cookie)) && \ ((*((__portpair *)&(inet_twsk(__sk)->tw_dport))) == (__ports)) && \ (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif)))) #else /* 32-bit arch */ #define INET_ADDR_COOKIE(__name, __saddr, __daddr) #define INET_MATCH(__sk, __net, __hash, __cookie, __saddr, __daddr, __ports, __dif) \ - (((__sk)->sk_hash == (__hash)) && ((__sk)->sk_net == (__net)) && \ + (((__sk)->sk_hash == (__hash)) && sock_net((__sk)) == (__net) && \ (inet_sk(__sk)->daddr == (__saddr)) && \ (inet_sk(__sk)->rcv_saddr == (__daddr)) && \ ((*((__portpair *)&(inet_sk(__sk)->dport))) == (__ports)) && \ (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif)))) #define INET_TW_MATCH(__sk, __net, __hash,__cookie, __saddr, __daddr, __ports, __dif) \ - (((__sk)->sk_hash == (__hash)) && ((__sk)->sk_net == (__net)) && \ + (((__sk)->sk_hash == (__hash)) && sock_net((__sk)) == (__net) && \ (inet_twsk(__sk)->tw_daddr == (__saddr)) && \ (inet_twsk(__sk)->tw_rcv_saddr == (__daddr)) && \ ((*((__portpair *)&(inet_twsk(__sk)->tw_dport))) == (__ports)) && \ diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h index 296547bfb0b7..07fe0d1a4f03 100644 --- a/include/net/inet_timewait_sock.h +++ b/include/net/inet_timewait_sock.h @@ -207,4 +207,22 @@ extern void inet_twsk_schedule(struct inet_timewait_sock *tw, const int timeo, const int timewait_len); extern void inet_twsk_deschedule(struct inet_timewait_sock *tw, struct inet_timewait_death_row *twdr); + +static inline +struct net *twsk_net(const struct inet_timewait_sock *twsk) +{ +#ifdef CONFIG_NET_NS + return twsk->tw_net; +#else + return &init_net; +#endif +} + +static inline +void twsk_net_set(struct inet_timewait_sock *twsk, const struct net *net) +{ +#ifdef CONFIG_NET_NS + twsk->tw_net = net; +#endif +} #endif /* _INET_TIMEWAIT_SOCK_ */ diff --git a/include/net/route.h b/include/net/route.h index 28dba925663c..c6338802e8f1 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -160,7 +160,7 @@ static inline int ip_route_connect(struct rtable **rp, __be32 dst, .dport = dport } } }; int err; - struct net *net = sk->sk_net; + struct net *net = sock_net(sk); if (!dst || !src) { err = __ip_route_output_key(net, rp, &fl); if (err) @@ -188,7 +188,7 @@ static inline int ip_route_newports(struct rtable **rp, u8 protocol, ip_rt_put(*rp); *rp = NULL; security_sk_classify_flow(sk, &fl); - return ip_route_output_flow(sk->sk_net, rp, &fl, sk, 0); + return ip_route_output_flow(sock_net(sk), rp, &fl, sk, 0); } return 0; } diff --git a/include/net/sock.h b/include/net/sock.h index b433b1ed203d..7e0d4a0c4d12 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -126,7 +126,9 @@ struct sock_common { atomic_t skc_refcnt; unsigned int skc_hash; struct proto *skc_prot; +#ifdef CONFIG_NET_NS struct net *skc_net; +#endif }; /** @@ -1345,6 +1347,24 @@ static inline void sk_eat_skb(struct sock *sk, struct sk_buff *skb, int copied_e } #endif +static inline +struct net *sock_net(const struct sock *sk) +{ +#ifdef CONFIG_NET_NS + return sk->sk_net; +#else + return &init_net; +#endif +} + +static inline +void sock_net_set(struct sock *sk, const struct net *net) +{ +#ifdef CONFIG_NET_NS + sk->sk_net = net; +#endif +} + /* * Kernel sockets, f.e. rtnl or icmp_socket, are a part of a namespace. * They should not hold a referrence to a namespace in order to allow @@ -1353,8 +1373,8 @@ static inline void sk_eat_skb(struct sock *sk, struct sk_buff *skb, int copied_e */ static inline void sk_change_net(struct sock *sk, struct net *net) { - put_net(sk->sk_net); - sk->sk_net = net; + put_net(sock_net(sk)); + sock_net_set(sk, net); } extern void sock_enable_timestamp(struct sock *sk); diff --git a/net/atm/svc.c b/net/atm/svc.c index daf9a48a7db0..de1e4f2f3a43 100644 --- a/net/atm/svc.c +++ b/net/atm/svc.c @@ -326,7 +326,7 @@ static int svc_accept(struct socket *sock,struct socket *newsock,int flags) lock_sock(sk); - error = svc_create(sk->sk_net, newsock,0); + error = svc_create(sock_net(sk), newsock,0); if (error) goto out; diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index ee9dd83e7561..2712544cf0ca 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c @@ -869,7 +869,7 @@ struct sock *ax25_make_new(struct sock *osk, struct ax25_dev *ax25_dev) struct sock *sk; ax25_cb *ax25, *oax25; - sk = sk_alloc(osk->sk_net, PF_AX25, GFP_ATOMIC, osk->sk_prot); + sk = sk_alloc(sock_net(osk), PF_AX25, GFP_ATOMIC, osk->sk_prot); if (sk == NULL) return NULL; diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 34f8bf98bc05..6b995ac832f5 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -1499,7 +1499,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd goto response; } - sk = l2cap_sock_alloc(parent->sk_net, NULL, BTPROTO_L2CAP, GFP_ATOMIC); + sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC); if (!sk) goto response; diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index c46d51035e77..c103fa02893b 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c @@ -868,7 +868,7 @@ int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc * goto done; } - sk = rfcomm_sock_alloc(parent->sk_net, NULL, BTPROTO_RFCOMM, GFP_ATOMIC); + sk = rfcomm_sock_alloc(sock_net(parent), NULL, BTPROTO_RFCOMM, GFP_ATOMIC); if (!sk) goto done; diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index b91d3c81a73c..2a5953b4405d 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -803,7 +803,7 @@ static void sco_conn_ready(struct sco_conn *conn) bh_lock_sock(parent); - sk = sco_sock_alloc(parent->sk_net, NULL, BTPROTO_SCO, GFP_ATOMIC); + sk = sco_sock_alloc(sock_net(parent), NULL, BTPROTO_SCO, GFP_ATOMIC); if (!sk) { bh_unlock_sock(parent); goto done; diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index f5d69336d97b..f155e6ce8a21 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c @@ -108,7 +108,7 @@ errout: */ static int br_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); struct net_device *dev; int idx; @@ -140,7 +140,7 @@ skip: */ static int br_rtm_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); struct ifinfomsg *ifm; struct nlattr *protinfo; struct net_device *dev; diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index 942be93a2eb0..540c07283e31 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c @@ -214,7 +214,7 @@ errout: static int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); struct fib_rule_hdr *frh = nlmsg_data(nlh); struct fib_rules_ops *ops = NULL; struct fib_rule *rule, *r, *last = NULL; @@ -352,7 +352,7 @@ errout: static int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); struct fib_rule_hdr *frh = nlmsg_data(nlh); struct fib_rules_ops *ops = NULL; struct fib_rule *rule, *tmp; @@ -534,7 +534,7 @@ skip: static int fib_nl_dumprule(struct sk_buff *skb, struct netlink_callback *cb) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); struct fib_rules_ops *ops; int idx = 0, family; diff --git a/net/core/neighbour.c b/net/core/neighbour.c index c978bd1cd659..065fbac7ecd3 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -1478,7 +1478,7 @@ int neigh_table_clear(struct neigh_table *tbl) static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); struct ndmsg *ndm; struct nlattr *dst_attr; struct neigh_table *tbl; @@ -1544,7 +1544,7 @@ out: static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); struct ndmsg *ndm; struct nlattr *tb[NDA_MAX+1]; struct neigh_table *tbl; @@ -1812,7 +1812,7 @@ static const struct nla_policy nl_ntbl_parm_policy[NDTPA_MAX+1] = { static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); struct neigh_table *tbl; struct ndtmsg *ndtmsg; struct nlattr *tb[NDTA_MAX+1]; @@ -1937,7 +1937,7 @@ errout: static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); int family, tidx, nidx = 0; int tbl_skip = cb->args[0]; int neigh_skip = cb->args[1]; @@ -2037,7 +2037,7 @@ static void neigh_update_notify(struct neighbour *neigh) static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb, struct netlink_callback *cb) { - struct net * net = skb->sk->sk_net; + struct net * net = sock_net(skb->sk); struct neighbour *n; int rc, h, s_h = cb->args[1]; int idx, s_idx = idx = cb->args[2]; diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 09250a0800f6..da99ac0871bf 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -662,7 +662,7 @@ nla_put_failure: static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); int idx; int s_idx = cb->args[0]; struct net_device *dev; @@ -879,7 +879,7 @@ errout: static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); struct ifinfomsg *ifm; struct net_device *dev; int err; @@ -921,7 +921,7 @@ errout: static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); const struct rtnl_link_ops *ops; struct net_device *dev; struct ifinfomsg *ifm; @@ -1000,7 +1000,7 @@ err: static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); const struct rtnl_link_ops *ops; struct net_device *dev; struct ifinfomsg *ifm; @@ -1132,7 +1132,7 @@ replay: static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); struct ifinfomsg *ifm; struct nlattr *tb[IFLA_MAX+1]; struct net_device *dev = NULL; @@ -1227,7 +1227,7 @@ static int rtattr_max; static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); rtnl_doit_func doit; int sz_idx, kind; int min_len; diff --git a/net/core/sock.c b/net/core/sock.c index b1a6ed4d33c1..3ee95060dbd0 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -372,7 +372,7 @@ static int sock_bindtodevice(struct sock *sk, char __user *optval, int optlen) { int ret = -ENOPROTOOPT; #ifdef CONFIG_NETDEVICES - struct net *net = sk->sk_net; + struct net *net = sock_net(sk); char devname[IFNAMSIZ]; int index; @@ -958,7 +958,7 @@ struct sock *sk_alloc(struct net *net, int family, gfp_t priority, */ sk->sk_prot = sk->sk_prot_creator = prot; sock_lock_init(sk); - sk->sk_net = get_net(net); + sock_net_set(sk, get_net(net)); } return sk; @@ -983,7 +983,7 @@ void sk_free(struct sock *sk) printk(KERN_DEBUG "%s: optmem leakage (%d bytes) detected.\n", __func__, atomic_read(&sk->sk_omem_alloc)); - put_net(sk->sk_net); + put_net(sock_net(sk)); sk_prot_free(sk->sk_prot_creator, sk); } @@ -1001,7 +1001,7 @@ void sk_release_kernel(struct sock *sk) sock_hold(sk); sock_release(sk->sk_socket); - sk->sk_net = get_net(&init_net); + sock_net_set(sk, get_net(&init_net)); sock_put(sk); } EXPORT_SYMBOL(sk_release_kernel); @@ -1017,7 +1017,7 @@ struct sock *sk_clone(const struct sock *sk, const gfp_t priority) sock_copy(newsk, sk); /* SANITY */ - get_net(newsk->sk_net); + get_net(sock_net(newsk)); sk_node_init(&newsk->sk_node); sock_lock_init(newsk); bh_lock_sock(newsk); diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c index 3554fb3d251c..fc2efe899e91 100644 --- a/net/decnet/af_decnet.c +++ b/net/decnet/af_decnet.c @@ -1094,7 +1094,7 @@ static int dn_accept(struct socket *sock, struct socket *newsock, int flags) cb = DN_SKB_CB(skb); sk->sk_ack_backlog--; - newsk = dn_alloc_sock(sk->sk_net, newsock, sk->sk_allocation); + newsk = dn_alloc_sock(sock_net(sk), newsock, sk->sk_allocation); if (newsk == NULL) { release_sock(sk); kfree_skb(skb); diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c index 1bbfce5f7a2d..2f0ac3c3eb71 100644 --- a/net/decnet/dn_dev.c +++ b/net/decnet/dn_dev.c @@ -625,7 +625,7 @@ static const struct nla_policy dn_ifa_policy[IFA_MAX+1] = { static int dn_nl_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); struct nlattr *tb[IFA_MAX+1]; struct dn_dev *dn_db; struct ifaddrmsg *ifm; @@ -663,7 +663,7 @@ errout: static int dn_nl_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); struct nlattr *tb[IFA_MAX+1]; struct net_device *dev; struct dn_dev *dn_db; @@ -779,7 +779,7 @@ errout: static int dn_nl_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); int idx, dn_idx = 0, skip_ndevs, skip_naddr; struct net_device *dev; struct dn_dev *dn_db; diff --git a/net/decnet/dn_fib.c b/net/decnet/dn_fib.c index 4aa9a423e606..27ea2e9b080a 100644 --- a/net/decnet/dn_fib.c +++ b/net/decnet/dn_fib.c @@ -504,7 +504,7 @@ static int dn_fib_check_attr(struct rtmsg *r, struct rtattr **rta) static int dn_fib_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); struct dn_fib_table *tb; struct rtattr **rta = arg; struct rtmsg *r = NLMSG_DATA(nlh); @@ -524,7 +524,7 @@ static int dn_fib_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh, void * static int dn_fib_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); struct dn_fib_table *tb; struct rtattr **rta = arg; struct rtmsg *r = NLMSG_DATA(nlh); diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 0a46b6c10e51..2f665a516476 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -1512,7 +1512,7 @@ rtattr_failure: */ static int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void *arg) { - struct net *net = in_skb->sk->sk_net; + struct net *net = sock_net(in_skb->sk); struct rtattr **rta = arg; struct rtmsg *rtm = NLMSG_DATA(nlh); struct dn_route *rt = NULL; @@ -1601,7 +1601,7 @@ out_free: */ int dn_cache_dump(struct sk_buff *skb, struct netlink_callback *cb) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); struct dn_route *rt; int h, s_h; int idx, s_idx; diff --git a/net/decnet/dn_table.c b/net/decnet/dn_table.c index e09d915dbd77..3a2830ac89c2 100644 --- a/net/decnet/dn_table.c +++ b/net/decnet/dn_table.c @@ -463,7 +463,7 @@ static int dn_fib_table_dump(struct dn_fib_table *tb, struct sk_buff *skb, int dn_fib_dump(struct sk_buff *skb, struct netlink_callback *cb) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); unsigned int h, s_h; unsigned int e = 0, s_e; struct dn_fib_table *tb; diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 06cfb0bed631..5882a1316441 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -464,7 +464,7 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) if (addr_len < sizeof(struct sockaddr_in)) goto out; - chk_addr_ret = inet_addr_type(sk->sk_net, addr->sin_addr.s_addr); + chk_addr_ret = inet_addr_type(sock_net(sk), addr->sin_addr.s_addr); /* Not specified by any standard per-se, however it breaks too * many applications when removed. It is unfortunate since @@ -802,7 +802,7 @@ int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) { struct sock *sk = sock->sk; int err = 0; - struct net *net = sk->sk_net; + struct net *net = sock_net(sk); switch (cmd) { case SIOCGSTAMP: @@ -1132,7 +1132,7 @@ int inet_sk_rebuild_header(struct sock *sk) }; security_sk_classify_flow(sk, &fl); - err = ip_route_output_flow(sk->sk_net, &rt, &fl, sk, 0); + err = ip_route_output_flow(sock_net(sk), &rt, &fl, sk, 0); } if (!err) sk_setup_caps(sk, &rt->u.dst); diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 823c724a8593..6848e4760f34 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -437,7 +437,7 @@ struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, __be32 prefix, static int inet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); struct nlattr *tb[IFA_MAX+1]; struct in_device *in_dev; struct ifaddrmsg *ifm; @@ -552,7 +552,7 @@ errout: static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); struct in_ifaddr *ifa; ASSERT_RTNL(); @@ -1158,7 +1158,7 @@ nla_put_failure: static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); int idx, ip_idx; struct net_device *dev; struct in_device *in_dev; diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 0e4b34b07cb5..0f1557a4ac7a 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -583,7 +583,7 @@ errout: static int inet_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); struct fib_config cfg; struct fib_table *tb; int err; @@ -605,7 +605,7 @@ errout: static int inet_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); struct fib_config cfg; struct fib_table *tb; int err; @@ -627,7 +627,7 @@ errout: static int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); unsigned int h, s_h; unsigned int e = 0, s_e; struct fib_table *tb; @@ -857,7 +857,7 @@ static void nl_fib_input(struct sk_buff *skb) struct fib_table *tb; u32 pid; - net = skb->sk->sk_net; + net = sock_net(skb->sk); nlh = nlmsg_hdr(skb); if (skb->len < NLMSG_SPACE(0) || skb->len < nlh->nlmsg_len || nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*frn))) diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c index 19274d01afa4..1fb56876be54 100644 --- a/net/ipv4/fib_rules.c +++ b/net/ipv4/fib_rules.c @@ -137,7 +137,7 @@ static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb, struct nlmsghdr *nlh, struct fib_rule_hdr *frh, struct nlattr **tb) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); int err = -EINVAL; struct fib4_rule *rule4 = (struct fib4_rule *) rule; diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 682f632bfb77..6250f4239b61 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -1762,7 +1762,7 @@ int ip_mc_join_group(struct sock *sk , struct ip_mreqn *imr) if (!ipv4_is_multicast(addr)) return -EINVAL; - if (sk->sk_net != &init_net) + if (sock_net(sk) != &init_net) return -EPROTONOSUPPORT; rtnl_lock(); @@ -1833,7 +1833,7 @@ int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr) u32 ifindex; int ret = -EADDRNOTAVAIL; - if (sk->sk_net != &init_net) + if (sock_net(sk) != &init_net) return -EPROTONOSUPPORT; rtnl_lock(); @@ -1881,7 +1881,7 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct if (!ipv4_is_multicast(addr)) return -EINVAL; - if (sk->sk_net != &init_net) + if (sock_net(sk) != &init_net) return -EPROTONOSUPPORT; rtnl_lock(); @@ -2017,7 +2017,7 @@ int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf, int ifindex) msf->imsf_fmode != MCAST_EXCLUDE) return -EINVAL; - if (sk->sk_net != &init_net) + if (sock_net(sk) != &init_net) return -EPROTONOSUPPORT; rtnl_lock(); @@ -2100,7 +2100,7 @@ int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf, if (!ipv4_is_multicast(addr)) return -EINVAL; - if (sk->sk_net != &init_net) + if (sock_net(sk) != &init_net) return -EPROTONOSUPPORT; rtnl_lock(); @@ -2165,7 +2165,7 @@ int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf, if (!ipv4_is_multicast(addr)) return -EINVAL; - if (sk->sk_net != &init_net) + if (sock_net(sk) != &init_net) return -EPROTONOSUPPORT; rtnl_lock(); @@ -2252,7 +2252,7 @@ void ip_mc_drop_socket(struct sock *sk) if (inet->mc_list == NULL) return; - if (sk->sk_net != &init_net) + if (sock_net(sk) != &init_net) return; rtnl_lock(); diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index d13c5f12bb32..a7fcaf205644 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c @@ -85,7 +85,7 @@ int inet_csk_get_port(struct sock *sk, unsigned short snum) struct hlist_node *node; struct inet_bind_bucket *tb; int ret; - struct net *net = sk->sk_net; + struct net *net = sock_net(sk); local_bh_disable(); if (!snum) { @@ -333,7 +333,7 @@ struct dst_entry* inet_csk_route_req(struct sock *sk, .dport = ireq->rmt_port } } }; security_req_classify_flow(req, &fl); - if (ip_route_output_flow(sk->sk_net, &rt, &fl, sk, 0)) { + if (ip_route_output_flow(sock_net(sk), &rt, &fl, sk, 0)) { IP_INC_STATS_BH(IPSTATS_MIB_OUTNOROUTES); return NULL; } diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index 8cd1ad9b9111..1064111e5b96 100644 --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c @@ -139,7 +139,7 @@ static struct sock *inet_lookup_listener_slow(struct net *net, sk_for_each(sk, node, head) { const struct inet_sock *inet = inet_sk(sk); - if (sk->sk_net == net && inet->num == hnum && + if (sock_net(sk) == net && inet->num == hnum && !ipv6_only_sock(sk)) { const __be32 rcv_saddr = inet->rcv_saddr; int score = sk->sk_family == PF_INET ? 1 : 0; @@ -182,7 +182,7 @@ struct sock *__inet_lookup_listener(struct net *net, if (inet->num == hnum && !sk->sk_node.next && (!inet->rcv_saddr || inet->rcv_saddr == daddr) && (sk->sk_family == PF_INET || !ipv6_only_sock(sk)) && - !sk->sk_bound_dev_if && sk->sk_net == net) + !sk->sk_bound_dev_if && sock_net(sk) == net) goto sherry_cache; sk = inet_lookup_listener_slow(net, head, daddr, hnum, dif); } @@ -254,7 +254,7 @@ static int __inet_check_established(struct inet_timewait_death_row *death_row, struct sock *sk2; const struct hlist_node *node; struct inet_timewait_sock *tw; - struct net *net = sk->sk_net; + struct net *net = sock_net(sk); prefetch(head->chain.first); write_lock(lock); @@ -406,7 +406,7 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row, struct inet_bind_hashbucket *head; struct inet_bind_bucket *tb; int ret; - struct net *net = sk->sk_net; + struct net *net = sock_net(sk); if (!snum) { int i, remaining, low, high, port; diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c index 717c411a5c6b..f12bc24de46f 100644 --- a/net/ipv4/inet_timewait_sock.c +++ b/net/ipv4/inet_timewait_sock.c @@ -124,7 +124,7 @@ struct inet_timewait_sock *inet_twsk_alloc(const struct sock *sk, const int stat tw->tw_hash = sk->sk_hash; tw->tw_ipv6only = 0; tw->tw_prot = sk->sk_prot_creator; - tw->tw_net = sk->sk_net; + twsk_net_set(tw, sock_net(sk)); atomic_set(&tw->tw_refcnt, 1); inet_twsk_dead_node_init(tw); __module_get(tw->tw_prot->owner); diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index 26685c83a146..4be00959b748 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c @@ -172,7 +172,7 @@ int ip_call_ra_chain(struct sk_buff *skb) if (sk && inet_sk(sk)->num == protocol && (!sk->sk_bound_dev_if || sk->sk_bound_dev_if == dev->ifindex) && - sk->sk_net == dev_net(dev)) { + sock_net(sk) == dev_net(dev)) { if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) { if (ip_defrag(skb, IP_DEFRAG_CALL_RA_CHAIN)) { read_unlock(&ip_ra_lock); diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 913266cd9902..08349267ceb4 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -351,7 +351,7 @@ int ip_queue_xmit(struct sk_buff *skb, int ipfragok) * itself out. */ security_sk_classify_flow(sk, &fl); - if (ip_route_output_flow(sk->sk_net, &rt, &fl, sk, 0)) + if (ip_route_output_flow(sock_net(sk), &rt, &fl, sk, 0)) goto no_route; } sk_setup_caps(sk, &rt->u.dst); @@ -1382,7 +1382,7 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar .dport = tcp_hdr(skb)->source } }, .proto = sk->sk_protocol }; security_skb_classify_flow(skb, &fl); - if (ip_route_output_key(sk->sk_net, &rt, &fl)) + if (ip_route_output_key(sock_net(sk), &rt, &fl)) return; } diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index b854431047a4..d6e76f5229cc 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -449,7 +449,7 @@ static int do_ip_setsockopt(struct sock *sk, int level, struct ip_options * opt = NULL; if (optlen > 40 || optlen < 0) goto e_inval; - err = ip_options_get_from_user(sk->sk_net, &opt, + err = ip_options_get_from_user(sock_net(sk), &opt, optval, optlen); if (err) break; @@ -590,13 +590,13 @@ static int do_ip_setsockopt(struct sock *sk, int level, err = 0; break; } - dev = ip_dev_find(sk->sk_net, mreq.imr_address.s_addr); + dev = ip_dev_find(sock_net(sk), mreq.imr_address.s_addr); if (dev) { mreq.imr_ifindex = dev->ifindex; dev_put(dev); } } else - dev = __dev_get_by_index(sk->sk_net, mreq.imr_ifindex); + dev = __dev_get_by_index(sock_net(sk), mreq.imr_ifindex); err = -EADDRNOTAVAIL; diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index e54bc1364473..11700a4dcd95 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -849,7 +849,7 @@ static void mrtsock_destruct(struct sock *sk) { rtnl_lock(); if (sk == mroute_socket) { - IPV4_DEVCONF_ALL(sk->sk_net, MC_FORWARDING)--; + IPV4_DEVCONF_ALL(sock_net(sk), MC_FORWARDING)--; write_lock_bh(&mrt_lock); mroute_socket=NULL; @@ -898,7 +898,7 @@ int ip_mroute_setsockopt(struct sock *sk,int optname,char __user *optval,int opt mroute_socket=sk; write_unlock_bh(&mrt_lock); - IPV4_DEVCONF_ALL(sk->sk_net, MC_FORWARDING)++; + IPV4_DEVCONF_ALL(sock_net(sk), MC_FORWARDING)++; } rtnl_unlock(); return ret; diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index 756bc0e1a7c6..1563f29b5117 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c @@ -1496,11 +1496,11 @@ static int compat_do_arpt_set_ctl(struct sock *sk, int cmd, void __user *user, switch (cmd) { case ARPT_SO_SET_REPLACE: - ret = compat_do_replace(sk->sk_net, user, len); + ret = compat_do_replace(sock_net(sk), user, len); break; case ARPT_SO_SET_ADD_COUNTERS: - ret = do_add_counters(sk->sk_net, user, len, 1); + ret = do_add_counters(sock_net(sk), user, len, 1); break; default: @@ -1644,10 +1644,10 @@ static int compat_do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, switch (cmd) { case ARPT_SO_GET_INFO: - ret = get_info(sk->sk_net, user, len, 1); + ret = get_info(sock_net(sk), user, len, 1); break; case ARPT_SO_GET_ENTRIES: - ret = compat_get_entries(sk->sk_net, user, len); + ret = compat_get_entries(sock_net(sk), user, len); break; default: ret = do_arpt_get_ctl(sk, cmd, user, len); @@ -1665,11 +1665,11 @@ static int do_arpt_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned switch (cmd) { case ARPT_SO_SET_REPLACE: - ret = do_replace(sk->sk_net, user, len); + ret = do_replace(sock_net(sk), user, len); break; case ARPT_SO_SET_ADD_COUNTERS: - ret = do_add_counters(sk->sk_net, user, len, 0); + ret = do_add_counters(sock_net(sk), user, len, 0); break; default: @@ -1689,11 +1689,11 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len switch (cmd) { case ARPT_SO_GET_INFO: - ret = get_info(sk->sk_net, user, len, 0); + ret = get_info(sock_net(sk), user, len, 0); break; case ARPT_SO_GET_ENTRIES: - ret = get_entries(sk->sk_net, user, len); + ret = get_entries(sock_net(sk), user, len); break; case ARPT_SO_GET_REVISION_TARGET: { diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 85a75e186b4b..a819d191e1aa 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -1852,11 +1852,11 @@ compat_do_ipt_set_ctl(struct sock *sk, int cmd, void __user *user, switch (cmd) { case IPT_SO_SET_REPLACE: - ret = compat_do_replace(sk->sk_net, user, len); + ret = compat_do_replace(sock_net(sk), user, len); break; case IPT_SO_SET_ADD_COUNTERS: - ret = do_add_counters(sk->sk_net, user, len, 1); + ret = do_add_counters(sock_net(sk), user, len, 1); break; default: @@ -1963,10 +1963,10 @@ compat_do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) switch (cmd) { case IPT_SO_GET_INFO: - ret = get_info(sk->sk_net, user, len, 1); + ret = get_info(sock_net(sk), user, len, 1); break; case IPT_SO_GET_ENTRIES: - ret = compat_get_entries(sk->sk_net, user, len); + ret = compat_get_entries(sock_net(sk), user, len); break; default: ret = do_ipt_get_ctl(sk, cmd, user, len); @@ -1985,11 +1985,11 @@ do_ipt_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len) switch (cmd) { case IPT_SO_SET_REPLACE: - ret = do_replace(sk->sk_net, user, len); + ret = do_replace(sock_net(sk), user, len); break; case IPT_SO_SET_ADD_COUNTERS: - ret = do_add_counters(sk->sk_net, user, len, 0); + ret = do_add_counters(sock_net(sk), user, len, 0); break; default: @@ -2010,11 +2010,11 @@ do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) switch (cmd) { case IPT_SO_GET_INFO: - ret = get_info(sk->sk_net, user, len, 0); + ret = get_info(sock_net(sk), user, len, 0); break; case IPT_SO_GET_ENTRIES: - ret = get_entries(sk->sk_net, user, len); + ret = get_entries(sock_net(sk), user, len); break; case IPT_SO_GET_REVISION_MATCH: diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 8756d502a47f..be19a4048d7c 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -117,7 +117,7 @@ static struct sock *__raw_v4_lookup(struct net *net, struct sock *sk, sk_for_each_from(sk, node) { struct inet_sock *inet = inet_sk(sk); - if (sk->sk_net == net && inet->num == num && + if (sock_net(sk) == net && inet->num == num && !(inet->daddr && inet->daddr != raddr) && !(inet->rcv_saddr && inet->rcv_saddr != laddr) && !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif)) @@ -499,7 +499,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, ipc.oif = sk->sk_bound_dev_if; if (msg->msg_controllen) { - err = ip_cmsg_send(sk->sk_net, msg, &ipc); + err = ip_cmsg_send(sock_net(sk), msg, &ipc); if (err) goto out; if (ipc.opt) @@ -553,7 +553,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, } security_sk_classify_flow(sk, &fl); - err = ip_route_output_flow(sk->sk_net, &rt, &fl, sk, 1); + err = ip_route_output_flow(sock_net(sk), &rt, &fl, sk, 1); } if (err) goto done; @@ -620,7 +620,7 @@ static int raw_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) if (sk->sk_state != TCP_CLOSE || addr_len < sizeof(struct sockaddr_in)) goto out; - chk_addr_ret = inet_addr_type(sk->sk_net, addr->sin_addr.s_addr); + chk_addr_ret = inet_addr_type(sock_net(sk), addr->sin_addr.s_addr); ret = -EADDRNOTAVAIL; if (addr->sin_addr.s_addr && chk_addr_ret != RTN_LOCAL && chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST) @@ -856,7 +856,7 @@ static struct sock *raw_get_first(struct seq_file *seq) struct hlist_node *node; sk_for_each(sk, node, &state->h->ht[state->bucket]) - if (sk->sk_net == state->p.net) + if (sock_net(sk) == state->p.net) goto found; } sk = NULL; @@ -872,7 +872,7 @@ static struct sock *raw_get_next(struct seq_file *seq, struct sock *sk) sk = sk_next(sk); try_again: ; - } while (sk && sk->sk_net != state->p.net); + } while (sk && sock_net(sk) != state->p.net); if (!sk && ++state->bucket < RAW_HTABLE_SIZE) { sk = sk_head(&state->h->ht[state->bucket]); diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 7768d718e199..194f5cca3121 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -2689,7 +2689,7 @@ nla_put_failure: static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg) { - struct net *net = in_skb->sk->sk_net; + struct net *net = sock_net(in_skb->sk); struct rtmsg *rtm; struct nlattr *tb[RTA_MAX+1]; struct rtable *rt = NULL; @@ -2785,7 +2785,7 @@ int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb) int idx, s_idx; struct net *net; - net = skb->sk->sk_net; + net = sock_net(skb->sk); s_h = cb->args[0]; if (s_h < 0) diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 28bece6f281b..46847e600a46 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1486,7 +1486,7 @@ static struct sock *tcp_v4_hnd_req(struct sock *sk, struct sk_buff *skb) if (req) return tcp_check_req(sk, skb, req, prev); - nsk = inet_lookup_established(sk->sk_net, &tcp_hashinfo, iph->saddr, + nsk = inet_lookup_established(sock_net(sk), &tcp_hashinfo, iph->saddr, th->source, iph->daddr, th->dest, inet_iif(skb)); if (nsk) { @@ -1974,7 +1974,7 @@ static void *listening_get_next(struct seq_file *seq, void *cur) while (1) { while (req) { if (req->rsk_ops->family == st->family && - req->sk->sk_net == net) { + sock_net(req->sk) == net) { cur = req; goto out; } @@ -1998,7 +1998,7 @@ get_req: } get_sk: sk_for_each_from(sk, node) { - if (sk->sk_family == st->family && sk->sk_net == net) { + if (sk->sk_family == st->family && sock_net(sk) == net) { cur = sk; goto out; } @@ -2049,7 +2049,7 @@ static void *established_get_first(struct seq_file *seq) read_lock_bh(lock); sk_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) { if (sk->sk_family != st->family || - sk->sk_net != net) { + sock_net(sk) != net) { continue; } rc = sk; @@ -2059,7 +2059,7 @@ static void *established_get_first(struct seq_file *seq) inet_twsk_for_each(tw, node, &tcp_hashinfo.ehash[st->bucket].twchain) { if (tw->tw_family != st->family || - tw->tw_net != net) { + twsk_net(tw) != net) { continue; } rc = tw; @@ -2086,7 +2086,7 @@ static void *established_get_next(struct seq_file *seq, void *cur) tw = cur; tw = tw_next(tw); get_tw: - while (tw && (tw->tw_family != st->family || tw->tw_net != net)) { + while (tw && (tw->tw_family != st->family || twsk_net(tw) != net)) { tw = tw_next(tw); } if (tw) { @@ -2107,7 +2107,7 @@ get_tw: sk = sk_next(sk); sk_for_each_from(sk, node) { - if (sk->sk_family == st->family && sk->sk_net == net) + if (sk->sk_family == st->family && sock_net(sk) == net) goto found; } diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index e2cd93481359..76d52d37d6ac 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -137,7 +137,7 @@ static inline int __udp_lib_lport_inuse(struct net *net, __u16 num, struct hlist_node *node; sk_for_each(sk, node, &udptable[num & (UDP_HTABLE_SIZE - 1)]) - if (sk->sk_net == net && sk->sk_hash == num) + if (sock_net(sk) == net && sk->sk_hash == num) return 1; return 0; } @@ -158,7 +158,7 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum, struct hlist_head *head; struct sock *sk2; int error = 1; - struct net *net = sk->sk_net; + struct net *net = sock_net(sk); write_lock_bh(&udp_hash_lock); @@ -218,7 +218,7 @@ gotit: sk_for_each(sk2, node, head) if (sk2->sk_hash == snum && sk2 != sk && - sk2->sk_net == net && + sock_net(sk2) == net && (!sk2->sk_reuse || !sk->sk_reuse) && (!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if || sk2->sk_bound_dev_if == sk->sk_bound_dev_if) && @@ -269,7 +269,7 @@ static struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr, sk_for_each(sk, node, &udptable[hnum & (UDP_HTABLE_SIZE - 1)]) { struct inet_sock *inet = inet_sk(sk); - if (sk->sk_net == net && sk->sk_hash == hnum && + if (sock_net(sk) == net && sk->sk_hash == hnum && !ipv6_only_sock(sk)) { int score = (sk->sk_family == PF_INET ? 1 : 0); if (inet->rcv_saddr) { @@ -607,7 +607,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, ipc.oif = sk->sk_bound_dev_if; if (msg->msg_controllen) { - err = ip_cmsg_send(sk->sk_net, msg, &ipc); + err = ip_cmsg_send(sock_net(sk), msg, &ipc); if (err) return err; if (ipc.opt) @@ -656,7 +656,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, { .sport = inet->sport, .dport = dport } } }; security_sk_classify_flow(sk, &fl); - err = ip_route_output_flow(sk->sk_net, &rt, &fl, sk, 1); + err = ip_route_output_flow(sock_net(sk), &rt, &fl, sk, 1); if (err) { if (err == -ENETUNREACH) IP_INC_STATS_BH(IPSTATS_MIB_OUTNOROUTES); @@ -1511,7 +1511,7 @@ static struct sock *udp_get_first(struct seq_file *seq) for (state->bucket = 0; state->bucket < UDP_HTABLE_SIZE; ++state->bucket) { struct hlist_node *node; sk_for_each(sk, node, state->hashtable + state->bucket) { - if (sk->sk_net != net) + if (sock_net(sk) != net) continue; if (sk->sk_family == state->family) goto found; @@ -1531,7 +1531,7 @@ static struct sock *udp_get_next(struct seq_file *seq, struct sock *sk) sk = sk_next(sk); try_again: ; - } while (sk && (sk->sk_net != net || sk->sk_family != state->family)); + } while (sk && (sock_net(sk) != net || sk->sk_family != state->family)); if (!sk && ++state->bucket < UDP_HTABLE_SIZE) { sk = sk_head(state->hashtable + state->bucket); diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index d1de9ec74261..f2c90f145cbb 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -3054,7 +3054,7 @@ static const struct nla_policy ifa_ipv6_policy[IFA_MAX+1] = { static int inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); struct ifaddrmsg *ifm; struct nlattr *tb[IFA_MAX+1]; struct in6_addr *pfx; @@ -3112,7 +3112,7 @@ static int inet6_addr_modify(struct inet6_ifaddr *ifp, u8 ifa_flags, static int inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); struct ifaddrmsg *ifm; struct nlattr *tb[IFA_MAX+1]; struct in6_addr *pfx; @@ -3322,7 +3322,7 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, struct inet6_ifaddr *ifa; struct ifmcaddr6 *ifmca; struct ifacaddr6 *ifaca; - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); s_idx = cb->args[0]; s_ip_idx = ip_idx = cb->args[1]; @@ -3418,7 +3418,7 @@ static int inet6_dump_ifacaddr(struct sk_buff *skb, struct netlink_callback *cb) static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg) { - struct net *net = in_skb->sk->sk_net; + struct net *net = sock_net(in_skb->sk); struct ifaddrmsg *ifm; struct nlattr *tb[IFA_MAX+1]; struct in6_addr *addr = NULL; @@ -3645,7 +3645,7 @@ nla_put_failure: static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); int idx, err; int s_idx = cb->args[0]; struct net_device *dev; diff --git a/net/ipv6/addrlabel.c b/net/ipv6/addrlabel.c index de371b5997fe..9bfa8846f262 100644 --- a/net/ipv6/addrlabel.c +++ b/net/ipv6/addrlabel.c @@ -364,7 +364,7 @@ static const struct nla_policy ifal_policy[IFAL_MAX+1] = { static int ip6addrlbl_newdel(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); struct ifaddrlblmsg *ifal; struct nlattr *tb[IFAL_MAX+1]; struct in6_addr *pfx; @@ -452,7 +452,7 @@ static int ip6addrlbl_fill(struct sk_buff *skb, static int ip6addrlbl_dump(struct sk_buff *skb, struct netlink_callback *cb) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); struct ip6addrlbl_entry *p; struct hlist_node *pos; int idx = 0, s_idx = cb->args[0]; @@ -490,7 +490,7 @@ static inline int ip6addrlbl_msgsize(void) static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg) { - struct net *net = in_skb->sk->sk_net; + struct net *net = sock_net(in_skb->sk); struct ifaddrlblmsg *ifal; struct nlattr *tb[IFAL_MAX+1]; struct in6_addr *addr; diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index f52bdaed8a1b..12f04e9d3e88 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -245,7 +245,7 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) struct sock *sk = sock->sk; struct inet_sock *inet = inet_sk(sk); struct ipv6_pinfo *np = inet6_sk(sk); - struct net *net = sk->sk_net; + struct net *net = sock_net(sk); __be32 v4addr = 0; unsigned short snum; int addr_type = 0; @@ -438,7 +438,7 @@ EXPORT_SYMBOL(inet6_getname); int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) { struct sock *sk = sock->sk; - struct net *net = sk->sk_net; + struct net *net = sock_net(sk); switch(cmd) { diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index e7a7fe26cebf..cac580749ebe 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c @@ -154,7 +154,7 @@ static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb, struct nlattr **tb) { int err = -EINVAL; - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); struct fib6_rule *rule6 = (struct fib6_rule *) rule; if (rule->action == FR_ACT_TO_TBL) { diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 50857662e6b7..63309d10df3a 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -163,7 +163,7 @@ static inline int icmpv6_xrlim_allow(struct sock *sk, int type, struct flowi *fl) { struct dst_entry *dst; - struct net *net = sk->sk_net; + struct net *net = sock_net(sk); int res = 0; /* Informational messages are not limited. */ diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c index c0c8d2d17682..21c467675412 100644 --- a/net/ipv6/inet6_hashtables.c +++ b/net/ipv6/inet6_hashtables.c @@ -105,7 +105,7 @@ struct sock *inet6_lookup_listener(struct net *net, read_lock(&hashinfo->lhash_lock); sk_for_each(sk, node, &hashinfo->listening_hash[inet_lhashfn(hnum)]) { - if (sk->sk_net == net && inet_sk(sk)->num == hnum && + if (sock_net(sk) == net && inet_sk(sk)->num == hnum && sk->sk_family == PF_INET6) { const struct ipv6_pinfo *np = inet6_sk(sk); @@ -172,7 +172,7 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row, struct sock *sk2; const struct hlist_node *node; struct inet_timewait_sock *tw; - struct net *net = sk->sk_net; + struct net *net = sock_net(sk); prefetch(head->chain.first); write_lock(lock); diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index b0814b0082e7..b3f6e03c454c 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -346,7 +346,7 @@ end: static int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); unsigned int h, s_h; unsigned int e = 0, s_e; struct rt6_rtnl_dump_arg arg; diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 556300f0eba5..a8b4da25b0a7 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -910,7 +910,7 @@ static int ip6_dst_lookup_tail(struct sock *sk, struct dst_entry **dst, struct flowi *fl) { int err; - struct net *net = sk->sk_net; + struct net *net = sock_net(sk); if (*dst == NULL) *dst = ip6_route_output(net, sk, fl); diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index dc6695cc5767..d3d93d752e10 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -107,7 +107,7 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, char __user *optval, int optlen) { struct ipv6_pinfo *np = inet6_sk(sk); - struct net *net = sk->sk_net; + struct net *net = sock_net(sk); int val, valbool; int retv = -ENOPROTOOPT; diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 0357de8e78c8..20a3d8e2f6c6 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c @@ -181,7 +181,7 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, struct in6_addr *addr) struct net_device *dev = NULL; struct ipv6_mc_socklist *mc_lst; struct ipv6_pinfo *np = inet6_sk(sk); - struct net *net = sk->sk_net; + struct net *net = sock_net(sk); int err; if (!ipv6_addr_is_multicast(addr)) @@ -255,7 +255,7 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, struct in6_addr *addr) { struct ipv6_pinfo *np = inet6_sk(sk); struct ipv6_mc_socklist *mc_lst, **lnk; - struct net *net = sk->sk_net; + struct net *net = sock_net(sk); write_lock_bh(&ipv6_sk_mc_lock); for (lnk = &np->ipv6_mc_list; (mc_lst = *lnk) !=NULL ; lnk = &mc_lst->next) { @@ -327,7 +327,7 @@ void ipv6_sock_mc_close(struct sock *sk) { struct ipv6_pinfo *np = inet6_sk(sk); struct ipv6_mc_socklist *mc_lst; - struct net *net = sk->sk_net; + struct net *net = sock_net(sk); write_lock_bh(&ipv6_sk_mc_lock); while ((mc_lst = np->ipv6_mc_list) != NULL) { @@ -365,7 +365,7 @@ int ip6_mc_source(int add, int omode, struct sock *sk, struct inet6_dev *idev; struct ipv6_pinfo *inet6 = inet6_sk(sk); struct ip6_sf_socklist *psl; - struct net *net = sk->sk_net; + struct net *net = sock_net(sk); int i, j, rv; int leavegroup = 0; int pmclocked = 0; @@ -505,7 +505,7 @@ int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf) struct inet6_dev *idev; struct ipv6_pinfo *inet6 = inet6_sk(sk); struct ip6_sf_socklist *newpsl, *psl; - struct net *net = sk->sk_net; + struct net *net = sock_net(sk); int leavegroup = 0; int i, err; @@ -598,7 +598,7 @@ int ip6_mc_msfget(struct sock *sk, struct group_filter *gsf, struct net_device *dev; struct ipv6_pinfo *inet6 = inet6_sk(sk); struct ip6_sf_socklist *psl; - struct net *net = sk->sk_net; + struct net *net = sock_net(sk); group = &((struct sockaddr_in6 *)&gsf->gf_group)->sin6_addr; diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index af1ec7ba757c..70ef0d276cc0 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -1879,11 +1879,11 @@ compat_do_ip6t_set_ctl(struct sock *sk, int cmd, void __user *user, switch (cmd) { case IP6T_SO_SET_REPLACE: - ret = compat_do_replace(sk->sk_net, user, len); + ret = compat_do_replace(sock_net(sk), user, len); break; case IP6T_SO_SET_ADD_COUNTERS: - ret = do_add_counters(sk->sk_net, user, len, 1); + ret = do_add_counters(sock_net(sk), user, len, 1); break; default: @@ -1990,10 +1990,10 @@ compat_do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) switch (cmd) { case IP6T_SO_GET_INFO: - ret = get_info(sk->sk_net, user, len, 1); + ret = get_info(sock_net(sk), user, len, 1); break; case IP6T_SO_GET_ENTRIES: - ret = compat_get_entries(sk->sk_net, user, len); + ret = compat_get_entries(sock_net(sk), user, len); break; default: ret = do_ip6t_get_ctl(sk, cmd, user, len); @@ -2012,11 +2012,11 @@ do_ip6t_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len) switch (cmd) { case IP6T_SO_SET_REPLACE: - ret = do_replace(sk->sk_net, user, len); + ret = do_replace(sock_net(sk), user, len); break; case IP6T_SO_SET_ADD_COUNTERS: - ret = do_add_counters(sk->sk_net, user, len, 0); + ret = do_add_counters(sock_net(sk), user, len, 0); break; default: @@ -2037,11 +2037,11 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) switch (cmd) { case IP6T_SO_GET_INFO: - ret = get_info(sk->sk_net, user, len, 0); + ret = get_info(sock_net(sk), user, len, 0); break; case IP6T_SO_GET_ENTRIES: - ret = get_entries(sk->sk_net, user, len); + ret = get_entries(sock_net(sk), user, len); break; case IP6T_SO_GET_REVISION_MATCH: diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index efb0047f6880..12c7a1560977 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -76,7 +76,7 @@ static struct sock *__raw_v6_lookup(struct net *net, struct sock *sk, if (inet_sk(sk)->num == num) { struct ipv6_pinfo *np = inet6_sk(sk); - if (sk->sk_net != net) + if (sock_net(sk) != net) continue; if (!ipv6_addr_any(&np->daddr) && @@ -280,7 +280,7 @@ static int rawv6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) if (!sk->sk_bound_dev_if) goto out; - dev = dev_get_by_index(sk->sk_net, sk->sk_bound_dev_if); + dev = dev_get_by_index(sock_net(sk), sk->sk_bound_dev_if); if (!dev) { err = -ENODEV; goto out; @@ -293,7 +293,7 @@ static int rawv6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) v4addr = LOOPBACK4_IPV6; if (!(addr_type & IPV6_ADDR_MULTICAST)) { err = -EADDRNOTAVAIL; - if (!ipv6_chk_addr(sk->sk_net, &addr->sin6_addr, + if (!ipv6_chk_addr(sock_net(sk), &addr->sin6_addr, dev, 0)) { if (dev) dev_put(dev); diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 65053fba8c1a..ac4428371432 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -2020,7 +2020,7 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh, cfg->fc_nlinfo.pid = NETLINK_CB(skb).pid; cfg->fc_nlinfo.nlh = nlh; - cfg->fc_nlinfo.nl_net = skb->sk->sk_net; + cfg->fc_nlinfo.nl_net = sock_net(skb->sk); if (tb[RTA_GATEWAY]) { nla_memcpy(&cfg->fc_gateway, tb[RTA_GATEWAY], 16); @@ -2216,7 +2216,7 @@ int rt6_dump_route(struct rt6_info *rt, void *p_arg) static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg) { - struct net *net = in_skb->sk->sk_net; + struct net *net = sock_net(in_skb->sk); struct nlattr *tb[RTA_MAX+1]; struct rt6_info *rt; struct sk_buff *skb; diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 086deffff9c9..323c7e06ef43 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1218,7 +1218,7 @@ static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb) if (req) return tcp_check_req(sk, skb, req, prev); - nsk = __inet6_lookup_established(sk->sk_net, &tcp_hashinfo, + nsk = __inet6_lookup_established(sock_net(sk), &tcp_hashinfo, &ipv6_hdr(skb)->saddr, th->source, &ipv6_hdr(skb)->daddr, ntohs(th->dest), inet6_iif(skb)); diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 6683c04b427e..db266ff297e5 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -70,7 +70,7 @@ static struct sock *__udp6_lib_lookup(struct net *net, sk_for_each(sk, node, &udptable[hnum & (UDP_HTABLE_SIZE - 1)]) { struct inet_sock *inet = inet_sk(sk); - if (sk->sk_net == net && sk->sk_hash == hnum && + if (sock_net(sk) == net && sk->sk_hash == hnum && sk->sk_family == PF_INET6) { struct ipv6_pinfo *np = inet6_sk(sk); int score = 0; @@ -323,7 +323,7 @@ static struct sock *udp_v6_mcast_next(struct sock *sk, sk_for_each_from(s, node) { struct inet_sock *inet = inet_sk(s); - if (s->sk_net != sk->sk_net) + if (sock_net(s) != sock_net(sk)) continue; if (s->sk_hash == num && s->sk_family == PF_INET6) { diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index 6f21a53cb3e7..ae54b20d0470 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c @@ -837,7 +837,7 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags) IRDA_DEBUG(2, "%s()\n", __func__); - err = irda_create(sk->sk_net, newsock, sk->sk_protocol); + err = irda_create(sock_net(sk), newsock, sk->sk_protocol); if (err) return err; diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c index 5ebfd93ff5e7..5c6d89c6d51d 100644 --- a/net/llc/llc_conn.c +++ b/net/llc/llc_conn.c @@ -700,7 +700,7 @@ static struct sock *llc_create_incoming_sock(struct sock *sk, struct llc_addr *saddr, struct llc_addr *daddr) { - struct sock *newsk = llc_sk_alloc(sk->sk_net, sk->sk_family, GFP_ATOMIC, + struct sock *newsk = llc_sk_alloc(sock_net(sk), sk->sk_family, GFP_ATOMIC, sk->sk_prot); struct llc_sock *newllc, *llc = llc_sk(sk); diff --git a/net/netfilter/nf_sockopt.c b/net/netfilter/nf_sockopt.c index 3dd4b3c76d81..69d699f95f4c 100644 --- a/net/netfilter/nf_sockopt.c +++ b/net/netfilter/nf_sockopt.c @@ -65,7 +65,7 @@ static struct nf_sockopt_ops *nf_sockopt_find(struct sock *sk, int pf, { struct nf_sockopt_ops *ops; - if (sk->sk_net != &init_net) + if (sock_net(sk) != &init_net) return ERR_PTR(-ENOPROTOOPT); if (mutex_lock_interruptible(&nf_sockopt_mutex) != 0) diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 86bd8660a8f2..712a7bff8560 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -228,7 +228,7 @@ static inline struct sock *netlink_lookup(struct net *net, int protocol, read_lock(&nl_table_lock); head = nl_pid_hashfn(hash, pid); sk_for_each(sk, node, head) { - if ((sk->sk_net == net) && (nlk_sk(sk)->pid == pid)) { + if (sock_net(sk) == net && (nlk_sk(sk)->pid == pid)) { sock_hold(sk); goto found; } @@ -348,7 +348,7 @@ static int netlink_insert(struct sock *sk, struct net *net, u32 pid) head = nl_pid_hashfn(hash, pid); len = 0; sk_for_each(osk, node, head) { - if ((osk->sk_net == net) && (nlk_sk(osk)->pid == pid)) + if (sock_net(osk) == net && (nlk_sk(osk)->pid == pid)) break; len++; } @@ -486,7 +486,7 @@ static int netlink_release(struct socket *sock) if (nlk->pid && !nlk->subscriptions) { struct netlink_notify n = { - .net = sk->sk_net, + .net = sock_net(sk), .protocol = sk->sk_protocol, .pid = nlk->pid, }; @@ -518,7 +518,7 @@ static int netlink_release(struct socket *sock) static int netlink_autobind(struct socket *sock) { struct sock *sk = sock->sk; - struct net *net = sk->sk_net; + struct net *net = sock_net(sk); struct nl_pid_hash *hash = &nl_table[sk->sk_protocol].hash; struct hlist_head *head; struct sock *osk; @@ -532,7 +532,7 @@ retry: netlink_table_grab(); head = nl_pid_hashfn(hash, pid); sk_for_each(osk, node, head) { - if ((osk->sk_net != net)) + if (sock_net(osk) != net) continue; if (nlk_sk(osk)->pid == pid) { /* Bind collision, search negative pid values. */ @@ -611,7 +611,7 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr, int addr_len) { struct sock *sk = sock->sk; - struct net *net = sk->sk_net; + struct net *net = sock_net(sk); struct netlink_sock *nlk = nlk_sk(sk); struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr; int err; @@ -720,7 +720,7 @@ static struct sock *netlink_getsockbypid(struct sock *ssk, u32 pid) struct sock *sock; struct netlink_sock *nlk; - sock = netlink_lookup(ssk->sk_net, ssk->sk_protocol, pid); + sock = netlink_lookup(sock_net(ssk), ssk->sk_protocol, pid); if (!sock) return ERR_PTR(-ECONNREFUSED); @@ -962,7 +962,7 @@ static inline int do_one_broadcast(struct sock *sk, !test_bit(p->group - 1, nlk->groups)) goto out; - if ((sk->sk_net != p->net)) + if (sock_net(sk) != p->net) goto out; if (p->failure) { @@ -1006,7 +1006,7 @@ out: int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, u32 pid, u32 group, gfp_t allocation) { - struct net *net = ssk->sk_net; + struct net *net = sock_net(ssk); struct netlink_broadcast_data info; struct hlist_node *node; struct sock *sk; @@ -1064,7 +1064,7 @@ static inline int do_one_set_err(struct sock *sk, if (sk == p->exclude_sk) goto out; - if (sk->sk_net != p->exclude_sk->sk_net) + if (sock_net(sk) != sock_net(p->exclude_sk)) goto out; if (nlk->pid == p->pid || p->group - 1 >= nlk->ngroups || @@ -1601,7 +1601,7 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb, atomic_inc(&skb->users); cb->skb = skb; - sk = netlink_lookup(ssk->sk_net, ssk->sk_protocol, NETLINK_CB(skb).pid); + sk = netlink_lookup(sock_net(ssk), ssk->sk_protocol, NETLINK_CB(skb).pid); if (sk == NULL) { netlink_destroy_callback(cb); return -ECONNREFUSED; @@ -1643,7 +1643,7 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err) if (!skb) { struct sock *sk; - sk = netlink_lookup(in_skb->sk->sk_net, + sk = netlink_lookup(sock_net(in_skb->sk), in_skb->sk->sk_protocol, NETLINK_CB(in_skb).pid); if (sk) { @@ -1758,7 +1758,7 @@ static struct sock *netlink_seq_socket_idx(struct seq_file *seq, loff_t pos) for (j = 0; j <= hash->mask; j++) { sk_for_each(s, node, &hash->table[j]) { - if (iter->p.net != s->sk_net) + if (sock_net(s) != iter->p.net) continue; if (off == pos) { iter->link = i; @@ -1794,7 +1794,7 @@ static void *netlink_seq_next(struct seq_file *seq, void *v, loff_t *pos) s = v; do { s = sk_next(s); - } while (s && (iter->p.net != s->sk_net)); + } while (s && (sock_net(s) != iter->p.net)); if (s) return s; @@ -1806,7 +1806,7 @@ static void *netlink_seq_next(struct seq_file *seq, void *v, loff_t *pos) for (; j <= hash->mask; j++) { s = sk_head(&hash->table[j]); - while (s && (iter->p.net != s->sk_net)) + while (s && sock_net(s) != iter->p.net) s = sk_next(s); if (s) { iter->link = i; diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c index a270ebf9f765..4bae8b998cab 100644 --- a/net/netrom/af_netrom.c +++ b/net/netrom/af_netrom.c @@ -466,7 +466,7 @@ static struct sock *nr_make_new(struct sock *osk) if (osk->sk_type != SOCK_SEQPACKET) return NULL; - sk = sk_alloc(osk->sk_net, PF_NETROM, GFP_ATOMIC, osk->sk_prot); + sk = sk_alloc(sock_net(osk), PF_NETROM, GFP_ATOMIC, osk->sk_prot); if (sk == NULL) return NULL; diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index baa290d3444a..25070240d4ae 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -263,7 +263,7 @@ static int packet_rcv_spkt(struct sk_buff *skb, struct net_device *dev, struct if (skb->pkt_type == PACKET_LOOPBACK) goto out; - if (dev_net(dev) != sk->sk_net) + if (dev_net(dev) != sock_net(sk)) goto out; if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) @@ -337,7 +337,7 @@ static int packet_sendmsg_spkt(struct kiocb *iocb, struct socket *sock, */ saddr->spkt_device[13] = 0; - dev = dev_get_by_name(sk->sk_net, saddr->spkt_device); + dev = dev_get_by_name(sock_net(sk), saddr->spkt_device); err = -ENODEV; if (dev == NULL) goto out_unlock; @@ -451,7 +451,7 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, struct packet sk = pt->af_packet_priv; po = pkt_sk(sk); - if (dev_net(dev) != sk->sk_net) + if (dev_net(dev) != sock_net(sk)) goto drop; skb->dev = dev; @@ -568,7 +568,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe sk = pt->af_packet_priv; po = pkt_sk(sk); - if (dev_net(dev) != sk->sk_net) + if (dev_net(dev) != sock_net(sk)) goto drop; if (dev->header_ops) { @@ -728,7 +728,7 @@ static int packet_sendmsg(struct kiocb *iocb, struct socket *sock, } - dev = dev_get_by_index(sk->sk_net, ifindex); + dev = dev_get_by_index(sock_net(sk), ifindex); err = -ENXIO; if (dev == NULL) goto out_unlock; @@ -800,7 +800,7 @@ static int packet_release(struct socket *sock) if (!sk) return 0; - net = sk->sk_net; + net = sock_net(sk); po = pkt_sk(sk); write_lock_bh(&net->packet.sklist_lock); @@ -914,7 +914,7 @@ static int packet_bind_spkt(struct socket *sock, struct sockaddr *uaddr, int add return -EINVAL; strlcpy(name,uaddr->sa_data,sizeof(name)); - dev = dev_get_by_name(sk->sk_net, name); + dev = dev_get_by_name(sock_net(sk), name); if (dev) { err = packet_do_bind(sk, dev, pkt_sk(sk)->num); dev_put(dev); @@ -941,7 +941,7 @@ static int packet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len if (sll->sll_ifindex) { err = -ENODEV; - dev = dev_get_by_index(sk->sk_net, sll->sll_ifindex); + dev = dev_get_by_index(sock_net(sk), sll->sll_ifindex); if (dev == NULL) goto out; } @@ -1135,7 +1135,7 @@ static int packet_getname_spkt(struct socket *sock, struct sockaddr *uaddr, return -EOPNOTSUPP; uaddr->sa_family = AF_PACKET; - dev = dev_get_by_index(sk->sk_net, pkt_sk(sk)->ifindex); + dev = dev_get_by_index(sock_net(sk), pkt_sk(sk)->ifindex); if (dev) { strlcpy(uaddr->sa_data, dev->name, 15); dev_put(dev); @@ -1160,7 +1160,7 @@ static int packet_getname(struct socket *sock, struct sockaddr *uaddr, sll->sll_family = AF_PACKET; sll->sll_ifindex = po->ifindex; sll->sll_protocol = po->num; - dev = dev_get_by_index(sk->sk_net, po->ifindex); + dev = dev_get_by_index(sock_net(sk), po->ifindex); if (dev) { sll->sll_hatype = dev->type; sll->sll_halen = dev->addr_len; @@ -1212,7 +1212,7 @@ static int packet_mc_add(struct sock *sk, struct packet_mreq_max *mreq) rtnl_lock(); err = -ENODEV; - dev = __dev_get_by_index(sk->sk_net, mreq->mr_ifindex); + dev = __dev_get_by_index(sock_net(sk), mreq->mr_ifindex); if (!dev) goto done; @@ -1266,7 +1266,7 @@ static int packet_mc_drop(struct sock *sk, struct packet_mreq_max *mreq) if (--ml->count == 0) { struct net_device *dev; *mlp = ml->next; - dev = dev_get_by_index(sk->sk_net, ml->ifindex); + dev = dev_get_by_index(sock_net(sk), ml->ifindex); if (dev) { packet_dev_mc(dev, ml, -1); dev_put(dev); @@ -1294,7 +1294,7 @@ static void packet_flush_mclist(struct sock *sk) struct net_device *dev; po->mclist = ml->next; - if ((dev = dev_get_by_index(sk->sk_net, ml->ifindex)) != NULL) { + if ((dev = dev_get_by_index(sock_net(sk), ml->ifindex)) != NULL) { packet_dev_mc(dev, ml, -1); dev_put(dev); } @@ -1540,7 +1540,7 @@ static int packet_ioctl(struct socket *sock, unsigned int cmd, case SIOCGIFDSTADDR: case SIOCSIFDSTADDR: case SIOCSIFFLAGS: - if (sk->sk_net != &init_net) + if (sock_net(sk) != &init_net) return -ENOIOCTLCMD; return inet_dgram_ops.ioctl(sock, cmd, arg); #endif diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index 1a7f143cf741..92d85c38e4d2 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c @@ -551,7 +551,7 @@ static struct sock *rose_make_new(struct sock *osk) if (osk->sk_type != SOCK_SEQPACKET) return NULL; - sk = sk_alloc(osk->sk_net, PF_ROSE, GFP_ATOMIC, &rose_proto); + sk = sk_alloc(sock_net(osk), PF_ROSE, GFP_ATOMIC, &rose_proto); if (sk == NULL) return NULL; diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 0b8eb235bc13..74e662cbb2c5 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -951,7 +951,7 @@ done: static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n, void *arg) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); struct nlattr *tca[TCA_ACT_MAX + 1]; u32 pid = skb ? NETLINK_CB(skb).pid : 0; int ret = 0, ovr = 0; @@ -1029,7 +1029,7 @@ find_dump_kind(struct nlmsghdr *n) static int tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); struct nlmsghdr *nlh; unsigned char *b = skb_tail_pointer(skb); struct nlattr *nest; diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 0fbedcabf111..1086df7478bc 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -118,7 +118,7 @@ static inline u32 tcf_auto_prio(struct tcf_proto *tp) static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); struct nlattr *tca[TCA_MAX + 1]; struct tcmsg *t; u32 protocol; @@ -389,7 +389,7 @@ static int tcf_node_dump(struct tcf_proto *tp, unsigned long n, static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); int t; int s_t; struct net_device *dev; diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 7e3c048ba9b1..15b91a9ee8e8 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -605,7 +605,7 @@ check_loop_fn(struct Qdisc *q, unsigned long cl, struct qdisc_walker *w) static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); struct tcmsg *tcm = NLMSG_DATA(n); struct nlattr *tca[TCA_MAX + 1]; struct net_device *dev; @@ -674,7 +674,7 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg) static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); struct tcmsg *tcm; struct nlattr *tca[TCA_MAX + 1]; struct net_device *dev; @@ -893,7 +893,7 @@ err_out: static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); int idx, q_idx; int s_idx, s_q_idx; struct net_device *dev; @@ -945,7 +945,7 @@ done: static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); struct tcmsg *tcm = NLMSG_DATA(n); struct nlattr *tca[TCA_MAX + 1]; struct net_device *dev; @@ -1139,7 +1139,7 @@ static int qdisc_class_dump(struct Qdisc *q, unsigned long cl, struct qdisc_walk static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); int t; int s_t; struct net_device *dev; diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index dc71d0d83753..036bfcc8d15b 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c @@ -636,7 +636,7 @@ static struct sock *sctp_v6_create_accept_sk(struct sock *sk, struct ipv6_pinfo *newnp, *np = inet6_sk(sk); struct sctp6_sock *newsctp6sk; - newsk = sk_alloc(sk->sk_net, PF_INET6, GFP_KERNEL, sk->sk_prot); + newsk = sk_alloc(sock_net(sk), PF_INET6, GFP_KERNEL, sk->sk_prot); if (!newsk) goto out; diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 2faa0d8839eb..5aea91137fbb 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -554,7 +554,7 @@ static struct sock *sctp_v4_create_accept_sk(struct sock *sk, { struct inet_sock *inet = inet_sk(sk); struct inet_sock *newinet; - struct sock *newsk = sk_alloc(sk->sk_net, PF_INET, GFP_KERNEL, + struct sock *newsk = sk_alloc(sock_net(sk), PF_INET, GFP_KERNEL, sk->sk_prot); if (!newsk) diff --git a/net/socket.c b/net/socket.c index 9d3fbfbc8535..79e5382fd110 100644 --- a/net/socket.c +++ b/net/socket.c @@ -857,7 +857,7 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg) sock = file->private_data; sk = sock->sk; - net = sk->sk_net; + net = sock_net(sk); if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) { err = dev_ioctl(net, cmd, argp); } else @@ -1375,7 +1375,7 @@ asmlinkage long sys_listen(int fd, int backlog) sock = sockfd_lookup_light(fd, &err, &fput_needed); if (sock) { - somaxconn = sock->sk->sk_net->sysctl_somaxconn; + somaxconn = sock_net(sock->sk)->sysctl_somaxconn; if ((unsigned)backlog > somaxconn) backlog = somaxconn; diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 3220d5cb5b5d..ae45df060e3a 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -1375,7 +1375,7 @@ static int accept(struct socket *sock, struct socket *newsock, int flags) } buf = skb_peek(&sock->sk->sk_receive_queue); - res = tipc_create(sock->sk->sk_net, newsock, 0); + res = tipc_create(sock_net(sock->sk), newsock, 0); if (!res) { struct tipc_sock *new_tsock = tipc_sk(newsock->sk); struct tipc_portid id; diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index ae584356852c..cb9d0cb5f270 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -252,7 +252,7 @@ static struct sock *__unix_find_socket_byname(struct net *net, sk_for_each(s, node, &unix_socket_table[hash ^ type]) { struct unix_sock *u = unix_sk(s); - if (s->sk_net != net) + if (sock_net(s) != net) continue; if (u->addr->len == len && @@ -289,7 +289,7 @@ static struct sock *unix_find_socket_byinode(struct net *net, struct inode *i) &unix_socket_table[i->i_ino & (UNIX_HASH_SIZE - 1)]) { struct dentry *dentry = unix_sk(s)->dentry; - if (s->sk_net != net) + if (sock_net(s) != net) continue; if(dentry && dentry->d_inode == i) @@ -654,7 +654,7 @@ static int unix_release(struct socket *sock) static int unix_autobind(struct socket *sock) { struct sock *sk = sock->sk; - struct net *net = sk->sk_net; + struct net *net = sock_net(sk); struct unix_sock *u = unix_sk(sk); static u32 ordernum = 1; struct unix_address * addr; @@ -758,7 +758,7 @@ fail: static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) { struct sock *sk = sock->sk; - struct net *net = sk->sk_net; + struct net *net = sock_net(sk); struct unix_sock *u = unix_sk(sk); struct sockaddr_un *sunaddr=(struct sockaddr_un *)uaddr; struct dentry * dentry = NULL; @@ -899,7 +899,7 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags) { struct sock *sk = sock->sk; - struct net *net = sk->sk_net; + struct net *net = sock_net(sk); struct sockaddr_un *sunaddr=(struct sockaddr_un*)addr; struct sock *other; unsigned hash; @@ -996,7 +996,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr, { struct sockaddr_un *sunaddr=(struct sockaddr_un *)uaddr; struct sock *sk = sock->sk; - struct net *net = sk->sk_net; + struct net *net = sock_net(sk); struct unix_sock *u = unix_sk(sk), *newu, *otheru; struct sock *newsk = NULL; struct sock *other = NULL; @@ -1025,7 +1025,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr, err = -ENOMEM; /* create new sock for complete connection */ - newsk = unix_create1(sk->sk_net, NULL); + newsk = unix_create1(sock_net(sk), NULL); if (newsk == NULL) goto out; @@ -1312,7 +1312,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, { struct sock_iocb *siocb = kiocb_to_siocb(kiocb); struct sock *sk = sock->sk; - struct net *net = sk->sk_net; + struct net *net = sock_net(sk); struct unix_sock *u = unix_sk(sk); struct sockaddr_un *sunaddr=msg->msg_name; struct sock *other = NULL; @@ -2022,7 +2022,7 @@ static struct sock *unix_seq_idx(struct unix_iter_state *iter, loff_t pos) struct sock *s; for (s = first_unix_socket(&iter->i); s; s = next_unix_socket(&iter->i, s)) { - if (s->sk_net != iter->p.net) + if (sock_net(s) != iter->p.net) continue; if (off == pos) return s; @@ -2050,7 +2050,7 @@ static void *unix_seq_next(struct seq_file *seq, void *v, loff_t *pos) sk = first_unix_socket(&iter->i); else sk = next_unix_socket(&iter->i, sk); - while (sk && (sk->sk_net != iter->p.net)) + while (sk && (sock_net(sk) != iter->p.net)) sk = next_unix_socket(&iter->i, sk); return sk; } diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index 7a46ea73fe2d..6ba67c523c16 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -549,7 +549,7 @@ static struct sock *x25_make_new(struct sock *osk) if (osk->sk_type != SOCK_SEQPACKET) goto out; - if ((sk = x25_alloc_socket(osk->sk_net)) == NULL) + if ((sk = x25_alloc_socket(sock_net(osk))) == NULL) goto out; x25 = x25_sk(sk); -- cgit v1.2.3 From ff4e1fb0be7386e97580d50f09a804b33b58377a Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Thu, 10 Apr 2008 15:41:28 +0900 Subject: [IPV6] FIB_RULE: Sparse: fib6_rules_cleanup() is of void. | net/ipv6/fib6_rules.c:319:2: warning: returning void-valued expression Signed-off-by: YOSHIFUJI Hideaki --- net/ipv6/fib6_rules.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net/ipv6/fib6_rules.c') diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index cac580749ebe..8d05527524e3 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c @@ -316,5 +316,5 @@ int __init fib6_rules_init(void) void fib6_rules_cleanup(void) { - return unregister_pernet_subsys(&fib6_rules_net_ops); + unregister_pernet_subsys(&fib6_rules_net_ops); } -- cgit v1.2.3