Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 236832
b: refs/heads/master
c: 0c838ff
h: refs/heads/master
v: v3
  • Loading branch information
David S. Miller committed Feb 1, 2011
1 parent 2aadb29 commit 00d19c9
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 168 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: 5b4704419cbd0b7597a91c19f9e8e8b17c1af071
refs/heads/master: 0c838ff1ade71162775afffd9e5c6478a60bdca6
6 changes: 1 addition & 5 deletions trunk/include/net/ip_fib.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,6 @@ extern int fib_table_delete(struct fib_table *, struct fib_config *);
extern int fib_table_dump(struct fib_table *table, struct sk_buff *skb,
struct netlink_callback *cb);
extern int fib_table_flush(struct fib_table *table);
extern void fib_table_select_default(struct fib_table *table,
const struct flowi *flp,
struct fib_result *res);
extern void fib_free_table(struct fib_table *tb);


Expand Down Expand Up @@ -221,8 +218,7 @@ extern void ip_fib_init(void);
extern int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,
struct net_device *dev, __be32 *spec_dst,
u32 *itag, u32 mark);
extern void fib_select_default(struct net *net, const struct flowi *flp,
struct fib_result *res);
extern void fib_select_default(struct fib_result *res);

/* Exported by fib_semantics.c */
extern int ip_fib_check_default(__be32 gw, struct net_device *dev);
Expand Down
15 changes: 0 additions & 15 deletions trunk/net/ipv4/fib_frontend.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,21 +114,6 @@ struct fib_table *fib_get_table(struct net *net, u32 id)
}
#endif /* CONFIG_IP_MULTIPLE_TABLES */

void fib_select_default(struct net *net,
const struct flowi *flp, struct fib_result *res)
{
struct fib_table *tb;
int table = RT_TABLE_MAIN;
#ifdef CONFIG_IP_MULTIPLE_TABLES
if (res->r == NULL || res->r->action != FR_ACT_TO_TBL)
return;
table = res->r->table;
#endif
tb = fib_get_table(net, table);
if (FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK)
fib_table_select_default(tb, flp, res);
}

