OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [net/] [appletalk/] [aarp.c] - Blame information for rev 1772

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1629 jcastillo
/*
2
 *      AARP:           An implementation of the Appletalk aarp protocol for
3
 *                      ethernet 'ELAP'.
4
 *
5
 *              Alan Cox  <Alan.Cox@linux.org>
6
 *                        <alan@cymru.net>
7
 *
8
 *      This doesn't fit cleanly with the IP arp. This isn't a problem as
9
 *      the IP arp wants extracting from the device layer in 1.3.x anyway.
10
 *      [see the pre-1.3 test code for details 8)]
11
 *
12
 *      FIXME:
13
 *              We ought to handle the retransmits with a single list and a
14
 *      separate fast timer for when it is needed.
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
 */
25
 
26
#include <asm/segment.h>
27
#include <asm/system.h>
28
#include <asm/bitops.h>
29
#include <linux/types.h>
30
#include <linux/kernel.h>
31
#include <linux/sched.h>
32
#include <linux/string.h>
33
#include <linux/mm.h>
34
#include <linux/socket.h>
35
#include <linux/sockios.h>
36
#include <linux/in.h>
37
#include <linux/errno.h>
38
#include <linux/interrupt.h>
39
#include <linux/if_ether.h>
40
#include <linux/inet.h>
41
#include <linux/notifier.h>
42
#include <linux/netdevice.h>
43
#include <linux/etherdevice.h>
44
#include <linux/if_arp.h>
45
#include <linux/skbuff.h>
46
#include <net/sock.h>
47
#include <net/datalink.h>
48
#include <net/psnap.h>
49
#include <linux/atalk.h>
50
 
51
/*
52
 *      Lists of aarp entries
53
 */
54
 
55
struct aarp_entry
56
{
57
        /* These first two are only used for unresolved entries */
58
        unsigned long last_sent;                /* Last time we xmitted the aarp request */
59
        struct sk_buff_head packet_queue;       /* Queue of frames wait for resolution */
60
        unsigned long expires_at;               /* Entry expiry time */
61
        struct at_addr target_addr;             /* DDP Address */
62
        struct device *dev;                     /* Device to use */
63
        char hwaddr[6];                         /* Physical i/f address of target/router */
64
        unsigned short xmit_count;              /* When this hits 10 we give up */
65
        struct aarp_entry *next;                /* Next entry in chain */
66
};
67
 
68
 
69
/*
70
 *      Hashed list of resolved and unresolved entries
71
 */
72
 
73
static struct aarp_entry *resolved[AARP_HASH_SIZE], *unresolved[AARP_HASH_SIZE];
74
static int unresolved_count=0;
75
 
76
/*
77
 *      Used to walk the list and purge/kick entries.
78
 */
79
 
80
static struct timer_list aarp_timer;
81
 
82
/*
83
 *      Delete an aarp queue
84
 */
85
 
86
static void aarp_expire(struct aarp_entry *a)
87
{
88
        struct sk_buff *skb;
89
 
90
        while((skb=skb_dequeue(&a->packet_queue))!=NULL)
91
                kfree_skb(skb, FREE_WRITE);
92
        kfree_s(a,sizeof(*a));
93
}
94
 
95
/*
96
 *      Send an aarp queue entry request
97
 */
98
 
