Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 81859
b: refs/heads/master
c: c18865f
h: refs/heads/master
i:
  81857: b72b265
  81855: 30b0743
v: v3
  • Loading branch information
Julian Anastasov authored and David S. Miller committed Feb 1, 2008
1 parent 34813f1 commit 7af3ee6
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 17 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: ec9dbb1c3ee785ddc0c327497df42c16188d1fd8
refs/heads/master: c18865f39276435abb9286f9a816cb5b66c99a00
47 changes: 31 additions & 16 deletions trunk/net/ipv4/fib_hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -424,19 +424,43 @@ static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg)

if (fa && fa->fa_tos == tos &&
fa->fa_info->fib_priority == fi->fib_priority) {
struct fib_alias *fa_orig;
struct fib_alias *fa_first, *fa_match;

err = -EEXIST;
if (cfg->fc_nlflags & NLM_F_EXCL)
goto out;

/* We have 2 goals:
* 1. Find exact match for type, scope, fib_info to avoid
* duplicate routes
* 2. Find next 'fa' (or head), NLM_F_APPEND inserts before it
*/
fa_match = NULL;
fa_first = fa;
fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list);
list_for_each_entry_continue(fa, &f->fn_alias, fa_list) {
if (fa->fa_tos != tos)
break;
if (fa->fa_info->fib_priority != fi->fib_priority)
break;
if (fa->fa_type == cfg->fc_type &&
fa->fa_scope == cfg->fc_scope &&
fa->fa_info == fi) {
fa_match = fa;
break;
}
}

if (cfg->fc_nlflags & NLM_F_REPLACE) {
struct fib_info *fi_drop;
u8 state;

if (fi->fib_treeref > 1)
fa = fa_first;
if (fa_match) {
if (fa == fa_match)
err = 0;
goto out;

}
write_lock_bh(&fib_hash_lock);
fi_drop = fa->fa_info;
fa->fa_info = fi;
Expand All @@ -459,20 +483,11 @@ static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg)
* uses the same scope, type, and nexthop
* information.
*/
fa_orig = fa;
fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list);
list_for_each_entry_continue(fa, &f->fn_alias, fa_list) {
if (fa->fa_tos != tos)
break;
if (fa->fa_info->fib_priority != fi->fib_priority)
break;
if (fa->fa_type == cfg->fc_type &&
fa->fa_scope == cfg->fc_scope &&
fa->fa_info == fi)
goto out;
}
if (fa_match)
goto out;

if (!(cfg->fc_nlflags & NLM_F_APPEND))
fa = fa_orig;
fa = fa_first;
}

err = -ENOENT;
Expand Down

0 comments on commit 7af3ee6

Please sign in to comment.