Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 34411
b: refs/heads/master
c: c71099a
h: refs/heads/master
i:
  34409: 6028c54
  34407: 640ba1d
v: v3
  • Loading branch information
Thomas Graf authored and David S. Miller committed Sep 22, 2006
1 parent d1cec67 commit 2c4f6c9
Show file tree
Hide file tree
Showing 7 changed files with 442 additions and 138 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 5d0bbeeb144f631150881712607345c532e38e7e
refs/heads/master: c71099acce933455123ee505cc75964610a209ad
39 changes: 38 additions & 1 deletion trunk/include/net/ip6_fib.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ struct rt6key
int plen;
};

struct fib6_table;

struct rt6_info
{
union {
Expand All @@ -71,6 +73,7 @@ struct rt6_info
u32 rt6i_flags;
u32 rt6i_metric;
atomic_t rt6i_ref;
struct fib6_table *rt6i_table;

struct rt6key rt6i_dst;
struct rt6key rt6i_src;
Expand Down Expand Up @@ -143,12 +146,43 @@ struct rt6_statistics {

typedef void (*f_pnode)(struct fib6_node *fn, void *);

extern struct fib6_node ip6_routing_table;
struct fib6_table {
struct hlist_node tb6_hlist;
u32 tb6_id;
rwlock_t tb6_lock;
struct fib6_node tb6_root;
};

#define RT6_TABLE_UNSPEC RT_TABLE_UNSPEC
#define RT6_TABLE_MAIN RT_TABLE_MAIN
#define RT6_TABLE_LOCAL RT6_TABLE_MAIN
#define RT6_TABLE_DFLT RT6_TABLE_MAIN
#define RT6_TABLE_INFO RT6_TABLE_MAIN
#define RT6_TABLE_PREFIX RT6_TABLE_MAIN

#ifdef CONFIG_IPV6_MULTIPLE_TABLES
#define FIB6_TABLE_MIN 1
#define FIB6_TABLE_MAX RT_TABLE_MAX
#else
#define FIB6_TABLE_MIN RT_TABLE_MAIN
#define FIB6_TABLE_MAX FIB6_TABLE_MIN
#endif

#define RT6_F_STRICT 1
#define RT6_F_HAS_SADDR 2

typedef struct rt6_info *(*pol_lookup_t)(struct fib6_table *,
struct flowi *, int);

/*
* 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_node *fib6_lookup(struct fib6_node *root,
struct in6_addr *daddr,
struct in6_addr *saddr);
Expand All @@ -161,6 +195,9 @@ extern void fib6_clean_tree(struct fib6_node *root,
int (*func)(struct rt6_info *, void *arg),
int prune, void *arg);

extern void fib6_clean_all(int (*func)(struct rt6_info *, void *arg),
int prune, void *arg);

extern int fib6_walk(struct fib6_walker_t *w);
extern int fib6_walk_continue(struct fib6_walker_t *w);

Expand Down
3 changes: 2 additions & 1 deletion trunk/include/net/ip6_route.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ extern int ipv6_route_ioctl(unsigned int cmd, void __user *arg);
extern int ip6_route_add(struct in6_rtmsg *rtmsg,
struct nlmsghdr *,
void *rtattr,
struct netlink_skb_parms *req);
struct netlink_skb_parms *req,
u32 table_id);
extern int ip6_ins_rt(struct rt6_info *,
struct nlmsghdr *,
void *rtattr,
Expand Down
6 changes: 6 additions & 0 deletions trunk/net/ipv6/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,9 @@ config IPV6_TUNNEL

If unsure, say N.

config IPV6_MULTIPLE_TABLES
bool "IPv6: Multiple Routing Tables"
depends on IPV6 && EXPERIMENTAL
---help---
Support multiple routing tables.

6 changes: 3 additions & 3 deletions trunk/net/ipv6/addrconf.c
Original file line number Diff line number Diff line change
Expand Up @@ -1525,7 +1525,7 @@ addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev,
if (dev->type == ARPHRD_SIT && (dev->flags&IFF_POINTOPOINT))
rtmsg.rtmsg_flags |= RTF_NONEXTHOP;

ip6_route_add(&rtmsg, NULL, NULL, NULL);
ip6_route_add(&rtmsg, NULL, NULL, NULL, RT6_TABLE_PREFIX);
}

/* Create "default" multicast route to the interface */
Expand All @@ -1542,7 +1542,7 @@ static void addrconf_add_mroute(struct net_device *dev)
rtmsg.rtmsg_ifindex = dev->ifindex;
rtmsg.rtmsg_flags = RTF_UP;
rtmsg.rtmsg_type = RTMSG_NEWROUTE;
ip6_route_add(&rtmsg, NULL, NULL, NULL);
ip6_route_add(&rtmsg, NULL, NULL, NULL, RT6_TABLE_LOCAL);
}

static void sit_route_add(struct net_device *dev)
Expand All @@ -1559,7 +1559,7 @@ static void sit_route_add(struct net_device *dev)
rtmsg.rtmsg_flags = RTF_UP|RTF_NONEXTHOP;
rtmsg.rtmsg_ifindex = dev->ifindex;

ip6_route_add(&rtmsg, NULL, NULL, NULL);
ip6_route_add(&rtmsg, NULL, NULL, NULL, RT6_TABLE_MAIN);
}

static void addrconf_add_lroute(struct net_device *dev)
Expand Down
144 changes: 140 additions & 4 deletions trunk/net/ipv6/ip6_fib.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <linux/netdevice.h>
#include <linux/in6.h>
#include <linux/init.h>
#include <linux/list.h>

#ifdef CONFIG_PROC_FS
#include <linux/proc_fs.h>
Expand Down Expand Up @@ -147,6 +148,126 @@ static __inline__ void rt6_release(struct rt6_info *rt)
dst_free(&rt->u.dst);
}