99
static void aarp_send_query(struct aarp_entry *a)
100
{
101
        static char aarp_eth_multicast[ETH_ALEN]={ 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF };
102
        struct device *dev=a->dev;
103
        int len=dev->hard_header_len+sizeof(struct elapaarp)+aarp_dl->header_length;
104
        struct sk_buff *skb=alloc_skb(len, GFP_ATOMIC);
105
        struct elapaarp *eah;
106
        struct at_addr *sat=atalk_find_dev_addr(dev);
107
 
108
        if(skb==NULL || sat==NULL)
109
                return;
110
 
111
        /*
112
         *      Set up the buffer.
113
         */
114
 
115
        skb_reserve(skb,dev->hard_header_len+aarp_dl->header_length);
116
        eah             =       (struct elapaarp *)skb_put(skb,sizeof(struct elapaarp));
117
        skb->arp        =       1;
118
        skb->free       =       1;
119
        skb->dev        =       a->dev;
120
 
121
        /*
122
         *      Set up the ARP.
123
         */
124
 
125
        eah->hw_type    =       htons(AARP_HW_TYPE_ETHERNET);
126
        eah->pa_type    =       htons(ETH_P_ATALK);
127
        eah->hw_len     =       ETH_ALEN;
128
        eah->pa_len     =       AARP_PA_ALEN;
129
        eah->function   =       htons(AARP_REQUEST);
130
 
131
        memcpy(eah->hw_src, dev->dev_addr, ETH_ALEN);
132
 
133
        eah->pa_src_zero=       0;
134
        eah->pa_src_net =       sat->s_net;
135
        eah->pa_src_node=       sat->s_node;
136
 
137
        memset(eah->hw_dst, '\0', ETH_ALEN);
138
 
139
        eah->pa_dst_zero=       0;
140
        eah->pa_dst_net =       a->target_addr.s_net;
141
        eah->pa_dst_node=       a->target_addr.s_node;
142
 
143
        /*
144
         *      Add ELAP headers and set target to the AARP multicast.
145
         */
146
 
147
        aarp_dl->datalink_header(aarp_dl, skb, aarp_eth_multicast);
148
 
149
        /*
150
         *      Send it.
151
         */
152
 
153
        dev_queue_xmit(skb, dev, SOPRI_NORMAL);
154
 
155
        /*
156
         *      Update the sending count
157
         */
158
 
159
        a->xmit_count++;
160
}
161
 
162
static void aarp_send_reply(struct device *dev, struct at_addr *us, struct at_addr *them, unsigned char *sha)
163
{
164
        int len=dev->hard_header_len+sizeof(struct elapaarp)+aarp_dl->header_length;
165
        struct sk_buff *skb=alloc_skb(len, GFP_ATOMIC);
166
        struct elapaarp *eah;
167
 
168
        if(skb==NULL)
169
                return;
170
 
171
        /*
172
         *      Set up the buffer.
173
         */
174
 
175
        skb_reserve(skb,dev->hard_header_len+aarp_dl->header_length);
176
        eah             =       (struct elapaarp *)skb_put(skb,sizeof(struct elapaarp));
177
        skb->arp        =       1;
178
        skb->free       =       1;
179
        skb->dev        =       dev;
180
 
181
        /*
182
         *      Set up the ARP.
183
         */
184
 
185
        eah->hw_type    =       htons(AARP_HW_TYPE_ETHERNET);
186
        eah->pa_type    =       htons(ETH_P_ATALK);
187
        eah->hw_len     =       ETH_ALEN;
188
        eah->pa_len     =       AARP_PA_ALEN;
189
        eah->function   =       htons(AARP_REPLY);
190
 
191
        memcpy(eah->hw_src, dev->dev_addr, ETH_ALEN);
192
 
193
        eah->pa_src_zero=       0;
194
        eah->pa_src_net =       us->s_net;
195
        eah->pa_src_node=       us->s_node;
196
 
197
        if(sha==NULL)
198
                memset(eah->hw_dst, '\0', ETH_ALEN);
199
        else
200
                memcpy(eah->hw_dst, sha, ETH_ALEN);
201
 
202
        eah->pa_dst_zero=       0;
203
        eah->pa_dst_net =       them->s_net;
204
        eah->pa_dst_node=       them->s_node;
205
 
206
        /*
207
         *      Add ELAP headers and set target to the AARP multicast.
208
         */
209
 
210
        aarp_dl->datalink_header(aarp_dl, skb, sha);
211
 
212
        /*
213
         *      Send it.
214
         */
215
 
216
        dev_queue_xmit(skb, dev, SOPRI_NORMAL);
217
 
218
}
219
 
220
/*
221
 *      Send probe frames. Called from atif_probe_device.
222
 */
