* Checks if we need to switch from STALE state. * * RFC 4861 requires switching from STALE to DELAY state * on first packet matching entry, waiting V_nd6_delay and * transition to PROBE state (if upper layer confirmation was * not received). * * This code performs a bit differently: * On packet hit we don't change state (but desired state * can be guessed by control plane). However, after
| 613 | * PROBE (store that in @do_switch variable). |
| 614 | */ |
| 615 | static int |
| 616 | nd6_is_stale(struct llentry *lle, long *pdelay, int *do_switch) |
| 617 | { |
| 618 | int nd_delay, nd_gctimer, r_skip_req; |
| 619 | time_t lle_hittime; |
| 620 | long delay; |
| 621 | |
| 622 | *do_switch = 0; |
| 623 | nd_gctimer = V_nd6_gctimer; |
| 624 | nd_delay = V_nd6_delay; |
| 625 | |
| 626 | LLE_REQ_LOCK(lle); |
| 627 | r_skip_req = lle->r_skip_req; |
| 628 | lle_hittime = lle->lle_hittime; |
| 629 | LLE_REQ_UNLOCK(lle); |
| 630 | |
| 631 | if (r_skip_req > 0) { |
| 632 | /* |
| 633 | * Nonzero r_skip_req value was set upon entering |
| 634 | * STALE state. Since value was not changed, no |
| 635 | * packets were passed using this lle. Ask for |
| 636 | * timer reschedule and keep STALE state. |
| 637 | */ |
| 638 | delay = (long)(MIN(nd_gctimer, nd_delay)); |
| 639 | delay *= hz; |
| 640 | if (lle->lle_remtime > delay) |
| 641 | lle->lle_remtime -= delay; |
| 642 | else { |
| 643 | delay = lle->lle_remtime; |
| 644 | lle->lle_remtime = 0; |
| 645 | } |
| 646 | |
| 647 | if (delay == 0) { |
| 648 | /* |
| 649 | * The original ng6_gctime timeout ended, |
| 650 | * no more rescheduling. |
| 651 | */ |
| 652 | return (0); |
| 653 | } |
| 654 | |
| 655 | *pdelay = delay; |
| 656 | return (1); |
| 657 | } |
| 658 | |
| 659 | /* |
| 660 | * Packet received. Verify timestamp |
| 661 | */ |
| 662 | delay = (long)(time_uptime - lle_hittime); |
| 663 | if (delay < nd_delay) { |
| 664 | /* |
| 665 | * V_nd6_delay still not passed since the first |
| 666 | * hit in STALE state. |
| 667 | * Reshedule timer and return. |
| 668 | */ |
| 669 | *pdelay = (long)(nd_delay - delay) * hz; |
| 670 | return (1); |
| 671 | } |
| 672 |