pre-2.3.4..
[davej-history.git] / net / ipv4 / devinet.c
blobe4e73ff7736d3a1c4b56df98ba4be22166715179
1 /*
2 * NET3 IP device support routines.
4 * Version: $Id: devinet.c,v 1.28 1999/05/08 20:00:16 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;
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 (!buf) {
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 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);
638 return done;
641 u32 inet_select_addr(struct device *dev, u32 dst, int scope)
643 u32 addr = 0;
644 struct in_device *in_dev = dev->ip_ptr;
646 if (in_dev == NULL)
647 return 0;
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);
657 if (addr || scope >= RT_SCOPE_LINK)
658 return addr;
660 /* Not loopback addresses on loopback should be preferred
661 in this case. It is importnat that lo is the first interface
662 in dev_base list.
664 read_lock_bh(&dev_base_lock);
665 for (dev=dev_base; dev; dev=dev->next) {
666 if ((in_dev=dev->ip_ptr) == NULL)
667 continue;
669 for_primary_ifa(in_dev) {
670 if (ifa->ifa_scope <= scope) {
671 read_unlock_bh(&dev_base_lock);
672 return ifa->ifa_local;
674 } endfor_ifa(in_dev);
676 read_unlock_bh(&dev_base_lock);
678 return 0;
682 * Device notifier
685 int register_inetaddr_notifier(struct notifier_block *nb)
687 return notifier_chain_register(&inetaddr_chain, nb);
690 int unregister_inetaddr_notifier(struct notifier_block *nb)
692 return notifier_chain_unregister(&inetaddr_chain,nb);
695 static int inetdev_event(struct notifier_block *this, unsigned long event, void *ptr)
697 struct device *dev = ptr;
698 struct in_device *in_dev = dev->ip_ptr;
700 if (in_dev == NULL)
701 return NOTIFY_DONE;
703 switch (event) {
704 case NETDEV_REGISTER:
705 if (in_dev)
706 printk(KERN_DEBUG "inetdev_event: bug\n");
707 dev->ip_ptr = NULL;
708 break;
709 case NETDEV_UP:
710 if (dev == &loopback_dev) {
711 struct in_ifaddr *ifa;
712 if ((ifa = inet_alloc_ifa()) != NULL) {
713 ifa->ifa_local =
714 ifa->ifa_address = htonl(INADDR_LOOPBACK);
715 ifa->ifa_prefixlen = 8;
716 ifa->ifa_mask = inet_make_mask(8);
717 ifa->ifa_dev = in_dev;
718 ifa->ifa_scope = RT_SCOPE_HOST;
719 memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
720 inet_insert_ifa(in_dev, ifa);
723 ip_mc_up(in_dev);
724 break;
725 case NETDEV_DOWN:
726 ip_mc_down(in_dev);
727 break;
728 case NETDEV_UNREGISTER:
729 inetdev_destroy(in_dev);
730 break;
731 case NETDEV_CHANGENAME:
732 if (in_dev->ifa_list) {
733 struct in_ifaddr *ifa;
734 for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next)
735 memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
736 /* Do not notify about label change, this event is
737 not interesting to applications using netlink.
740 break;
743 return NOTIFY_DONE;
746 struct notifier_block ip_netdev_notifier={
747 inetdev_event,
748 NULL,
752 #ifdef CONFIG_RTNETLINK
754 static int inet_fill_ifaddr(struct sk_buff *skb, struct in_ifaddr *ifa,
755 u32 pid, u32 seq, int event)
757 struct ifaddrmsg *ifm;
758 struct nlmsghdr *nlh;
759 unsigned char *b = skb->tail;
761 nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*ifm));
762 ifm = NLMSG_DATA(nlh);
763 ifm->ifa_family = AF_INET;
764 ifm->ifa_prefixlen = ifa->ifa_prefixlen;
765 ifm->ifa_flags = ifa->ifa_flags|IFA_F_PERMANENT;
766 ifm->ifa_scope = ifa->ifa_scope;
767 ifm->ifa_index = ifa->ifa_dev->dev->ifindex;
768 if (ifa->ifa_address)
769 RTA_PUT(skb, IFA_ADDRESS, 4, &ifa->ifa_address);
770 if (ifa->ifa_local)
771 RTA_PUT(skb, IFA_LOCAL, 4, &ifa->ifa_local);
772 if (ifa->ifa_broadcast)
773 RTA_PUT(skb, IFA_BROADCAST, 4, &ifa->ifa_broadcast);
774 if (ifa->ifa_anycast)
775 RTA_PUT(skb, IFA_ANYCAST, 4, &ifa->ifa_anycast);
776 if (ifa->ifa_label[0])
777 RTA_PUT(skb, IFA_LABEL, IFNAMSIZ, &ifa->ifa_label);
778 nlh->nlmsg_len = skb->tail - b;
779 return skb->len;
781 nlmsg_failure:
782 rtattr_failure:
783 skb_trim(skb, b - skb->data);
784 return -1;
787 static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
789 int idx, ip_idx;
790 int s_idx, s_ip_idx;
791 struct device *dev;
792 struct in_device *in_dev;
793 struct in_ifaddr *ifa;
795 s_idx = cb->args[0];
796 s_ip_idx = ip_idx = cb->args[1];
797 read_lock_bh(&dev_base_lock);
798 for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) {
799 if (idx < s_idx)
800 continue;
801 if (idx > s_idx)
802 s_ip_idx = 0;
803 if ((in_dev = dev->ip_ptr) == NULL)
804 continue;
805 for (ifa = in_dev->ifa_list, ip_idx = 0; ifa;
806 ifa = ifa->ifa_next, ip_idx++) {
807 if (ip_idx < s_ip_idx)
808 continue;
809 if (inet_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid,
810 cb->nlh->nlmsg_seq, RTM_NEWADDR) <= 0)
811 goto done;
814 done:
815 read_unlock_bh(&dev_base_lock);
816 cb->args[0] = idx;
817 cb->args[1] = ip_idx;
819 return skb->len;
822 static void rtmsg_ifa(int event, struct in_ifaddr * ifa)
824 struct sk_buff *skb;
825 int size = NLMSG_SPACE(sizeof(struct ifaddrmsg)+128);
827 skb = alloc_skb(size, GFP_KERNEL);
828 if (!skb) {
829 netlink_set_err(rtnl, 0, RTMGRP_IPV4_IFADDR, ENOBUFS);
830 return;
832 if (inet_fill_ifaddr(skb, ifa, 0, 0, event) < 0) {
833 kfree_skb(skb);
834 netlink_set_err(rtnl, 0, RTMGRP_IPV4_IFADDR, EINVAL);
835 return;
837 NETLINK_CB(skb).dst_groups = RTMGRP_IPV4_IFADDR;
838 netlink_broadcast(rtnl, skb, 0, RTMGRP_IPV4_IFADDR, GFP_KERNEL);
842 static struct rtnetlink_link inet_rtnetlink_table[RTM_MAX-RTM_BASE+1] =
844 { NULL, NULL, },
845 { NULL, NULL, },
846 { NULL, NULL, },
847 { NULL, NULL, },
849 { inet_rtm_newaddr, NULL, },
850 { inet_rtm_deladdr, NULL, },
851 { NULL, inet_dump_ifaddr, },
852 { NULL, NULL, },
854 { inet_rtm_newroute, NULL, },
855 { inet_rtm_delroute, NULL, },
856 { inet_rtm_getroute, inet_dump_fib, },
857 { NULL, NULL, },
859 { NULL, NULL, },
860 { NULL, NULL, },
861 { NULL, NULL, },
862 { NULL, NULL, },
864 #ifdef CONFIG_IP_MULTIPLE_TABLES
865 { inet_rtm_newrule, NULL, },
866 { inet_rtm_delrule, NULL, },
867 { NULL, inet_dump_rules, },
868 { NULL, NULL, },
869 #else
870 { NULL, NULL, },
871 { NULL, NULL, },
872 { NULL, NULL, },
873 { NULL, NULL, },
874 #endif
877 #endif /* CONFIG_RTNETLINK */
880 #ifdef CONFIG_SYSCTL
882 void inet_forward_change()
884 struct device *dev;
885 int on = ipv4_devconf.forwarding;
887 ipv4_devconf.accept_redirects = !on;
888 ipv4_devconf_dflt.forwarding = on;
890 read_lock_bh(&dev_base_lock);
891 for (dev = dev_base; dev; dev = dev->next) {
892 struct in_device *in_dev = dev->ip_ptr;
893 if (in_dev)
894 in_dev->cnf.forwarding = on;
896 read_unlock_bh(&dev_base_lock);
898 rt_cache_flush(0);
900 ip_statistics.IpForwarding = on ? 1 : 2;
903 static
904 int devinet_sysctl_forward(ctl_table *ctl, int write, struct file * filp,
905 void *buffer, size_t *lenp)
907 int *valp = ctl->data;
908 int val = *valp;
909 int ret;
911 ret = proc_dointvec(ctl, write, filp, buffer, lenp);
913 if (write && *valp != val) {
914 if (valp == &ipv4_devconf.forwarding)
915 inet_forward_change();
916 else if (valp != &ipv4_devconf_dflt.forwarding)
917 rt_cache_flush(0);
920 return ret;
923 static struct devinet_sysctl_table
925 struct ctl_table_header *sysctl_header;
926 ctl_table devinet_vars[12];
927 ctl_table devinet_dev[2];
928 ctl_table devinet_conf_dir[2];
929 ctl_table devinet_proto_dir[2];
930 ctl_table devinet_root_dir[2];
931 } devinet_sysctl = {
932 NULL,
933 {{NET_IPV4_CONF_FORWARDING, "forwarding",
934 &ipv4_devconf.forwarding, sizeof(int), 0644, NULL,
935 &devinet_sysctl_forward},
936 {NET_IPV4_CONF_MC_FORWARDING, "mc_forwarding",
937 &ipv4_devconf.mc_forwarding, sizeof(int), 0444, NULL,
938 &proc_dointvec},
939 {NET_IPV4_CONF_ACCEPT_REDIRECTS, "accept_redirects",
940 &ipv4_devconf.accept_redirects, sizeof(int), 0644, NULL,
941 &proc_dointvec},
942 {NET_IPV4_CONF_SECURE_REDIRECTS, "secure_redirects",
943 &ipv4_devconf.secure_redirects, sizeof(int), 0644, NULL,
944 &proc_dointvec},
945 {NET_IPV4_CONF_SHARED_MEDIA, "shared_media",
946 &ipv4_devconf.shared_media, sizeof(int), 0644, NULL,
947 &proc_dointvec},
948 {NET_IPV4_CONF_RP_FILTER, "rp_filter",
949 &ipv4_devconf.rp_filter, sizeof(int), 0644, NULL,
950 &proc_dointvec},
951 {NET_IPV4_CONF_SEND_REDIRECTS, "send_redirects",
952 &ipv4_devconf.send_redirects, sizeof(int), 0644, NULL,
953 &proc_dointvec},
954 {NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE, "accept_source_route",
955 &ipv4_devconf.accept_source_route, sizeof(int), 0644, NULL,
956 &proc_dointvec},
957 {NET_IPV4_CONF_PROXY_ARP, "proxy_arp",
958 &ipv4_devconf.proxy_arp, sizeof(int), 0644, NULL,
959 &proc_dointvec},
960 {NET_IPV4_CONF_BOOTP_RELAY, "bootp_relay",
961 &ipv4_devconf.bootp_relay, sizeof(int), 0644, NULL,
962 &proc_dointvec},
963 {NET_IPV4_CONF_LOG_MARTIANS, "log_martians",
964 &ipv4_devconf.log_martians, sizeof(int), 0644, NULL,
965 &proc_dointvec},
966 {0}},
968 {{NET_PROTO_CONF_ALL, "all", NULL, 0, 0555, devinet_sysctl.devinet_vars},{0}},
969 {{NET_IPV4_CONF, "conf", NULL, 0, 0555, devinet_sysctl.devinet_dev},{0}},
970 {{NET_IPV4, "ipv4", NULL, 0, 0555, devinet_sysctl.devinet_conf_dir},{0}},
971 {{CTL_NET, "net", NULL, 0, 0555, devinet_sysctl.devinet_proto_dir},{0}}
974 static void devinet_sysctl_register(struct in_device *in_dev, struct ipv4_devconf *p)
976 int i;
977 struct device *dev = in_dev ? in_dev->dev : NULL;
978 struct devinet_sysctl_table *t;
980 t = kmalloc(sizeof(*t), GFP_KERNEL);
981 if (t == NULL)
982 return;
983 memcpy(t, &devinet_sysctl, sizeof(*t));
984 for (i=0; i<sizeof(t->devinet_vars)/sizeof(t->devinet_vars[0])-1; i++) {
985 t->devinet_vars[i].data += (char*)p - (char*)&ipv4_devconf;
986 t->devinet_vars[i].de = NULL;
988 if (dev) {
989 t->devinet_dev[0].procname = dev->name;
990 t->devinet_dev[0].ctl_name = dev->ifindex;
991 } else {
992 t->devinet_dev[0].procname = "default";
993 t->devinet_dev[0].ctl_name = NET_PROTO_CONF_DEFAULT;
995 t->devinet_dev[0].child = t->devinet_vars;
996 t->devinet_dev[0].de = NULL;
997 t->devinet_conf_dir[0].child = t->devinet_dev;
998 t->devinet_conf_dir[0].de = NULL;
999 t->devinet_proto_dir[0].child = t->devinet_conf_dir;
1000 t->devinet_proto_dir[0].de = NULL;
1001 t->devinet_root_dir[0].child = t->devinet_proto_dir;
1002 t->devinet_root_dir[0].de = NULL;
1004 t->sysctl_header = register_sysctl_table(t->devinet_root_dir, 0);
1005 if (t->sysctl_header == NULL)
1006 kfree(t);
1007 else
1008 p->sysctl = t;
1011 static void devinet_sysctl_unregister(struct ipv4_devconf *p)
1013 if (p->sysctl) {
1014 struct devinet_sysctl_table *t = p->sysctl;
1015 p->sysctl = NULL;
1016 unregister_sysctl_table(t->sysctl_header);
1017 kfree(t);
1020 #endif
1022 __initfunc(void devinet_init(void))
1024 register_gifconf(PF_INET, inet_gifconf);
1025 register_netdevice_notifier(&ip_netdev_notifier);
1026 #ifdef CONFIG_RTNETLINK
1027 rtnetlink_links[PF_INET] = inet_rtnetlink_table;
1028 #endif
1029 #ifdef CONFIG_SYSCTL
1030 devinet_sysctl.sysctl_header =
1031 register_sysctl_table(devinet_sysctl.devinet_root_dir, 0);
1032 devinet_sysctl_register(NULL, &ipv4_devconf_dflt);
1033 #endif