223
 
224
void aarp_send_probe(struct device *dev, struct at_addr *us)
225
{
226
        int len=dev->hard_header_len+sizeof(struct elapaarp)+aarp_dl->header_length;
227
        struct sk_buff *skb=alloc_skb(len, GFP_ATOMIC);
228
        struct elapaarp *eah;
229
        static char aarp_eth_multicast[ETH_ALEN]={ 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF };
230
 
231
        if(skb==NULL)
232
                return;
233
 
234
        /*
235
         *      Set up the buffer.
236
         */
237
 
238
        skb_reserve(skb,dev->hard_header_len+aarp_dl->header_length);
239
        eah             =       (struct elapaarp *)skb_put(skb,sizeof(struct elapaarp));
240
 
241
        skb->arp        =       1;
242
        skb->free       =       1;
243
        skb->dev        =       dev;
244
 
245
        /*
246
         *      Set up the ARP.
247
         */
248
 
249
        eah->hw_type    =       htons(AARP_HW_TYPE_ETHERNET);
250
        eah->pa_type    =       htons(ETH_P_ATALK);
251
        eah->hw_len     =       ETH_ALEN;
252
        eah->pa_len     =       AARP_PA_ALEN;
253
        eah->function   =       htons(AARP_PROBE);
254
 
255
        memcpy(eah->hw_src, dev->dev_addr, ETH_ALEN);
256
 
257
        eah->pa_src_zero=       0;
258
        eah->pa_src_net =       us->s_net;
259
        eah->pa_src_node=       us->s_node;
260
 
261
        memset(eah->hw_dst, '\0', ETH_ALEN);
262
 
263
        eah->pa_dst_zero=       0;
264
        eah->pa_dst_net =       us->s_net;
265
        eah->pa_dst_node=       us->s_node;
266
 
267
        /*
268
         *      Add ELAP headers and set target to the AARP multicast.
269
         */
270
 
271
        aarp_dl->datalink_header(aarp_dl, skb, aarp_eth_multicast);
272
 
273
        /*
274
         *      Send it.
275
         */
276
 
277
        dev_queue_xmit(skb, dev, SOPRI_NORMAL);
278
 
279
}
280
 
281
/*
282
 *      Handle an aarp timer expire
283
 */
284
 
285
static void aarp_expire_timer(struct aarp_entry **n)
286
{
287
        struct aarp_entry *t;
288
        while((*n)!=NULL)
289
        {
290
                /* Expired ? */
291
                if((*n)->expires_at < jiffies)
292
                {
293
                        t= *n;
294
                        *n=(*n)->next;
295
                        aarp_expire(t);
296
                }
297
                else
298
                        n=&((*n)->next);
299
        }
300
}
301
 
302
/*
303
 *      Kick all pending requests 5 times a second.
304
 */
305
 
306
static void aarp_kick(struct aarp_entry **n)
307
{
308
        struct aarp_entry *t;
309
        while((*n)!=NULL)
310
        {
311
                /* Expired - if this will be the 11th transmit, we delete
312
                   instead */
313
                if((*n)->xmit_count>=AARP_RETRANSMIT_LIMIT)
314
                {
315
                        t= *n;
316
                        *n=(*n)->next;
317
                        aarp_expire(t);
318
                }
319
                else
320
                {
321
                        aarp_send_query(*n);
322
                        n=&((*n)->next);
323
                }
324
        }
325
}
326
 
327
/*
328
 *      A device has gone down. Take all entries referring to the device
329
 *      and remove them.
330
 */
331
 
332
static void aarp_expire_device(struct aarp_entry **n, struct device *dev)
333
{
334
        struct aarp_entry *t;
335
        while((*n)!=NULL)
336
        {
337
                if((*n)->dev==dev)
338
                {
339
                        t= *n;
340
                        *n=(*n)->next;
341
                        aarp_expire(t);
342
                }
343
                else
344
                        n=&((*n)->next);
345
        }
346
}
347
 
