aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/ipv4/fib_hash.c19
-rw-r--r--net/ipv4/fib_lookup.h10
-rw-r--r--net/ipv4/fib_trie.c19
3 files changed, 18 insertions, 30 deletions
diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c
index 143a5213a185..86087d45c64e 100644
--- a/net/ipv4/fib_hash.c
+++ b/net/ipv4/fib_hash.c
@@ -315,10 +315,7 @@ fn_hash_select_default(struct fib_table *tb, const struct flowi *flp, struct fib
315 break; 315 break;
316 } else if (!fib_detect_death(fi, order, &last_resort, 316 } else if (!fib_detect_death(fi, order, &last_resort,
317 &last_idx, fn_hash_last_dflt)) { 317 &last_idx, fn_hash_last_dflt)) {
318 if (res->fi) 318 fib_result_assign(res, fi);
319 fib_info_put(res->fi);
320 res->fi = fi;
321 atomic_inc(&fi->fib_clntref);
322 fn_hash_last_dflt = order; 319 fn_hash_last_dflt = order;
323 goto out; 320 goto out;
324 } 321 }
@@ -333,21 +330,13 @@ fn_hash_select_default(struct fib_table *tb, const struct flowi *flp, struct fib
333 } 330 }
334 331
335 if (!fib_detect_death(fi, order, &last_resort, &last_idx, fn_hash_last_dflt)) { 332 if (!fib_detect_death(fi, order, &last_resort, &last_idx, fn_hash_last_dflt)) {
336 if (res->fi) 333 fib_result_assign(res, fi);
337 fib_info_put(res->fi);
338 res->fi = fi;
339 atomic_inc(&fi->fib_clntref);
340 fn_hash_last_dflt = order; 334 fn_hash_last_dflt = order;
341 goto out; 335 goto out;
342 } 336 }
343 337
344 if (last_idx >= 0) { 338 if (last_idx >= 0)
345 if (res->fi) 339 fib_result_assign(res, last_resort);
346 fib_info_put(res->fi);
347 res->fi = last_resort;
348 if (last_resort)
349 atomic_inc(&last_resort->fib_clntref);
350 }
351 fn_hash_last_dflt = last_idx; 340 fn_hash_last_dflt = last_idx;
352out: 341out:
353 read_unlock(&fib_hash_lock); 342 read_unlock(&fib_hash_lock);
diff --git a/net/ipv4/fib_lookup.h b/net/ipv4/fib_lookup.h
index 6c9dd4282db0..26ee66d78c18 100644
--- a/net/ipv4/fib_lookup.h
+++ b/net/ipv4/fib_lookup.h
@@ -38,4 +38,14 @@ extern int fib_detect_death(struct fib_info *fi, int order,
38 struct fib_info **last_resort, 38 struct fib_info **last_resort,
39 int *last_idx, int dflt); 39 int *last_idx, int dflt);
40 40
41static inline void fib_result_assign(struct fib_result *res,
42 struct fib_info *fi)
43{
44 if (res->fi != NULL)
45 fib_info_put(res->fi);
46 res->fi = fi;
47 if (fi != NULL)
48 atomic_inc(&fi->fib_clntref);
49}
50
41#endif /* _FIB_LOOKUP_H */ 51#endif /* _FIB_LOOKUP_H */
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index d48a9bbcf54d..c7c5c6c802df 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -1831,10 +1831,7 @@ fn_trie_select_default(struct fib_table *tb, const struct flowi *flp, struct fib
1831 break; 1831 break;
1832 } else if (!fib_detect_death(fi, order, &last_resort, 1832 } else if (!fib_detect_death(fi, order, &last_resort,
1833 &last_idx, trie_last_dflt)) { 1833 &last_idx, trie_last_dflt)) {
1834 if (res->fi) 1834 fib_result_assign(res, fi);
1835 fib_info_put(res->fi);
1836 res->fi = fi;
1837 atomic_inc(&fi->fib_clntref);
1838 trie_last_dflt = order; 1835 trie_last_dflt = order;
1839 goto out; 1836 goto out;
1840 } 1837 }
@@ -1847,20 +1844,12 @@ fn_trie_select_default(struct fib_table *tb, const struct flowi *flp, struct fib
1847 } 1844 }
1848 1845
1849 if (!fib_detect_death(fi, order, &last_resort, &last_idx, trie_last_dflt)) { 1846 if (!fib_detect_death(fi, order, &last_resort, &last_idx, trie_last_dflt)) {
1850 if (res->fi) 1847 fib_result_assign(res, fi);
1851 fib_info_put(res->fi);
1852 res->fi = fi;
1853 atomic_inc(&fi->fib_clntref);
1854 trie_last_dflt = order; 1848 trie_last_dflt = order;
1855 goto out; 1849 goto out;
1856 } 1850 }
1857 if (last_idx >= 0) { 1851 if (last_idx >= 0)
1858 if (res->fi) 1852 fib_result_assign(res, last_resort);
1859 fib_info_put(res->fi);
1860 res->fi = last_resort;
1861 if (last_resort)
1862 atomic_inc(&last_resort->fib_clntref);
1863 }
1864 trie_last_dflt = last_idx; 1853 trie_last_dflt = last_idx;
1865 out:; 1854 out:;
1866 rcu_read_unlock(); 1855 rcu_read_unlock();