Outline
After dispensing neighborhood subsystem, the timer is set to the timer processing status that require treatment, the timer callback function neigh_timer_handler; function of the state of the state machine switches according to the conversion rule, after switching state, if the function needs to be updated output update, and update once the timeout timer; which NUD_INCOMPLETE | NUD_PROBE state needs to send a neighbor solicitation, if more than the maximum number, the packet buffer is released;
Source code analysis
1 / * Timer Processing in respective states of the neighbor callback * / 2 static void neigh_timer_handler (unsigned Long Arg) . 3 { . 4 unsigned Long now, Next; . 5 struct Neighbor neigh * = ( struct Neighbor * ) Arg; . 6 unsigned int State; . 7 int Notify = 0 ; . 8 . 9 write_lock (& neigh-> Lock ); 10 . 11 State = neigh-> NUD_STATE; 12 is now =of jiffies; 13 is Next = now + HZ; 14 15 / * no timer status * / 16 IF ((State &! NUD_IN_TIMER)) . 17 GOTO OUT ; 18 is . 19 / * REACHABLE state * / 20 is IF (State & NUD_REACHABLE) { 21 is / * confirmation period expires, the next set timeout * / 22 is IF (time_before_eq (now, 23 is neigh-> confirmed + neigh-> parms-> reachable_time)) { 24 neigh_dbg ( 2 , "Still Alive IS% P neigh \ n- " , neigh); 25 Next neigh- => Confirmed + neigh-> parms-> reachable_time; 26 is } 27 / * acknowledgment time has expired, but does not reach the idle time * / 28 the else IF (time_before_eq (now, 29 neigh-> Used + 30 NEIGH_VAR (neigh-> parms, DELAY_PROBE_TIME))) { 31 is neigh_dbg ( 2 , " neigh IS DELAYED P% \ n- " , neigh); 32 / * enter DELAY state * / 33 neigh-> NUD_STATE = NUD_DELAY; 34 is neigh-> = Updated of jiffies; 35 36 / * update the output function * / 37 [ neigh_suspect (neigh); 38 is Next NEIGH_VAR = now + (neigh-> parms, DELAY_PROBE_TIME); 39 } 40 / * confirmation time and idle timeout time * / 41 is the else { 42 is neigh_dbg ( 2 , " neigh% P IS Suspected \ n- " , neigh); 43 is / * enter STALE state * / 44 neigh-> NUD_STATE = NUD_STALE; 45 neigh-> = Updated of jiffies; 46 is / * update output functions * / 47 neigh_suspect (neigh); 48 Notify = . 1 ; 49 } 50 } 51 is / * the DELAY state * / 52 is the else IF (State & NUD_DELAY) { 53 is / * last time does not reach acknowledgment timeout * / 54 is IF (time_before_eq (now, 55 neigh-> confirmed + 56 is NEIGH_VAR(neigh->parms, DELAY_PROBE_TIME))) { 57 neigh_dbg(2, "neigh %p is now reachable\n", neigh); 58 59 /* 进入REACHABLE状态,更新输出函数 */ 60 neigh->nud_state = NUD_REACHABLE; 61 neigh->updated = jiffies; 62 neigh_connect(neigh); 63 notify = 1; 64 next = neigh->confirmed + neigh->parms->reachable_time; 65 } 66 /*Final confirmation time has reached timeout, enters a state PROBE * / 67 the else { 68 neigh_dbg ( 2 , " neigh% P IS probed \ n- " , neigh); 69 neigh-> NUD_STATE = NUD_PROBE; 70 neigh-> = Updated of jiffies ; 71 is the atomic_set (& neigh-> Probes, 0 ); 72 Notify = . 1 ; 73 is Next NEIGH_VAR = now + (neigh-> parms, RETRANS_TIME); 74 } 75 } 76 / *NUD_PROBE | NUD_INCOMPLETE * / 77 the else { 78 / * NUD_PROBE | NUD_INCOMPLETE * / 79 Next NEIGH_VAR = now + (neigh-> parms, RETRANS_TIME); 80 } 81 82 / * NUD_PROBE | NUD_INCOMPLETE state, to achieve the maximum number of attempts * / 83 IF ((neigh-> & NUD_STATE (NUD_INCOMPLETE | NUD_PROBE)) && 84 atomic_read (& neigh-> Probes)> = neigh_max_probes (neigh)) { 85 / * is FAILED state, buffer empty packet queue * / 86 neigh-> = NUD_STATE NUD_FAILED; 87 Notify =. 1 ; 88 neigh_invalidate (neigh); 89 GOTO OUT ; 90 } 91 is 92 / * timer processing mode, the refresh timer * / 93 IF (neigh-> NUD_STATE & NUD_IN_TIMER) { 94 IF (time_before (Next, of jiffies + HZ / 2 )) 95 Next = HZ of jiffies + / 2 ; 96 IF (mod_timer (& neigh->! Timer, Next)) 97 neigh_hold (neigh); 98 } 99 100 / * NUD_PROBE | NUD_INCOMPLETE state transmission request packet*/ 101 if (neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) { 102 neigh_probe(neigh); 103 } else { 104 out: 105 write_unlock(&neigh->lock); 106 } 107 108 /* 通知关心的模块 */ 109 if (notify) 110 neigh_update_notify(neigh, 0); 111 112 neigh_release(neigh); 113 }