348
/*
349
 *      Handle the timer event
350
 */
351
 
352
static void aarp_expire_timeout(unsigned long unused)
353
{
354
        int ct=0;
355
        for(ct=0;ct<AARP_HASH_SIZE;ct++)
356
        {
357
                aarp_expire_timer(&resolved[ct]);
358
                aarp_kick(&unresolved[ct]);
359
                aarp_expire_timer(&unresolved[ct]);
360
        }
361
        del_timer(&aarp_timer);
362
        if(unresolved_count==0)
363
                aarp_timer.expires=jiffies+AARP_EXPIRY_TIME;
364
        else
365
                aarp_timer.expires=jiffies+AARP_TICK_TIME;
366
        add_timer(&aarp_timer);
367
}
368
 
369
/*
370
 *      Network device notifier chain handler.
371
 */
372
 
373
static int aarp_device_event(struct notifier_block *this, unsigned long event, void *ptr)
374
{
375
        int ct=0;
376
        if(event==NETDEV_DOWN)
377
        {
378
                for(ct=0;ct<AARP_HASH_SIZE;ct++)
379
                {
380
                        aarp_expire_device(&resolved[ct],ptr);
381
                        aarp_expire_device(&unresolved[ct],ptr);
382
                }
383
        }
384
        return NOTIFY_DONE;
385
}
386
 
387
/*
388
 *      Create a new aarp entry.
389
 */
390
 
391
static struct aarp_entry *aarp_alloc(void)
392
{
393
        struct aarp_entry *a=kmalloc(sizeof(struct aarp_entry), GFP_ATOMIC);
394
        if(a==NULL)
395
                return NULL;
396
        skb_queue_head_init(&a->packet_queue);
397
        return a;
398
}
399
 
400
/*
401
 *      Find an entry. We might return an expired but not yet purged entry. We
402
 *      don't care as it will do no harm.
403
 */
404
 
405
static struct aarp_entry *aarp_find_entry(struct aarp_entry *list, struct device *dev, struct at_addr *sat)
406
{
407
        unsigned long flags;
408
        save_flags(flags);
409
        cli();
410
        while(list)
411
        {
412
                if(list->target_addr.s_net==sat->s_net &&
413
                   list->target_addr.s_node==sat->s_node && list->dev==dev)
414
                        break;
415
                list=list->next;
416
        }
417
        restore_flags(flags);
418
        return list;
419
}
420
 
421
/*
422
 *      Send a DDP frame
423
 */
424
 
