|
|
@@ -1856,7 +1856,7 @@ void fib_table_flush_external(struct fib_table *tb)
|
|
|
}
|
|
|
|
|
|
/* Caller must hold RTNL. */
|
|
|
-int fib_table_flush(struct net *net, struct fib_table *tb)
|
|
|
+int fib_table_flush(struct net *net, struct fib_table *tb, bool flush_all)
|
|
|
{
|
|
|
struct trie *t = (struct trie *)tb->tb_data;
|
|
|
struct key_vector *pn = t->kv;
|
|
|
@@ -1904,8 +1904,17 @@ int fib_table_flush(struct net *net, struct fib_table *tb)
|
|
|
hlist_for_each_entry_safe(fa, tmp, &n->leaf, fa_list) {
|
|
|
struct fib_info *fi = fa->fa_info;
|
|
|
|
|
|
- if (!fi || !(fi->fib_flags & RTNH_F_DEAD) ||
|
|
|
- tb->tb_id != fa->tb_id) {
|
|
|
+ if (!fi || tb->tb_id != fa->tb_id ||
|
|
|
+ (!(fi->fib_flags & RTNH_F_DEAD) &&
|
|
|
+ !fib_props[fa->fa_type].error)) {
|
|
|
+ slen = fa->fa_slen;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Do not flush error routes if network namespace is
|
|
|
+ * not being dismantled
|
|
|
+ */
|
|
|
+ if (!flush_all && fib_props[fa->fa_type].error) {
|
|
|
slen = fa->fa_slen;
|
|
|
continue;
|
|
|
}
|