diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-12-06 09:06:51 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-12-06 09:06:51 -0800 |
commit | da1b466fa47a9c1107e3709395778845dc3bbad7 (patch) | |
tree | 4a9b4795d4bfb2d964058751740a39a7b16a7b2f /net/ipv4/fib_trie.c | |
parent | 10d20bd25e06b220b1d816228b036e367215dc60 (diff) | |
parent | 32f16e142d7acabad68ef27c123d0caf1548aac3 (diff) | |
download | linux-da1b466fa47a9c1107e3709395778845dc3bbad7.tar.bz2 |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller:
1) When dcbnl_cee_fill() fails to be able to push a new netlink
attribute, it return 0 instead of an error code. From Pan Bian.
2) Two suffix handling fixes to FIB trie code, from Alexander Duyck.
3) bnxt_hwrm_stat_ctx_alloc() goes through all the trouble of setting
and maintaining a return code 'rc' but fails to actually return it.
Also from Pan Bian.
4) ping socket ICMP handler needs to validate ICMP header length, from
Kees Cook.
5) caif_sktinit_module() has this interesting logic:
int err = sock_register(...);
if (!err)
return err;
return 0;
Just return sock_register()'s return value directly which is the
only possible correct thing to do.
6) Two bnx2x driver fixes from Yuval Mintz, return a reasonable
estimate from get_ringparam() ethtool op when interface is down and
avoid trying to use UDP port based tunneling on 577xx chips.
7) Fix ep93xx_eth crash on module unload from Florian Fainelli.
8) Missing uapi exports, from Stephen Hemminger.
9) Don't schedule work from sk_destruct(), because the socket will be
freed upon return from that function. From Herbert Xu.
10) Buggy drivers, of which we know there is at least one, can send a
huge packet into the TCP stack but forget to set the gso_size in the
SKB, which causes all kinds of problems.
Correct this when it happens, and emit a one-time warning with the
device name included so that it can be diagnosed more easily.
From Marcelo Ricardo Leitner.
11) virtio-net does DMA off the stack causes hiccups with VMAP_STACK,
fix from Andy Lutomirski.
12) Fix fec driver compilation with CONFIG_M5272, from Nikita
Yushchenko.
13) mlx5 fixes from Kamal Heib, Saeed Mahameed, and Mohamad Haj Yahia.
(erroneously flushing queues on error, module parameter validation,
etc)
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (34 commits)
net/mlx5e: Change the SQ/RQ operational state to positive logic
net/mlx5e: Don't flush SQ on error
net/mlx5e: Don't notify HW when filling the edge of ICO SQ
net/mlx5: Fix query ISSI flow
net/mlx5: Remove duplicate pci dev name print
net/mlx5: Verify module parameters
net: fec: fix compile with CONFIG_M5272
be2net: Add DEVSEC privilege to SET_HSW_CONFIG command.
virtio-net: Fix DMA-from-the-stack in virtnet_set_mac_address()
tcp: warn on bogus MSS and try to amend it
uapi glibc compat: fix outer guard of net device flags enum
net: stmmac: clear reset value of snps, wr_osr_lmt/snps, rd_osr_lmt before writing
netlink: Do not schedule work from sk_destruct
uapi: export nf_log.h
uapi: export tc_skbmod.h
net: ep93xx_eth: Do not crash unloading module
bnx2x: Prevent tunnel config for 577xx
bnx2x: Correct ringparam estimate when DOWN
isdn: hisax: set error code on failure
net: bnx2x: fix improper return value
...
Diffstat (limited to 'net/ipv4/fib_trie.c')
-rw-r--r-- | net/ipv4/fib_trie.c | 68 |
1 files changed, 35 insertions, 33 deletions
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 026f309c51e9..e3665bf7a7f3 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -719,6 +719,13 @@ static unsigned char update_suffix(struct key_vector *tn) { unsigned char slen = tn->pos; unsigned long stride, i; + unsigned char slen_max; + + /* only vector 0 can have a suffix length greater than or equal to + * tn->pos + tn->bits, the second highest node will have a suffix + * length at most of tn->pos + tn->bits - 1 + */ + slen_max = min_t(unsigned char, tn->pos + tn->bits - 1, tn->slen); /* search though the list of children looking for nodes that might * have a suffix greater than the one we currently have. This is @@ -736,12 +743,8 @@ static unsigned char update_suffix(struct key_vector *tn) slen = n->slen; i &= ~(stride - 1); - /* if slen covers all but the last bit we can stop here - * there will be nothing longer than that since only node - * 0 and 1 << (bits - 1) could have that as their suffix - * length. - */ - if ((slen + 1) >= (tn->pos + tn->bits)) + /* stop searching if we have hit the maximum possible value */ + if (slen >= slen_max) break; } @@ -913,39 +916,27 @@ static struct key_vector *resize(struct trie *t, struct key_vector *tn) return collapse(t, tn); /* update parent in case halve failed */ - tp = node_parent(tn); - - /* Return if at least one deflate was run */ - if (max_work != MAX_WORK) - return tp; - - /* push the suffix length to the parent node */ - if (tn->slen > tn->pos) { - unsigned char slen = update_suffix(tn); - - if (slen > tp->slen) - tp->slen = slen; - } - - return tp; + return node_parent(tn); } -static void leaf_pull_suffix(struct key_vector *tp, struct key_vector *l) +static void node_pull_suffix(struct key_vector *tn, unsigned char slen) { - while ((tp->slen > tp->pos) && (tp->slen > l->slen)) { - if (update_suffix(tp) > l->slen) + unsigned char node_slen = tn->slen; + + while ((node_slen > tn->pos) && (node_slen > slen)) { + slen = update_suffix(tn); + if (node_slen == slen) break; - tp = node_parent(tp); + + tn = node_parent(tn); + node_slen = tn->slen; } } -static void leaf_push_suffix(struct key_vector *tn, struct key_vector *l) +static void node_push_suffix(struct key_vector *tn, unsigned char slen) { - /* if this is a new leaf then tn will be NULL and we can sort - * out parent suffix lengths as a part of trie_rebalance - */ - while (tn->slen < l->slen) { - tn->slen = l->slen; + while (tn->slen < slen) { + tn->slen = slen; tn = node_parent(tn); } } @@ -1066,6 +1057,7 @@ static int fib_insert_node(struct trie *t, struct key_vector *tp, } /* Case 3: n is NULL, and will just insert a new leaf */ + node_push_suffix(tp, new->fa_slen); NODE_INIT_PARENT(l, tp); put_child_root(tp, key, l); trie_rebalance(t, tp); @@ -1107,7 +1099,7 @@ static int fib_insert_alias(struct trie *t, struct key_vector *tp, /* if we added to the tail node then we need to update slen */ if (l->slen < new->fa_slen) { l->slen = new->fa_slen; - leaf_push_suffix(tp, l); + node_push_suffix(tp, new->fa_slen); } return 0; @@ -1499,6 +1491,8 @@ static void fib_remove_alias(struct trie *t, struct key_vector *tp, * out parent suffix lengths as a part of trie_rebalance */ if (hlist_empty(&l->leaf)) { + if (tp->slen == l->slen) + node_pull_suffix(tp, tp->pos); put_child_root(tp, l->key, NULL); node_free(l); trie_rebalance(t, tp); @@ -1511,7 +1505,7 @@ static void fib_remove_alias(struct trie *t, struct key_vector *tp, /* update the trie with the latest suffix length */ l->slen = fa->fa_slen; - leaf_pull_suffix(tp, l); + node_pull_suffix(tp, fa->fa_slen); } /* Caller must hold RTNL. */ @@ -1783,6 +1777,10 @@ void fib_table_flush_external(struct fib_table *tb) if (IS_TRIE(pn)) break; + /* update the suffix to address pulled leaves */ + if (pn->slen > pn->pos) + update_suffix(pn); + /* resize completed node */ pn = resize(t, pn); cindex = get_index(pkey, pn); @@ -1849,6 +1847,10 @@ int fib_table_flush(struct net *net, struct fib_table *tb) if (IS_TRIE(pn)) break; + /* update the suffix to address pulled leaves */ + if (pn->slen > pn->pos) + update_suffix(pn); + /* resize completed node */ pn = resize(t, pn); cindex = get_index(pkey, pn); |