Home » Mailing lists » Devel » [RFC] network namespaces
[PATCH 2/9] network namespaces: IPv4 routing [message #5167 is a reply to message #5165] |
Tue, 15 August 2006 14:48   |
Andrey Savochkin
Messages: 47 Registered: December 2005
|
Member |
|
|
Structures related to IPv4 rounting (FIB and routing cache)
are made per-namespace.
Signed-off-by: Andrey Savochkin <saw@swsoft.com>
---
include/linux/net_ns.h | 10 +++
include/net/flow.h | 3 +
include/net/ip_fib.h | 46 ++++++++++++----
net/core/dev.c | 8 ++
net/core/fib_rules.c | 43 ++++++++++++---
net/ipv4/Kconfig | 4 -
net/ipv4/fib_frontend.c | 132 +++++++++++++++++++++++++++++++++++++----------
net/ipv4/fib_hash.c | 13 +++-
net/ipv4/fib_rules.c | 86 +++++++++++++++++++++++++-----
net/ipv4/fib_semantics.c | 99 +++++++++++++++++++++++------------
net/ipv4/route.c | 26 ++++++++-
11 files changed, 375 insertions(+), 95 deletions(-)
--- ./include/linux/net_ns.h.vensroute Mon Aug 14 17:18:59 2006
+++ ./include/linux/net_ns.h Mon Aug 14 19:19:14 2006
@@ -14,7 +14,17 @@ struct net_namespace {
atomic_t active_ref, use_ref;
struct net_device *dev_base_p, **dev_tail_p;
struct net_device *loopback;
+#ifndef CONFIG_IP_MULTIPLE_TABLES
+ struct fib_table *fib4_local_table, *fib4_main_table;
+#else
+ struct list_head fib_rules_ops_list;
+ struct fib_rules_ops *fib4_rules_ops;
+ struct hlist_head *fib4_tables;
+#endif
+ struct hlist_head *fib4_hash, *fib4_laddrhash;
+ unsigned fib4_hash_size, fib4_info_cnt;
unsigned int hash;
+ char destroying;
struct work_struct destroy_work;
};
--- ./include/net/flow.h.vensroute Mon Aug 14 17:04:04 2006
+++ ./include/net/flow.h Mon Aug 14 17:18:59 2006
@@ -79,6 +79,9 @@ struct flowi {
#define fl_icmp_code uli_u.icmpt.code
#define fl_ipsec_spi uli_u.spi
__u32 secid; /* used by xfrm; see secid.txt */
+#ifdef CONFIG_NET_NS
+ struct net_namespace *net_ns;
+#endif
} __attribute__((__aligned__(BITS_PER_LONG/8)));
#define FLOW_DIR_IN 0
--- ./include/net/ip_fib.h.vensroute Mon Aug 14 17:04:04 2006
+++ ./include/net/ip_fib.h Tue Aug 15 11:53:22 2006
@@ -18,6 +18,7 @@
#include <net/flow.h>
#include <linux/seq_file.h>
+#include <linux/net_ns.h>
#include <net/fib_rules.h>
/* WARNING: The ordering of these elements must match ordering
@@ -171,14 +172,21 @@ struct fib_table {
#ifndef CONFIG_IP_MULTIPLE_TABLES
-extern struct fib_table *ip_fib_local_table;
-extern struct fib_table *ip_fib_main_table;
+#ifndef CONFIG_NET_NS
+extern struct fib_table *ip_fib_local_table_static;
+extern struct fib_table *ip_fib_main_table_static;
+#define ip_fib_local_table_ns() ip_fib_local_table_static
+#define ip_fib_main_table_ns() ip_fib_main_table_static
+#else
+#define ip_fib_local_table_ns() (current_net_ns->fib4_local_table)
+#define ip_fib_main_table_ns() (current_net_ns->fib4_main_table)
+#endif
static inline struct fib_table *fib_get_table(u32 id)
{
if (id != RT_TABLE_LOCAL)
- return ip_fib_main_table;
- return ip_fib_local_table;
+ return ip_fib_main_table_ns();
+ return ip_fib_local_table_ns();
}
static inline struct fib_table *fib_new_table(u32 id)
@@ -188,21 +196,29 @@ static inline struct fib_table *fib_new_
static inline int fib_lookup(const struct flowi *flp, struct fib_result *res)
{
- if (ip_fib_local_table->tb_lookup(ip_fib_local_table, flp, res) &&
- ip_fib_main_table->tb_lookup(ip_fib_main_table, flp, res))
+ struct fib_table *tb;
+
+ tb = ip_fib_local_table_ns();
+ if (!tb->tb_lookup(tb, flp, res))
+ return 0;
+ tb = ip_fib_main_table_ns();
+ if (tb->tb_lookup(tb, flp, res))
return -ENETUNREACH;
return 0;
}
static inline void fib_select_default(const struct flowi *flp, struct fib_result *res)
{
+ struct fib_table *tb;
+
+ tb = ip_fib_main_table_ns();
if (FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK)
- ip_fib_main_table->tb_select_default(ip_fib_main_table, flp, res);
+ tb->tb_select_default(main_table, flp, res);
}
#else /* CONFIG_IP_MULTIPLE_TABLES */
-#define ip_fib_local_table fib_get_table(RT_TABLE_LOCAL)
-#define ip_fib_main_table fib_get_table(RT_TABLE_MAIN)
+#define ip_fib_local_table_ns() fib_get_table(RT_TABLE_LOCAL)
+#define ip_fib_main_table_ns() fib_get_table(RT_TABLE_MAIN)
extern int fib_lookup(struct flowi *flp, struct fib_result *res);
@@ -214,6 +230,10 @@ extern void fib_select_default(const str
/* Exported by fib_frontend.c */
extern void ip_fib_init(void);
+#ifdef CONFIG_NET_NS
+extern int ip_fib_struct_init(void);
+extern void ip_fib_struct_cleanup(void);
+#endif
extern int inet_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg);
extern int inet_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg);
extern int inet_rtm_getroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg);
@@ -231,6 +251,9 @@ extern int fib_sync_up(struct net_device
extern int fib_convert_rtentry(int cmd, struct nlmsghdr *nl, struct rtmsg *rtm,
struct kern_rta *rta, struct rtentry *r);
extern u32 __fib_res_prefsrc(struct fib_result *res);
+#ifdef CONFIG_NET_NS
+extern void fib_hashtable_destroy(void);
+#endif
/* Exported by fib_hash.c */
extern struct fib_table *fib_hash_init(u32 id);
@@ -238,7 +261,10 @@ extern struct fib_table *fib_hash_init(u
#ifdef CONFIG_IP_MULTIPLE_TABLES
extern int fib4_rules_dump(struct sk_buff *skb, struct netlink_callback *cb);
-extern void __init fib4_rules_init(void);
+extern int fib4_rules_init(void);
+#ifdef CONFIG_NET_NS
+extern void fib4_rules_cleanup(void);
+#endif
#ifdef CONFIG_NET_CLS_ROUTE
extern u32 fib_rules_tclass(struct fib_result *res);
--- ./net/core/dev.c.vensroute Mon Aug 14 17:18:59 2006
+++ ./net/core/dev.c Mon Aug 14 17:18:59 2006
@@ -3548,6 +3548,8 @@ static int __init netdev_dma_register(vo
#endif /* CONFIG_NET_DMA */
#ifdef CONFIG_NET_NS
+#include <net/ip_fib.h>
+
struct net_namespace init_net_ns = {
.active_ref = ATOMIC_INIT(2),
/* one for init_task->net_context,
@@ -3588,6 +3590,9 @@ int net_ns_start(void)
task = current;
orig_ns = task->net_context;
task->net_context = ns;
+ INIT_LIST_HEAD(&ns->fib_rules_ops_list);
+ if (ip_fib_struct_init())
+ goto out_fib4;
err = register_netdev(dev);
if (err)
goto out_register;
@@ -3595,6 +3600,8 @@ int net_ns_start(void)
return 0;
out_register:
+ ip_fib_struct_cleanup();
+out_fib4:
dev->destructor(dev);
task->net_context = orig_ns;
BUG_ON(atomic_read(&ns->active_ref) != 1);
@@ -3619,6 +3626,7 @@ static void net_ns_destroy(void *data)
pop_net_ns(orig_ns);
return;
}
+ ip_fib_struct_cleanup();
pop_net_ns(orig_ns);
kfree(ns);
}
--- ./net/core/fib_rules.c.vensroute Mon Aug 14 17:04:05 2006
+++ ./net/core/fib_rules.c Mon Aug 14 17:18:59 2006
@@ -11,9 +11,15 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/list.h>
+#include <linux/net_ns.h>
#include <net/fib_rules.h>
-static LIST_HEAD(rules_ops);
+#ifndef CONFIG_NET_NS
+static struct list_head rules_ops_static;
+#define rules_ops_ns() rules_ops_static
+#else
+#define rules_ops_ns() (current_net_ns->fib_rules_ops_list)
+#endif
static DEFINE_SPINLOCK(rules_mod_lock);
static void notify_rule_change(int event, struct fib_rule *rule,
@@ -21,10 +27,12 @@ static void notify_rule_change(int event
static struct fib_rules_ops *lookup_rules_ops(int family)
{
+ struct list_head *ops_list;
struct fib_rules_ops *ops;
+ ops_list = &rules_ops_ns();
rcu_read_lock();
- list_for_each_entry_rcu(ops, &rules_ops, list) {
+ list_for_each_entry_rcu(ops, ops_list, list) {
if (ops->family == family) {
if (!try_module_get(ops->owner))
ops = NULL;
@@ -46,6 +54,7 @@ static void rules_ops_put(struct fib_rul
int fib_rules_register(struct fib_rules_ops *ops)
{
int err = -EEXIST;
+ struct list_head *ops_list;
struct fib_rules_ops *o;
if (ops->rule_size < sizeof(struct fib_rule))
@@ -56,12 +65,13 @@ int fib_rules_register(struct fib_rules_
ops->action == NULL)
return -EINVAL;
+ ops_list = &rules_ops_ns();
spin_lock(&rules_mod_lock);
- list_for_each_entry(o, &rules_ops, list)
+ list_for_each_entry(o, ops_list, list)
if (ops->family == o->family)
goto errout;
- list_add_tail_rcu(&ops->list, &rules_ops);
+ list_add_tail_rcu(&ops->list, ops_list);
err = 0;
errout:
spin_unlock(&rules_mod_lock);
@@ -84,10 +94,12 @@ static void cleanup_ops(struct fib_rules
int fib_rules_unregister(struct fib_rules_ops *ops)
{
int err = 0;
+ struct list_head *ops_list;
struct fib_rules_ops *o;
+ ops_list = &rules_ops_ns();
spin_lock(&rules_mod_lock);
- list_for_each_entry(o, &rules_ops, list) {
+ list_for_each_entry(o, ops_list, list) {
if (o == ops) {
list_del_rcu(&o->list);
cleanup_ops(ops);
@@ -114,6 +126,14 @@ int fib_rules_lookup(struct fib_rules_op
rcu_read_lock();
+ err = -EINVAL;
+ if (ops->rules_list->next == NULL) {
+ if (net_ratelimit())
+ printk(" *** NULL head, ops %p, list %p\n",
+ ops, ops->rules_list);
+ goto out;
+ }
+
list_for_each_entry_rcu(rule, ops->rules_list, list) {
if (rule->ifindex && (rule->ifindex != fl->iif))
continue;
@@ -127,6 +147,12 @@ int fib_rules_lookup(struct fib_rules_op
arg->rule = rule;
goto out;
}
+ if (rule->list.next == NULL) {
+ if (net_ratelimit())
+ printk(" *** NULL, ops %p, list %p, item %p\n",
+ ops, ops->rules_list, rule);
+ goto out;
+ }
}
err = -ENETUNREACH;
@@ -382,19 +408,21 @@ static int fib_rules_event(struct notifi
void *ptr)
{
struct net_device *dev = ptr;
+ struct list_head *ops_list;
struct fib_rules_ops *ops;
ASSERT_RTNL();
rcu_read_lock();
+ ops_list = &rules_ops_ns();
switch (event) {
case NETDEV_REGISTER:
- list_for_each_entry(ops, &rules_ops, list)
+ list_for_each_entry(ops, ops_list, list)
attach_rules(ops->rules_list, dev);
break;
case NETDEV_UNREGISTER:
- list
...
|
|
|
 |
|
[RFC] network namespaces
|
 |
|
[PATCH 1/9] network namespaces: core and device list
|
 |
|
Re: [PATCH 1/9] network namespaces: core and device list
|
 |
|
Re: [PATCH 1/9] network namespaces: core and device list
|
 |
|
[PATCH 2/9] network namespaces: IPv4 routing
|
 |
|
[PATCH 6/9] allow proc_dir_entries to have destructor
|
 |
|
[PATCH 5/9] network namespaces: async socket operations
|
 |
|
Re: [PATCH 5/9] network namespaces: async socket operations
|
 |
|
Re: [PATCH 5/9] network namespaces: async socket operations
|
 |
|
[PATCH 7/9] net_device seq_file
|
 |
|
[PATCH 8/9] network namespaces: device to pass packets between namespaces
|
 |
|
[PATCH 4/9] network namespaces: socket hashes
|
 |
|
Re: [PATCH 4/9] network namespaces: socket hashes
|
 |
|
Re: [PATCH 4/9] network namespaces: socket hashes
|
 |
|
Re: [PATCH 4/9] network namespaces: socket hashes
|
 |
|
[PATCH 9/9] network namespaces: playing with pass-through device
|
 |
|
Re: [RFC] network namespaces
By: serue on Wed, 16 August 2006 11:53
|
 |
|
Re: [RFC] network namespaces
|
 |
|
Re: [RFC] network namespaces
By: ebiederm on Wed, 16 August 2006 17:35
|
 |
|
Re: [RFC] network namespaces
By: dev on Thu, 17 August 2006 08:28
|
 |
|
Re: [RFC] network namespaces
|
 |
|
Re: [RFC] network namespaces
By: ebiederm on Tue, 05 September 2006 14:45
|
 |
|
Re: [RFC] network namespaces
|
 |
|
Re: [RFC] network namespaces
|
 |
|
Re: [RFC] network namespaces
|
 |
|
Re: Re: [RFC] network namespaces
By: kir on Wed, 06 September 2006 17:36
|
 |
|
Re: [RFC] network namespaces
By: ebiederm on Wed, 06 September 2006 18:34
|
 |
|
Re: [RFC] network namespaces
By: kir on Wed, 06 September 2006 18:56
|
 |
|
Re: [RFC] network namespaces
|
 |
|
RE: [RFC] network namespaces
|
 |
|
Re: [RFC] network namespaces
|
 |
|
Re: [RFC] network namespaces
By: ebiederm on Thu, 07 September 2006 18:29
|
 |
|
Re: [RFC] network namespaces
|
 |
|
Re: Re: [RFC] network namespaces
By: dev on Thu, 07 September 2006 16:20
|
 |
|
Re: Re: [RFC] network namespaces
|
 |
|
Re: Re: [RFC] network namespaces
|
 |
|
Re: Re: [RFC] network namespaces
|
 |
|
Re: Re: [RFC] network namespaces
|
 |
|
Re: Re: [RFC] network namespaces
|
 |
|
Re: Re: [RFC] network namespaces
|
 |
|
Re: Re: [RFC] network namespaces
|
 |
|
Re: [RFC] network namespaces
By: ebiederm on Tue, 12 September 2006 03:26
|
 |
|
Re: Re: [RFC] network namespaces
By: ebiederm on Sun, 10 September 2006 03:41
|
 |
|
Re: Re: [RFC] network namespaces
|
 |
|
Re: Re: [RFC] network namespaces
|
 |
|
Re: Re: [RFC] network namespaces
|
 |
|
Re: Re: [RFC] network namespaces
|
 |
|
Re: Re: [RFC] network namespaces
|
 |
|
Re: Re: [RFC] network namespaces
|
 |
|
Re: [RFC] network namespaces
By: ebiederm on Tue, 12 September 2006 03:28
|
 |
|
Re: [RFC] network namespaces
|
 |
|
Re: Re: [RFC] network namespaces
By: ebiederm on Thu, 07 September 2006 19:50
|
 |
|
Re: Re: [RFC] network namespaces
|
 |
|
Re: [RFC] network namespaces
By: ebiederm on Wed, 06 September 2006 17:58
|
 |
|
Re: [RFC] network namespaces
By: ebiederm on Tue, 05 September 2006 18:27
|
 |
|
Re: [RFC] network namespaces
By: dev on Wed, 06 September 2006 14:52
|
 |
|
Re: [RFC] network namespaces
|
 |
|
Re: [RFC] network namespaces
By: dev on Tue, 05 September 2006 15:44
|
 |
|
Re: [RFC] network namespaces
By: ebiederm on Tue, 05 September 2006 17:09
|
 |
|
Re: [RFC] network namespaces
|
 |
|
Re: Re: [RFC] network namespaces
By: kir on Wed, 06 September 2006 15:09
|
 |
|
Re: [RFC] network namespaces
By: ebiederm on Wed, 06 September 2006 20:40
|
 |
|
Re: [RFC] network namespaces
By: ebiederm on Wed, 06 September 2006 23:25
|
 |
|
Re: [RFC] network namespaces
|
 |
|
Re: [RFC] network namespaces
By: ebiederm on Thu, 07 September 2006 05:11
|
 |
|
Re: [RFC] network namespaces
|
 |
|
Re: [RFC] network namespaces
By: ebiederm on Sun, 10 September 2006 11:48
|
Goto Forum:
Current Time: Mon Sep 08 23:30:46 GMT 2025
Total time taken to generate the page: 0.07863 seconds
|