425
int aarp_send_ddp(struct device *dev,struct sk_buff *skb, struct at_addr *sa, void *hwaddr)
426
{
427
        static char ddp_eth_multicast[ETH_ALEN]={ 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF };
428
        int hash;
429
        struct aarp_entry *a;
430
        unsigned long flags;
431
 
432
        /*
433
         *      Check for localtalk first
434
         */
435
 
436
        if(dev->type==ARPHRD_LOCALTLK)
437
        {
438
                struct at_addr *at=atalk_find_dev_addr(dev);
439
                struct ddpehdr *ddp=(struct ddpehdr *)skb->data;
440
                int ft=2;
441
 
442
                /*
443
                 *      Compressible ?
444
                 *
445
                 *      IFF: src_net==dest_net==device_net
446
                 */
447
 
448
                if(at->s_net==sa->s_net && sa->s_net==ddp->deh_snet)
449
                {
450
                        skb_pull(skb,sizeof(struct ddpehdr)-4);
451
                        /*
452
                         *      The upper two remaining bytes are the port
453
                         *      numbers we just happen to need. Now put the
454
                         *      length in the lower two.
455
                         */
456
                        *((__u16 *)skb->data)=htons(skb->len);
457
                        ft=1;
458
                }
459
                /*
460
                 *      Nice and easy. No AARP type protocols occur here
461
                 *      so we can just shovel it out with a 3 byte LLAP header
462
                 */
463
 
464
                skb_push(skb,3);
465
                skb->data[0]=sa->s_node;
466
                skb->data[1]=at->s_node;
467
                skb->data[2]=ft;
468
 
469
                if(skb->sk==NULL)
470
                        dev_queue_xmit(skb, skb->dev, SOPRI_NORMAL);
471
                else
472
                        dev_queue_xmit(skb, skb->dev, skb->sk->priority);
473
                return 1;
474
        }
475
 
476
        /*
477
         *      Non ELAP we cannot do.
478
         */
479
 
480
        if(dev->type!=ARPHRD_ETHER)
481
        {
482
                return -1;
483
        }
484
 
485
        skb->dev = dev;
486
        skb->protocol = htons(ETH_P_ATALK);
487
 
488
        hash=sa->s_node%(AARP_HASH_SIZE-1);
489
        save_flags(flags);
490
        cli();
491
 
492
        /*
493
         *      Do we have a resolved entry ?
494
         */
495
 
496
        if(sa->s_node==ATADDR_BCAST)
497
        {
498
                ddp_dl->datalink_header(ddp_dl, skb, ddp_eth_multicast);
499
                if(skb->sk==NULL)
500
                        dev_queue_xmit(skb, skb->dev, SOPRI_NORMAL);
501
                else
502
                        dev_queue_xmit(skb, skb->dev, skb->sk->priority);
503
                restore_flags(flags);
504
                return 1;
505
        }
506
        a=aarp_find_entry(resolved[hash],dev,sa);
507
        if(a!=NULL)
508
        {
509
                /*
510
                 *      Return 1 and fill in the address
511
                 */
512
 
513
                a->expires_at=jiffies+AARP_EXPIRY_TIME*10;
514
                ddp_dl->datalink_header(ddp_dl, skb, a->hwaddr);
515
                if(skb->sk==NULL)
516
                        dev_queue_xmit(skb, skb->dev, SOPRI_NORMAL);
517
                else
518
                        dev_queue_xmit(skb, skb->dev, skb->sk->priority);
519
                restore_flags(flags);
520
                return 1;
521
        }
522
 
523
        /*
524
         *      Do we have an unresolved entry: This is the less common path
525
         */
526
 
527
        a=aarp_find_entry(unresolved[hash],dev,sa);
528
        if(a!=NULL)
529
        {
530
                /*
531
                 *      Queue onto the unresolved queue
532
                 */
533
 
534
                skb_queue_tail(&a->packet_queue, skb);
535
                restore_flags(flags);
536
                return 0;
537
        }
538
 
539
        /*
540
         *      Allocate a new entry
541
         */
542
 
543
        a=aarp_alloc();
544
        if(a==NULL)
545
        {
546
                /*
547
                 *      Whoops slipped... good job it's an unreliable
548
                 *      protocol 8)
549
                 */
550
                restore_flags(flags);
551
                return -1;
552
        }
553
 
554
        /*
555
         *      Set up the queue
556
         */
557
 
558
        skb_queue_tail(&a->packet_queue, skb);
559
        a->expires_at=jiffies+AARP_RESOLVE_TIME;
560
        a->dev=dev;
561
        a->next=unresolved[hash];
562
        a->target_addr= *sa;
563
        a->xmit_count=0;
564
        unresolved[hash]=a;
565
        unresolved_count++;
566
        restore_flags(flags);
567
 
568
        /*
569
         *      Send an initial request for the address
570
         */
571
 
572
        aarp_send_query(a);
573
 
574
        /*
575
         *      Switch to fast timer if needed (That is if this is the
576
         *      first unresolved entry to get added)
577
         */
578
 
579
        if(unresolved_count==1)
580
        {
581
                del_timer(&aarp_timer);
582
                aarp_timer.expires=jiffies+AARP_TICK_TIME;
583
                add_timer(&aarp_timer);
584
        }
585
 
586
        /*
587
         *      Tell the ddp layer we have taken over for this frame.
588
         */
589
 
590
        return 0;
591
}
592
 
