This source file includes following definitions.
- nat_getbytype
- nat_addr32
- HASH
- nat_hash_key
- nat_attach_chg
- nat_bind
- nat_unbind
- nat_dev_addr_chk_1
- net_alias_devinit
- net_alias_hard_start_xmit
- net_alias_devsetup
- net_alias_slow_findp
- net_alias_dev_create
- net_alias_dev_delete
- net_alias_free
- net_alias_dev_get
- net_alias_dev_rehash
- net_alias_types_getinfo
- net_alias_getinfo
- net_alias_device_event
- nat_addr_chk
- nat_addr_chk32
- net_alias_dev_chk
- net_alias_dev_chk32
- net_alias_dev_rcv_sel
- net_alias_dev_rcv_sel32
- net_alias_init
- register_net_alias_type
- unregister_net_alias_type
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 #include <linux/config.h>
37 #include <linux/types.h>
38 #include <linux/errno.h>
39 #include <linux/netdevice.h>
40 #include <linux/notifier.h>
41 #include <linux/if.h>
42 #include <linux/inet.h>
43 #include <linux/in.h>
44 #include <linux/proc_fs.h>
45 #include <linux/stat.h>
46
47 #ifdef ALIAS_USER_LAND_DEBUG
48 #include "net_alias.h"
49 #include "user_stubs.h"
50 #endif
51
52 #include <linux/net_alias.h>
53
54 #ifdef CONFIG_KERNELD
55 #include <linux/kerneld.h>
56 #endif
57
58
59
60
61
62 #define NET_ALIAS_IFF_MASK (IFF_UP|IFF_BROADCAST|IFF_RUNNING|IFF_NOARP|IFF_LOOPBACK|IFF_POINTOPOINT)
63
64 static struct net_alias_type * nat_getbytype(int type);
65 static int nat_attach_chg(struct net_alias_type *nat, int delta);
66 static int nat_bind(struct net_alias_type *nat,struct net_alias *alias, struct sockaddr *sa);
67 static int nat_unbind(struct net_alias_type *nat, struct net_alias *alias);
68
69
70 static int net_alias_devinit(struct device *dev);
71 static int net_alias_hard_start_xmit(struct sk_buff *skb, struct device *dev);
72 static int net_alias_devsetup(struct net_alias *alias, struct net_alias_type *nat, struct sockaddr *sa);
73 static struct net_alias **net_alias_slow_findp(struct net_alias_info *alias_info, struct net_alias *alias);
74 static struct device *net_alias_dev_create(struct device *main_dev, int slot, int *err, struct sockaddr *sa, void *data);
75 static struct device *net_alias_dev_delete(struct device *main_dev, int slot, int *err);
76 static void net_alias_free(struct device *dev);
77
78
79
80
81
82 struct net_alias_type *nat_base[16];
83
84
85
86
87
88
89 static __inline__ struct net_alias_type *
90 nat_getbytype(int type)
91 {
92 struct net_alias_type *nat;
93 for(nat = nat_base[type & 0x0f]; nat ; nat = nat->next)
94 {
95 if (nat->type == type) return nat;
96 }
97 return NULL;
98 }
99
100
101
102
103
104
105
106 static __inline__ __u32
107 nat_addr32(struct net_alias_type *nat, struct sockaddr *sa)
108 {
109 if (nat->get_addr32)
110 return nat->get_addr32(nat, sa);
111 else
112 return (*(struct sockaddr_in *)sa).sin_addr.s_addr;
113 }
114
115
116
117
118
119
120
121 static __inline__ unsigned
122 HASH(__u32 addr, int af)
123 {
124 unsigned tmp = addr ^ (addr>>16);
125 tmp ^= (tmp>>8);
126 return (tmp^(tmp>>4)^af) & 0x0f;
127 }
128
129
130
131
132
133
134
135
136
137 static __inline__ int
138 nat_hash_key(struct net_alias_type *nat, struct sockaddr *sa)
139 {
140 return HASH(nat_addr32(nat,sa), sa->sa_family);
141 }
142
143
144
145
146
147
148 static int
149 nat_attach_chg(struct net_alias_type *nat, int delta)
150 {
151 unsigned long flags;
152 int n_at;
153 if (!nat) return -1;
154 save_flags(flags);
155 cli();
156 n_at = nat->n_attach + delta;
157 if (n_at < 0)
158 {
159 restore_flags(flags);
160 printk("net_alias: tried to set n_attach < 0 for (family==%d) nat object.\n",
161 nat->type);
162 return -1;
163 }
164 nat->n_attach = n_at;
165 restore_flags(flags);
166 return 0;
167 }
168
169
170
171
172
173
174 static __inline__ int
175 nat_bind(struct net_alias_type *nat,struct net_alias *alias, struct sockaddr *sa)
176 {
177 if (nat->alias_init_1) nat->alias_init_1(nat, alias, sa);
178 return nat_attach_chg(nat, +1);
179 }
180
181
182
183
184
185
186 static __inline__ int
187 nat_unbind(struct net_alias_type *nat, struct net_alias *alias)
188 {
189 if (nat->alias_done_1) nat->alias_done_1(nat, alias);
190 return nat_attach_chg(nat, -1);
191 }
192
193
194
195
196
197
198
199 static __inline__ int nat_dev_addr_chk_1(struct net_alias_type *nat,
200 struct device *dev, struct sockaddr *sa)
201 {
202 if (nat->dev_addr_chk)
203 return nat->dev_addr_chk(nat, dev, sa);
204 else
205 return (dev->pa_addr == (*(struct sockaddr_in *)sa).sin_addr.s_addr);
206 }
207
208
209
210
211
212
213
214 static int
215 net_alias_devinit(struct device *dev)
216 {
217 #ifdef ALIAS_USER_LAND_DEBUG
218 printk("net_alias_devinit(%s) called.\n", dev->name);
219 #endif
220 return 0;
221 }
222
223
224
225
226
227
228
229 static int
230 net_alias_hard_start_xmit(struct sk_buff *skb, struct device *dev)
231 {
232 printk("net_alias: net_alias_hard_start_xmit() for %s called (ignored)!!\n", dev->name);
233 dev_kfree_skb(skb, FREE_WRITE);
234 return 0;
235 }
236
237
238
239
240
241
242 static int
243 net_alias_devsetup(struct net_alias *alias, struct net_alias_type *nat,
244 struct sockaddr *sa)
245 {
246 struct device *main_dev;
247 struct device *dev;
248 int family;
249 int i;
250
251
252
253
254
255
256
257
258 main_dev = alias->main_dev;
259 dev = &alias->dev;
260 memset(dev, '\0', sizeof(struct device));
261 family = (sa)? sa->sa_family : main_dev->family;
262
263 dev->alias_info = NULL;
264 dev->my_alias = alias;
265 dev->name = alias->name;
266 dev->type = main_dev->type;
267 dev->hard_header_len = main_dev->hard_header_len;
268 memcpy(dev->broadcast, main_dev->broadcast, MAX_ADDR_LEN);
269 memcpy(dev->dev_addr, main_dev->dev_addr, MAX_ADDR_LEN);
270 dev->addr_len = main_dev->addr_len;
271 dev->init = net_alias_devinit;
272 dev->hard_start_xmit = net_alias_hard_start_xmit;
273 dev->flags = main_dev->flags & NET_ALIAS_IFF_MASK & ~IFF_UP;
274
275
276
277
278
279 if (family == main_dev->family)
280 {
281 dev->metric = main_dev->metric;
282 dev->mtu = main_dev->mtu;
283 dev->pa_alen = main_dev->pa_alen;
284 dev->hard_header = main_dev->hard_header;
285 dev->rebuild_header = main_dev->rebuild_header;
286 }
287
288
289
290
291
292
293 for (i = 0; i < DEV_NUMBUFFS; i++)
294 skb_queue_head_init(&dev->buffs[i]);
295
296 dev->family = family;
297 return 0;
298 }
299
300
301
302
303
304
305
306 static struct net_alias **
307 net_alias_slow_findp(struct net_alias_info *alias_info, struct net_alias *alias)
308 {
309 unsigned idx, n_aliases;
310 struct net_alias **aliasp;
311
312
313
314
315
316 n_aliases = alias_info->n_aliases;
317 for (idx=0; idx < 16 ; idx++)
318 for (aliasp = &alias_info->hash_tab[idx];*aliasp;aliasp = &(*aliasp)->next)
319 if (*aliasp == alias)
320 return aliasp;
321 else
322 if (--n_aliases == 0) break;
323 return NULL;
324 }
325
326
327
328
329
330
331
332 static struct device *
333 net_alias_dev_create(struct device *main_dev, int slot, int *err, struct sockaddr *sa, void *data)
334 {
335 struct net_alias_info *alias_info;
336 struct net_alias *alias, **aliasp;
337 struct net_alias_type *nat;
338 struct device *dev;
339 unsigned long flags;
340 int family;
341 __u32 addr32;
342
343
344 alias_info = main_dev->alias_info;
345
346
347
348
349
350 family = (sa)? sa->sa_family : main_dev->family;
351
352
353
354
355
356 nat = nat_getbytype(family);
357 if (!nat) {
358 #ifdef CONFIG_KERNELD
359 char modname[20];
360 sprintf (modname,"netalias-%d", family);
361 request_module(modname);
362
363 nat = nat_getbytype(family);
364 if (!nat) {
365 #endif
366 printk("net_alias_dev_create(%s:%d): unregistered family==%d\n",
367 main_dev->name, slot, family);
368
369 *err = -EINVAL;
370 return NULL;
371 #ifdef CONFIG_KERNELD
372 }
373 #endif
374 }
375
376
377
378
379
380 *err = -EIO;
381
382 if (! (main_dev->flags & IFF_UP) )
383 return NULL;
384
385
386
387
388
389 *err = -ENOMEM;
390
391 if (!alias_info)
392 {
393 alias_info = kmalloc(sizeof(struct net_alias_info), GFP_KERNEL);
394 if (!alias_info) return NULL;
395 memset(alias_info, 0, sizeof(struct net_alias_info));
396 }
397
398 if (!(alias = kmalloc(sizeof(struct net_alias), GFP_KERNEL)))
399 return NULL;
400
401
402
403
404
405 memset(alias, 0, sizeof(struct net_alias));
406 alias->slot = slot;
407 alias->main_dev = main_dev;
408 alias->nat = nat;
409 alias->next = NULL;
410 alias->data = data;
411 sprintf(alias->name, "%s:%d", main_dev->name, slot);
412
413
414
415
416
417 net_alias_devsetup(alias, nat, sa);
418
419 dev = &alias->dev;
420
421 save_flags(flags);
422 cli();
423
424
425
426
427
428
429 nat_bind(nat, alias, sa);
430
431
432
433
434
435
436 addr32 = (sa)? nat_addr32(nat, sa) : alias->dev.pa_addr;
437
438
439
440
441
442 alias->hash = HASH(addr32, family);
443
444
445
446
447
448 aliasp = &alias_info->hash_tab[alias->hash];
449 alias->next = *aliasp;
450 *aliasp = alias;
451
452
453
454
455
456 if (!alias_info->n_aliases++)
457 {
458 alias_info->taildev = main_dev;
459 main_dev->alias_info = alias_info;
460 }
461
462
463
464
465
466 dev->next = alias_info->taildev->next;
467 alias_info->taildev->next = dev;
468 alias_info->taildev = dev;
469 restore_flags(flags);
470 return dev;
471 }
472
473
474
475
476
477
478 static struct device *
479 net_alias_dev_delete(struct device *main_dev, int slot, int *err)
480 {
481 struct net_alias_info *alias_info;
482 struct net_alias *alias, **aliasp;
483 struct device *dev;
484 unsigned n_aliases;
485 unsigned long flags;
486 struct net_alias_type *nat;
487 struct device *prevdev;
488
489
490 *err = -ENODEV;
491
492 if (main_dev == NULL) return NULL;
493
494
495
496
497
498 alias_info = main_dev->alias_info;
499 if (!alias_info) return NULL;
500
501 n_aliases = alias_info->n_aliases;
502
503
504
505
506
507
508 for (prevdev=main_dev, alias = NULL;prevdev->next && n_aliases; prevdev = prevdev->next)
509 {
510 if (!(alias = prevdev->next->my_alias))
511 {
512 printk("ERROR: net_alias_dev_delete(): incorrect non-alias device after maindev\n");
513 continue;
514 }
515 if (alias->slot == slot) break;
516 alias = NULL;
517 n_aliases--;
518 }
519
520 if (!alias) return NULL;
521
522 dev = &alias->dev;
523
524
525
526
527
528 for(aliasp = &alias_info->hash_tab[alias->hash]; *aliasp; aliasp = &(*aliasp)->next)
529 if(*aliasp == alias) break;
530
531
532
533
534
535 if (*aliasp != alias)
536 if ((aliasp = net_alias_slow_findp(alias_info, alias)))
537 printk("net_alias_dev_delete(%s): bad hashing recovered\n", alias->name);
538 else
539 {
540 printk("ERROR: net_alias_dev_delete(%s): unhashed alias!\n",alias->name);
541 return NULL;
542 }
543
544 nat = alias->nat;
545
546 save_flags(flags);
547 cli();
548
549
550
551
552
553 nat_unbind(nat, alias);
554
555
556
557
558
559 if ( dev == alias_info->taildev )
560 alias_info->taildev = prevdev;
561
562
563
564
565 prevdev->next = dev->next;
566 dev_close(dev);
567
568
569
570
571
572 *aliasp = (*aliasp)->next;
573
574 if (--alias_info->n_aliases == 0)
575 main_dev->alias_info = NULL;
576 restore_flags(flags);
577
578
579
580
581
582 kfree_s(alias, sizeof(struct net_alias));
583 if (main_dev->alias_info == NULL)
584 kfree_s(alias_info, sizeof(struct net_alias_info));
585
586
587
588
589
590 *err = 0;
591 return NULL;
592 }
593
594
595
596
597
598
599 static void
600 net_alias_free(struct device *main_dev)
601 {
602 struct net_alias_info *alias_info;
603 struct net_alias *alias;
604 struct net_alias_type *nat;
605 struct device *dev;
606 unsigned long flags;
607
608
609
610
611
612 if (!(alias_info = main_dev->alias_info)) return;
613
614
615
616
617
618
619 save_flags(flags);
620 cli();
621
622 dev = main_dev->next;
623 main_dev->next = alias_info->taildev->next;
624 main_dev->alias_info = NULL;
625 alias_info->taildev->next = NULL;
626
627 restore_flags(flags);
628
629
630
631
632
633 while (dev)
634 {
635 if (net_alias_is(dev))
636 {
637 alias = dev->my_alias;
638 if (alias->main_dev == main_dev)
639 {
640
641
642
643
644 nat = alias->nat;
645 if (nat)
646 {
647 nat_unbind(nat, alias);
648 }
649
650 dev_close(dev);
651 dev = dev->next;
652
653 kfree_s(alias, sizeof(struct net_alias));
654 continue;
655 }
656 else
657 printk("net_alias_free(%s): '%s' is not my alias\n",
658 main_dev->name, alias->name);
659 }
660 else
661 printk("net_alias_free(%s): found a non-alias after device!\n",
662 main_dev->name);
663 dev = dev->next;
664 }
665
666 kfree_s(alias_info, sizeof(alias_info));
667 return;
668 }
669
670
671
672
673
674 struct device *
675 net_alias_dev_get(char *dev_name, int aliasing_ok, int *err,
676 struct sockaddr *sa, void *data)
677 {
678 struct device *dev;
679 char *sptr,*eptr;
680 int slot = 0;
681 int delete = 0;
682
683 *err = -ENODEV;
684 if ((dev=dev_get(dev_name)))
685 return dev;
686
687
688
689
690
691 if (!aliasing_ok) return NULL;
692
693 if (!dev_name || !*dev_name)
694 return NULL;
695
696
697
698
699
700 for (sptr=dev_name ; *sptr ; sptr++) if(*sptr==':') break;
701 if (!*sptr || !*(sptr+1))
702 return NULL;
703
704
705
706
707
708 *sptr='\0';
709 if (!(dev=dev_get(dev_name)))
710 return NULL;
711 *sptr++=':';
712
713
714
715
716
717 slot = simple_strtoul(sptr,&eptr,10);
718 if (slot >= NET_ALIAS_MAX_SLOT)
719 return NULL;
720
721
722
723
724
725 if (eptr[0] == '-' && !eptr[1] ) delete++;
726 else if (eptr[0])
727 return NULL;
728
729
730
731
732
733 if (delete)
734 return net_alias_dev_delete(dev, slot, err);
735 else
736 return net_alias_dev_create(dev, slot, err, sa, data);
737 }
738
739
740
741
742
743
744 int
745 net_alias_dev_rehash(struct device *dev, struct sockaddr *sa)
746 {
747 struct net_alias_info *alias_info;
748 struct net_alias *alias, **aliasp;
749 struct device *main_dev;
750 unsigned long flags;
751 struct net_alias_type *o_nat, *n_nat;
752 unsigned n_hash;
753
754
755
756
757
758 if (dev == NULL) return -1;
759 if ( (alias = dev->my_alias) == NULL ) return -1;
760
761 if (!sa)
762 {
763 printk("ERROR: net_alias_rehash(): NULL sockaddr passed\n");
764 return -1;
765 }
766
767
768
769
770
771 if ( (main_dev = alias->main_dev) == NULL )
772 {
773 printk("ERROR: net_alias_rehash for %s: NULL maindev\n", alias->name);
774 return -1;
775 }
776
777
778
779
780
781 if (!(alias_info=main_dev->alias_info))
782 {
783 printk("ERROR: net_alias_rehash for %s: NULL alias_info\n", alias->name);
784 return -1;
785 }
786
787
788
789
790
791 o_nat = alias->nat;
792 if (!o_nat)
793 {
794 printk("ERROR: net_alias_rehash(%s): unbound alias.\n", alias->name);
795 return -1;
796 }
797
798
799
800
801
802 if (o_nat->type == sa->sa_family)
803 n_nat = o_nat;
804 else
805 {
806 n_nat = nat_getbytype(sa->sa_family);
807 if (!n_nat)
808 {
809 printk("ERROR: net_alias_rehash(%s): unreg family==%d.\n", alias->name, sa->sa_family);
810 return -1;
811 }
812 }
813
814
815
816
817
818 n_hash = nat_hash_key(n_nat, sa);
819 if (n_hash == alias->hash && o_nat == n_nat )
820 return 0;
821
822
823
824
825
826 for (aliasp = &alias_info->hash_tab[alias->hash]; *aliasp; aliasp = &(*aliasp)->next)
827 if (*aliasp == alias) break;
828
829
830
831
832
833 if(!*aliasp)
834 if ((aliasp = net_alias_slow_findp(alias_info, alias)))
835 printk("net_alias_rehash(%s): bad hashing recovered\n", alias->name);
836 else
837 {
838 printk("ERROR: net_alias_rehash(%s): unhashed alias!\n", alias->name);
839 return -1;
840 }
841
842 save_flags(flags);
843 cli();
844
845
846
847
848
849
850 if (o_nat != n_nat)
851 nat_unbind(o_nat, alias);
852
853
854
855
856
857 if (n_hash != alias->hash)
858 {
859 *aliasp = (*aliasp)->next;
860 alias->hash = n_hash;
861 aliasp = &alias_info->hash_tab[n_hash];
862 alias->next = *aliasp;
863 *aliasp = alias;
864 }
865
866
867
868
869
870
871 if (o_nat != n_nat)
872 nat_bind(n_nat, alias, sa);
873
874 restore_flags(flags);
875 return 0;
876 }
877
878
879
880
881
882
883
884
885
886 int net_alias_types_getinfo(char *buffer, char **start, off_t offset, int length, int dummy)
887 {
888 off_t pos=0, begin=0;
889 int len=0;
890 struct net_alias_type *nat;
891 unsigned idx;
892 len=sprintf(buffer,"type name n_attach\n");
893 for (idx=0 ; idx < 16 ; idx++)
894 for (nat = nat_base[idx]; nat ; nat = nat->next)
895 {
896 len += sprintf(buffer+len, "%-7d %-15s %-7d\n",
897 nat->type, nat->name,nat->n_attach);
898 pos=begin+len;
899 if(pos<offset)
900 {
901 len=0;
902 begin=pos;
903 }
904 if(pos>offset+length)
905 break;
906 }
907 *start=buffer+(offset-begin);
908 len-=(offset-begin);
909 if(len>length)
910 len=length;
911 return len;
912 }
913
914
915
916
917
918
919
920
921
922 #define NET_ALIASES_RECSIZ 64
923 int net_alias_getinfo(char *buffer, char **start, off_t offset, int length, int dummy)
924 {
925 off_t pos=0, begin=0;
926 int len=0;
927 int dlen;
928 struct net_alias_type *nat;
929 struct net_alias *alias;
930 struct device *dev;
931
932 len=sprintf(buffer,"%-*s\n",NET_ALIASES_RECSIZ-1,"device family address");
933 for (dev = dev_base; dev ; dev = dev->next)
934 if (net_alias_is(dev))
935 {
936 alias = dev->my_alias;
937 nat = alias->nat;
938 dlen=sprintf(buffer+len, "%-16s %-6d ", alias->name, alias->dev.family);
939
940
941
942
943
944 if (nat->alias_print_1)
945 dlen += nat->alias_print_1(nat, alias, buffer+len+dlen, NET_ALIASES_RECSIZ - dlen);
946 else
947 dlen += sprintf(buffer+len+dlen, "-");
948
949
950
951
952
953 if (dlen < NET_ALIASES_RECSIZ) memset(buffer+len+dlen, ' ', NET_ALIASES_RECSIZ - dlen);
954
955
956
957
958 len += NET_ALIASES_RECSIZ;
959 buffer[len-1] = '\n';
960
961 pos=begin+len;
962 if(pos<offset)
963 {
964 len=0;
965 begin=pos;
966 }
967 if(pos>offset+length)
968 break;
969 }
970 *start=buffer+(offset-begin);
971 len-=(offset-begin);
972 if(len>length)
973 len=length;
974 return len;
975 }
976
977
978
979
980
981
982 int net_alias_device_event(struct notifier_block *this, unsigned long event, void *ptr)
983 {
984 struct device *dev = ptr;
985
986 if (event == NETDEV_DOWN)
987 {
988 #ifdef ALIAS_USER_LAND_DEBUG
989 printk("net_alias: NETDEV_DOWN for %s received\n", dev->name);
990 #endif
991 if (net_alias_has(dev))
992 net_alias_free(dev);
993 }
994
995 if (event == NETDEV_UP)
996 {
997 #ifdef ALIAS_USER_LAND_DEBUG
998 printk("net_alias: NETDEV_UP for %s received\n", dev->name);
999 #endif
1000 dev->alias_info = 0;
1001 }
1002
1003 return NOTIFY_DONE;
1004 }
1005
1006
1007
1008
1009
1010
1011
1012 static __inline__ struct device *
1013 nat_addr_chk(struct net_alias_type *nat, struct net_alias_info *alias_info, struct sockaddr *sa, int flags_on, int flags_off)
1014 {
1015 struct net_alias *alias;
1016 for(alias = alias_info->hash_tab[nat_hash_key(nat,sa)];
1017 alias; alias = alias->next)
1018 {
1019 if (alias->dev.family != sa->sa_family) continue;
1020
1021
1022
1023
1024
1025 if (alias->dev.flags & flags_on && !(alias->dev.flags & flags_off) &&
1026 nat_dev_addr_chk_1(nat,&alias->dev,sa))
1027 return &alias->dev;
1028 }
1029 return NULL;
1030 }
1031
1032
1033
1034
1035
1036
1037 static __inline__ struct device *
1038 nat_addr_chk32(struct net_alias_type *nat, struct net_alias_info *alias_info, int family, __u32 addr32, int flags_on, int flags_off)
1039 {
1040 struct net_alias *alias;
1041 for (alias=alias_info->hash_tab[HASH(addr32,family)];
1042 alias; alias=alias->next)
1043 {
1044 if (alias->dev.family != family) continue;
1045
1046
1047
1048
1049
1050 if (alias->dev.flags & flags_on && !(alias->dev.flags & flags_off) &&
1051 addr32 == alias->dev.pa_addr)
1052 return &alias->dev;
1053 }
1054 return NULL;
1055 }
1056
1057
1058
1059
1060
1061
1062
1063 struct device *
1064 net_alias_dev_chk(struct device *main_dev, struct sockaddr *sa,int flags_on, int flags_off)
1065 {
1066 struct net_alias_info *alias_info = main_dev->alias_info;
1067 struct net_alias_type *nat;
1068
1069
1070
1071
1072
1073 if (!alias_info) return NULL;
1074
1075
1076
1077
1078
1079 nat = nat_getbytype(sa->sa_family);
1080 if (!nat)
1081 return NULL;
1082
1083 return nat_addr_chk(nat, alias_info, sa, flags_on, flags_off);
1084 }
1085
1086
1087
1088
1089
1090
1091 struct device *
1092 net_alias_dev_chk32(struct device *main_dev, int family, __u32 addr32,
1093 int flags_on, int flags_off)
1094 {
1095 struct net_alias_info *alias_info = main_dev->alias_info;
1096
1097
1098
1099
1100
1101 if (!alias_info) return NULL;
1102
1103 return nat_addr_chk32(NULL, alias_info, family, addr32, flags_on, flags_off);
1104 }
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114 struct device *
1115 net_alias_dev_rcv_sel(struct device *main_dev, struct sockaddr *sa_src, struct sockaddr *sa_dst)
1116 {
1117 int family;
1118 struct net_alias_type *nat;
1119 struct net_alias_info *alias_info;
1120 struct device *dev;
1121
1122 if (main_dev == NULL) return NULL;
1123
1124
1125
1126
1127
1128 if ((alias_info = main_dev->alias_info) == NULL)
1129 return main_dev;
1130
1131
1132
1133
1134
1135 family = (sa_src)? sa_src->sa_family : ((sa_dst)? sa_dst->sa_family : AF_UNSPEC);
1136 if (family == AF_UNSPEC) return main_dev;
1137
1138
1139
1140
1141
1142 if ( (nat = nat_getbytype(family)) == NULL ) return main_dev;
1143
1144
1145
1146
1147
1148 if (sa_dst)
1149 {
1150 if (nat_dev_addr_chk_1(nat, main_dev,sa_dst))
1151 return main_dev;
1152
1153 dev = nat_addr_chk(nat, alias_info, sa_dst, IFF_UP, 0);
1154
1155 if (dev != NULL) return dev;
1156 }
1157
1158
1159
1160
1161
1162 if ( sa_src == NULL || nat->dev_select == NULL) return main_dev;
1163 dev = nat->dev_select(nat, main_dev, sa_src);
1164
1165 if (dev == NULL || dev->family != family) return main_dev;
1166
1167
1168
1169
1170
1171 dev = net_alias_is(dev)?
1172 ( (dev->my_alias->main_dev == main_dev)? dev : NULL) : NULL;
1173
1174
1175
1176
1177
1178 return (dev)? dev : main_dev;
1179
1180 }
1181
1182
1183
1184
1185
1186 struct device *
1187 net_alias_dev_rcv_sel32(struct device *main_dev, int family, __u32 src, __u32 dst)
1188 {
1189 struct net_alias_type *nat;
1190 struct net_alias_info *alias_info;
1191 struct sockaddr_in sin_src;
1192 struct device *dev;
1193
1194 if (main_dev == NULL) return NULL;
1195
1196
1197
1198
1199
1200 if ((alias_info = main_dev->alias_info) == NULL)
1201 return main_dev;
1202
1203
1204
1205
1206
1207 if (dst == main_dev->pa_addr)
1208 return main_dev;
1209
1210 if (family == AF_UNSPEC) return main_dev;
1211
1212
1213
1214
1215
1216 if ( (nat = nat_getbytype(family)) == NULL ) return main_dev;
1217
1218
1219
1220
1221
1222 if (dst)
1223 {
1224 dev = nat_addr_chk32(nat, alias_info, family, dst, IFF_UP, 0);
1225 if (dev) return dev;
1226 }
1227
1228
1229
1230
1231
1232 if ( src == 0 || nat->dev_select == NULL) return main_dev;
1233
1234 sin_src.sin_family = family;
1235 sin_src.sin_addr.s_addr = src;
1236
1237 dev = nat->dev_select(nat, main_dev, (struct sockaddr *)&sin_src);
1238
1239 if (dev == NULL || dev->family != family) return main_dev;
1240
1241
1242
1243
1244
1245 dev = net_alias_is(dev)?
1246 ( (dev->my_alias->main_dev == main_dev)? dev : NULL) : NULL;
1247
1248
1249
1250
1251
1252 return (dev)? dev : main_dev;
1253
1254 }
1255
1256
1257
1258
1259
1260
1261 static struct notifier_block net_alias_dev_notifier = {
1262 net_alias_device_event,
1263 NULL,
1264 0
1265 };
1266
1267
1268
1269
1270
1271
1272
1273 void net_alias_init(void)
1274 {
1275
1276
1277
1278
1279
1280 register_netdevice_notifier(&net_alias_dev_notifier);
1281
1282
1283
1284
1285
1286 #ifndef ALIAS_USER_LAND_DEBUG
1287 proc_net_register(&(struct proc_dir_entry) {
1288 PROC_NET_ALIAS_TYPES, 11, "alias_types",
1289 S_IFREG | S_IRUGO, 1, 0, 0,
1290 0, &proc_net_inode_operations,
1291 net_alias_types_getinfo
1292 });
1293 proc_net_register(&(struct proc_dir_entry) {
1294 PROC_NET_ALIASES, 7, "aliases",
1295 S_IFREG | S_IRUGO, 1, 0, 0,
1296 0, &proc_net_inode_operations,
1297 net_alias_getinfo
1298 });
1299 #endif
1300
1301 }
1302
1303
1304
1305
1306 int register_net_alias_type(struct net_alias_type *nat, int type)
1307 {
1308 unsigned hash;
1309 unsigned long flags;
1310 if (!nat)
1311 {
1312 printk("register_net_alias_type(): NULL arg\n");
1313 return -EINVAL;
1314 }
1315 nat->type = type;
1316 nat->n_attach = 0;
1317 hash = nat->type & 0x0f;
1318 save_flags(flags);
1319 cli();
1320 nat->next = nat_base[hash];
1321 nat_base[hash] = nat;
1322 restore_flags(flags);
1323 return 0;
1324 }
1325
1326
1327
1328
1329 int unregister_net_alias_type(struct net_alias_type *nat)
1330 {
1331 struct net_alias_type **natp;
1332 unsigned hash;
1333 unsigned long flags;
1334
1335 if (!nat)
1336 {
1337 printk("unregister_net_alias_type(): NULL arg\n");
1338 return -EINVAL;
1339 }
1340
1341
1342
1343
1344 if (nat->n_attach)
1345 {
1346 printk("unregister_net_alias_type(): has %d attachments. failed\n",
1347 nat->n_attach);
1348 return -EINVAL;
1349 }
1350 hash = nat->type & 0x0f;
1351 save_flags(flags);
1352 cli();
1353 for (natp = &nat_base[hash]; *natp ; natp = &(*natp)->next)
1354 {
1355 if (nat==(*natp))
1356 {
1357 *natp = nat->next;
1358 restore_flags(flags);
1359 return 0;
1360 }
1361 }
1362 restore_flags(flags);
1363 printk("unregister_net_alias_type(type=%d): not found!\n", nat->type);
1364 return -EINVAL;
1365 }
1366