~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/net/appletalk/aarp.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  *      AARP:           An implementation of the AppleTalk AARP protocol for
  3  *                      Ethernet 'ELAP'.
  4  *
  5  *              Alan Cox  <Alan.Cox@linux.org>
  6  *
  7  *      This doesn't fit cleanly with the IP arp. Potentially we can use
  8  *      the generic neighbour discovery code to clean this up.
  9  *
 10  *      FIXME:
 11  *              We ought to handle the retransmits with a single list and a 
 12  *      separate fast timer for when it is needed.
 13  *              Use neighbour discovery code.
 14  *              Token Ring Support.
 15  *
 16  *              This program is free software; you can redistribute it and/or
 17  *              modify it under the terms of the GNU General Public License
 18  *              as published by the Free Software Foundation; either version
 19  *              2 of the License, or (at your option) any later version.
 20  *
 21  *
 22  *      References:
 23  *              Inside AppleTalk (2nd Ed).
 24  *      Fixes:
 25  *              Jaume Grau      -       flush caches on AARP_PROBE
 26  *              Rob Newberry    -       Added proxy AARP and AARP proc fs, 
 27  *                                      moved probing from DDP module.
 28  *
 29  */
 30 
 31 #include <linux/config.h>
 32 #if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE) 
 33 #include <asm/uaccess.h>
 34 #include <asm/system.h>
 35 #include <asm/bitops.h>
 36 #include <linux/types.h>
 37 #include <linux/kernel.h>
 38 #include <linux/sched.h>
 39 #include <linux/string.h>
 40 #include <linux/mm.h>
 41 #include <linux/socket.h>
 42 #include <linux/sockios.h>
 43 #include <linux/in.h>
 44 #include <linux/errno.h>
 45 #include <linux/interrupt.h>
 46 #include <linux/if_ether.h>
 47 #include <linux/inet.h>
 48 #include <linux/notifier.h>
 49 #include <linux/netdevice.h>
 50 #include <linux/etherdevice.h>
 51 #include <linux/if_arp.h>
 52 #include <linux/skbuff.h>
 53 #include <linux/spinlock.h>
 54 #include <net/sock.h>
 55 #include <net/datalink.h>
 56 #include <net/psnap.h>
 57 #include <linux/atalk.h>
 58 #include <linux/init.h>
 59 #include <linux/proc_fs.h>
 60 
 61  
 62 int sysctl_aarp_expiry_time = AARP_EXPIRY_TIME;
 63 int sysctl_aarp_tick_time = AARP_TICK_TIME;
 64 int sysctl_aarp_retransmit_limit = AARP_RETRANSMIT_LIMIT;
 65 int sysctl_aarp_resolve_time = AARP_RESOLVE_TIME;
 66 
 67 /*
 68  *      Lists of aarp entries
 69  */
 70  
 71 struct aarp_entry {
 72         /* These first two are only used for unresolved entries */
 73         unsigned long last_sent;                /* Last time we xmitted the aarp request */
 74         struct sk_buff_head packet_queue;       /* Queue of frames wait for resolution */
 75         int status;                             /* Used for proxy AARP */
 76         unsigned long expires_at;               /* Entry expiry time */
 77         struct at_addr target_addr;             /* DDP Address */
 78         struct net_device *dev;                 /* Device to use */
 79         char hwaddr[6];                         /* Physical i/f address of target/router */
 80         unsigned short xmit_count;              /* When this hits 10 we give up */
 81         struct aarp_entry *next;                /* Next entry in chain */
 82 };
 83 
 84 /*
 85  *      Hashed list of resolved, unresolved and proxy entries
 86  */
 87 
 88 static struct aarp_entry *resolved[AARP_HASH_SIZE];
 89 static struct aarp_entry *unresolved[AARP_HASH_SIZE];
 90 static struct aarp_entry *proxies[AARP_HASH_SIZE];
 91 static int unresolved_count = 0;
 92 
 93 /* One lock protects it all. */
 94 static spinlock_t aarp_lock = SPIN_LOCK_UNLOCKED;
 95 
 96 /*
 97  *      Used to walk the list and purge/kick entries.
 98  */
 99  
