Import 2.3.5
[davej-history.git] / net / ipv4 / devinet.c
blob1f540628da0bf0491ae19c97fb7667ccfde407f1
1 /*
2 * NET3 IP device support routines.
4 * Version: $Id: devinet.c,v 1.30 1999/06/01 07:49:59 davem Exp $
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
11 * Derived from the IP parts of dev.c 1.0.19
12 * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
13 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
14 * Mark Evans, <evansmp@uhura.aston.ac.uk>
16 * Additional Authors:
17 * Alan Cox, <gw4pts@gw4pts.ampr.org>
18 * Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
20 * Changes:
21 * Alexey Kuznetsov: pa_* fields are replaced with ifaddr lists.
22 * Cyrus Durgin: updated for kmod
25 #include <linux/config.h>
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
57 #include <net/ip.h>
58 #include <net/route.h>
59 #include <net/ip_fib.h>
61 struct ipv4_devconf ipv4_devconf = { 1, 1, 1, 1, 0, };
62 static struct ipv4_devconf ipv4_devconf_dflt = { 1, 1, 1, 1, 1, };
64 #ifdef CONFIG_RTNETLINK
65 static void rtmsg_ifa(int event, struct in_ifaddr *);
66 #else
67 #define rtmsg_ifa(a,b) do { } while(0)
68 #endif
70 static struct notifier_block *inetaddr_chain;
71 static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, int destroy);
72 #ifdef CONFIG_SYSCTL
73 static void devinet_sysctl_register(struct in_device *in_dev, struct ipv4_devconf *p);
74 static void devinet_sysctl_unregister(struct ipv4_devconf *p);
75 #endif
77 int inet_ifa_count;
78 int inet_dev_count;
80 static struct in_ifaddr * inet_alloc_ifa(void)
82 struct in_ifaddr *ifa;
84 ifa = kmalloc(sizeof(*ifa), GFP_KERNEL);
85 if (ifa) {
86 memset(ifa, 0, sizeof(*ifa));
87 inet_ifa_count++;
90 return ifa;
93 static __inline__ void inet_free_ifa(struct in_ifaddr *ifa)
95 kfree_s(ifa, sizeof(*ifa));
96 inet_ifa_count--;
99 struct in_device *inetdev_init(struct device *dev)
101 struct in_device *in_dev;
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;
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;
127 static void inetdev_destroy(struct in_device *in_dev)
129 struct in_ifaddr *ifa;
131 ip_mc_destroy_dev(in_dev);
133 while ((ifa = in_dev->ifa_list) != NULL) {
134 inet_del_ifa(in_dev, &in_dev->ifa_list, 0);
135 inet_free_ifa(ifa);
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);
147 struct in_ifaddr * inet_addr_onlink(struct in_device *in_dev, u32 a, u32 b)
149 for_primary_ifa(in_dev) {
150 if (inet_ifa_match(a, ifa)) {
151 if (!b || inet_ifa_match(b, ifa))
152 return ifa;
154 } endfor_ifa(in_dev);
155 return NULL;
158 static void
159 inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, int destroy)
161 struct in_ifaddr *ifa1 = *ifap;
163 /* 1. Deleting primary ifaddr forces deletion all secondaries */
165 if (!(ifa1->ifa_flags&IFA_F_SECONDARY)) {
166 struct in_ifaddr *ifa;
167 struct in_ifaddr **ifap1 = &ifa1->ifa_next;
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;
176 *ifap1 = ifa->ifa_next;
177 synchronize_bh();
179 rtmsg_ifa(RTM_DELADDR, ifa);
180 notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa);
181 inet_free_ifa(ifa);
185 /* 2. Unlink it */
187 *ifap = ifa1->ifa_next;
188 synchronize_bh();
190 /* 3. Announce address deletion */
192 /* Send message first, then call notifier.
193 At first sight, FIB update triggered by notifier
194 will refer to already deleted ifaddr, that could confuse
195 netlink listeners. It is not true: look, gated sees
196 that route deleted and if it still thinks that ifaddr
197 is valid, it will try to restore deleted routes... Grr.
198 So that, this order is correct.
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);
209 static int
210 inet_insert_ifa(struct in_device *in_dev, struct in_ifaddr *ifa)
212 struct in_ifaddr *ifa1, **ifap, **last_primary;
214 if (ifa->ifa_local == 0) {
215 inet_free_ifa(ifa);
216 return 0;
219 ifa->ifa_flags &= ~IFA_F_SECONDARY;
220 last_primary = &in_dev->ifa_list;
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;
230 if (ifa1->ifa_scope != ifa->ifa_scope) {
231 inet_free_ifa(ifa);
232 return -EINVAL;
234 ifa->ifa_flags |= IFA_F_SECONDARY;
238 if (!(ifa->ifa_flags&IFA_F_SECONDARY)) {
239 net_srandom(ifa->ifa_local);
240 ifap = last_primary;
243 ifa->ifa_next = *ifap;
244 wmb();
245 *ifap = ifa;
247 /* Send message first, then call notifier.
248 Notifier will trigger FIB update, so that
249 listeners of netlink will know about new ifaddr */
250 rtmsg_ifa(RTM_NEWADDR, ifa);
251 notifier_call_chain(&inetaddr_chain, NETDEV_UP, ifa);
253 return 0;
256 static int
257 inet_set_ifa(struct device *dev, struct in_ifaddr *ifa)
259 struct in_device *in_dev = dev->ip_ptr;
261 if (in_dev == NULL) {
262 in_dev = inetdev_init(dev);
263 if (in_dev == NULL) {
264 inet_free_ifa(ifa);
265 return -ENOBUFS;
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);
274 struct in_device *inetdev_by_index(int ifindex)
276 struct device *dev;
277 dev = dev_get_by_index(ifindex);
278 if (dev)
279 return dev->ip_ptr;
280 return NULL;
283 struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, u32 prefix, u32 mask)
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;
292 #ifdef CONFIG_RTNETLINK
294 /* rtm_{add|del} functions are not reenterable, so that
295 this structure can be made static
299 inet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
301 struct rtattr **rta = arg;
302 struct in_device *in_dev;
303 struct ifaddrmsg *ifm = NLMSG_DATA(nlh);
304 struct in_ifaddr *ifa, **ifap;
306 if ((in_dev = inetdev_by_index(ifm->ifa_index)) == NULL)
307 return -EADDRNOTAVAIL;
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;
320 return -EADDRNOTAVAIL;
324 inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
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;
332 if (ifm->ifa_prefixlen > 32 || rta[IFA_LOCAL-1] == NULL)
333 return -EINVAL;
335 if ((dev = dev_get_by_index(ifm->ifa_index)) == NULL)
336 return -ENODEV;
338 if ((in_dev = dev->ip_ptr) == NULL) {
339 in_dev = inetdev_init(dev);
340 if (!in_dev)
341 return -ENOBUFS;
344 if ((ifa = inet_alloc_ifa()) == NULL)
345 return -ENOBUFS;
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);
365 return inet_insert_ifa(in_dev, ifa);
368 #endif
371 * Determine a default network mask, based on the IP address.
374 static __inline__ int inet_abc_len(u32 addr)
376 if (ZERONET(addr))
377 return 0;
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;
388 * Something else, probably a multicast.
391 return -1;
395 int devinet_ioctl(unsigned int cmd, void *arg)
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;
410 * Fetch the caller's info block into kernel space
413 if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))
414 return -EFAULT;
415 ifr.ifr_name[IFNAMSIZ-1] = 0;
417 #ifdef CONFIG_IP_ALIAS
418 colon = strchr(ifr.ifr_name, ':');
419 if (colon)
420 *colon = 0;
421 #endif
423 #ifdef CONFIG_KMOD
424 dev_load(ifr.ifr_name);
425 #endif
427 switch(cmd) {
428 case SIOCGIFADDR: /* Get interface address */
429 case SIOCGIFBRDADDR: /* Get the broadcast address */
430 case SIOCGIFDSTADDR: /* Get the destination address */
431 case SIOCGIFNETMASK: /* Get the netmask for the interface */
432 /* Note that this ioctls will not sleep,
433 so that we do not impose a lock.
434 One day we will be forced to put shlock here (I mean SMP)
436 memset(sin, 0, sizeof(*sin));
437 sin->sin_family = AF_INET;
438 break;
440 case SIOCSIFFLAGS:
441 if (!capable(CAP_NET_ADMIN))
442 return -EACCES;
443 rtnl_lock();
444 exclusive = 1;
445 break;
446 case SIOCSIFADDR: /* Set interface address (and family) */
447 case SIOCSIFBRDADDR: /* Set the broadcast address */
448 case SIOCSIFDSTADDR: /* Set the destination address */
449 case SIOCSIFNETMASK: /* Set the netmask for the interface */
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;
462 if ((dev = dev_get(ifr.ifr_name)) == NULL) {
463 ret = -ENODEV;
464 goto done;
467 #ifdef CONFIG_IP_ALIAS
468 if (colon)
469 *colon = ':';
470 #endif
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;
478 if (ifa == NULL && cmd != SIOCSIFADDR && cmd != SIOCSIFFLAGS) {
479 ret = -EADDRNOTAVAIL;
480 goto done;
483 switch(cmd) {
484 case SIOCGIFADDR: /* Get interface address */
485 sin->sin_addr.s_addr = ifa->ifa_local;
486 goto rarok;
488 case SIOCGIFBRDADDR: /* Get the broadcast address */
489 sin->sin_addr.s_addr = ifa->ifa_broadcast;
490 goto rarok;
492 case SIOCGIFDSTADDR: /* Get the destination address */
493 sin->sin_addr.s_addr = ifa->ifa_address;
494 goto rarok;
496 case SIOCGIFNETMASK: /* Get the netmask for the interface */
497 sin->sin_addr.s_addr = ifa->ifa_mask;
498 goto rarok;
500 case SIOCSIFFLAGS:
501 #ifdef CONFIG_IP_ALIAS
502 if (colon) {
503 if (ifa == NULL) {
504 ret = -EADDRNOTAVAIL;
505 break;
507 if (!(ifr.ifr_flags&IFF_UP))
508 inet_del_ifa(in_dev, ifap, 1);
509 break;
511 #endif
512 ret = dev_change_flags(dev, ifr.ifr_flags);
513 break;
515 case SIOCSIFADDR: /* Set interface address (and family) */
516 if (inet_abc_len(sin->sin_addr.s_addr) < 0) {
517 ret = -EINVAL;
518 break;
521 if (!ifa) {
522 if ((ifa = inet_alloc_ifa()) == NULL) {
523 ret = -ENOBUFS;
524 break;
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;
541 ifa->ifa_address =
542 ifa->ifa_local = sin->sin_addr.s_addr;
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);
553 ret = inet_set_ifa(dev, ifa);
554 break;
556 case SIOCSIFBRDADDR: /* Set the broadcast address */
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);
562 break;
564 case SIOCSIFDSTADDR: /* Set the destination address */
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;
570 inet_del_ifa(in_dev, ifap, 0);
571 ifa->ifa_address = sin->sin_addr.s_addr;
572 inet_insert_ifa(in_dev, ifa);
574 break;
576 case SIOCSIFNETMASK: /* Set the netmask for the interface */
579 * The mask we set must be legal.
581 if (bad_mask(sin->sin_addr.s_addr, 0)) {
582 ret = -EINVAL;
583 break;
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);
592 break;
594 done:
595 if (exclusive)
596 rtnl_unlock();
597 return ret;
599 rarok:
600 if (copy_to_user(arg, &ifr, sizeof(struct ifreq)))
601 return -EFAULT;
602 return 0;
605 static int
606 inet_gifconf(struct device *dev, char *buf, int len)
608 struct in_device *in_dev = dev->ip_ptr;
609 struct in_ifaddr *ifa;
610 struct ifreq *ifr = (struct ifreq *) buf;
611 int done=0;
613 if (in_dev==NULL || (ifa=in_dev->ifa_list)==NULL)
614 return 0;
616 for ( ; ifa; ifa = ifa->ifa_next) {
617 if (!ifr) {
618 done += sizeof(ifr);
619 continue;
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);
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;
632 ifr++;
633 len -= sizeof(struct ifreq);
634 done += sizeof(struct ifreq);
636 return done;
639 u32 inet_select_addr(struct device *dev, u32 dst, int scope)
641 u32 addr = 0;
642 struct in_device *in_dev = dev->ip_ptr;
644 if (in_dev == NULL)
645 return 0;
647 for_primary_ifa(in_dev) {
648 if (ifa->ifa_scope > scope)
649 continue;
650 addr = ifa->ifa_local;
651 if (!dst || inet_ifa_match(dst, ifa))
652 return addr;
653 } endfor_ifa(in_dev);
655 if (addr || scope >= RT_SCOPE_LINK)
656 return addr;
658 /* Not loopback addresses on loopback should be preferred
659 in this case. It is importnat that lo is the first interface
660 in dev_base list.
662 read_lock_bh(&dev_base_lock);
663 for (dev=dev_base; dev; dev=dev->next) {
664 if ((in_dev=dev->ip_ptr) == NULL)
665 continue;
667 for_primary_ifa(in_dev) {
668 if (ifa->ifa_scope <= scope) {
669 read_unlock_bh(&dev_base_lock);
670 return ifa->ifa_local;
672 } endfor_ifa(in_dev);
674 read_unlock_bh(&dev_base_lock);
676 return 0;
680 * Device notifier
683 int register_inetaddr_notifier(struct notifier_block *nb)
685 return notifier_chain_register(&inetaddr_chain, nb);
688 int unregister_inetaddr_notifier(struct notifier_block *nb)
690 return notifier_chain_unregister(&inetaddr_chain,nb);
693 static int inetdev_event(struct notifier_block *this, unsigned long event, void *ptr)
695 struct device *dev = ptr;
696 struct in_device *in_dev = dev->ip_ptr;
698 if (in_dev == NULL)
699 return NOTIFY_DONE;
701 switch (event) {
702 case NETDEV_REGISTER:
703 if (in_dev)
704 printk(KERN_DEBUG "inetdev_event: bug\n");
705 dev->ip_ptr = NULL;
706 break;
707 case NETDEV_UP:
708 if (dev == &loopback_dev) {
709 struct in_ifaddr *ifa;
710 if ((ifa = inet_alloc_ifa()) != NULL) {
711 ifa->ifa_local =
712 ifa->ifa_address = htonl(INADDR_LOOPBACK);
713 ifa->ifa_prefixlen = 8;
714 ifa->ifa_mask = inet_make_mask(8);
715 ifa->ifa_dev = in_dev;
716 ifa->ifa_scope = RT_SCOPE_HOST;
717 memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
718 inet_insert_ifa(in_dev, ifa);
721 ip_mc_up(in_dev);
722 break;
723 case NETDEV_DOWN:
724 ip_mc_down(in_dev);
725 break;
726 case NETDEV_UNREGISTER:
727 inetdev_destroy(in_dev);
728 break;
729 case NETDEV_CHANGENAME:
730 if (in_dev->ifa_list) {
731 struct in_ifaddr *ifa;
732 for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next)
733 memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
734 /* Do not notify about label change, this event is
735 not interesting to applications using netlink.
738 break;
741 return NOTIFY_DONE;
744 struct notifier_block ip_netdev_notifier={
745 inetdev_event,
746 NULL,
750 #ifdef CONFIG_RTNETLINK
752 static int inet_fill_ifaddr(struct sk_buff *skb, struct in_ifaddr *ifa,
753 u32 pid, u32 seq, int event)
755 struct ifaddrmsg *ifm;
756 struct nlmsghdr *nlh;
757 unsigned char *b = skb->tail;
759 nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*ifm));
760 ifm = NLMSG_DATA(nlh);
761 ifm->ifa_family = AF_INET;
762 ifm->ifa_prefixlen = ifa->ifa_prefixlen;
763 ifm->ifa_flags = ifa->ifa_flags|IFA_F_PERMANENT;
764 ifm->ifa_scope = ifa->ifa_scope;
765 ifm->ifa_index = ifa->ifa_dev->dev->ifindex;
766 if (ifa->ifa_address)
767 RTA_PUT(skb, IFA_ADDRESS, 4, &ifa->ifa_address);
768 if (ifa->ifa_local)
769 RTA_PUT(skb, IFA_LOCAL, 4, &ifa->ifa_local);
770 if (ifa->ifa_broadcast)
771 RTA_PUT(skb, IFA_BROADCAST, 4, &ifa->ifa_broadcast);
772 if (ifa->ifa_anycast)
773 RTA_PUT(skb, IFA_ANYCAST, 4, &ifa->ifa_anycast);
774 if (ifa->ifa_label[0])
775 RTA_PUT(skb, IFA_LABEL, IFNAMSIZ, &ifa->ifa_label);
776 nlh->nlmsg_len = skb->tail - b;
777 return skb->len;
779 nlmsg_failure:
780 rtattr_failure:
781 skb_trim(skb, b - skb->data);
782 return -1;
785 static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
787 int idx, ip_idx;
788 int s_idx, s_ip_idx;
789 struct device *dev;
790 struct in_device *in_dev;
791 struct in_ifaddr *ifa;
793 s_idx = cb->args[0];
794 s_ip_idx = ip_idx = cb->args[1];
795 read_lock_bh(&dev_base_lock);
796 for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) {
797 if (idx < s_idx)
798 continue;
799 if (idx > s_idx)
800 s_ip_idx = 0;
801 if ((in_dev = dev->ip_ptr) == NULL)
802 continue;
803 for (ifa = in_dev->ifa_list, ip_idx = 0; ifa;
804 ifa = ifa->ifa_next, ip_idx++) {
805 if (ip_idx < s_ip_idx)
806 continue;
807 if (inet_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid,
808 cb->nlh->nlmsg_seq, RTM_NEWADDR) <= 0)
809 goto done;
812 done:
813 read_unlock_bh(&dev_base_lock);
814 cb->args[0] = idx;
815 cb->args[1] = ip_idx;
817 return skb->len;
820 static void rtmsg_ifa(int event, struct in_ifaddr * ifa)
822 struct sk_buff *skb;
823 int size = NLMSG_SPACE(sizeof(struct ifaddrmsg)+128);
825 skb = alloc_skb(size, GFP_KERNEL);
826 if (!skb) {
827 netlink_set_err(rtnl, 0, RTMGRP_IPV4_IFADDR, ENOBUFS);
828 return;
830 if (inet_fill_ifaddr(skb, ifa, 0, 0, event) < 0) {
831 kfree_skb(skb);
832 netlink_set_err(rtnl, 0, RTMGRP_IPV4_IFADDR, EINVAL);
833 return;
835 NETLINK_CB(skb).dst_groups = RTMGRP_IPV4_IFADDR;
836 netlink_broadcast(rtnl, skb, 0, RTMGRP_IPV4_IFADDR, GFP_KERNEL);
840 static struct rtnetlink_link inet_rtnetlink_table[RTM_MAX-RTM_BASE+1] =
842 { NULL, NULL, },
843 { NULL, NULL, },
844 { NULL, NULL, },
845 { NULL, NULL, },
847 { inet_rtm_newaddr, NULL, },
848 { inet_rtm_deladdr, NULL, },
849 { NULL, inet_dump_ifaddr, },
850 { NULL, NULL, },
852 { inet_rtm_newroute, NULL, },
853 { inet_rtm_delroute, NULL, },
854 { inet_rtm_getroute, inet_dump_fib, },
855 { NULL, NULL, },
857 { NULL, NULL, },
858 { NULL, NULL, },
859 { NULL, NULL, },
860 { NULL, NULL, },
862 #ifdef CONFIG_IP_MULTIPLE_TABLES
863 { inet_rtm_newrule, NULL, },
864 { inet_rtm_delrule, NULL, },
865 { NULL, inet_dump_rules, },
866 { NULL, NULL, },
867 #else
868 { NULL, NULL, },
869 { NULL, NULL, },
870 { NULL, NULL, },
871 { NULL, NULL, },
872 #endif
875 #endif /* CONFIG_RTNETLINK */
878 #ifdef CONFIG_SYSCTL
880 void inet_forward_change()
882 struct device *dev;
883 int on = ipv4_devconf.forwarding;
885 ipv4_devconf.accept_redirects = !on;
886 ipv4_devconf_dflt.forwarding = on;
888 read_lock_bh(&dev_base_lock);
889 for (dev = dev_base; dev; dev = dev->next) {
890 struct in_device *in_dev = dev->ip_ptr;
891 if (in_dev)
892 in_dev->cnf.forwarding = on;
894 read_unlock_bh(&dev_base_lock);
896 rt_cache_flush(0);
898 ip_statistics.IpForwarding = on ? 1 : 2;
901 static
902 int devinet_sysctl_forward(ctl_table *ctl, int write, struct file * filp,
903 void *buffer, size_t *lenp)
905 int *valp = ctl->data;
906 int val = *valp;
907 int ret;
909 ret = proc_dointvec(ctl, write, filp, buffer, lenp);
911 if (write && *valp != val) {
912 if (valp == &ipv4_devconf.forwarding)
913 inet_forward_change();
914 else if (valp != &ipv4_devconf_dflt.forwarding)
915 rt_cache_flush(0);
918 return ret;
921 static struct devinet_sysctl_table
923 struct ctl_table_header *sysctl_header;
924 ctl_table devinet_vars[12];
925 ctl_table devinet_dev[2];
926 ctl_table devinet_conf_dir[2];
927 ctl_table devinet_proto_dir[2];
928 ctl_table devinet_root_dir[2];
929 } devinet_sysctl = {
930 NULL,
931 {{NET_IPV4_CONF_FORWARDING, "forwarding",
932 &ipv4_devconf.forwarding, sizeof(int), 0644, NULL,
933 &devinet_sysctl_forward},
934 {NET_IPV4_CONF_MC_FORWARDING, "mc_forwarding",
935 &ipv4_devconf.mc_forwarding, sizeof(int), 0444, NULL,
936 &proc_dointvec},
937 {NET_IPV4_CONF_ACCEPT_REDIRECTS, "accept_redirects",
938 &ipv4_devconf.accept_redirects, sizeof(int), 0644, NULL,
939 &proc_dointvec},
940 {NET_IPV4_CONF_SECURE_REDIRECTS, "secure_redirects",
941 &ipv4_devconf.secure_redirects, sizeof(int), 0644, NULL,
942 &proc_dointvec},
943 {NET_IPV4_CONF_SHARED_MEDIA, "shared_media",
944 &ipv4_devconf.shared_media, sizeof(int), 0644, NULL,
945 &proc_dointvec},
946 {NET_IPV4_CONF_RP_FILTER, "rp_filter",
947 &ipv4_devconf.rp_filter, sizeof(int), 0644, NULL,
948 &proc_dointvec},
949 {NET_IPV4_CONF_SEND_REDIRECTS, "send_redirects",
950 &ipv4_devconf.send_redirects, sizeof(int), 0644, NULL,
951 &proc_dointvec},
952 {NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE, "accept_source_route",
953 &ipv4_devconf.accept_source_route, sizeof(int), 0644, NULL,
954 &proc_dointvec},
955 {NET_IPV4_CONF_PROXY_ARP, "proxy_arp",
956 &ipv4_devconf.proxy_arp, sizeof(int), 0644, NULL,
957 &proc_dointvec},
958 {NET_IPV4_CONF_BOOTP_RELAY, "bootp_relay",
959 &ipv4_devconf.bootp_relay, sizeof(int), 0644, NULL,
960 &proc_dointvec},
961 {NET_IPV4_CONF_LOG_MARTIANS, "log_martians",
962 &ipv4_devconf.log_martians, sizeof(int), 0644, NULL,
963 &proc_dointvec},
964 {0}},
966 {{NET_PROTO_CONF_ALL, "all", NULL, 0, 0555, devinet_sysctl.devinet_vars},{0}},
967 {{NET_IPV4_CONF, "conf", NULL, 0, 0555, devinet_sysctl.devinet_dev},{0}},
968 {{NET_IPV4, "ipv4", NULL, 0, 0555, devinet_sysctl.devinet_conf_dir},{0}},
969 {{CTL_NET, "net", NULL, 0, 0555, devinet_sysctl.devinet_proto_dir},{0}}
972 static void devinet_sysctl_register(struct in_device *in_dev, struct ipv4_devconf *p)
974 int i;
975 struct device *dev = in_dev ? in_dev->dev : NULL;
976 struct devinet_sysctl_table *t;
978 t = kmalloc(sizeof(*t), GFP_KERNEL);
979 if (t == NULL)
980 return;
981 memcpy(t, &devinet_sysctl, sizeof(*t));
982 for (i=0; i<sizeof(t->devinet_vars)/sizeof(t->devinet_vars[0])-1; i++) {
983 t->devinet_vars[i].data += (char*)p - (char*)&ipv4_devconf;
984 t->devinet_vars[i].de = NULL;
986 if (dev) {
987 t->devinet_dev[0].procname = dev->name;
988 t->devinet_dev[0].ctl_name = dev->ifindex;
989 } else {
990 t->devinet_dev[0].procname = "default";
991 t->devinet_dev[0].ctl_name = NET_PROTO_CONF_DEFAULT;
993 t->devinet_dev[0].child = t->devinet_vars;
994 t->devinet_dev[0].de = NULL;
995 t->devinet_conf_dir[0].child = t->devinet_dev;
996 t->devinet_conf_dir[0].de = NULL;
997 t->devinet_proto_dir[0].child = t->devinet_conf_dir;
998 t->devinet_proto_dir[0].de = NULL;
999 t->devinet_root_dir[0].child = t->devinet_proto_dir;
1000 t->devinet_root_dir[0].de = NULL;
1002 t->sysctl_header = register_sysctl_table(t->devinet_root_dir, 0);
1003 if (t->sysctl_header == NULL)
1004 kfree(t);
1005 else
1006 p->sysctl = t;
1009 static void devinet_sysctl_unregister(struct ipv4_devconf *p)
1011 if (p->sysctl) {
1012 struct devinet_sysctl_table *t = p->sysctl;
1013 p->sysctl = NULL;
1014 unregister_sysctl_table(t->sysctl_header);
1015 kfree(t);
1018 #endif
1020 __initfunc(void devinet_init(void))
1022 register_gifconf(PF_INET, inet_gifconf);
1023 register_netdevice_notifier(&ip_netdev_notifier);
1024 #ifdef CONFIG_RTNETLINK
1025 rtnetlink_links[PF_INET] = inet_rtnetlink_table;
1026 #endif
1027 #ifdef CONFIG_SYSCTL
1028 devinet_sysctl.sysctl_header =
1029 register_sysctl_table(devinet_sysctl.devinet_root_dir, 0);
1030 devinet_sysctl_register(NULL, &ipv4_devconf_dflt);
1031 #endif