static struct fib6_table fib6_main_tbl = {
.tb6_id = RT6_TABLE_MAIN,
.tb6_lock = RW_LOCK_UNLOCKED,
.tb6_root = {
.leaf = &ip6_null_entry,
.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO,
},
};

#ifdef CONFIG_IPV6_MULTIPLE_TABLES

#define FIB_TABLE_HASHSZ 256
static struct hlist_head fib_table_hash[FIB_TABLE_HASHSZ];

static struct fib6_table *fib6_alloc_table(u32 id)
{
struct fib6_table *table;

table = kzalloc(sizeof(*table), GFP_ATOMIC);
if (table != NULL) {
table->tb6_id = id;
table->tb6_lock = RW_LOCK_UNLOCKED;
table->tb6_root.leaf = &ip6_null_entry;
table->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO;
}

return table;
}

static void fib6_link_table(struct fib6_table *tb)
{
unsigned int h;

h = tb->tb6_id & (FIB_TABLE_HASHSZ - 1);

/*
* 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]);
}

struct fib6_table *fib6_new_table(u32 id)
{
struct fib6_table *tb;

if (id == 0)
id = RT6_TABLE_MAIN;
tb = fib6_get_table(id);
if (tb)
return tb;

tb = fib6_alloc_table(id);
if (tb != NULL)
fib6_link_table(tb);

return tb;
}

struct fib6_table *fib6_get_table(u32 id)
{
struct fib6_table *tb;
struct hlist_node *node;
unsigned int h;

if (id == 0)
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) {
if (tb->tb6_id == id) {
rcu_read_unlock();
return tb;
}
}
rcu_read_unlock();

return NULL;
}

struct dst_entry *fib6_rule_lookup(struct flowi *fl, int flags,
pol_lookup_t lookup)
{
/*
* TODO: Add rule lookup
*/
struct fib6_table *table = fib6_get_table(RT6_TABLE_MAIN);

return (struct dst_entry *) lookup(table, fl, flags);
}

static void __init fib6_tables_init(void)
{
fib6_link_table(&fib6_main_tbl);
}

#else

struct fib6_table *fib6_new_table(u32 id)
{
return fib6_get_table(id);
}

struct fib6_table *fib6_get_table(u32 id)
{
return &fib6_main_tbl;
}

struct dst_entry *fib6_rule_lookup(struct flowi *fl, int flags,
pol_lookup_t lookup)
{
return (struct dst_entry *) lookup(&fib6_main_tbl, fl, flags);
}

static void __init fib6_tables_init(void)
{
}

#endif


/*
* Routing Table
Expand Down Expand Up @@ -1064,6 +1185,22 @@ void fib6_clean_tree(struct fib6_node *root,
fib6_walk(&c.w);
}

void fib6_clean_all(int (*func)(struct rt6_info *, void *arg),
int prune, void *arg)
{
int i;
struct fib6_table *table;

for (i = FIB6_TABLE_MIN; i <= FIB6_TABLE_MAX; i++) {
table = fib6_get_table(i);
if (table != NULL) {
write_lock_bh(&table->tb6_lock);
fib6_clean_tree(&table->tb6_root, func, prune, arg);
write_unlock_bh(&table->tb6_lock);
}
}
}

static int fib6_prune_clone(struct rt6_info *rt, void *arg)
{
if (rt->rt6i_flags & RTF_CACHE) {
Expand Down Expand Up @@ -1142,11 +1279,8 @@ void fib6_run_gc(unsigned long dummy)
}
gc_args.more = 0;


write_lock_bh(&rt6_lock);
ndisc_dst_gc(&gc_args.more);
fib6_clean_tree(&ip6_routing_table, fib6_age, 0, NULL);
write_unlock_bh(&rt6_lock);
fib6_clean_all(fib6_age, 0, NULL);

if (gc_args.more)
mod_timer(&ip6_fib_timer, jiffies + ip6_rt_gc_interval);
Expand All @@ -1165,6 +1299,8 @@ void __init fib6_init(void)
NULL, NULL);
if (!fib6_node_kmem)
panic("cannot create fib6_nodes cache");

fib6_tables_init();
}

void fib6_gc_cleanup(void)
Expand Down
Loading

0 comments on commit 2c4f6c9

Please sign in to comment.