593
/*
594
 *      An entry in the aarp unresolved queue has become resolved. Send
595
 *      all the frames queued under it.
596
 */
597
 
598
static void aarp_resolved(struct aarp_entry **list, struct aarp_entry *a, int hash)
599
{
600
        struct sk_buff *skb;
601
        while(*list!=NULL)
602
        {
603
                if(*list==a)
604
                {
605
                        unresolved_count--;
606
                        *list=a->next;
607
 
608
                        /*
609
                         *      Move into the resolved list
610
                         */
611
 
612
                        a->next=resolved[hash];
613
                        resolved[hash]=a;
614
 
615
                        /*
616
                         *      Kick frames off
617
                         */
618
 
619
                        while((skb=skb_dequeue(&a->packet_queue))!=NULL)
620
                        {
621
                                a->expires_at=jiffies+AARP_EXPIRY_TIME*10;
622
                                ddp_dl->datalink_header(ddp_dl,skb,a->hwaddr);
623
                                if(skb->sk==NULL)
624
                                        dev_queue_xmit(skb, skb->dev, SOPRI_NORMAL);
625
                                else
626
                                        dev_queue_xmit(skb, skb->dev, skb->sk->priority);
627
                        }
628
                }
629
                else
630
                        list=&((*list)->next);
631
        }
632
}
633
 
634
/*
635
 *      This is called by the SNAP driver whenever we see an AARP SNAP
636
 *      frame. We currently only support ethernet.
637
 */
638
 
639
static int aarp_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
640
{
641
        struct elapaarp *ea=(struct elapaarp *)skb->h.raw;
642
        struct aarp_entry *a;
643
        struct at_addr sa, *ma;
644
        unsigned long flags;
645
        int hash;
646
        struct atalk_iface *ifa;
647
 
648
 
649
        /*
650
         *      We only do ethernet SNAP AARP
651
         */
652
 
653
        if(dev->type!=ARPHRD_ETHER)
654
        {
655
                kfree_skb(skb, FREE_READ);
656
                return 0;
657
        }
658
 
659
        /*
660
         *      Frame size ok ?
661
         */
662
 
663
        if(!skb_pull(skb,sizeof(*ea)))
664
        {
665
                kfree_skb(skb, FREE_READ);
666
                return 0;
667
        }
668
 
669
        ea->function=ntohs(ea->function);
670
 
671
        /*
672
         *      Sanity check fields.
673
         */
674
 
675
        if(ea->function<AARP_REQUEST || ea->function > AARP_PROBE || ea->hw_len != ETH_ALEN || ea->pa_len != AARP_PA_ALEN ||
676
                ea->pa_src_zero != 0 || ea->pa_dst_zero != 0)
677
        {
678
                kfree_skb(skb, FREE_READ);
679
                return 0;
680
        }
681
 
682
        /*
683
         *      Looks good
684
         */
685
 
686
        hash=ea->pa_src_node%(AARP_HASH_SIZE-1);
687
 
688
        /*
689
         *      Build an address
690
         */
691
 
692
        sa.s_node=ea->pa_src_node;
693
        sa.s_net=ea->pa_src_net;
694
 
695
        /*
696
         *      Process the packet
697
         */
698
 
699
        save_flags(flags);
700
 
701
        /*
702
         *      Check for replies of me
703
         */
704
 
705
        ifa=atalk_find_dev(dev);
706
        if(ifa==NULL)
707
        {
708
                restore_flags(flags);
709
                kfree_skb(skb, FREE_READ);
710
                return 1;
711
        }
712
        if(ifa->status&ATIF_PROBE)
713
        {
714
                if(ifa->address.s_node==ea->pa_dst_node && ifa->address.s_net==ea->pa_dst_net)
715
                {
716
                        /*
717
                         *      Fail the probe (in use)
718
                         */
719
 
720
                        ifa->status|=ATIF_PROBE_FAIL;
721
                        restore_flags(flags);
722
                        kfree_skb(skb, FREE_READ);
723
                        return 1;
724
                }
725
        }
726
 
727
        switch(ea->function)
728
        {
729
                case AARP_REPLY:
730
                        if(unresolved_count==0)  /* Speed up */
731
                                break;
732
                        /*
733
                         *      Find the entry
734
                         */
735
 
736
                        cli();
737
                        if((a=aarp_find_entry(unresolved[hash],dev,&sa))==NULL || dev != a->dev)
738
                                break;
739
                        /*
740
                         *      We can fill one in - this is good
741
                         */
742
 
743
                        memcpy(a->hwaddr,ea->hw_src,ETH_ALEN);
744
                        aarp_resolved(&unresolved[hash],a,hash);
745
                        if(unresolved_count==0)
746
                        {
747
                                del_timer(&aarp_timer);
748
                                aarp_timer.expires=jiffies+AARP_EXPIRY_TIME;
749
                                add_timer(&aarp_timer);
750
                        }
751
                        break;
752
 
753
                case AARP_REQUEST:
754
                case AARP_PROBE:
755
                        /*
756
                         *      If it is my address set ma to my address and reply. We can treat probe and
757
                         *      request the same. Probe simply means we shouldn't cache the querying host,
758
                         *      as in a probe they are proposing an address not using one.
759
                         */
760
 
761
                        ma=&ifa->address;
762
                        sa.s_node=ea->pa_dst_node;
763
                        sa.s_net=ea->pa_dst_net;
764
 
765
                        if(sa.s_node!=ma->s_node)
766
                                break;
767
                        if(sa.s_net && ma->s_net && sa.s_net!=ma->s_net)
768
                                break;
769
 
770
                        sa.s_node=ea->pa_src_node;
771
                        sa.s_net=ea->pa_src_net;
772
 
773
                        /*
774
                         *      aarp_my_address has found the address to use for us.
775
                         */
776
 
777
                        aarp_send_reply(dev,ma,&sa,ea->hw_src);
778
                        break;
779
        }
780
        restore_flags(flags);
781
        kfree_skb(skb, FREE_READ);
782
        return 1;
783
}
784
 
