Neighbor subsystem of linux protocol stack (related process 6)

  

static inline struct neighbour *__neigh_lookup(struct neigh_table *tbl, const void *pkey, struct net_device *dev, int creat){struct neighbour *n = neigh_lookup(tbl , pkey, dev);if (n | |  !creat)return n;

//Add interest to the neighbor table n = neigh_create(tbl, pkey, dev); return IS_ERR(n) ? NULL : n;}int neigh_update(struct neighbour *neigh , const u8 *lladdr, u8 new, u32 flags){u8 old;int err;#ifdef CONFIG_ARPDint notify = 0;#endifstruct net_device *dev;int update_isrouter = 0;write_lock_bh(&neigh->lock);dev = Neigh->dev;old = neigh->nud_state;err = -EPERM;if (!(flags & NEIGH_UPDATE_F_ADMIN) &&

(old & (NUD_NOARP |  NUD_PERMANENT))) goto out; //if not changed to a valid state if (! (new & NUD_VALID)) { //remove the timer neigh_del_timer (neigh); //if the previous state is NUD_CONNECTED //then adjust the neighbor The out function pointer corresponding to the item if (old & NUD_CONNECTED) neigh_suspect(neigh);neigh->nud_state = new;err = 0;#ifdef CONFIG_ARPDnotify = old & NUD_VALID;#endifgoto out;}/* Compare new lladdr with Cached one */if (!dev->addr_len) {/* First case: device needs no address. */lladdr = neigh->ha;} else if (lladdr) {/* The second case: if something is Already cachedand a new address is proposed:- compare new & old- if they are different, check override flag*/if ((old & NUD_VALID) &&

!memcmp(lladdr, neigh- >ha, dev->addr_len))lladdr = neigh->ha;} else {/* No address is supplied; if we know something,use it, otherwise discard the request.*/err = -EINVAL;if (!(old & NUD_VALID))goto out;lladdr = neigh->ha;}//If it is converted to the connected state, reset the confirmed time if (new &a Nmp_CONNECTED)neigh->confirmed = jiffies;//Reset update time neigh->updated = jiffies;/* If entry was valid and address is not changed, do not change entry state, if new one is STALE. */err = 0; update_isrouter = flags & NEIGH_UPDATE_F_OVERRIDE_ISROUTER; //Update the neighbor L2 address corresponding to the neighbor item if (old & NUD_VALID) {if (lladdr != neigh->ha && !(flags & NEIGH_UPDATE_F_OVERRIDE)) {update_isrouter = 0; if ((flags & NEIGH_UPDATE_F_WEAK_OVERRIDE) &&(old & NUD_CONNECTED)) {lladdr = neigh->ha;new = NUD_STALE;} elsegoto out;} else {if (lladdr == neigh->ha && new == NUD_STALE &&((flags & NEIGH_UPDATE_F_WEAK_OVERRIDE) | | (old & NUD_CONNECTED)))new = old;}}if (new != old) {neigh_del_timer(neigh);if (new & NUD_IN_TIMER) {neigh_hold(neigh);neigh->timer.expires = jiffies +

((new & NUD_REACHABLE) ?

neigh->parms->reachable_time : 0);add_timer(&neigh->timer);}neigh->nud_state = new;}//Set the ha item if (lladdr != neigh->ha) {memcpy(&neigh->ha, lladdr, dev->addr_len); //update the hh item neigh_update_hhs(neigh); If (!(new & NUD_CONNECTED))neigh->confirmed = jiffies -(neigh->parms->base_reachable_time <1);#ifdef CONFIG_ARPDnotify = 1;#endif}if (new == old Goto out; //If it is transferred to the connection state, set out to connect_outpif (new & NUD_CONNECTED) neigh_connect (neigh); elseneigh_suspect (neigh); //if the neighbor item is from invalid to valid, then put arp_queue Corresponding //skb is sentzh-CN"],null,[0.9693771],zh-CN"]]]

Copyright © Windows knowledge All Rights Reserved