aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/fib_trie.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/fib_trie.c')
-rw-r--r--net/ipv4/fib_trie.c51
1 files changed, 43 insertions, 8 deletions
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index edf3b0997e01..a4109a544778 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -1349,23 +1349,58 @@ static int check_leaf(struct fib_table *tb, struct trie *t, struct leaf *l,
1349 struct hlist_node *node; 1349 struct hlist_node *node;
1350 1350
1351 hlist_for_each_entry_rcu(li, node, hhead, hlist) { 1351 hlist_for_each_entry_rcu(li, node, hhead, hlist) {
1352 int err; 1352 struct fib_alias *fa;
1353 int plen = li->plen; 1353 int plen = li->plen;
1354 __be32 mask = inet_make_mask(plen); 1354 __be32 mask = inet_make_mask(plen);
1355 1355
1356 if (l->key != (key & ntohl(mask))) 1356 if (l->key != (key & ntohl(mask)))
1357 continue; 1357 continue;
1358 1358
1359 err = fib_semantic_match(tb, &li->falh, flp, res, plen, fib_flags); 1359 list_for_each_entry_rcu(fa, &li->falh, fa_list) {
1360 struct fib_info *fi = fa->fa_info;
1361 int nhsel, err;
1360 1362
1363 if (fa->fa_tos && fa->fa_tos != flp->fl4_tos)
1364 continue;
1365 if (fa->fa_scope < flp->fl4_scope)
1366 continue;
1367 fib_alias_accessed(fa);
1368 err = fib_props[fa->fa_type].error;
1369 if (err) {
1361#ifdef CONFIG_IP_FIB_TRIE_STATS 1370#ifdef CONFIG_IP_FIB_TRIE_STATS
1362 if (err <= 0) 1371 t->stats.semantic_match_miss++;
1363 t->stats.semantic_match_passed++; 1372#endif
1364 else 1373 return 1;
1365 t->stats.semantic_match_miss++; 1374 }
1375 if (fi->fib_flags & RTNH_F_DEAD)
1376 continue;
1377 for (nhsel = 0; nhsel < fi->fib_nhs; nhsel++) {
1378 const struct fib_nh *nh = &fi->fib_nh[nhsel];
1379
1380 if (nh->nh_flags & RTNH_F_DEAD)
1381 continue;
1382 if (flp->oif && flp->oif != nh->nh_oif)
1383 continue;
1384
1385#ifdef CONFIG_IP_FIB_TRIE_STATS
1386 t->stats.semantic_match_passed++;
1387#endif
1388 res->prefixlen = plen;
1389 res->nh_sel = nhsel;
1390 res->type = fa->fa_type;
1391 res->scope = fa->fa_scope;
1392 res->fi = fi;
1393 res->table = tb;
1394 res->fa_head = &li->falh;
1395 if (!(fib_flags & FIB_LOOKUP_NOREF))
1396 atomic_inc(&res->fi->fib_clntref);
1397 return 0;
1398 }
1399 }
1400
1401#ifdef CONFIG_IP_FIB_TRIE_STATS
1402 t->stats.semantic_match_miss++;
1366#endif 1403#endif
1367 if (err <= 0)
1368 return err;
1369 } 1404 }
1370 1405
1371 return 1; 1406 return 1;