* Timer-dependent part of nd state machine. * * Set noinline to be dtrace-friendly */
| 735 | * Set noinline to be dtrace-friendly |
| 736 | */ |
| 737 | static __noinline void |
| 738 | nd6_llinfo_timer(void *arg) |
| 739 | { |
| 740 | struct epoch_tracker et; |
| 741 | struct llentry *ln; |
| 742 | struct in6_addr *dst, *pdst, *psrc, src; |
| 743 | struct ifnet *ifp; |
| 744 | struct nd_ifinfo *ndi; |
| 745 | int do_switch, send_ns; |
| 746 | long delay; |
| 747 | |
| 748 | KASSERT(arg != NULL, ("%s: arg NULL", __func__)); |
| 749 | ln = (struct llentry *)arg; |
| 750 | ifp = lltable_get_ifp(ln->lle_tbl); |
| 751 | CURVNET_SET(ifp->if_vnet); |
| 752 | |
| 753 | ND6_RLOCK(); |
| 754 | LLE_WLOCK(ln); |
| 755 | if (callout_pending(&ln->lle_timer)) { |
| 756 | /* |
| 757 | * Here we are a bit odd here in the treatment of |
| 758 | * active/pending. If the pending bit is set, it got |
| 759 | * rescheduled before I ran. The active |
| 760 | * bit we ignore, since if it was stopped |
| 761 | * in ll_tablefree() and was currently running |
| 762 | * it would have return 0 so the code would |
| 763 | * not have deleted it since the callout could |
| 764 | * not be stopped so we want to go through |
| 765 | * with the delete here now. If the callout |
| 766 | * was restarted, the pending bit will be back on and |
| 767 | * we just want to bail since the callout_reset would |
| 768 | * return 1 and our reference would have been removed |
| 769 | * by nd6_llinfo_settimer_locked above since canceled |
| 770 | * would have been 1. |
| 771 | */ |
| 772 | LLE_WUNLOCK(ln); |
| 773 | ND6_RUNLOCK(); |
| 774 | CURVNET_RESTORE(); |
| 775 | return; |
| 776 | } |
| 777 | NET_EPOCH_ENTER(et); |
| 778 | ndi = ND_IFINFO(ifp); |
| 779 | send_ns = 0; |
| 780 | dst = &ln->r_l3addr.addr6; |
| 781 | pdst = dst; |
| 782 | |
| 783 | if (ln->ln_ntick > 0) { |
| 784 | if (ln->ln_ntick > INT_MAX) { |
| 785 | ln->ln_ntick -= INT_MAX; |
| 786 | nd6_llinfo_settimer_locked(ln, INT_MAX); |
| 787 | } else { |
| 788 | ln->ln_ntick = 0; |
| 789 | nd6_llinfo_settimer_locked(ln, ln->ln_ntick); |
| 790 | } |
| 791 | goto done; |
| 792 | } |
| 793 | |
| 794 | if (ln->la_flags & LLE_STATIC) { |
nothing calls this directly
no test coverage detected