785
static struct notifier_block aarp_notifier={
786
        aarp_device_event,
787
        NULL,
788
 
789
};
790
 
791
static char aarp_snap_id[]={0x00,0x00,0x00,0x80,0xF3};
792
 
793
 
794
void aarp_proto_init(void)
795
{
796
        if((aarp_dl=register_snap_client(aarp_snap_id, aarp_rcv))==NULL)
797
                printk(KERN_CRIT "Unable to register AARP with SNAP.\n");
798
        init_timer(&aarp_timer);
799
        aarp_timer.function=aarp_expire_timeout;
800
        aarp_timer.data=0;
801
        aarp_timer.expires=jiffies+AARP_EXPIRY_TIME;
802
        add_timer(&aarp_timer);
803
        register_netdevice_notifier(&aarp_notifier);
804
}
805
 
806
 
807
#ifdef MODULE
808
 
809
/* Free all the entries in an aarp list. Caller should turn off interrupts. */
810
static void free_entry_list(struct aarp_entry *list)
811
{
812
        struct aarp_entry *tmp;
813
 
814
        while (list != NULL)
815
        {
816
                tmp = list->next;
817
                aarp_expire(list);
818
                list = tmp;
819
        }
820
}
821
 
822
/* General module cleanup. Called from cleanup_module() in ddp.c. */
823
void aarp_cleanup_module(void)
824
{
825
        unsigned long flags;
826
        int i;
827
 
828
        save_flags(flags);
829
        cli();
830
 
831
        del_timer(&aarp_timer);
832
        unregister_netdevice_notifier(&aarp_notifier);
833
        unregister_snap_client(aarp_snap_id);
834
 
835
        for (i = 0; i < AARP_HASH_SIZE; i++)
836
        {
837
                free_entry_list(resolved[i]);
838
                free_entry_list(unresolved[i]);
839
        }
840
 
841
        restore_flags(flags);
842
}
843
 
844
#endif  /* MODULE */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.