static void fib_flush(struct net *net)
{
int flushed = 0;
Expand Down
72 changes: 0 additions & 72 deletions trunk/net/ipv4/fib_hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -302,78 +302,6 @@ int fib_table_lookup(struct fib_table *tb,
return err;
}

void fib_table_select_default(struct fib_table *tb,
const struct flowi *flp, struct fib_result *res)
{
int order, last_idx;
struct hlist_node *node;
struct fib_node *f;
struct fib_info *fi = NULL;
struct fib_info *last_resort;
struct fn_hash *t = (struct fn_hash *)tb->tb_data;
struct fn_zone *fz = t->fn_zones[0];
struct hlist_head *head;

if (fz == NULL)
return;

last_idx = -1;
last_resort = NULL;
order = -1;

rcu_read_lock();
head = rcu_dereference(fz->fz_hash);
hlist_for_each_entry_rcu(f, node, head, fn_hash) {
struct fib_alias *fa;

list_for_each_entry_rcu(fa, &f->fn_alias, fa_list) {
struct fib_info *next_fi = fa->fa_info;

if (fa->fa_scope != res->scope ||
fa->fa_type != RTN_UNICAST)
continue;

if (next_fi->fib_priority > res->fi->fib_priority)
break;
if (!next_fi->fib_nh[0].nh_gw ||
next_fi->fib_nh[0].nh_scope != RT_SCOPE_LINK)
continue;

fib_alias_accessed(fa);

if (fi == NULL) {
if (next_fi != res->fi)
break;
} else if (!fib_detect_death(fi, order, &last_resort,
&last_idx, tb->tb_default)) {
fib_result_assign(res, fi);
tb->tb_default = order;
goto out;
}
fi = next_fi;
order++;
}
}

if (order <= 0 || fi == NULL) {
tb->tb_default = -1;
goto out;
}

if (!fib_detect_death(fi, order, &last_resort, &last_idx,
tb->tb_default)) {
fib_result_assign(res, fi);
tb->tb_default = order;
goto out;
}

if (last_idx >= 0)
fib_result_assign(res, last_resort);
tb->tb_default = last_idx;
out:
rcu_read_unlock();
}

/* Insert node F to FZ. */
static inline void fib_insert_node(struct fn_zone *fz, struct fib_node *f)
{
Expand Down
56 changes: 56 additions & 0 deletions trunk/net/ipv4/fib_semantics.c
Original file line number Diff line number Diff line change
Expand Up @@ -1136,6 +1136,62 @@ int fib_sync_down_dev(struct net_device *dev, int force)
return ret;
}

/* Must be invoked inside of an RCU protected region. */
void fib_select_default(struct fib_result *res)
{
struct fib_info *fi = NULL, *last_resort = NULL;
struct list_head *fa_head = res->fa_head;
struct fib_table *tb = res->table;
int order = -1, last_idx = -1;
struct fib_alias *fa;

list_for_each_entry_rcu(fa, fa_head, fa_list) {
struct fib_info *next_fi = fa->fa_info;

if (fa->fa_scope != res->scope ||
fa->fa_type != RTN_UNICAST)
continue;

if (next_fi->fib_priority > res->fi->fib_priority)
break;
if (!next_fi->fib_nh[0].nh_gw ||
next_fi->fib_nh[0].nh_scope != RT_SCOPE_LINK)
continue;

fib_alias_accessed(fa);

if (fi == NULL) {
if (next_fi != res->fi)
break;
} else if (!fib_detect_death(fi, order, &last_resort,
&last_idx, tb->tb_default)) {
fib_result_assign(res, fi);
tb->tb_default = order;
goto out;
}
fi = next_fi;
order++;
}

if (order <= 0 || fi == NULL) {
tb->tb_default = -1;
goto out;
}

if (!fib_detect_death(fi, order, &last_resort, &last_idx,
tb->tb_default)) {
fib_result_assign(res, fi);
tb->tb_default = order;
goto out;
}

if (last_idx >= 0)
fib_result_assign(res, last_resort);
tb->tb_default = last_idx;
out:
rcu_read_unlock();
}

#ifdef CONFIG_IP_ROUTE_MULTIPATH

/*
Expand Down
74 changes: 0 additions & 74 deletions trunk/net/ipv4/fib_trie.c
Original file line number Diff line number Diff line change
Expand Up @@ -1802,80 +1802,6 @@ void fib_free_table(struct fib_table *tb)
kfree(tb);
}

void fib_table_select_default(struct fib_table *tb,
const struct flowi *flp,
struct fib_result *res)
{
struct trie *t = (struct trie *) tb->tb_data;
int order, last_idx;
struct fib_info *fi = NULL;
struct fib_info *last_resort;
struct fib_alias *fa = NULL;
struct list_head *fa_head;
struct leaf *l;

last_idx = -1;
last_resort = NULL;
order = -1;

rcu_read_lock();

l = fib_find_node(t, 0);
if (!l)
goto out;

fa_head = get_fa_head(l, 0);
if (!fa_head)
goto out;

if (list_empty(fa_head))
goto out;

list_for_each_entry_rcu(fa, fa_head, fa_list) {
struct fib_info *next_fi = fa->fa_info;

if (fa->fa_scope != res->scope ||
fa->fa_type != RTN_UNICAST)
continue;

if (next_fi->fib_priority > res->fi->fib_priority)
break;
if (!next_fi->fib_nh[0].nh_gw ||
next_fi->fib_nh[0].nh_scope != RT_SCOPE_LINK)
continue;

fib_alias_accessed(fa);

if (fi == NULL) {
if (next_fi != res->fi)
break;
} else if (!fib_detect_death(fi, order, &last_resort,
&last_idx, tb->tb_default)) {
fib_result_assign(res, fi);
tb->tb_default = order;
goto out;
}
fi = next_fi;
order++;
}
if (order <= 0 || fi == NULL) {
tb->tb_default = -1;
goto out;
}

if (!fib_detect_death(fi, order, &last_resort, &last_idx,
tb->tb_default)) {
fib_result_assign(res, fi);
tb->tb_default = order;
goto out;
}
if (last_idx >= 0)
fib_result_assign(res, last_resort);
tb->tb_default = last_idx;
out:
rcu_read_unlock();
}

static int fn_trie_dump_fa(t_key key, int plen, struct list_head *fah,
struct fib_table *tb,
struct sk_buff *skb, struct netlink_callback *cb)
Expand Down
2 changes: 1 addition & 1 deletion trunk/net/ipv4/route.c
Original file line number Diff line number Diff line change
Expand Up @@ -2711,7 +2711,7 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp,
else
#endif
if (!res.prefixlen && res.type == RTN_UNICAST && !fl.oif)
fib_select_default(net, &fl, &res);
fib_select_default(&res);

if (!fl.fl4_src)
fl.fl4_src = FIB_RES_PREFSRC(res);
Expand Down

0 comments on commit 00d19c9

Please sign in to comment.