lkml.org 
[lkml]   [2008]   [Feb]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch 15/38] IPV4: fib_trie: apply fixes from fib_hash
    2.6.24-stable review patch.  If anyone has any objections, please let us
    know.

    ------------------
    Upstream commit: 936f6f8e1bc46834bbb3e3fa3ac13ab44f1e7ba6

    Update fib_trie with some fib_hash fixes:
    - check for duplicate alternative routes for prefix+tos+priority when
    replacing route
    - properly insert by matching tos together with priority
    - fix alias walking to use list_for_each_entry_continue for insertion
    and deletion when fa_head is not NULL
    - copy state from fa to new_fa on replace (not a problem for now)
    - additionally, avoid replacement without error if new route is same,
    as Joonwoo Park suggests.

    Signed-off-by: Julian Anastasov <ja@ssi.bg>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

    ---
    net/ipv4/fib_trie.c | 57 ++++++++++++++++++++++++++++++++--------------------
    1 file changed, 36 insertions(+), 21 deletions(-)

    --- a/net/ipv4/fib_trie.c
    +++ b/net/ipv4/fib_trie.c
    @@ -1203,20 +1203,45 @@ static int fn_trie_insert(struct fib_tab
    * and we need to allocate a new one of those as well.
    */

    - if (fa && fa->fa_info->fib_priority == fi->fib_priority) {
    - struct fib_alias *fa_orig;
    + if (fa && fa->fa_tos == tos &&
    + fa->fa_info->fib_priority == fi->fib_priority) {
    + 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, fa_head, 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;
    -
    + }
    err = -ENOBUFS;
    new_fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL);
    if (new_fa == NULL)
    @@ -1228,7 +1253,7 @@ static int fn_trie_insert(struct fib_tab
    new_fa->fa_type = cfg->fc_type;
    new_fa->fa_scope = cfg->fc_scope;
    state = fa->fa_state;
    - new_fa->fa_state &= ~FA_S_ACCESSED;
    + new_fa->fa_state = state & ~FA_S_ACCESSED;

    list_replace_rcu(&fa->fa_list, &new_fa->fa_list);
    alias_free_mem_rcu(fa);
    @@ -1245,20 +1270,11 @@ static int fn_trie_insert(struct fib_tab
    * uses the same scope, type, and nexthop
    * information.
    */
    - fa_orig = fa;
    - list_for_each_entry(fa, fa_orig->fa_list.prev, 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;
    if (!(cfg->fc_nlflags & NLM_F_CREATE))
    @@ -1614,9 +1630,8 @@ static int fn_trie_delete(struct fib_tab
    pr_debug("Deleting %08x/%d tos=%d t=%p\n", key, plen, tos, t);

    fa_to_delete = NULL;
    - fa_head = fa->fa_list.prev;
    -
    - list_for_each_entry(fa, fa_head, fa_list) {
    + fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list);
    + list_for_each_entry_continue(fa, fa_head, fa_list) {
    struct fib_info *fi = fa->fa_info;

    if (fa->fa_tos != tos)
    --


    \
     
     \ /
      Last update: 2008-02-23 01:43    [W:0.026 / U:121.188 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site