* Switch @lle state to new state optionally arming timers. * * Set noinline to be dtrace-friendly */
| 681 | * Set noinline to be dtrace-friendly |
| 682 | */ |
| 683 | __noinline void |
| 684 | nd6_llinfo_setstate(struct llentry *lle, int newstate) |
| 685 | { |
| 686 | struct ifnet *ifp; |
| 687 | int nd_gctimer, nd_delay; |
| 688 | long delay, remtime; |
| 689 | |
| 690 | delay = 0; |
| 691 | remtime = 0; |
| 692 | |
| 693 | switch (newstate) { |
| 694 | case ND6_LLINFO_INCOMPLETE: |
| 695 | ifp = lle->lle_tbl->llt_ifp; |
| 696 | delay = (long)ND_IFINFO(ifp)->retrans * hz / 1000; |
| 697 | break; |
| 698 | case ND6_LLINFO_REACHABLE: |
| 699 | if (!ND6_LLINFO_PERMANENT(lle)) { |
| 700 | ifp = lle->lle_tbl->llt_ifp; |
| 701 | delay = (long)ND_IFINFO(ifp)->reachable * hz; |
| 702 | } |
| 703 | break; |
| 704 | case ND6_LLINFO_STALE: |
| 705 | |
| 706 | /* |
| 707 | * Notify fast path that we want to know if any packet |
| 708 | * is transmitted by setting r_skip_req. |
| 709 | */ |
| 710 | LLE_REQ_LOCK(lle); |
| 711 | lle->r_skip_req = 1; |
| 712 | LLE_REQ_UNLOCK(lle); |
| 713 | nd_delay = V_nd6_delay; |
| 714 | nd_gctimer = V_nd6_gctimer; |
| 715 | |
| 716 | delay = (long)(MIN(nd_gctimer, nd_delay)) * hz; |
| 717 | remtime = (long)nd_gctimer * hz - delay; |
| 718 | break; |
| 719 | case ND6_LLINFO_DELAY: |
| 720 | lle->la_asked = 0; |
| 721 | delay = (long)V_nd6_delay * hz; |
| 722 | break; |
| 723 | } |
| 724 | |
| 725 | if (delay > 0) |
| 726 | nd6_llinfo_settimer_locked(lle, delay); |
| 727 | |
| 728 | lle->lle_remtime = remtime; |
| 729 | lle->ln_state = newstate; |
| 730 | } |
| 731 | |
| 732 | /* |
| 733 | * Timer-dependent part of nd state machine. |
no test coverage detected