100 static struct timer_list aarp_timer;
101 
102 /*
103  *      Delete an aarp queue
104  *
105  *      Must run under aarp_lock.
106  */
107 static void __aarp_expire(struct aarp_entry *a)
108 {
109         struct sk_buff *skb;
110         
111         while ((skb=skb_dequeue(&a->packet_queue)) != NULL)
112                 kfree_skb(skb);
113 
114         kfree(a);
115 }
116 
117 /*
118  *      Send an aarp queue entry request
119  *
120  *      Must run under aarp_lock.
121  */
122  
123 static void __aarp_send_query(struct aarp_entry *a)
124 {
125         static char aarp_eth_multicast[ETH_ALEN] =
126                 { 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF };
127         struct net_device *dev = a->dev;
128         int len = dev->hard_header_len + sizeof(struct elapaarp) + aarp_dl->header_length;
129         struct sk_buff *skb = alloc_skb(len, GFP_ATOMIC);
130         struct elapaarp *eah;
131         struct at_addr *sat = atalk_find_dev_addr(dev);
132         
133         if (skb == NULL)
134                 return;
135 
136         if (sat == NULL) {
137                 kfree_skb(skb);
138                 return;
139         }
140         
141         /*
142          *      Set up the buffer.
143          */             
144 
145         skb_reserve(skb, dev->hard_header_len + aarp_dl->header_length);
146         eah             =       (struct elapaarp *)skb_put(skb, sizeof(struct elapaarp));
147         skb->protocol   =       htons(ETH_P_ATALK);
148         skb->nh.raw     =       skb->h.raw = (void *) eah;
149         skb->dev        =       dev;
150         
151         /*
152          *      Set up the ARP.
153          */
154          
155         eah->hw_type    =       htons(AARP_HW_TYPE_ETHERNET);
156         eah->pa_type    =       htons(ETH_P_ATALK);
157         eah->hw_len     =       ETH_ALEN;       
158         eah->pa_len     =       AARP_PA_ALEN;
159         eah->function   =       htons(AARP_REQUEST);
160         
161         memcpy(eah->hw_src, dev->dev_addr, ETH_ALEN);
162         
163         eah->pa_src_zero=       0;
164         eah->pa_src_net =       sat->s_net;
165         eah->pa_src_node=       sat->s_node;
166         
167         memset(eah->hw_dst, '\0', ETH_ALEN);
168         
169         eah->pa_dst_zero=       0;
170         eah->pa_dst_net =       a->target_addr.s_net;
171         eah->pa_dst_node=       a->target_addr.s_node;
172         
173         /*
174          *      Add ELAP headers and set target to the AARP multicast.
175          */
176          
177         aarp_dl->datalink_header(aarp_dl, skb, aarp_eth_multicast);     
178 
179         /*
180          *      Send it.
181          */     
182         
183         dev_queue_xmit(skb);
184         
185         /*
186          *      Update the sending count
187          */
188          
189         a->xmit_count++;
190 }
191 
192 /* This runs under aarp_lock and in softint context, so only
193  * atomic memory allocations can be used.
194  */
195 static void aarp_send_reply(struct net_device *dev, struct at_addr *us,
196                             struct at_addr *them, unsigned char *sha)
197 {
198         int len = dev->hard_header_len + sizeof(struct elapaarp) + aarp_dl->header_length;
199         struct sk_buff *skb = alloc_skb(len, GFP_ATOMIC);
200         struct elapaarp *eah;
201         
202         if (skb == NULL)
203                 return;
204         
205         /*
206          *      Set up the buffer.
207          */             
208 
209         skb_reserve(skb, dev->hard_header_len + aarp_dl->header_length);
210         eah             =       (struct elapaarp *)skb_put(skb, sizeof(struct elapaarp));        
211         skb->protocol   =       htons(ETH_P_ATALK);
212         skb->nh.raw     =       skb->h.raw = (void *) eah;
213         skb->dev        =       dev;
214         
215         /*
216          *      Set up the ARP.
217          */
218          
219         eah->hw_type    =       htons(AARP_HW_TYPE_ETHERNET);
220         eah->pa_type    =       htons(ETH_P_ATALK);
221         eah->hw_len     =       ETH_ALEN;       
222         eah->pa_len     =       AARP_PA_ALEN;
223         eah->function   =       htons(AARP_REPLY);
224         
225         memcpy(eah->hw_src, dev->dev_addr, ETH_ALEN);
226         
227         eah->pa_src_zero=       0;
228         eah->pa_src_net =       us->s_net;
229         eah->pa_src_node=       us->s_node;
230         
231         if (sha == NULL)
232                 memset(eah->hw_dst, '\0', ETH_ALEN);
233         else
234                 memcpy(eah->hw_dst, sha, ETH_ALEN);
235         
236         eah->pa_dst_zero=       0;
237         eah->pa_dst_net =       them->s_net;
238         eah->pa_dst_node=       them->s_node;
239         
240         /*
241          *      Add ELAP headers and set target to the AARP multicast.
242          */
243          
244         aarp_dl->datalink_header(aarp_dl, skb, sha);    
245 
246         /*
247          *      Send it.
248          */     
249         dev_queue_xmit(skb);
250 }
251 
252 /*
253  *      Send probe frames. Called from aarp_probe_network and aarp_proxy_probe_network.
254  */
255 
256 void aarp_send_probe(struct net_device *dev, struct at_addr *us)
257 {
258         int len = dev->hard_header_len + sizeof(struct elapaarp) + aarp_dl->header_length;
259         struct sk_buff *skb = alloc_skb(len, GFP_ATOMIC);
260         struct elapaarp *eah;
261         static char aarp_eth_multicast[ETH_ALEN] =
262                 { 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF };
263 
264         if (skb == NULL)
265                 return;
266 
267         /*
268          *      Set up the buffer.
269          */
270 
271         skb_reserve(skb, dev->hard_header_len + aarp_dl->header_length);
272         eah             =       (struct elapaarp *)skb_put(skb, sizeof(struct elapaarp));
273         skb->protocol   =       htons(ETH_P_ATALK);
274         skb->nh.raw     =       skb->h.raw = (void *) eah;
275         skb->dev        =       dev;
276 
277         /*
278          *      Set up the ARP.
279          */
280 
281         eah->hw_type    =       htons(AARP_HW_TYPE_ETHERNET);
282         eah->pa_type    =       htons(ETH_P_ATALK);
283         eah->hw_len     =       ETH_ALEN;
284         eah->pa_len     =       AARP_PA_ALEN;
285         eah->function   =       htons(AARP_PROBE);
286 
287         memcpy(eah->hw_src, dev->dev_addr, ETH_ALEN);
288 
289         eah->pa_src_zero=       0;
290         eah->pa_src_net =       us->s_net;
291         eah->pa_src_node=       us->s_node;
292 
293         memset(eah->hw_dst, '\0', ETH_ALEN);
294 
295         eah->pa_dst_zero=       0;
296         eah->pa_dst_net =       us->s_net;
297         eah->pa_dst_node=       us->s_node;
298 
299         /*
300          *      Add ELAP headers and set target to the AARP multicast.
301          */
302 
303         aarp_dl->datalink_header(aarp_dl, skb, aarp_eth_multicast);
304 
305         /*
306          *      Send it.
307          */
308         dev_queue_xmit(skb);
309 }
310         
311 /*
312  *      Handle an aarp timer expire
313  *
314  *      Must run under the aarp_lock.
315  */
316 
317 static void __aarp_expire_timer(struct aarp_entry **n)
318 {
319         struct aarp_entry *t;
320 
321         while ((*n) != NULL) {
322                 /* Expired ? */
323                 if(time_after(jiffies, (*n)->expires_at)) {
324                         t = *n;
325                         *n = (*n)->next;
326                         __aarp_expire(t);
327                 } else {
328                         n = &((*n)->next);
329                 }
330         }
331 }
332 
333 /*
334  *      Kick all pending requests 5 times a second.
335  *
336  *      Must run under the aarp_lock.
337  */
338  
339 static void __aarp_kick(struct aarp_entry **n)
340 {
341         struct aarp_entry *t;
342 
343         while ((*n) != NULL) {
344                 /* Expired - if this will be the 11th transmit, we delete
345                  * instead.
346                  */
347                 if ((*n)->xmit_count >= sysctl_aarp_retransmit_limit) {
348                         t = *n;
349                         *n = (*n)->next;
350                         __aarp_expire(t);
351                 } else {
352                         __aarp_send_query(*n);
353                         n = &((*n)->next);
354                 }
355         }
356 }
357 
358 /*
359  *      A device has gone down. Take all entries referring to the device
360  *      and remove them.
361  *
362  *      Must run under the aarp_lock.
363  */
364  
365 static void __aarp_expire_device(struct aarp_entry **n, struct net_device *dev)
366 {
367         struct aarp_entry *t;
368 
369         while ((*n) != NULL) {
370                 if ((*n)->dev == dev) {
371                         t = *n;
372                         *n = (*n)->next;
373                         __aarp_expire(t);
374                 } else {
375                         n = &((*n)->next);
376                 }
377         }
378 }
379                 
380 /*
381  *      Handle the timer event 
382  */
383  
384 static void aarp_expire_timeout(unsigned long unused)
385 {
386         int ct;
387 
388         spin_lock_bh(&aarp_lock);
389 
390         for (ct = 0; ct < AARP_HASH_SIZE; ct++) {
391                 __aarp_expire_timer(&resolved[ct]);
392                 __aarp_kick(&unresolved[ct]);
393                 __aarp_expire_timer(&unresolved[ct]);
394                 __aarp_expire_timer(&proxies[ct]);
395         }
396 
397         spin_unlock_bh(&aarp_lock);
398 
399         mod_timer(&aarp_timer, jiffies + 
400                   (unresolved_count ? sysctl_aarp_tick_time:
401                    sysctl_aarp_expiry_time));
402 }
403 
404 /*
405  *      Network device notifier chain handler.
406  */
407  
408 static int aarp_device_event(struct notifier_block *this, unsigned long event, void *ptr)
409 {
410         int ct;
411 
412         if (event == NETDEV_DOWN) {
413                 spin_lock_bh(&aarp_lock);
414 
415                 for (ct = 0; ct < AARP_HASH_SIZE; ct++) {
416                         __aarp_expire_device(&resolved[ct], ptr);
417                         __aarp_expire_device(&unresolved[ct], ptr);
418                         __aarp_expire_device(&proxies[ct], ptr);
419                 }
420 
421                 spin_unlock_bh(&aarp_lock);
422         }
423         return NOTIFY_DONE;
424 }
425 
426 /*
427  *      Create a new aarp entry.  This must use GFP_ATOMIC because it
428  *      runs while holding spinlocks.
429  */
430  
431 static struct aarp_entry *aarp_alloc(void)
432 {
433         struct aarp_entry *a = kmalloc(sizeof(struct aarp_entry), GFP_ATOMIC);
434 
435         if (a == NULL)
436                 return NULL;
437 
438         skb_queue_head_init(&a->packet_queue);
439 
440         return a;
441 }
442 
443 /*
444  * Find an entry. We might return an expired but not yet purged entry. We
445  * don't care as it will do no harm.
446  *
447  * This must run under the aarp_lock.
448  */
449 static struct aarp_entry *__aarp_find_entry(struct aarp_entry *list,
450                                             struct net_device *dev,
451                                             struct at_addr *sat)
452 {
453         while (list) {
454                 if (list->target_addr.s_net == sat->s_net &&
455                     list->target_addr.s_node == sat->s_node &&
456                     list->dev == dev)
457                         break;
458                 list = list->next;
459         }
460 
461         return list;
462 }
463 
464 /* Called from the DDP code, and thus must be exported. */
465 void aarp_proxy_remove(struct net_device *dev, struct at_addr *sa)
466 {
467         struct aarp_entry *a;
468         int hash;
469         
470         hash =  sa->s_node % (AARP_HASH_SIZE-1);
471 
472         spin_lock_bh(&aarp_lock);
473 
474         a = __aarp_find_entry(proxies[hash], dev, sa);
475         if (a)
476                 a->expires_at = jiffies - 1;
477 
478         spin_unlock_bh(&aarp_lock);
479 }
480 
481 /* This must run under aarp_lock. */
482 static struct at_addr *__aarp_proxy_find(struct net_device *dev, struct at_addr *sa)
483 {
484         struct at_addr *retval;
485         struct aarp_entry *a;
486         int hash;
487 
488         hash =  sa->s_node % (AARP_HASH_SIZE-1);
489 
490         retval = NULL;
491         a = __aarp_find_entry(proxies[hash], dev, sa);
492         if (a != NULL)
493                 retval = sa;
494 
495         return retval;
496 }
497 
498         
499 /*
500  * Probe a Phase 1 device or a device that requires its Net:Node to
501  * be set via an ioctl.
502  */
503 void aarp_send_probe_phase1(struct atalk_iface *iface)
504 {
505     struct ifreq atreq;
506     struct sockaddr_at *sa = (struct sockaddr_at *)&atreq.ifr_addr;
507 
508     sa->sat_addr.s_node = iface->address.s_node;
509     sa->sat_addr.s_net  = ntohs(iface->address.s_net);
510 
511     /* We pass the Net:Node to the drivers/cards by a Device ioctl. */
512     if (!(iface->dev->do_ioctl(iface->dev, &atreq, SIOCSIFADDR))) {
513             (void)iface->dev->do_ioctl(iface->dev, &atreq, SIOCGIFADDR);
514             if ((iface->address.s_net != htons(sa->sat_addr.s_net)) ||
515                 (iface->address.s_node != sa->sat_addr.s_node))
516                     iface->status |= ATIF_PROBE_FAIL;
517 
518             iface->address.s_net  = htons(sa->sat_addr.s_net);
519             iface->address.s_node = sa->sat_addr.s_node;
520     }
521 }
522 
523 
524 void aarp_probe_network(struct atalk_iface *atif)
525 {
526         if(atif->dev->type == ARPHRD_LOCALTLK || atif->dev->type == ARPHRD_PPP) {
527                 aarp_send_probe_phase1(atif);
528         } else {
529                 unsigned int count;
530 
531                 for (count = 0; count < AARP_RETRANSMIT_LIMIT; count++) {
532                         aarp_send_probe(atif->dev, &atif->address);
533 
534                         /*
535                          * Defer 1/10th
536                          */
537                         current->state = TASK_INTERRUPTIBLE;
538                         schedule_timeout(HZ/10);
539                                                         
540                         if (atif->status & ATIF_PROBE_FAIL)
541                                 break;
542                 }
543         }
544 }
545 
546 int aarp_proxy_probe_network(struct atalk_iface *atif, struct at_addr *sa)
547 {
548         struct  aarp_entry      *entry;
549         unsigned int count;
550         int     hash, retval;
551         
552         /*
553          * we don't currently support LocalTalk or PPP for proxy AARP;
554          * if someone wants to try and add it, have fun
555          */
556         if (atif->dev->type == ARPHRD_LOCALTLK)
557                 return -EPROTONOSUPPORT;
558                 
559         if (atif->dev->type == ARPHRD_PPP)
560                 return -EPROTONOSUPPORT;
561                 
562         /* 
563          * create a new AARP entry with the flags set to be published -- 
564          * we need this one to hang around even if it's in use
565          */
566         entry = aarp_alloc();
567         if (entry == NULL)
568                 return -ENOMEM;
569         
570         entry->expires_at = -1;
571         entry->status = ATIF_PROBE;
572         entry->target_addr.s_node = sa->s_node;
573         entry->target_addr.s_net = sa->s_net;
574         entry->dev = atif->dev;
575 
576         spin_lock_bh(&aarp_lock);
577 
578         hash = sa->s_node % (AARP_HASH_SIZE - 1);
579         entry->next = proxies[hash];
580         proxies[hash] = entry;
581         
582         for (count = 0; count < AARP_RETRANSMIT_LIMIT; count++) {
583                 aarp_send_probe(atif->dev, sa);
584 
585                 /*
586                  * Defer 1/10th
587                  */
588                 current->state = TASK_INTERRUPTIBLE;
589 
590                 spin_unlock_bh(&aarp_lock);
591 
592                 schedule_timeout(HZ/10);
593                                                 
594                 spin_lock_bh(&aarp_lock);
595 
596                 if (entry->status & ATIF_PROBE_FAIL)
597                         break;
598         }
599         
600         retval = 1;
601 
602         if (entry->status & ATIF_PROBE_FAIL) {
603                 /* free the entry */
604                 entry->expires_at = jiffies - 1;
605                 
606                 /* return network full */
607                 retval = -EADDRINUSE;
608         } else {
609                 /* clear the probing flag */
610                 entry->status &= ~ATIF_PROBE;
611         }
612 
613         spin_unlock_bh(&aarp_lock);
614 
615         return retval;
616 }
617 
618 
619 /*
620  *      Send a DDP frame
621  */
622 int aarp_send_ddp(struct net_device *dev,struct sk_buff *skb, struct at_addr *sa, void *hwaddr)
623 {
624         static char ddp_eth_multicast[ETH_ALEN] = { 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF };
625         int hash;
626         struct aarp_entry *a;
627         
628         skb->nh.raw = skb->data;
629         
630         /*
631          *      Check for LocalTalk first
632          */
633          
634          
635         if (dev->type == ARPHRD_LOCALTLK) {
636                 struct at_addr *at = atalk_find_dev_addr(dev);
637                 struct ddpehdr *ddp = (struct ddpehdr *)skb->data;
638                 int ft = 2;
639                 
640                 /*
641                  *      Compressible ?
642                  * 
643                  *      IFF: src_net==dest_net==device_net
644                  *      (zero matches anything)
645                  */
646                  
647                 if( ( ddp->deh_snet==0 || at->s_net==ddp->deh_snet) &&
648                     ( ddp->deh_dnet==0 || at->s_net==ddp->deh_dnet) ) {
649                         skb_pull(skb, sizeof(struct ddpehdr) - 4);
650 
651                         /*
652                          *      The upper two remaining bytes are the port 
653                          *      numbers we just happen to need. Now put the 
654                          *      length in the lower two.
655                          */
656                         *((__u16 *)skb->data) = htons(skb->len);
657                         ft = 1;
658                 }
659                 /*
660                  *      Nice and easy. No AARP type protocols occur here
661                  *      so we can just shovel it out with a 3 byte LLAP header
662                  */
663                  
664                 skb_push(skb, 3);
665                 skb->data[0] = sa->s_node;
666                 skb->data[1] = at->s_node;
667                 skb->data[2] = ft;
668                  
669                 if (skb->sk)
670                         skb->priority = skb->sk->priority;
671                 skb->dev = dev;
672                 dev_queue_xmit(skb);
673                 return 1;
674         }       
675 
676         /*
677          *      On a PPP link we neither compress nor aarp.
678          */
679         if (dev->type == ARPHRD_PPP) {
680                 skb->protocol = htons(ETH_P_PPPTALK);
681                 if (skb->sk)
682                         skb->priority = skb->sk->priority;
683                 skb->dev = dev;
684                 dev_queue_xmit(skb);
685                 return 1;
686         }
687          
688         /*
689          *      Non ELAP we cannot do.
690          */
691 
692         if (dev->type != ARPHRD_ETHER)
693                 return -1;
694 
695         skb->dev = dev;
696         skb->protocol = htons(ETH_P_ATALK);
697                         
698         hash = sa->s_node % (AARP_HASH_SIZE - 1);
699         
700         /*
701          *      Do we have a resolved entry ?
702          */
703          
704         if (sa->s_node == ATADDR_BCAST) {
705                 ddp_dl->datalink_header(ddp_dl, skb, ddp_eth_multicast);
706 
707                 if (skb->sk)
708                         skb->priority = skb->sk->priority;
709                 dev_queue_xmit(skb);
710                 return 1;
711         }
712 
713         spin_lock_bh(&aarp_lock);
714 
715         a = __aarp_find_entry(resolved[hash], dev, sa);
716 
717         if (a != NULL) {
718                 /*
719                  *      Return 1 and fill in the address
720                  */
721 
722                 a->expires_at = jiffies + (sysctl_aarp_expiry_time * 10);
723                 ddp_dl->datalink_header(ddp_dl, skb, a->hwaddr);
724                 if(skb->sk)
725                         skb->priority = skb->sk->priority;
726                 dev_queue_xmit(skb);
727 
728                 spin_unlock_bh(&aarp_lock);
729                 return 1;
730         }
731 
732         /*
733          *      Do we have an unresolved entry: This is the less common path
734          */
735 
736         a = __aarp_find_entry(unresolved[hash], dev, sa);
737         if (a != NULL) {
738                 /*
739                  *      Queue onto the unresolved queue
740                  */
741 
742                 skb_queue_tail(&a->packet_queue, skb);
743 
744                 spin_unlock_bh(&aarp_lock);
745                 return 0;
746         }
747 
748         /*
749          *      Allocate a new entry
750          */
751 
752         a = aarp_alloc();
753         if (a == NULL) {
754                 /*
755                  *      Whoops slipped... good job it's an unreliable 
756                  *      protocol 8)     
757                  */
758                 spin_unlock_bh(&aarp_lock);
759                 return -1;
760         }
761 
762         /*
763          *      Set up the queue
764          */
765 
766         skb_queue_tail(&a->packet_queue, skb);
767         a->expires_at = jiffies + sysctl_aarp_resolve_time;
768         a->dev = dev;
769         a->next = unresolved[hash];
770         a->target_addr = *sa;
771         a->xmit_count = 0;
772         unresolved[hash] = a;
773         unresolved_count++;
774 
775         /*
776          *      Send an initial request for the address
777          */
778 
779         __aarp_send_query(a);
780 
781         /*
782          *      Switch to fast timer if needed (That is if this is the
783          *      first unresolved entry to get added)
784          */
785 
786         if (unresolved_count == 1)
787                 mod_timer(&aarp_timer, jiffies + sysctl_aarp_tick_time);
788 
789 
790         /*
791          *      Now finally, it is safe to drop the lock.
792          */
793 
794         spin_unlock_bh(&aarp_lock);
795 
796         /*
797          *      Tell the ddp layer we have taken over for this frame.
798          */
799 
800         return 0;
801 }
802 
803 /*
804  *      An entry in the aarp unresolved queue has become resolved. Send
805  *      all the frames queued under it.
806  *
807  *      Must run under aarp_lock.
808  */
809 static void __aarp_resolved(struct aarp_entry **list, struct aarp_entry *a, int hash)
810 {
811         struct sk_buff *skb;
812 
813         while (*list != NULL) {
814                 if (*list == a) {
815                         unresolved_count--;
816 
817                         *list = a->next;
818 
819                         /* 
820                          *      Move into the resolved list 
821                          */
822 
823                         a->next = resolved[hash];
824                         resolved[hash] = a;
825 
826                         /*
827                          *      Kick frames off 
828                          */
829 
830                         while ((skb = skb_dequeue(&a->packet_queue)) != NULL) {
831                                 a->expires_at = jiffies + (sysctl_aarp_expiry_time*10);
832                                 ddp_dl->datalink_header(ddp_dl, skb, a->hwaddr);
833                                 if (skb->sk)
834                                         skb->priority = skb->sk->priority;
835                                 dev_queue_xmit(skb);
836                         }
837                 } else {
838                         list = &((*list)->next);
839                 }
840         }
841 }
842 
843 /*
844  *      This is called by the SNAP driver whenever we see an AARP SNAP
845  *      frame. We currently only support Ethernet.
846  */
847 static int aarp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
848 {
849         struct elapaarp *ea=(struct elapaarp *)skb->h.raw;
850         struct aarp_entry *a;
851         struct at_addr sa, *ma, da;
852         int hash;
853         struct atalk_iface *ifa;
854 
855         /*
856          *      We only do Ethernet SNAP AARP.
857          */
858 
859         if (dev->type != ARPHRD_ETHER) {
860                 kfree_skb(skb);
861                 return 0;
862         }
863 
864         /*
865          *      Frame size ok ?
866          */
867 
868         if (!skb_pull(skb, sizeof(*ea))) {
869                 kfree_skb(skb);
870                 return 0;
871         }
872 
873         ea->function = ntohs(ea->function);
874 
875         /*
876          *      Sanity check fields.
877          */
878 
879         if (ea->function < AARP_REQUEST ||
880             ea->function > AARP_PROBE ||
881             ea->hw_len != ETH_ALEN ||
882             ea->pa_len != AARP_PA_ALEN ||
883             ea->pa_src_zero != 0 ||
884             ea->pa_dst_zero != 0) {
885                 kfree_skb(skb);
886                 return 0;
887         }
888 
889         /*
890          *      Looks good.
891          */
892 
893         hash = ea->pa_src_node % (AARP_HASH_SIZE - 1);
894 
895         /*
896          *      Build an address.
897          */
898 
899         sa.s_node = ea->pa_src_node;
900         sa.s_net = ea->pa_src_net;
901 
902         /*
903          *      Process the packet.
904          *      Check for replies of me.
905          */
906 
907         ifa = atalk_find_dev(dev);
908         if (ifa == NULL) {
909                 kfree_skb(skb);
910                 return 1;
911         }
912 
913         if (ifa->status & ATIF_PROBE) {
914                 if (ifa->address.s_node == ea->pa_dst_node &&
915                     ifa->address.s_net == ea->pa_dst_net) {
916                         /*
917                          *      Fail the probe (in use)
918                          */
919 
920                         ifa->status |= ATIF_PROBE_FAIL;
921                         kfree_skb(skb);
922                         return 1;
923                 }
924         }
925 
926         /*
927          * Check for replies of proxy AARP entries
928          */
929 
930         da.s_node = ea->pa_dst_node;
931         da.s_net = ea->pa_dst_net;
932 
933         spin_lock_bh(&aarp_lock);
934 
935         a = __aarp_find_entry(proxies[hash], dev, &da);
936 
937         if (a != NULL) {
938                 if (a->status & ATIF_PROBE) {
939                         a->status |= ATIF_PROBE_FAIL;
940 
941                         spin_unlock_bh(&aarp_lock);
942 
943                         /*
944                          * we do not respond to probe or request packets for
945                          * this address while we are probing this address
946                          */
947                         kfree_skb(skb);
948 
949                         return 1;
950                 }
951         }
952 
953         switch (ea->function) {
954                 case AARP_REPLY:        
955                         if (unresolved_count == 0)      /* Speed up */
956                                 break;
957 
958                         /*
959                          *      Find the entry.
960                          */
961                          
962                         if ((a = __aarp_find_entry(unresolved[hash],dev,&sa)) == NULL ||
963                             (dev != a->dev))
964                                 break;
965 
966                         /*
967                          *      We can fill one in - this is good.
968                          */
969                          
970                         memcpy(a->hwaddr,ea->hw_src,ETH_ALEN);
971                         __aarp_resolved(&unresolved[hash],a,hash);
972                         if (unresolved_count == 0)
973                                 mod_timer(&aarp_timer,
974                                           jiffies + sysctl_aarp_expiry_time);
975                         break;
976                         
977                 case AARP_REQUEST:
978                 case AARP_PROBE:
979                         /*
980                          *      If it is my address set ma to my address and reply. We can treat probe and
981                          *      request the same. Probe simply means we shouldn't cache the querying host, 
982                          *      as in a probe they are proposing an address not using one.
983                          *      
984                          *      Support for proxy-AARP added.  We check if the address is one
985                          *      of our proxies before we toss the packet out.
986                          */
987                          
988                         sa.s_node = ea->pa_dst_node;
989                         sa.s_net = ea->pa_dst_net;
990 
991                         /*
992                          * See if we have a matching proxy.
993                          */
994                         ma = __aarp_proxy_find(dev, &sa);
995                         if (!ma) {
996                                 ma = &ifa->address;
997                         } else {
998                                 /*
999                                  * We need to make a copy of the entry.
1000                                  */
1001                                 da.s_node = sa.s_node;
1002                                 da.s_net = da.s_net;
1003                                 ma = &da;
1004                         }
1005 
1006                         if (ea->function == AARP_PROBE) {
1007                                 /* A probe implies someone trying to get an
1008                                  * address. So as a precaution flush any
1009                                  * entries we have for this address.
1010                                  */
1011                                 struct aarp_entry *a = __aarp_find_entry(
1012                                                 resolved[sa.s_node%(AARP_HASH_SIZE-1)],
1013                                                 skb->dev,
1014                                                 &sa);
1015                                 /* Make it expire next tick - that avoids us
1016                                  * getting into a probe/flush/learn/probe/flush/learn
1017                                  * cycle during probing of a slow to respond host addr.
1018                                  */
1019                                 if (a != NULL)
1020                                 {
1021                                         a->expires_at = jiffies - 1;
1022                                         mod_timer(&aarp_timer, jiffies + sysctl_aarp_tick_time);
1023                                 }
1024                         }
1025 
1026                         if (sa.s_node != ma->s_node)
1027                                 break;
1028 
1029                         if (sa.s_net && ma->s_net && sa.s_net != ma->s_net)
1030                                 break;
1031 
1032                         sa.s_node = ea->pa_src_node;
1033                         sa.s_net = ea->pa_src_net;
1034                         
1035                         /*
1036                          *      aarp_my_address has found the address to use for us.
1037                          */
1038                          
1039                         aarp_send_reply(dev, ma, &sa, ea->hw_src);
1040                         break;
1041         };
1042 
1043         spin_unlock_bh(&aarp_lock);
1044 
1045         kfree_skb(skb);
1046         return 1;
1047 }
1048 
1049 static struct notifier_block aarp_notifier = {
1050         aarp_device_event,
1051         NULL,
1052         0
1053 };
1054 
1055 static char aarp_snap_id[] = { 0x00, 0x00, 0x00, 0x80, 0xF3 };
1056 
1057 
1058 void __init aarp_proto_init(void)
1059 {
1060         if ((aarp_dl = register_snap_client(aarp_snap_id, aarp_rcv)) == NULL)
1061                 printk(KERN_CRIT "Unable to register AARP with SNAP.\n");
1062         init_timer(&aarp_timer);
1063         aarp_timer.function = aarp_expire_timeout;
1064         aarp_timer.data = 0;
1065         aarp_timer.expires = jiffies + sysctl_aarp_expiry_time;
1066         add_timer(&aarp_timer);
1067         register_netdevice_notifier(&aarp_notifier);
1068 }
1069 
1070 /*
1071  * Remove the AARP entries associated with a device.
1072  */
1073 void aarp_device_down(struct net_device *dev)
1074 {
1075         int ct;
1076 
1077         spin_lock_bh(&aarp_lock);
1078 
1079         for (ct = 0; ct < AARP_HASH_SIZE; ct++) {
1080                 __aarp_expire_device(&resolved[ct], dev);
1081                 __aarp_expire_device(&unresolved[ct], dev);
1082                 __aarp_expire_device(&proxies[ct], dev);
1083         }
1084 
1085         spin_unlock_bh(&aarp_lock);
1086 }
1087 
1088 /*
1089  * Called from proc fs
1090  */
1091 static int aarp_get_info(char *buffer, char **start, off_t offset, int length)
1092 {
1093         /* we should dump all our AARP entries */
1094         struct aarp_entry       *entry;
1095         int                     len, ct;
1096 
1097         len = sprintf(buffer,
1098                 "%-10.10s  ""%-10.10s""%-18.18s""%12.12s""%12.12s"" xmit_count  status\n",
1099                 "address","device","hw addr","last_sent", "expires");
1100 
1101         spin_lock_bh(&aarp_lock);
1102 
1103         for (ct = 0; ct < AARP_HASH_SIZE; ct++) {
1104                 for (entry = resolved[ct]; entry; entry = entry->next) {
1105                         len+= sprintf(buffer+len,"%6u:%-3u  ",
1106                                 (unsigned int)ntohs(entry->target_addr.s_net),
1107                                 (unsigned int)(entry->target_addr.s_node));
1108                         len+= sprintf(buffer+len,"%-10.10s",
1109                                 entry->dev->name);
1110                         len+= sprintf(buffer+len,"%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
1111                                 (int)(entry->hwaddr[0] & 0x000000FF),
1112                                 (int)(entry->hwaddr[1] & 0x000000FF),
1113                                 (int)(entry->hwaddr[2] & 0x000000FF),
1114                                 (int)(entry->hwaddr[3] & 0x000000FF),
1115                                 (int)(entry->hwaddr[4] & 0x000000FF),
1116                                 (int)(entry->hwaddr[5] & 0x000000FF));
1117                         len+= sprintf(buffer+len,"%12lu ""%12lu ",
1118                                 (unsigned long)entry->last_sent,
1119                                 (unsigned long)entry->expires_at);
1120                         len+=sprintf(buffer+len,"%10u",
1121                                 (unsigned int)entry->xmit_count);
1122 
1123                         len+=sprintf(buffer+len,"   resolved\n");
1124                 }
1125         }
1126 
1127         for (ct = 0; ct < AARP_HASH_SIZE; ct++) {
1128                 for (entry = unresolved[ct]; entry; entry = entry->next) {
1129                         len+= sprintf(buffer+len,"%6u:%-3u  ",
1130                                 (unsigned int)ntohs(entry->target_addr.s_net),
1131                                 (unsigned int)(entry->target_addr.s_node));
1132                         len+= sprintf(buffer+len,"%-10.10s",
1133                                 entry->dev->name);
1134                         len+= sprintf(buffer+len,"%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
1135                                 (int)(entry->hwaddr[0] & 0x000000FF),
1136                                 (int)(entry->hwaddr[1] & 0x000000FF),
1137                                 (int)(entry->hwaddr[2] & 0x000000FF),
1138                                 (int)(entry->hwaddr[3] & 0x000000FF),
1139                                 (int)(entry->hwaddr[4] & 0x000000FF),
1140                                 (int)(entry->hwaddr[5] & 0x000000FF));
1141                         len+= sprintf(buffer+len,"%12lu ""%12lu ",
1142                                 (unsigned long)entry->last_sent,
1143                                 (unsigned long)entry->expires_at);
1144                         len+=sprintf(buffer+len,"%10u",
1145                                 (unsigned int)entry->xmit_count);
1146                         len+=sprintf(buffer+len," unresolved\n");
1147                 }
1148         }
1149 
1150         for (ct = 0; ct < AARP_HASH_SIZE; ct++) {
1151                 for (entry = proxies[ct]; entry; entry = entry->next) {
1152                         len+= sprintf(buffer+len,"%6u:%-3u  ",
1153                                 (unsigned int)ntohs(entry->target_addr.s_net),
1154                                 (unsigned int)(entry->target_addr.s_node));
1155                         len+= sprintf(buffer+len,"%-10.10s",
1156                                 entry->dev->name);
1157                         len+= sprintf(buffer+len,"%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
1158                                 (int)(entry->hwaddr[0] & 0x000000FF),
1159                                 (int)(entry->hwaddr[1] & 0x000000FF),
1160                                 (int)(entry->hwaddr[2] & 0x000000FF),
1161                                 (int)(entry->hwaddr[3] & 0x000000FF),
1162                                 (int)(entry->hwaddr[4] & 0x000000FF),
1163                                 (int)(entry->hwaddr[5] & 0x000000FF));
1164                         len+= sprintf(buffer+len,"%12lu ""%12lu ",
1165                                 (unsigned long)entry->last_sent,
1166                                 (unsigned long)entry->expires_at);
1167                         len+=sprintf(buffer+len,"%10u",
1168                                 (unsigned int)entry->xmit_count);
1169                         len+=sprintf(buffer+len,"      proxy\n");
1170                 }
1171         }
1172 
1173         spin_unlock_bh(&aarp_lock);
1174 
1175         return len;
1176 }
1177 
1178 #ifdef MODULE
1179 /*
1180  * General module cleanup. Called from cleanup_module() in ddp.c.
1181  */
1182 void aarp_cleanup_module(void)
1183 {
1184         del_timer(&aarp_timer);
1185         unregister_netdevice_notifier(&aarp_notifier);
1186         unregister_snap_client(aarp_snap_id);
1187 }
1188 
1189 #endif  /* MODULE */
1190 
1191 #ifdef CONFIG_PROC_FS
1192 
1193 void aarp_register_proc_fs(void)
1194 {
1195         proc_net_create("aarp", 0, aarp_get_info);
1196 }
1197 
1198 void aarp_unregister_proc_fs(void)
1199 {
1200         proc_net_remove("aarp");
1201 }
1202 
1203 #endif
1204 
1205 #endif  /* CONFIG_ATALK || CONFIG_ATALK_MODULE */
1206 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.