State neighbor subsystems timer callback neigh_timer_handler

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 }

 

Guess you like

Origin www.cnblogs.com/wanpengcoder/p/11755403.html