| 462 | } |
| 463 | |
| 464 | static int |
| 465 | modify_dp(struct rte_trie_tbl *dp, struct rte_rib6 *rib, |
| 466 | const uint8_t ip[RTE_FIB6_IPV6_ADDR_SIZE], |
| 467 | uint8_t depth, uint64_t next_hop) |
| 468 | { |
| 469 | struct rte_rib6_node *tmp = NULL; |
| 470 | uint8_t ledge[RTE_FIB6_IPV6_ADDR_SIZE]; |
| 471 | uint8_t redge[RTE_FIB6_IPV6_ADDR_SIZE]; |
| 472 | int ret; |
| 473 | uint8_t tmp_depth; |
| 474 | |
| 475 | if (next_hop > get_max_nh(dp->nh_sz)) |
| 476 | return -EINVAL; |
| 477 | |
| 478 | rte_rib6_copy_addr(ledge, ip); |
| 479 | do { |
| 480 | tmp = rte_rib6_get_nxt(rib, ip, depth, tmp, |
| 481 | RTE_RIB6_GET_NXT_COVER); |
| 482 | if (tmp != NULL) { |
| 483 | rte_rib6_get_depth(tmp, &tmp_depth); |
| 484 | if (tmp_depth == depth) |
| 485 | continue; |
| 486 | rte_rib6_get_ip(tmp, redge); |
| 487 | if (rte_rib6_is_equal(ledge, redge)) { |
| 488 | get_nxt_net(ledge, tmp_depth); |
| 489 | continue; |
| 490 | } |
| 491 | ret = install_to_dp(dp, ledge, redge, |
| 492 | next_hop); |
| 493 | if (ret != 0) |
| 494 | return ret; |
| 495 | get_nxt_net(redge, tmp_depth); |
| 496 | rte_rib6_copy_addr(ledge, redge); |
| 497 | /* |
| 498 | * we got to the end of address space |
| 499 | * and wrapped around |
| 500 | */ |
| 501 | if (v6_addr_is_zero(ledge)) |
| 502 | break; |
| 503 | } else { |
| 504 | rte_rib6_copy_addr(redge, ip); |
| 505 | get_nxt_net(redge, depth); |
| 506 | if (rte_rib6_is_equal(ledge, redge) && |
| 507 | !v6_addr_is_zero(ledge)) |
| 508 | break; |
| 509 | |
| 510 | ret = install_to_dp(dp, ledge, redge, |
| 511 | next_hop); |
| 512 | if (ret != 0) |
| 513 | return ret; |
| 514 | } |
| 515 | } while (tmp); |
| 516 | |
| 517 | return 0; |
| 518 | } |
| 519 | |
| 520 | int |
| 521 | trie_modify(struct rte_fib6 *fib, const uint8_t ip[RTE_FIB6_IPV6_ADDR_SIZE], |
no test coverage detected