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>
17 * Alan Cox, <gw4pts@gw4pts.ampr.org>
18 * Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
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>
35 #include <linux/socket.h>
36 #include <linux/sockios.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>
51 #include <linux/sysctl.h>
54 #include <linux/kmod.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
*);
67 #define rtmsg_ifa(a,b) do { } while(0)
70 static struct notifier_block
*inetaddr_chain
;
71 static void inet_del_ifa(struct in_device
*in_dev
, struct in_ifaddr
**ifap
, int destroy
);
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
);
80 static struct in_ifaddr
* inet_alloc_ifa(void)
82 struct in_ifaddr
*ifa
;
84 ifa
= kmalloc(sizeof(*ifa
), GFP_KERNEL
);
86 memset(ifa
, 0, sizeof(*ifa
));
93 static __inline__
void inet_free_ifa(struct in_ifaddr
*ifa
)
95 kfree_s(ifa
, sizeof(*ifa
));
99 struct in_device
*inetdev_init(struct device
*dev
)
101 struct in_device
*in_dev
;
103 in_dev
= kmalloc(sizeof(*in_dev
), GFP_KERNEL
);
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
;
111 if ((in_dev
->arp_parms
= neigh_parms_alloc(dev
, &arp_tbl
)) == NULL
) {
116 neigh_sysctl_register(dev
, in_dev
->arp_parms
, NET_IPV4
, NET_IPV4_NEIGH
, "ipv4");
118 dev
->ip_ptr
= in_dev
;
120 devinet_sysctl_register(in_dev
, &in_dev
->cnf
);
122 if (dev
->flags
&IFF_UP
)
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);
139 devinet_sysctl_unregister(&in_dev
->cnf
);
141 in_dev
->dev
->ip_ptr
= NULL
;
143 neigh_parms_release(&arp_tbl
, in_dev
->arp_parms
);
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
))
154 } endfor_ifa(in_dev
);
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
;
176 *ifap1
= ifa
->ifa_next
;
179 rtmsg_ifa(RTM_DELADDR
, ifa
);
180 notifier_call_chain(&inetaddr_chain
, NETDEV_DOWN
, ifa
);
187 *ifap
= ifa1
->ifa_next
;
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
);
204 if (in_dev
->ifa_list
== NULL
)
205 inetdev_destroy(in_dev
);
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) {
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
) {
230 if (ifa1
->ifa_scope
!= ifa
->ifa_scope
) {
234 ifa
->ifa_flags
|= IFA_F_SECONDARY
;
238 if (!(ifa
->ifa_flags
&IFA_F_SECONDARY
)) {
239 net_srandom(ifa
->ifa_local
);
243 ifa
->ifa_next
= *ifap
;
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
);
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
) {
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
)
277 dev
= dev_get_by_index(ifindex
);
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
))
288 } endfor_ifa(in_dev
);
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
))))
316 inet_del_ifa(in_dev
, ifap
, 1);
320 return -EADDRNOTAVAIL
;
324 inet_rtm_newaddr(struct sk_buff
*skb
, struct nlmsghdr
*nlh
, void *arg
)
326 struct rtattr
**rta
= arg
;
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
)
335 if ((dev
= dev_get_by_index(ifm
->ifa_index
)) == NULL
)
338 if ((in_dev
= dev
->ip_ptr
) == NULL
) {
339 in_dev
= inetdev_init(dev
);
344 if ((ifa
= inet_alloc_ifa()) == NULL
)
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
);
363 memcpy(ifa
->ifa_label
, dev
->name
, IFNAMSIZ
);
365 return inet_insert_ifa(in_dev
, ifa
);
371 * Determine a default network mask, based on the IP address.
374 static __inline__
int inet_abc_len(u32 addr
)
388 * Something else, probably a multicast.
395 int devinet_ioctl(unsigned int cmd
, void *arg
)
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
;
403 #ifdef CONFIG_IP_ALIAS
410 * Fetch the caller's info block into kernel space
413 if (copy_from_user(&ifr
, arg
, sizeof(struct ifreq
)))
415 ifr
.ifr_name
[IFNAMSIZ
-1] = 0;
417 #ifdef CONFIG_IP_ALIAS
418 colon
= strchr(ifr
.ifr_name
, ':');
424 dev_load(ifr
.ifr_name
);
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
;
441 if (!capable(CAP_NET_ADMIN
))
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
))
452 if (sin
->sin_family
!= AF_INET
)
462 if ((dev
= dev_get(ifr
.ifr_name
)) == NULL
) {
467 #ifdef CONFIG_IP_ALIAS
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)
478 if (ifa
== NULL
&& cmd
!= SIOCSIFADDR
&& cmd
!= SIOCSIFFLAGS
) {
479 ret
= -EADDRNOTAVAIL
;
484 case SIOCGIFADDR
: /* Get interface address */
485 sin
->sin_addr
.s_addr
= ifa
->ifa_local
;
488 case SIOCGIFBRDADDR
: /* Get the broadcast address */
489 sin
->sin_addr
.s_addr
= ifa
->ifa_broadcast
;
492 case SIOCGIFDSTADDR
: /* Get the destination address */
493 sin
->sin_addr
.s_addr
= ifa
->ifa_address
;
496 case SIOCGIFNETMASK
: /* Get the netmask for the interface */
497 sin
->sin_addr
.s_addr
= ifa
->ifa_mask
;
501 #ifdef CONFIG_IP_ALIAS
504 ret
= -EADDRNOTAVAIL
;
507 if (!(ifr
.ifr_flags
&IFF_UP
))
508 inet_del_ifa(in_dev
, ifap
, 1);
512 ret
= dev_change_flags(dev
, ifr
.ifr_flags
);
515 case SIOCSIFADDR
: /* Set interface address (and family) */
516 if (inet_abc_len(sin
->sin_addr
.s_addr
) < 0) {
522 if ((ifa
= inet_alloc_ifa()) == NULL
) {
526 #ifdef CONFIG_IP_ALIAS
528 memcpy(ifa
->ifa_label
, ifr
.ifr_name
, IFNAMSIZ
);
531 memcpy(ifa
->ifa_label
, dev
->name
, IFNAMSIZ
);
534 if (ifa
->ifa_local
== sin
->sin_addr
.s_addr
)
536 inet_del_ifa(in_dev
, ifap
, 0);
537 ifa
->ifa_broadcast
= 0;
538 ifa
->ifa_anycast
= 0;
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
;
550 ifa
->ifa_prefixlen
= 32;
551 ifa
->ifa_mask
= inet_make_mask(32);
553 ret
= inet_set_ifa(dev
, ifa
);
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
);
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) {
570 inet_del_ifa(in_dev
, ifap
, 0);
571 ifa
->ifa_address
= sin
->sin_addr
.s_addr
;
572 inet_insert_ifa(in_dev
, ifa
);
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)) {
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
);
600 if (copy_to_user(arg
, &ifr
, sizeof(struct ifreq
)))
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
;
613 if (in_dev
==NULL
|| (ifa
=in_dev
->ifa_list
)==NULL
)
616 for ( ; ifa
; ifa
= ifa
->ifa_next
) {
621 if (len
< (int) sizeof(ifr
))
623 memset(ifr
, 0, sizeof(struct ifreq
));
625 strcpy(ifr
->ifr_name
, ifa
->ifa_label
);
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
;
633 len
-= sizeof(struct ifreq
);
634 done
+= sizeof(struct ifreq
);
639 u32
inet_select_addr(struct device
*dev
, u32 dst
, int scope
)
642 struct in_device
*in_dev
= dev
->ip_ptr
;
647 for_primary_ifa(in_dev
) {
648 if (ifa
->ifa_scope
> scope
)
650 addr
= ifa
->ifa_local
;
651 if (!dst
|| inet_ifa_match(dst
, ifa
))
653 } endfor_ifa(in_dev
);
655 if (addr
|| scope
>= RT_SCOPE_LINK
)
658 /* Not loopback addresses on loopback should be preferred
659 in this case. It is importnat that lo is the first interface
662 read_lock_bh(&dev_base_lock
);
663 for (dev
=dev_base
; dev
; dev
=dev
->next
) {
664 if ((in_dev
=dev
->ip_ptr
) == NULL
)
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
);
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
;
702 case NETDEV_REGISTER
:
704 printk(KERN_DEBUG
"inetdev_event: bug\n");
708 if (dev
== &loopback_dev
) {
709 struct in_ifaddr
*ifa
;
710 if ((ifa
= inet_alloc_ifa()) != NULL
) {
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
);
726 case NETDEV_UNREGISTER
:
727 inetdev_destroy(in_dev
);
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.
744 struct notifier_block ip_netdev_notifier
={
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
);
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
;
781 skb_trim(skb
, b
- skb
->data
);
785 static int inet_dump_ifaddr(struct sk_buff
*skb
, struct netlink_callback
*cb
)
790 struct in_device
*in_dev
;
791 struct in_ifaddr
*ifa
;
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
++) {
801 if ((in_dev
= dev
->ip_ptr
) == NULL
)
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
)
807 if (inet_fill_ifaddr(skb
, ifa
, NETLINK_CB(cb
->skb
).pid
,
808 cb
->nlh
->nlmsg_seq
, RTM_NEWADDR
) <= 0)
813 read_unlock_bh(&dev_base_lock
);
815 cb
->args
[1] = ip_idx
;
820 static void rtmsg_ifa(int event
, struct in_ifaddr
* ifa
)
823 int size
= NLMSG_SPACE(sizeof(struct ifaddrmsg
)+128);
825 skb
= alloc_skb(size
, GFP_KERNEL
);
827 netlink_set_err(rtnl
, 0, RTMGRP_IPV4_IFADDR
, ENOBUFS
);
830 if (inet_fill_ifaddr(skb
, ifa
, 0, 0, event
) < 0) {
832 netlink_set_err(rtnl
, 0, RTMGRP_IPV4_IFADDR
, EINVAL
);
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] =
847 { inet_rtm_newaddr
, NULL
, },
848 { inet_rtm_deladdr
, NULL
, },
849 { NULL
, inet_dump_ifaddr
, },
852 { inet_rtm_newroute
, NULL
, },
853 { inet_rtm_delroute
, NULL
, },
854 { inet_rtm_getroute
, inet_dump_fib
, },
862 #ifdef CONFIG_IP_MULTIPLE_TABLES
863 { inet_rtm_newrule
, NULL
, },
864 { inet_rtm_delrule
, NULL
, },
865 { NULL
, inet_dump_rules
, },
875 #endif /* CONFIG_RTNETLINK */
880 void inet_forward_change()
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
;
892 in_dev
->cnf
.forwarding
= on
;
894 read_unlock_bh(&dev_base_lock
);
898 ip_statistics
.IpForwarding
= on
? 1 : 2;
902 int devinet_sysctl_forward(ctl_table
*ctl
, int write
, struct file
* filp
,
903 void *buffer
, size_t *lenp
)
905 int *valp
= ctl
->data
;
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
)
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];
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
,
937 {NET_IPV4_CONF_ACCEPT_REDIRECTS
, "accept_redirects",
938 &ipv4_devconf
.accept_redirects
, sizeof(int), 0644, NULL
,
940 {NET_IPV4_CONF_SECURE_REDIRECTS
, "secure_redirects",
941 &ipv4_devconf
.secure_redirects
, sizeof(int), 0644, NULL
,
943 {NET_IPV4_CONF_SHARED_MEDIA
, "shared_media",
944 &ipv4_devconf
.shared_media
, sizeof(int), 0644, NULL
,
946 {NET_IPV4_CONF_RP_FILTER
, "rp_filter",
947 &ipv4_devconf
.rp_filter
, sizeof(int), 0644, NULL
,
949 {NET_IPV4_CONF_SEND_REDIRECTS
, "send_redirects",
950 &ipv4_devconf
.send_redirects
, sizeof(int), 0644, NULL
,
952 {NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE
, "accept_source_route",
953 &ipv4_devconf
.accept_source_route
, sizeof(int), 0644, NULL
,
955 {NET_IPV4_CONF_PROXY_ARP
, "proxy_arp",
956 &ipv4_devconf
.proxy_arp
, sizeof(int), 0644, NULL
,
958 {NET_IPV4_CONF_BOOTP_RELAY
, "bootp_relay",
959 &ipv4_devconf
.bootp_relay
, sizeof(int), 0644, NULL
,
961 {NET_IPV4_CONF_LOG_MARTIANS
, "log_martians",
962 &ipv4_devconf
.log_martians
, sizeof(int), 0644, NULL
,
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
)
975 struct device
*dev
= in_dev
? in_dev
->dev
: NULL
;
976 struct devinet_sysctl_table
*t
;
978 t
= kmalloc(sizeof(*t
), GFP_KERNEL
);
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
;
987 t
->devinet_dev
[0].procname
= dev
->name
;
988 t
->devinet_dev
[0].ctl_name
= dev
->ifindex
;
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
)
1009 static void devinet_sysctl_unregister(struct ipv4_devconf
*p
)
1012 struct devinet_sysctl_table
*t
= p
->sysctl
;
1014 unregister_sysctl_table(t
->sysctl_header
);
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
;
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
);