* Rib subscription handler. Checks if the algorithm is ready to * receive updates, handles nexthop refcounting and passes change * data to the algorithm callback. */
| 535 | * data to the algorithm callback. |
| 536 | */ |
| 537 | static void |
| 538 | handle_rtable_change_cb(struct rib_head *rnh, struct rib_cmd_info *rc, |
| 539 | void *_data) |
| 540 | { |
| 541 | struct fib_data *fd = (struct fib_data *)_data; |
| 542 | enum flm_op_result result; |
| 543 | |
| 544 | RIB_WLOCK_ASSERT(rnh); |
| 545 | |
| 546 | /* |
| 547 | * There is a small gap between subscribing for route changes |
| 548 | * and initiating rtable dump. Avoid receiving route changes |
| 549 | * prior to finishing rtable dump by checking `init_done`. |
| 550 | */ |
| 551 | if (!fd->init_done) |
| 552 | return; |
| 553 | /* |
| 554 | * If algo requested rebuild, stop sending updates by default. |
| 555 | * This simplifies nexthop refcount handling logic. |
| 556 | */ |
| 557 | if (fd->fd_need_rebuild) |
| 558 | return; |
| 559 | |
| 560 | /* Consider scheduling algorithm re-evaluation */ |
| 561 | schedule_algo_eval(fd); |
| 562 | |
| 563 | /* |
| 564 | * Maintain guarantee that every nexthop returned by the dataplane |
| 565 | * lookup has > 0 refcount, so can be safely referenced within current |
| 566 | * epoch. |
| 567 | */ |
| 568 | if (rc->rc_nh_new != NULL) { |
| 569 | if (fib_ref_nhop(fd, rc->rc_nh_new) == 0) { |
| 570 | /* ran out of indexes */ |
| 571 | schedule_fd_rebuild(fd, "ran out of nhop indexes"); |
| 572 | return; |
| 573 | } |
| 574 | } |
| 575 | |
| 576 | result = fd->fd_flm->flm_change_rib_item_cb(rnh, rc, fd->fd_algo_data); |
| 577 | |
| 578 | switch (result) { |
| 579 | case FLM_SUCCESS: |
| 580 | /* Unref old nexthop on success */ |
| 581 | if (rc->rc_nh_old != NULL) |
| 582 | fib_unref_nhop(fd, rc->rc_nh_old); |
| 583 | break; |
| 584 | case FLM_REBUILD: |
| 585 | |
| 586 | /* |
| 587 | * Algo is not able to apply the update. |
| 588 | * Schedule algo rebuild. |
| 589 | */ |
| 590 | if (!need_immediate_rebuild(fd, rc)) { |
| 591 | schedule_fd_rebuild(fd, "algo requested rebuild"); |
| 592 | break; |
| 593 | } |
| 594 |
nothing calls this directly
no test coverage detected