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#include <linux/config.h>
26
27#include <asm/uaccess.h>
28#include <asm/system.h>
29#include <asm/bitops.h>
30#include <linux/types.h>
31#include <linux/kernel.h>
32#include <linux/sched.h>
33#include <linux/string.h>
34#include <linux/mm.h>
35#include <linux/socket.h>
36#include <linux/sockios.h>
37#include <linux/in.h>
38#include <linux/errno.h>
39#include <linux/interrupt.h>
40#include <linux/if_ether.h>
41#include <linux/inet.h>
42#include <linux/netdevice.h>
43#include <linux/etherdevice.h>
44#include <linux/skbuff.h>
45#include <linux/rtnetlink.h>
46#include <linux/init.h>
47#include <linux/notifier.h>
48#include <linux/inetdevice.h>
49#include <linux/igmp.h>
50#ifdef CONFIG_SYSCTL
51#include <linux/sysctl.h>
52#endif
53#ifdef CONFIG_KMOD
54#include <linux/kmod.h>
55#endif
56
57#include <net/ip.h>
58#include <net/route.h>
59#include <net/ip_fib.h>
60
61struct ipv4_devconf ipv4_devconf = { 1, 1, 1, 1, 0, };
62static struct ipv4_devconf ipv4_devconf_dflt = { 1, 1, 1, 1, 1, };
63
64#ifdef CONFIG_RTNETLINK
65static void rtmsg_ifa(int event, struct in_ifaddr *);
66#else
67#define rtmsg_ifa(a,b) do { } while(0)
68#endif
69
70static struct notifier_block *inetaddr_chain;
71static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, int destroy);
72#ifdef CONFIG_SYSCTL
73static void devinet_sysctl_register(struct in_device *in_dev, struct ipv4_devconf *p);
74static void devinet_sysctl_unregister(struct ipv4_devconf *p);
75#endif
76
77int inet_ifa_count;
78int inet_dev_count;
79
80static struct in_ifaddr * inet_alloc_ifa(void)
81{
82 struct in_ifaddr *ifa;
83
84 ifa = kmalloc(sizeof(*ifa), GFP_KERNEL);
85 if (ifa) {
86 memset(ifa, 0, sizeof(*ifa));
87 inet_ifa_count++;
88 }
89
90 return ifa;
91}
92
93static __inline__ void inet_free_ifa(struct in_ifaddr *ifa)
94{
95 kfree_s(ifa, sizeof(*ifa));
96 inet_ifa_count--;
97}
98
99struct in_device *inetdev_init(struct device *dev)
100{
101 struct in_device *in_dev;
102
103 in_dev = kmalloc(sizeof(*in_dev), GFP_KERNEL);
104 if (!in_dev)
105 return NULL;
106 inet_dev_count++;
107 memset(in_dev, 0, sizeof(*in_dev));
108 memcpy(&in_dev->cnf, &ipv4_devconf_dflt, sizeof(in_dev->cnf));
109 in_dev->cnf.sysctl = NULL;
110 in_dev->dev = dev;
111 if ((in_dev->arp_parms = neigh_parms_alloc(dev, &arp_tbl)) == NULL) {
112 kfree(in_dev);
113 return NULL;
114 }
115#ifdef CONFIG_SYSCTL
116 neigh_sysctl_register(dev, in_dev->arp_parms, NET_IPV4, NET_IPV4_NEIGH, "ipv4");
117#endif
118 dev->ip_ptr = in_dev;
119#ifdef CONFIG_SYSCTL
120 devinet_sysctl_register(in_dev, &in_dev->cnf);
121#endif
122 if (dev->flags&IFF_UP)
123 ip_mc_up(in_dev);
124 return in_dev;
125}
126
127static void inetdev_destroy(struct in_device *in_dev)
128{
129 struct in_ifaddr *ifa;
130
131 ip_mc_destroy_dev(in_dev);
132
133 while ((ifa = in_dev->ifa_list) != NULL) {
134 inet_del_ifa(in_dev, &in_dev->ifa_list, 0);
135 inet_free_ifa(ifa);
136 }
137
138#ifdef CONFIG_SYSCTL
139 devinet_sysctl_unregister(&in_dev->cnf);
140#endif
141 in_dev->dev->ip_ptr = NULL;
142 synchronize_bh();
143 neigh_parms_release(&arp_tbl, in_dev->arp_parms);
144 kfree(in_dev);
145}
146
147struct in_ifaddr * inet_addr_onlink(struct in_device *in_dev, u32 a, u32 b)
148{
149 for_primary_ifa(in_dev) {
150 if (inet_ifa_match(a, ifa)) {
151 if (!b || inet_ifa_match(b, ifa))
152 return ifa;
153 }
154 } endfor_ifa(in_dev);
155 return NULL;
156}
157
158static void
159inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, int destroy)
160{
161 struct in_ifaddr *ifa1 = *ifap;
162
163
164
165 if (!(ifa1->ifa_flags&IFA_F_SECONDARY)) {
166 struct in_ifaddr *ifa;
167 struct in_ifaddr **ifap1 = &ifa1->ifa_next;
168
169 while ((ifa=*ifap1) != NULL) {
170 if (!(ifa->ifa_flags&IFA_F_SECONDARY) ||
171 ifa1->ifa_mask != ifa->ifa_mask ||
172 !inet_ifa_match(ifa1->ifa_address, ifa)) {
173 ifap1 = &ifa->ifa_next;
174 continue;
175 }
176 *ifap1 = ifa->ifa_next;
177 synchronize_bh();
178
179 rtmsg_ifa(RTM_DELADDR, ifa);
180 notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa);
181 inet_free_ifa(ifa);
182 }
183 }
184
185
186
187 *ifap = ifa1->ifa_next;
188 synchronize_bh();
189
190
191
192
193
194
195
196
197
198
199
200 rtmsg_ifa(RTM_DELADDR, ifa1);
201 notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa1);
202 if (destroy) {
203 inet_free_ifa(ifa1);
204 if (in_dev->ifa_list == NULL)
205 inetdev_destroy(in_dev);
206 }
207}
208
209static int
210inet_insert_ifa(struct in_device *in_dev, struct in_ifaddr *ifa)
211{
212 struct in_ifaddr *ifa1, **ifap, **last_primary;
213
214 if (ifa->ifa_local == 0) {
215 inet_free_ifa(ifa);
216 return 0;
217 }
218
219 ifa->ifa_flags &= ~IFA_F_SECONDARY;
220 last_primary = &in_dev->ifa_list;
221
222 for (ifap=&in_dev->ifa_list; (ifa1=*ifap)!=NULL; ifap=&ifa1->ifa_next) {
223 if (!(ifa1->ifa_flags&IFA_F_SECONDARY) && ifa->ifa_scope <= ifa1->ifa_scope)
224 last_primary = &ifa1->ifa_next;
225 if (ifa1->ifa_mask == ifa->ifa_mask && inet_ifa_match(ifa1->ifa_address, ifa)) {
226 if (ifa1->ifa_local == ifa->ifa_local) {
227 inet_free_ifa(ifa);
228 return -EEXIST;
229 }
230 if (ifa1->ifa_scope != ifa->ifa_scope) {
231 inet_free_ifa(ifa);
232 return -EINVAL;
233 }
234 ifa->ifa_flags |= IFA_F_SECONDARY;
235 }
236 }
237
238 if (!(ifa->ifa_flags&IFA_F_SECONDARY)) {
239 net_srandom(ifa->ifa_local);
240 ifap = last_primary;
241 }
242
243 ifa->ifa_next = *ifap;
244 wmb();
245 *ifap = ifa;
246
247
248
249
250 rtmsg_ifa(RTM_NEWADDR, ifa);
251 notifier_call_chain(&inetaddr_chain, NETDEV_UP, ifa);
252
253 return 0;
254}
255
256static int
257inet_set_ifa(struct device *dev, struct in_ifaddr *ifa)
258{
259 struct in_device *in_dev = dev->ip_ptr;
260
261 if (in_dev == NULL) {
262 in_dev = inetdev_init(dev);
263 if (in_dev == NULL) {
264 inet_free_ifa(ifa);
265 return -ENOBUFS;
266 }
267 }
268 ifa->ifa_dev = in_dev;
269 if (LOOPBACK(ifa->ifa_local))
270 ifa->ifa_scope = RT_SCOPE_HOST;
271 return inet_insert_ifa(in_dev, ifa);
272}
273
274struct in_device *inetdev_by_index(int ifindex)
275{
276 struct device *dev;
277 dev = dev_get_by_index(ifindex);
278 if (dev)
279 return dev->ip_ptr;
280 return NULL;
281}
282
283struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, u32 prefix, u32 mask)
284{
285 for_primary_ifa(in_dev) {
286 if (ifa->ifa_mask == mask && inet_ifa_match(prefix, ifa))
287 return ifa;
288 } endfor_ifa(in_dev);
289 return NULL;
290}
291
292#ifdef CONFIG_RTNETLINK
293
294
295
296
297
298int
299inet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
300{
301 struct rtattr **rta = arg;
302 struct in_device *in_dev;
303 struct ifaddrmsg *ifm = NLMSG_DATA(nlh);
304 struct in_ifaddr *ifa, **ifap;
305
306 if ((in_dev = inetdev_by_index(ifm->ifa_index)) == NULL)
307 return -EADDRNOTAVAIL;
308
309 for (ifap=&in_dev->ifa_list; (ifa=*ifap)!=NULL; ifap=&ifa->ifa_next) {
310 if ((rta[IFA_LOCAL-1] && memcmp(RTA_DATA(rta[IFA_LOCAL-1]), &ifa->ifa_local, 4)) ||
311 (rta[IFA_LABEL-1] && strcmp(RTA_DATA(rta[IFA_LABEL-1]), ifa->ifa_label)) ||
312 (rta[IFA_ADDRESS-1] &&
313 (ifm->ifa_prefixlen != ifa->ifa_prefixlen ||
314 !inet_ifa_match(*(u32*)RTA_DATA(rta[IFA_ADDRESS-1]), ifa))))
315 continue;
316 inet_del_ifa(in_dev, ifap, 1);
317 return 0;
318 }
319
320 return -EADDRNOTAVAIL;
321}
322
323int
324inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
325{
326 struct rtattr **rta = arg;
327 struct device *dev;
328 struct in_device *in_dev;
329 struct ifaddrmsg *ifm = NLMSG_DATA(nlh);
330 struct in_ifaddr *ifa;
331
332 if (ifm->ifa_prefixlen > 32 || rta[IFA_LOCAL-1] == NULL)
333 return -EINVAL;
334
335 if ((dev = dev_get_by_index(ifm->ifa_index)) == NULL)
336 return -ENODEV;
337
338 if ((in_dev = dev->ip_ptr) == NULL) {
339 in_dev = inetdev_init(dev);
340 if (!in_dev)
341 return -ENOBUFS;
342 }
343
344 if ((ifa = inet_alloc_ifa()) == NULL)
345 return -ENOBUFS;
346
347 if (rta[IFA_ADDRESS-1] == NULL)
348 rta[IFA_ADDRESS-1] = rta[IFA_LOCAL-1];
349 memcpy(&ifa->ifa_local, RTA_DATA(rta[IFA_LOCAL-1]), 4);
350 memcpy(&ifa->ifa_address, RTA_DATA(rta[IFA_ADDRESS-1]), 4);
351 ifa->ifa_prefixlen = ifm->ifa_prefixlen;
352 ifa->ifa_mask = inet_make_mask(ifm->ifa_prefixlen);
353 if (rta[IFA_BROADCAST-1])
354 memcpy(&ifa->ifa_broadcast, RTA_DATA(rta[IFA_BROADCAST-1]), 4);
355 if (rta[IFA_ANYCAST-1])
356 memcpy(&ifa->ifa_anycast, RTA_DATA(rta[IFA_ANYCAST-1]), 4);
357 ifa->ifa_flags = ifm->ifa_flags;
358 ifa->ifa_scope = ifm->ifa_scope;
359 ifa->ifa_dev = in_dev;
360 if (rta[IFA_LABEL-1])
361 memcpy(ifa->ifa_label, RTA_DATA(rta[IFA_LABEL-1]), IFNAMSIZ);
362 else
363 memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
364
365 return inet_insert_ifa(in_dev, ifa);
366}
367
368#endif
369
370
371
372
373
374static __inline__ int inet_abc_len(u32 addr)
375{
376 if (ZERONET(addr))
377 return 0;
378
379 addr = ntohl(addr);
380 if (IN_CLASSA(addr))
381 return 8;
382 if (IN_CLASSB(addr))
383 return 16;
384 if (IN_CLASSC(addr))
385 return 24;
386
387
388
389
390
391 return -1;
392}
393
394
395int devinet_ioctl(unsigned int cmd, void *arg)
396{
397 struct ifreq ifr;
398 struct sockaddr_in *sin = (struct sockaddr_in *)&ifr.ifr_addr;
399 struct in_device *in_dev;
400 struct in_ifaddr **ifap = NULL;
401 struct in_ifaddr *ifa = NULL;
402 struct device *dev;
403#ifdef CONFIG_IP_ALIAS
404 char *colon;
405#endif
406 int exclusive = 0;
407 int ret = 0;
408
409
410
411
412
413 if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))
414 return -EFAULT;
415 ifr.ifr_name[IFNAMSIZ-1] = 0;
416
417#ifdef CONFIG_IP_ALIAS
418 colon = strchr(ifr.ifr_name, ':');
419 if (colon)
420 *colon = 0;
421#endif
422
423#ifdef CONFIG_KMOD
424 dev_load(ifr.ifr_name);
425#endif
426
427 switch(cmd) {
428 case SIOCGIFADDR:
429 case SIOCGIFBRDADDR:
430 case SIOCGIFDSTADDR:
431 case SIOCGIFNETMASK:
432
433
434
435
436 memset(sin, 0, sizeof(*sin));
437 sin->sin_family = AF_INET;
438 break;
439
440 case SIOCSIFFLAGS:
441 if (!capable(CAP_NET_ADMIN))
442 return -EACCES;
443 rtnl_lock();
444 exclusive = 1;
445 break;
446 case SIOCSIFADDR:
447 case SIOCSIFBRDADDR:
448 case SIOCSIFDSTADDR:
449 case SIOCSIFNETMASK:
450 if (!capable(CAP_NET_ADMIN))
451 return -EACCES;
452 if (sin->sin_family != AF_INET)
453 return -EINVAL;
454 rtnl_lock();
455 exclusive = 1;
456 break;
457 default:
458 return -EINVAL;
459 }
460
461
462 if ((dev = dev_get(ifr.ifr_name)) == NULL) {
463 ret = -ENODEV;
464 goto done;
465 }
466
467#ifdef CONFIG_IP_ALIAS
468 if (colon)
469 *colon = ':';
470#endif
471
472 if ((in_dev=dev->ip_ptr) != NULL) {
473 for (ifap=&in_dev->ifa_list; (ifa=*ifap) != NULL; ifap=&ifa->ifa_next)
474 if (strcmp(ifr.ifr_name, ifa->ifa_label) == 0)
475 break;
476 }
477
478 if (ifa == NULL && cmd != SIOCSIFADDR && cmd != SIOCSIFFLAGS) {
479 ret = -EADDRNOTAVAIL;
480 goto done;
481 }
482
483 switch(cmd) {
484 case SIOCGIFADDR:
485 sin->sin_addr.s_addr = ifa->ifa_local;
486 goto rarok;
487
488 case SIOCGIFBRDADDR:
489 sin->sin_addr.s_addr = ifa->ifa_broadcast;
490 goto rarok;
491
492 case SIOCGIFDSTADDR:
493 sin->sin_addr.s_addr = ifa->ifa_address;
494 goto rarok;
495
496 case SIOCGIFNETMASK:
497 sin->sin_addr.s_addr = ifa->ifa_mask;
498 goto rarok;
499
500 case SIOCSIFFLAGS:
501#ifdef CONFIG_IP_ALIAS
502 if (colon) {
503 if (ifa == NULL) {
504 ret = -EADDRNOTAVAIL;
505 break;
506 }
507 if (!(ifr.ifr_flags&IFF_UP))
508 inet_del_ifa(in_dev, ifap, 1);
509 break;
510 }
511#endif
512 ret = dev_change_flags(dev, ifr.ifr_flags);
513 break;
514
515 case SIOCSIFADDR:
516 if (inet_abc_len(sin->sin_addr.s_addr) < 0) {
517 ret = -EINVAL;
518 break;
519 }
520
521 if (!ifa) {
522 if ((ifa = inet_alloc_ifa()) == NULL) {
523 ret = -ENOBUFS;
524 break;
525 }
526#ifdef CONFIG_IP_ALIAS
527 if (colon)
528 memcpy(ifa->ifa_label, ifr.ifr_name, IFNAMSIZ);
529 else
530#endif
531 memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
532 } else {
533 ret = 0;
534 if (ifa->ifa_local == sin->sin_addr.s_addr)
535 break;
536 inet_del_ifa(in_dev, ifap, 0);
537 ifa->ifa_broadcast = 0;
538 ifa->ifa_anycast = 0;
539 }
540
541 ifa->ifa_address =
542 ifa->ifa_local = sin->sin_addr.s_addr;
543
544 if (!(dev->flags&IFF_POINTOPOINT)) {
545 ifa->ifa_prefixlen = inet_abc_len(ifa->ifa_address);
546 ifa->ifa_mask = inet_make_mask(ifa->ifa_prefixlen);
547 if ((dev->flags&IFF_BROADCAST) && ifa->ifa_prefixlen < 31)
548 ifa->ifa_broadcast = ifa->ifa_address|~ifa->ifa_mask;
549 } else {
550 ifa->ifa_prefixlen = 32;
551 ifa->ifa_mask = inet_make_mask(32);
552 }
553 ret = inet_set_ifa(dev, ifa);
554 break;
555
556 case SIOCSIFBRDADDR:
557 if (ifa->ifa_broadcast != sin->sin_addr.s_addr) {
558 inet_del_ifa(in_dev, ifap, 0);
559 ifa->ifa_broadcast = sin->sin_addr.s_addr;
560 inet_insert_ifa(in_dev, ifa);
561 }
562 break;
563
564 case SIOCSIFDSTADDR:
565 if (ifa->ifa_address != sin->sin_addr.s_addr) {
566 if (inet_abc_len(sin->sin_addr.s_addr) < 0) {
567 ret = -EINVAL;
568 break;
569 }
570 inet_del_ifa(in_dev, ifap, 0);
571 ifa->ifa_address = sin->sin_addr.s_addr;
572 inet_insert_ifa(in_dev, ifa);
573 }
574 break;
575
576 case SIOCSIFNETMASK:
577
578
579
580
581 if (bad_mask(sin->sin_addr.s_addr, 0)) {
582 ret = -EINVAL;
583 break;
584 }
585
586 if (ifa->ifa_mask != sin->sin_addr.s_addr) {
587 inet_del_ifa(in_dev, ifap, 0);
588 ifa->ifa_mask = sin->sin_addr.s_addr;
589 ifa->ifa_prefixlen = inet_mask_len(ifa->ifa_mask);
590 inet_set_ifa(dev, ifa);
591 }
592 break;
593 }
594done:
595 if (exclusive)
596 rtnl_unlock();
597 return ret;
598
599rarok:
600 if (copy_to_user(arg, &ifr, sizeof(struct ifreq)))
601 return -EFAULT;
602 return 0;
603}
604
605static int
606inet_gifconf(struct device *dev, char *buf, int len)
607{
608 struct in_device *in_dev = dev->ip_ptr;
609 struct in_ifaddr *ifa;
610 struct ifreq ifr;
611 int done=0;
612
613 if (in_dev==NULL || (ifa=in_dev->ifa_list)==NULL)
614 return 0;
615
616 for ( ; ifa; ifa = ifa->ifa_next) {
617 if (!buf) {
618 done += sizeof(ifr);
619 continue;
620 }
621 if (len < (int) sizeof(ifr))
622 return done;
623 memset(&ifr, 0, sizeof(struct ifreq));
624 if (ifa->ifa_label)
625 strcpy(ifr.ifr_name, ifa->ifa_label);
626 else
627 strcpy(ifr.ifr_name, dev->name);
628
629 (*(struct sockaddr_in *) &ifr.ifr_addr).sin_family = AF_INET;
630 (*(struct sockaddr_in *) &ifr.ifr_addr).sin_addr.s_addr = ifa->ifa_local;
631
632 if (copy_to_user(buf, &ifr, sizeof(struct ifreq)))
633 return -EFAULT;
634 buf += sizeof(struct ifreq);
635 len -= sizeof(struct ifreq);
636 done += sizeof(struct ifreq);
637 }
638 return done;
639}
640
641u32 inet_select_addr(struct device *dev, u32 dst, int scope)
642{
643 u32 addr = 0;
644 struct in_device *in_dev = dev->ip_ptr;
645
646 if (in_dev == NULL)
647 return 0;
648
649 for_primary_ifa(in_dev) {
650 if (ifa->ifa_scope > scope)
651 continue;
652 addr = ifa->ifa_local;
653 if (!dst || inet_ifa_match(dst, ifa))
654 return addr;
655 } endfor_ifa(in_dev);
656
657 if (addr || scope >= RT_SCOPE_LINK)
658 return addr;
659
660
661
662
663
664 for (dev=dev_base; dev; dev=dev->next) {
665 if ((in_dev=dev->ip_ptr) == NULL)
666 continue;
667
668 for_primary_ifa(in_dev) {
669 if (ifa->ifa_scope <= scope)
670 return ifa->ifa_local;
671 } endfor_ifa(in_dev);
672 }
673
674 return 0;
675}
676
677
678
679
680
681int register_inetaddr_notifier(struct notifier_block *nb)
682{
683 return notifier_chain_register(&inetaddr_chain, nb);
684}
685
686int unregister_inetaddr_notifier(struct notifier_block *nb)
687{
688 return notifier_chain_unregister(&inetaddr_chain,nb);
689}
690
691static int inetdev_event(struct notifier_block *this, unsigned long event, void *ptr)
692{
693 struct device *dev = ptr;
694 struct in_device *in_dev = dev->ip_ptr;
695
696 if (in_dev == NULL)
697 return NOTIFY_DONE;
698
699 switch (event) {
700 case NETDEV_REGISTER:
701 if (in_dev)
702 printk(KERN_DEBUG "inetdev_event: bug\n");
703 dev->ip_ptr = NULL;
704 break;
705 case NETDEV_UP:
706 if (dev == &loopback_dev) {
707 struct in_ifaddr *ifa;
708 if ((ifa = inet_alloc_ifa()) != NULL) {
709 ifa->ifa_local =
710 ifa->ifa_address = htonl(INADDR_LOOPBACK);
711 ifa->ifa_prefixlen = 8;
712 ifa->ifa_mask = inet_make_mask(8);
713 ifa->ifa_dev = in_dev;
714 ifa->ifa_scope = RT_SCOPE_HOST;
715 inet_insert_ifa(in_dev, ifa);
716 }
717 }
718 ip_mc_up(in_dev);
719 break;
720 case NETDEV_DOWN:
721 ip_mc_down(in_dev);
722 break;
723 case NETDEV_UNREGISTER:
724 inetdev_destroy(in_dev);
725 break;
726 case NETDEV_CHANGENAME:
727 if (in_dev->ifa_list) {
728 struct in_ifaddr *ifa;
729 for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next)
730 memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
731
732
733
734 }
735 break;
736 }
737
738 return NOTIFY_DONE;
739}
740
741struct notifier_block ip_netdev_notifier={
742 inetdev_event,
743 NULL,
744 0
745};
746
747#ifdef CONFIG_RTNETLINK
748
749static int inet_fill_ifaddr(struct sk_buff *skb, struct in_ifaddr *ifa,
750 u32 pid, u32 seq, int event)
751{
752 struct ifaddrmsg *ifm;
753 struct nlmsghdr *nlh;
754 unsigned char *b = skb->tail;
755
756 nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*ifm));
757 ifm = NLMSG_DATA(nlh);
758 ifm->ifa_family = AF_INET;
759 ifm->ifa_prefixlen = ifa->ifa_prefixlen;
760 ifm->ifa_flags = ifa->ifa_flags|IFA_F_PERMANENT;
761 ifm->ifa_scope = ifa->ifa_scope;
762 ifm->ifa_index = ifa->ifa_dev->dev->ifindex;
763 if (ifa->ifa_address)
764 RTA_PUT(skb, IFA_ADDRESS, 4, &ifa->ifa_address);
765 if (ifa->ifa_local)
766 RTA_PUT(skb, IFA_LOCAL, 4, &ifa->ifa_local);
767 if (ifa->ifa_broadcast)
768 RTA_PUT(skb, IFA_BROADCAST, 4, &ifa->ifa_broadcast);
769 if (ifa->ifa_anycast)
770 RTA_PUT(skb, IFA_ANYCAST, 4, &ifa->ifa_anycast);
771 if (ifa->ifa_label[0])
772 RTA_PUT(skb, IFA_LABEL, IFNAMSIZ, &ifa->ifa_label);
773 nlh->nlmsg_len = skb->tail - b;
774 return skb->len;
775
776nlmsg_failure:
777rtattr_failure:
778 skb_trim(skb, b - skb->data);
779 return -1;
780}
781
782static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
783{
784 int idx, ip_idx;
785 int s_idx, s_ip_idx;
786 struct device *dev;
787 struct in_device *in_dev;
788 struct in_ifaddr *ifa;
789
790 s_idx = cb->args[0];
791 s_ip_idx = ip_idx = cb->args[1];
792 for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) {
793 if (idx < s_idx)
794 continue;
795 if (idx > s_idx)
796 s_ip_idx = 0;
797 if ((in_dev = dev->ip_ptr) == NULL)
798 continue;
799 for (ifa = in_dev->ifa_list, ip_idx = 0; ifa;
800 ifa = ifa->ifa_next, ip_idx++) {
801 if (ip_idx < s_ip_idx)
802 continue;
803 if (inet_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid,
804 cb->nlh->nlmsg_seq, RTM_NEWADDR) <= 0)
805 goto done;
806 }
807 }
808done:
809 cb->args[0] = idx;
810 cb->args[1] = ip_idx;
811
812 return skb->len;
813}
814
815static void rtmsg_ifa(int event, struct in_ifaddr * ifa)
816{
817 struct sk_buff *skb;
818 int size = NLMSG_SPACE(sizeof(struct ifaddrmsg)+128);
819
820 skb = alloc_skb(size, GFP_KERNEL);
821 if (!skb) {
822 netlink_set_err(rtnl, 0, RTMGRP_IPV4_IFADDR, ENOBUFS);
823 return;
824 }
825 if (inet_fill_ifaddr(skb, ifa, 0, 0, event) < 0) {
826 kfree_skb(skb);
827 netlink_set_err(rtnl, 0, RTMGRP_IPV4_IFADDR, EINVAL);
828 return;
829 }
830 NETLINK_CB(skb).dst_groups = RTMGRP_IPV4_IFADDR;
831 netlink_broadcast(rtnl, skb, 0, RTMGRP_IPV4_IFADDR, GFP_KERNEL);
832}
833
834
835static struct rtnetlink_link inet_rtnetlink_table[RTM_MAX-RTM_BASE+1] =
836{
837 { NULL, NULL, },
838 { NULL, NULL, },
839 { NULL, NULL, },
840 { NULL, NULL, },
841
842 { inet_rtm_newaddr, NULL, },
843 { inet_rtm_deladdr, NULL, },
844 { NULL, inet_dump_ifaddr, },
845 { NULL, NULL, },
846
847 { inet_rtm_newroute, NULL, },
848 { inet_rtm_delroute, NULL, },
849 { inet_rtm_getroute, inet_dump_fib, },
850 { NULL, NULL, },
851
852 { NULL, NULL, },
853 { NULL, NULL, },
854 { NULL, NULL, },
855 { NULL, NULL, },
856
857#ifdef CONFIG_IP_MULTIPLE_TABLES
858 { inet_rtm_newrule, NULL, },
859 { inet_rtm_delrule, NULL, },
860 { NULL, inet_dump_rules, },
861 { NULL, NULL, },
862#else
863 { NULL, NULL, },
864 { NULL, NULL, },
865 { NULL, NULL, },
866 { NULL, NULL, },
867#endif
868};
869
870#endif
871
872
873#ifdef CONFIG_SYSCTL
874
875void inet_forward_change()
876{
877 struct device *dev;
878 int on = ipv4_devconf.forwarding;
879
880 ipv4_devconf.accept_redirects = !on;
881 ipv4_devconf_dflt.forwarding = on;
882
883 for (dev = dev_base; dev; dev = dev->next) {
884 struct in_device *in_dev = dev->ip_ptr;
885 if (in_dev)
886 in_dev->cnf.forwarding = on;
887 }
888
889 rt_cache_flush(0);
890
891 ip_statistics.IpForwarding = on ? 1 : 2;
892}
893
894static
895int devinet_sysctl_forward(ctl_table *ctl, int write, struct file * filp,
896 void *buffer, size_t *lenp)
897{
898 int *valp = ctl->data;
899 int val = *valp;
900 int ret;
901
902 ret = proc_dointvec(ctl, write, filp, buffer, lenp);
903
904 if (write && *valp != val) {
905 if (valp == &ipv4_devconf.forwarding)
906 inet_forward_change();
907 else if (valp != &ipv4_devconf_dflt.forwarding)
908 rt_cache_flush(0);
909 }
910
911 return ret;
912}
913
914static struct devinet_sysctl_table
915{
916 struct ctl_table_header *sysctl_header;
917 ctl_table devinet_vars[12];
918 ctl_table devinet_dev[2];
919 ctl_table devinet_conf_dir[2];
920 ctl_table devinet_proto_dir[2];
921 ctl_table devinet_root_dir[2];
922} devinet_sysctl = {
923 NULL,
924 {{NET_IPV4_CONF_FORWARDING, "forwarding",
925 &ipv4_devconf.forwarding, sizeof(int), 0644, NULL,
926 &devinet_sysctl_forward},
927 {NET_IPV4_CONF_MC_FORWARDING, "mc_forwarding",
928 &ipv4_devconf.mc_forwarding, sizeof(int), 0444, NULL,
929 &proc_dointvec},
930 {NET_IPV4_CONF_ACCEPT_REDIRECTS, "accept_redirects",
931 &ipv4_devconf.accept_redirects, sizeof(int), 0644, NULL,
932 &proc_dointvec},
933 {NET_IPV4_CONF_SECURE_REDIRECTS, "secure_redirects",
934 &ipv4_devconf.secure_redirects, sizeof(int), 0644, NULL,
935 &proc_dointvec},
936 {NET_IPV4_CONF_SHARED_MEDIA, "shared_media",
937 &ipv4_devconf.shared_media, sizeof(int), 0644, NULL,
938 &proc_dointvec},
939 {NET_IPV4_CONF_RP_FILTER, "rp_filter",
940 &ipv4_devconf.rp_filter, sizeof(int), 0644, NULL,
941 &proc_dointvec},
942 {NET_IPV4_CONF_SEND_REDIRECTS, "send_redirects",
943 &ipv4_devconf.send_redirects, sizeof(int), 0644, NULL,
944 &proc_dointvec},
945 {NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE, "accept_source_route",
946 &ipv4_devconf.accept_source_route, sizeof(int), 0644, NULL,
947 &proc_dointvec},
948 {NET_IPV4_CONF_PROXY_ARP, "proxy_arp",
949 &ipv4_devconf.proxy_arp, sizeof(int), 0644, NULL,
950 &proc_dointvec},
951 {NET_IPV4_CONF_BOOTP_RELAY, "bootp_relay",
952 &ipv4_devconf.bootp_relay, sizeof(int), 0644, NULL,
953 &proc_dointvec},
954 {NET_IPV4_CONF_LOG_MARTIANS, "log_martians",
955 &ipv4_devconf.log_martians, sizeof(int), 0644, NULL,
956 &proc_dointvec},
957 {0}},
958
959 {{NET_PROTO_CONF_ALL, "all", NULL, 0, 0555, devinet_sysctl.devinet_vars},{0}},
960 {{NET_IPV4_CONF, "conf", NULL, 0, 0555, devinet_sysctl.devinet_dev},{0}},
961 {{NET_IPV4, "ipv4", NULL, 0, 0555, devinet_sysctl.devinet_conf_dir},{0}},
962 {{CTL_NET, "net", NULL, 0, 0555, devinet_sysctl.devinet_proto_dir},{0}}
963};
964
965static void devinet_sysctl_register(struct in_device *in_dev, struct ipv4_devconf *p)
966{
967 int i;
968 struct device *dev = in_dev ? in_dev->dev : NULL;
969 struct devinet_sysctl_table *t;
970
971 t = kmalloc(sizeof(*t), GFP_KERNEL);
972 if (t == NULL)
973 return;
974 memcpy(t, &devinet_sysctl, sizeof(*t));
975 for (i=0; i<sizeof(t->devinet_vars)/sizeof(t->devinet_vars[0])-1; i++) {
976 t->devinet_vars[i].data += (char*)p - (char*)&ipv4_devconf;
977 t->devinet_vars[i].de = NULL;
978 }
979 if (dev) {
980 t->devinet_dev[0].procname = dev->name;
981 t->devinet_dev[0].ctl_name = dev->ifindex;
982 } else {
983 t->devinet_dev[0].procname = "default";
984 t->devinet_dev[0].ctl_name = NET_PROTO_CONF_DEFAULT;
985 }
986 t->devinet_dev[0].child = t->devinet_vars;
987 t->devinet_dev[0].de = NULL;
988 t->devinet_conf_dir[0].child = t->devinet_dev;
989 t->devinet_conf_dir[0].de = NULL;
990 t->devinet_proto_dir[0].child = t->devinet_conf_dir;
991 t->devinet_proto_dir[0].de = NULL;
992 t->devinet_root_dir[0].child = t->devinet_proto_dir;
993 t->devinet_root_dir[0].de = NULL;
994
995 t->sysctl_header = register_sysctl_table(t->devinet_root_dir, 0);
996 if (t->sysctl_header == NULL)
997 kfree(t);
998 else
999 p->sysctl = t;
1000}
1001
1002static void devinet_sysctl_unregister(struct ipv4_devconf *p)
1003{
1004 if (p->sysctl) {
1005 struct devinet_sysctl_table *t = p->sysctl;
1006 p->sysctl = NULL;
1007 unregister_sysctl_table(t->sysctl_header);
1008 kfree(t);
1009 }
1010}
1011#endif
1012
1013__initfunc(void devinet_init(void))
1014{
1015 register_gifconf(PF_INET, inet_gifconf);
1016 register_netdevice_notifier(&ip_netdev_notifier);
1017#ifdef CONFIG_RTNETLINK
1018 rtnetlink_links[PF_INET] = inet_rtnetlink_table;
1019#endif
1020#ifdef CONFIG_SYSCTL
1021 devinet_sysctl.sysctl_header =
1022 register_sysctl_table(devinet_sysctl.devinet_root_dir, 0);
1023 devinet_sysctl_register(NULL, &ipv4_devconf_dflt);
1024#endif
1025}
1026