ip6_fib.c (c757faa8bfa26a0dd24b41ff783e0da042156887) | ip6_fib.c (38fbeeeeccdb38d0635398e8e344d245f6d8dc52) |
---|---|
1/* 2 * Linux INET6 implementation 3 * Forwarding Information Database 4 * 5 * Authors: 6 * Pedro Roque <roque@di.fc.ul.pt> 7 * 8 * This program is free software; you can redistribute it and/or --- 1329 unchanged lines hidden (view full) --- 1338 fn = root; 1339 1340 return fn; 1341} 1342 1343/* 1344 * Get node with specified destination prefix (and source prefix, 1345 * if subtrees are used) | 1/* 2 * Linux INET6 implementation 3 * Forwarding Information Database 4 * 5 * Authors: 6 * Pedro Roque <roque@di.fc.ul.pt> 7 * 8 * This program is free software; you can redistribute it and/or --- 1329 unchanged lines hidden (view full) --- 1338 fn = root; 1339 1340 return fn; 1341} 1342 1343/* 1344 * Get node with specified destination prefix (and source prefix, 1345 * if subtrees are used) |
1346 * exact_match == true means we try to find fn with exact match of 1347 * the passed in prefix addr 1348 * exact_match == false means we try to find fn with longest prefix 1349 * match of the passed in prefix addr. This is useful for finding fn 1350 * for cached route as it will be stored in the exception table under 1351 * the node with longest prefix length. |
|
1346 */ 1347 1348 1349static struct fib6_node *fib6_locate_1(struct fib6_node *root, 1350 const struct in6_addr *addr, | 1352 */ 1353 1354 1355static struct fib6_node *fib6_locate_1(struct fib6_node *root, 1356 const struct in6_addr *addr, |
1351 int plen, int offset) | 1357 int plen, int offset, 1358 bool exact_match) |
1352{ | 1359{ |
1353 struct fib6_node *fn; | 1360 struct fib6_node *fn, *prev = NULL; |
1354 1355 for (fn = root; fn ; ) { 1356 struct rt6key *key = (struct rt6key *)((u8 *)fn->leaf + offset); 1357 1358 /* 1359 * Prefix match 1360 */ 1361 if (plen < fn->fn_bit || 1362 !ipv6_prefix_equal(&key->addr, addr, fn->fn_bit)) | 1361 1362 for (fn = root; fn ; ) { 1363 struct rt6key *key = (struct rt6key *)((u8 *)fn->leaf + offset); 1364 1365 /* 1366 * Prefix match 1367 */ 1368 if (plen < fn->fn_bit || 1369 !ipv6_prefix_equal(&key->addr, addr, fn->fn_bit)) |
1363 return NULL; | 1370 goto out; |
1364 1365 if (plen == fn->fn_bit) 1366 return fn; 1367 | 1371 1372 if (plen == fn->fn_bit) 1373 return fn; 1374 |
1375 prev = fn; 1376 |
|
1368 /* 1369 * We have more bits to go 1370 */ 1371 if (addr_bit_set(addr, fn->fn_bit)) 1372 fn = fn->right; 1373 else 1374 fn = fn->left; 1375 } | 1377 /* 1378 * We have more bits to go 1379 */ 1380 if (addr_bit_set(addr, fn->fn_bit)) 1381 fn = fn->right; 1382 else 1383 fn = fn->left; 1384 } |
1376 return NULL; | 1385out: 1386 if (exact_match) 1387 return NULL; 1388 else 1389 return prev; |
1377} 1378 1379struct fib6_node *fib6_locate(struct fib6_node *root, 1380 const struct in6_addr *daddr, int dst_len, | 1390} 1391 1392struct fib6_node *fib6_locate(struct fib6_node *root, 1393 const struct in6_addr *daddr, int dst_len, |
1381 const struct in6_addr *saddr, int src_len) | 1394 const struct in6_addr *saddr, int src_len, 1395 bool exact_match) |
1382{ 1383 struct fib6_node *fn; 1384 1385 fn = fib6_locate_1(root, daddr, dst_len, | 1396{ 1397 struct fib6_node *fn; 1398 1399 fn = fib6_locate_1(root, daddr, dst_len, |
1386 offsetof(struct rt6_info, rt6i_dst)); | 1400 offsetof(struct rt6_info, rt6i_dst), 1401 exact_match); |
1387 1388#ifdef CONFIG_IPV6_SUBTREES 1389 if (src_len) { 1390 WARN_ON(saddr == NULL); 1391 if (fn && fn->subtree) 1392 fn = fib6_locate_1(fn->subtree, saddr, src_len, | 1402 1403#ifdef CONFIG_IPV6_SUBTREES 1404 if (src_len) { 1405 WARN_ON(saddr == NULL); 1406 if (fn && fn->subtree) 1407 fn = fib6_locate_1(fn->subtree, saddr, src_len, |
1393 offsetof(struct rt6_info, rt6i_src)); | 1408 offsetof(struct rt6_info, rt6i_src), 1409 exact_match); |
1394 } 1395#endif 1396 1397 if (fn && fn->fn_flags & RTN_RTINFO) 1398 return fn; 1399 1400 return NULL; 1401} --- 885 unchanged lines hidden --- | 1410 } 1411#endif 1412 1413 if (fn && fn->fn_flags & RTN_RTINFO) 1414 return fn; 1415 1416 return NULL; 1417} --- 885 unchanged lines hidden --- |