]> bbs.cooldavid.org Git - net-next-2.6.git/blame_incremental - net/ipv4/devinet.c
softmac: mark as obsolete and schedule for removal
[net-next-2.6.git] / net / ipv4 / devinet.c
... / ...
CommitLineData
1/*
2 * NET3 IP device support routines.
3 *
4 * Version: $Id: devinet.c,v 1.44 2001/10/31 21:55:54 davem Exp $
5 *
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.
10 *
11 * Derived from the IP parts of dev.c 1.0.19
12 * Authors: Ross Biro
13 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
14 * Mark Evans, <evansmp@uhura.aston.ac.uk>
15 *
16 * Additional Authors:
17 * Alan Cox, <gw4pts@gw4pts.ampr.org>
18 * Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
19 *
20 * Changes:
21 * Alexey Kuznetsov: pa_* fields are replaced with ifaddr
22 * lists.
23 * Cyrus Durgin: updated for kmod
24 * Matthias Andree: in devinet_ioctl, compare label and
25 * address (4.4BSD alias style support),
26 * fall back to comparing just the label
27 * if no match found.
28 */
29
30
31#include <asm/uaccess.h>
32#include <asm/system.h>
33#include <linux/bitops.h>
34#include <linux/capability.h>
35#include <linux/module.h>
36#include <linux/types.h>
37#include <linux/kernel.h>
38#include <linux/string.h>
39#include <linux/mm.h>
40#include <linux/socket.h>
41#include <linux/sockios.h>
42#include <linux/in.h>
43#include <linux/errno.h>
44#include <linux/interrupt.h>
45#include <linux/if_addr.h>
46#include <linux/if_ether.h>
47#include <linux/inet.h>
48#include <linux/netdevice.h>
49#include <linux/etherdevice.h>
50#include <linux/skbuff.h>
51#include <linux/init.h>
52#include <linux/notifier.h>
53#include <linux/inetdevice.h>
54#include <linux/igmp.h>
55#ifdef CONFIG_SYSCTL
56#include <linux/sysctl.h>
57#endif
58#include <linux/kmod.h>
59
60#include <net/arp.h>
61#include <net/ip.h>
62#include <net/route.h>
63#include <net/ip_fib.h>
64#include <net/rtnetlink.h>
65
66struct ipv4_devconf ipv4_devconf = {
67 .data = {
68 [NET_IPV4_CONF_ACCEPT_REDIRECTS - 1] = 1,
69 [NET_IPV4_CONF_SEND_REDIRECTS - 1] = 1,
70 [NET_IPV4_CONF_SECURE_REDIRECTS - 1] = 1,
71 [NET_IPV4_CONF_SHARED_MEDIA - 1] = 1,
72 },
73};
74
75static struct ipv4_devconf ipv4_devconf_dflt = {
76 .data = {
77 [NET_IPV4_CONF_ACCEPT_REDIRECTS - 1] = 1,
78 [NET_IPV4_CONF_SEND_REDIRECTS - 1] = 1,
79 [NET_IPV4_CONF_SECURE_REDIRECTS - 1] = 1,
80 [NET_IPV4_CONF_SHARED_MEDIA - 1] = 1,
81 [NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE - 1] = 1,
82 },
83};
84
85#define IPV4_DEVCONF_DFLT(attr) IPV4_DEVCONF(ipv4_devconf_dflt, attr)
86
87static const struct nla_policy ifa_ipv4_policy[IFA_MAX+1] = {
88 [IFA_LOCAL] = { .type = NLA_U32 },
89 [IFA_ADDRESS] = { .type = NLA_U32 },
90 [IFA_BROADCAST] = { .type = NLA_U32 },
91 [IFA_ANYCAST] = { .type = NLA_U32 },
92 [IFA_LABEL] = { .type = NLA_STRING, .len = IFNAMSIZ - 1 },
93};
94
95static void rtmsg_ifa(int event, struct in_ifaddr *, struct nlmsghdr *, u32);
96
97static BLOCKING_NOTIFIER_HEAD(inetaddr_chain);
98static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
99 int destroy);
100#ifdef CONFIG_SYSCTL
101static void devinet_sysctl_register(struct in_device *in_dev,
102 struct ipv4_devconf *p);
103static void devinet_sysctl_unregister(struct ipv4_devconf *p);
104#endif
105
106/* Locks all the inet devices. */
107
108static struct in_ifaddr *inet_alloc_ifa(void)
109{
110 struct in_ifaddr *ifa = kzalloc(sizeof(*ifa), GFP_KERNEL);
111
112 if (ifa) {
113 INIT_RCU_HEAD(&ifa->rcu_head);
114 }
115
116 return ifa;
117}
118
119static void inet_rcu_free_ifa(struct rcu_head *head)
120{
121 struct in_ifaddr *ifa = container_of(head, struct in_ifaddr, rcu_head);
122 if (ifa->ifa_dev)
123 in_dev_put(ifa->ifa_dev);
124 kfree(ifa);
125}
126
127static inline void inet_free_ifa(struct in_ifaddr *ifa)
128{
129 call_rcu(&ifa->rcu_head, inet_rcu_free_ifa);
130}
131
132void in_dev_finish_destroy(struct in_device *idev)
133{
134 struct net_device *dev = idev->dev;
135
136 BUG_TRAP(!idev->ifa_list);
137 BUG_TRAP(!idev->mc_list);
138#ifdef NET_REFCNT_DEBUG
139 printk(KERN_DEBUG "in_dev_finish_destroy: %p=%s\n",
140 idev, dev ? dev->name : "NIL");
141#endif
142 dev_put(dev);
143 if (!idev->dead)
144 printk("Freeing alive in_device %p\n", idev);
145 else {
146 kfree(idev);
147 }
148}
149
150static struct in_device *inetdev_init(struct net_device *dev)
151{
152 struct in_device *in_dev;
153
154 ASSERT_RTNL();
155
156 in_dev = kzalloc(sizeof(*in_dev), GFP_KERNEL);
157 if (!in_dev)
158 goto out;
159 INIT_RCU_HEAD(&in_dev->rcu_head);
160 memcpy(&in_dev->cnf, &ipv4_devconf_dflt, sizeof(in_dev->cnf));
161 in_dev->cnf.sysctl = NULL;
162 in_dev->dev = dev;
163 if ((in_dev->arp_parms = neigh_parms_alloc(dev, &arp_tbl)) == NULL)
164 goto out_kfree;
165 /* Reference in_dev->dev */
166 dev_hold(dev);
167#ifdef CONFIG_SYSCTL
168 neigh_sysctl_register(dev, in_dev->arp_parms, NET_IPV4,
169 NET_IPV4_NEIGH, "ipv4", NULL, NULL);
170#endif
171
172 /* Account for reference dev->ip_ptr (below) */
173 in_dev_hold(in_dev);
174
175#ifdef CONFIG_SYSCTL
176 devinet_sysctl_register(in_dev, &in_dev->cnf);
177#endif
178 ip_mc_init_dev(in_dev);
179 if (dev->flags & IFF_UP)
180 ip_mc_up(in_dev);
181
182 /* we can receive as soon as ip_ptr is set -- do this last */
183 rcu_assign_pointer(dev->ip_ptr, in_dev);
184out:
185 return in_dev;
186out_kfree:
187 kfree(in_dev);
188 in_dev = NULL;
189 goto out;
190}
191
192static void in_dev_rcu_put(struct rcu_head *head)
193{
194 struct in_device *idev = container_of(head, struct in_device, rcu_head);
195 in_dev_put(idev);
196}
197
198static void inetdev_destroy(struct in_device *in_dev)
199{
200 struct in_ifaddr *ifa;
201 struct net_device *dev;
202
203 ASSERT_RTNL();
204
205 dev = in_dev->dev;
206
207 in_dev->dead = 1;
208
209 ip_mc_destroy_dev(in_dev);
210
211 while ((ifa = in_dev->ifa_list) != NULL) {
212 inet_del_ifa(in_dev, &in_dev->ifa_list, 0);
213 inet_free_ifa(ifa);
214 }
215
216#ifdef CONFIG_SYSCTL
217 devinet_sysctl_unregister(&in_dev->cnf);
218#endif
219
220 dev->ip_ptr = NULL;
221
222#ifdef CONFIG_SYSCTL
223 neigh_sysctl_unregister(in_dev->arp_parms);
224#endif
225 neigh_parms_release(&arp_tbl, in_dev->arp_parms);
226 arp_ifdown(dev);
227
228 call_rcu(&in_dev->rcu_head, in_dev_rcu_put);
229}
230
231int inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b)
232{
233 rcu_read_lock();
234 for_primary_ifa(in_dev) {
235 if (inet_ifa_match(a, ifa)) {
236 if (!b || inet_ifa_match(b, ifa)) {
237 rcu_read_unlock();
238 return 1;
239 }
240 }
241 } endfor_ifa(in_dev);
242 rcu_read_unlock();
243 return 0;
244}
245
246static void __inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
247 int destroy, struct nlmsghdr *nlh, u32 pid)
248{
249 struct in_ifaddr *promote = NULL;
250 struct in_ifaddr *ifa, *ifa1 = *ifap;
251 struct in_ifaddr *last_prim = in_dev->ifa_list;
252 struct in_ifaddr *prev_prom = NULL;
253 int do_promote = IN_DEV_PROMOTE_SECONDARIES(in_dev);
254
255 ASSERT_RTNL();
256
257 /* 1. Deleting primary ifaddr forces deletion all secondaries
258 * unless alias promotion is set
259 **/
260
261 if (!(ifa1->ifa_flags & IFA_F_SECONDARY)) {
262 struct in_ifaddr **ifap1 = &ifa1->ifa_next;
263
264 while ((ifa = *ifap1) != NULL) {
265 if (!(ifa->ifa_flags & IFA_F_SECONDARY) &&
266 ifa1->ifa_scope <= ifa->ifa_scope)
267 last_prim = ifa;
268
269 if (!(ifa->ifa_flags & IFA_F_SECONDARY) ||
270 ifa1->ifa_mask != ifa->ifa_mask ||
271 !inet_ifa_match(ifa1->ifa_address, ifa)) {
272 ifap1 = &ifa->ifa_next;
273 prev_prom = ifa;
274 continue;
275 }
276
277 if (!do_promote) {
278 *ifap1 = ifa->ifa_next;
279
280 rtmsg_ifa(RTM_DELADDR, ifa, nlh, pid);
281 blocking_notifier_call_chain(&inetaddr_chain,
282 NETDEV_DOWN, ifa);
283 inet_free_ifa(ifa);
284 } else {
285 promote = ifa;
286 break;
287 }
288 }
289 }
290
291 /* 2. Unlink it */
292
293 *ifap = ifa1->ifa_next;
294
295 /* 3. Announce address deletion */
296
297 /* Send message first, then call notifier.
298 At first sight, FIB update triggered by notifier
299 will refer to already deleted ifaddr, that could confuse
300 netlink listeners. It is not true: look, gated sees
301 that route deleted and if it still thinks that ifaddr
302 is valid, it will try to restore deleted routes... Grr.
303 So that, this order is correct.
304 */
305 rtmsg_ifa(RTM_DELADDR, ifa1, nlh, pid);
306 blocking_notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa1);
307
308 if (promote) {
309
310 if (prev_prom) {
311 prev_prom->ifa_next = promote->ifa_next;
312 promote->ifa_next = last_prim->ifa_next;
313 last_prim->ifa_next = promote;
314 }
315
316 promote->ifa_flags &= ~IFA_F_SECONDARY;
317 rtmsg_ifa(RTM_NEWADDR, promote, nlh, pid);
318 blocking_notifier_call_chain(&inetaddr_chain,
319 NETDEV_UP, promote);
320 for (ifa = promote->ifa_next; ifa; ifa = ifa->ifa_next) {
321 if (ifa1->ifa_mask != ifa->ifa_mask ||
322 !inet_ifa_match(ifa1->ifa_address, ifa))
323 continue;
324 fib_add_ifaddr(ifa);
325 }
326
327 }
328 if (destroy)
329 inet_free_ifa(ifa1);
330}
331
332static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
333 int destroy)
334{
335 __inet_del_ifa(in_dev, ifap, destroy, NULL, 0);
336}
337
338static int __inet_insert_ifa(struct in_ifaddr *ifa, struct nlmsghdr *nlh,
339 u32 pid)
340{
341 struct in_device *in_dev = ifa->ifa_dev;
342 struct in_ifaddr *ifa1, **ifap, **last_primary;
343
344 ASSERT_RTNL();
345
346 if (!ifa->ifa_local) {
347 inet_free_ifa(ifa);
348 return 0;
349 }
350
351 ifa->ifa_flags &= ~IFA_F_SECONDARY;
352 last_primary = &in_dev->ifa_list;
353
354 for (ifap = &in_dev->ifa_list; (ifa1 = *ifap) != NULL;
355 ifap = &ifa1->ifa_next) {
356 if (!(ifa1->ifa_flags & IFA_F_SECONDARY) &&
357 ifa->ifa_scope <= ifa1->ifa_scope)
358 last_primary = &ifa1->ifa_next;
359 if (ifa1->ifa_mask == ifa->ifa_mask &&
360 inet_ifa_match(ifa1->ifa_address, ifa)) {
361 if (ifa1->ifa_local == ifa->ifa_local) {
362 inet_free_ifa(ifa);
363 return -EEXIST;
364 }
365 if (ifa1->ifa_scope != ifa->ifa_scope) {
366 inet_free_ifa(ifa);
367 return -EINVAL;
368 }
369 ifa->ifa_flags |= IFA_F_SECONDARY;
370 }
371 }
372
373 if (!(ifa->ifa_flags & IFA_F_SECONDARY)) {
374 net_srandom(ifa->ifa_local);
375 ifap = last_primary;
376 }
377
378 ifa->ifa_next = *ifap;
379 *ifap = ifa;
380
381 /* Send message first, then call notifier.
382 Notifier will trigger FIB update, so that
383 listeners of netlink will know about new ifaddr */
384 rtmsg_ifa(RTM_NEWADDR, ifa, nlh, pid);
385 blocking_notifier_call_chain(&inetaddr_chain, NETDEV_UP, ifa);
386
387 return 0;
388}
389
390static int inet_insert_ifa(struct in_ifaddr *ifa)
391{
392 return __inet_insert_ifa(ifa, NULL, 0);
393}
394
395static int inet_set_ifa(struct net_device *dev, struct in_ifaddr *ifa)
396{
397 struct in_device *in_dev = __in_dev_get_rtnl(dev);
398
399 ASSERT_RTNL();
400
401 if (!in_dev) {
402 inet_free_ifa(ifa);
403 return -ENOBUFS;
404 }
405 ipv4_devconf_setall(in_dev);
406 if (ifa->ifa_dev != in_dev) {
407 BUG_TRAP(!ifa->ifa_dev);
408 in_dev_hold(in_dev);
409 ifa->ifa_dev = in_dev;
410 }
411 if (LOOPBACK(ifa->ifa_local))
412 ifa->ifa_scope = RT_SCOPE_HOST;
413 return inet_insert_ifa(ifa);
414}
415
416struct in_device *inetdev_by_index(int ifindex)
417{
418 struct net_device *dev;
419 struct in_device *in_dev = NULL;
420 read_lock(&dev_base_lock);
421 dev = __dev_get_by_index(&init_net, ifindex);
422 if (dev)
423 in_dev = in_dev_get(dev);
424 read_unlock(&dev_base_lock);
425 return in_dev;
426}
427
428/* Called only from RTNL semaphored context. No locks. */
429
430struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, __be32 prefix,
431 __be32 mask)
432{
433 ASSERT_RTNL();
434
435 for_primary_ifa(in_dev) {
436 if (ifa->ifa_mask == mask && inet_ifa_match(prefix, ifa))
437 return ifa;
438 } endfor_ifa(in_dev);
439 return NULL;
440}
441
442static int inet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
443{
444 struct net *net = skb->sk->sk_net;
445 struct nlattr *tb[IFA_MAX+1];
446 struct in_device *in_dev;
447 struct ifaddrmsg *ifm;
448 struct in_ifaddr *ifa, **ifap;
449 int err = -EINVAL;
450
451 ASSERT_RTNL();
452
453 if (net != &init_net)
454 return -EINVAL;
455
456 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv4_policy);
457 if (err < 0)
458 goto errout;
459
460 ifm = nlmsg_data(nlh);
461 in_dev = inetdev_by_index(ifm->ifa_index);
462 if (in_dev == NULL) {
463 err = -ENODEV;
464 goto errout;
465 }
466
467 __in_dev_put(in_dev);
468
469 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
470 ifap = &ifa->ifa_next) {
471 if (tb[IFA_LOCAL] &&
472 ifa->ifa_local != nla_get_be32(tb[IFA_LOCAL]))
473 continue;
474
475 if (tb[IFA_LABEL] && nla_strcmp(tb[IFA_LABEL], ifa->ifa_label))
476 continue;
477
478 if (tb[IFA_ADDRESS] &&
479 (ifm->ifa_prefixlen != ifa->ifa_prefixlen ||
480 !inet_ifa_match(nla_get_be32(tb[IFA_ADDRESS]), ifa)))
481 continue;
482
483 __inet_del_ifa(in_dev, ifap, 1, nlh, NETLINK_CB(skb).pid);
484 return 0;
485 }
486
487 err = -EADDRNOTAVAIL;
488errout:
489 return err;
490}
491
492static struct in_ifaddr *rtm_to_ifaddr(struct nlmsghdr *nlh)
493{
494 struct nlattr *tb[IFA_MAX+1];
495 struct in_ifaddr *ifa;
496 struct ifaddrmsg *ifm;
497 struct net_device *dev;
498 struct in_device *in_dev;
499 int err = -EINVAL;
500
501 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv4_policy);
502 if (err < 0)
503 goto errout;
504
505 ifm = nlmsg_data(nlh);
506 if (ifm->ifa_prefixlen > 32 || tb[IFA_LOCAL] == NULL) {
507 err = -EINVAL;
508 goto errout;
509 }
510
511 dev = __dev_get_by_index(&init_net, ifm->ifa_index);
512 if (dev == NULL) {
513 err = -ENODEV;
514 goto errout;
515 }
516
517 in_dev = __in_dev_get_rtnl(dev);
518 if (in_dev == NULL) {
519 err = -ENOBUFS;
520 goto errout;
521 }
522
523 ifa = inet_alloc_ifa();
524 if (ifa == NULL) {
525 /*
526 * A potential indev allocation can be left alive, it stays
527 * assigned to its device and is destroy with it.
528 */
529 err = -ENOBUFS;
530 goto errout;
531 }
532
533 ipv4_devconf_setall(in_dev);
534 in_dev_hold(in_dev);
535
536 if (tb[IFA_ADDRESS] == NULL)
537 tb[IFA_ADDRESS] = tb[IFA_LOCAL];
538
539 ifa->ifa_prefixlen = ifm->ifa_prefixlen;
540 ifa->ifa_mask = inet_make_mask(ifm->ifa_prefixlen);
541 ifa->ifa_flags = ifm->ifa_flags;
542 ifa->ifa_scope = ifm->ifa_scope;
543 ifa->ifa_dev = in_dev;
544
545 ifa->ifa_local = nla_get_be32(tb[IFA_LOCAL]);
546 ifa->ifa_address = nla_get_be32(tb[IFA_ADDRESS]);
547
548 if (tb[IFA_BROADCAST])
549 ifa->ifa_broadcast = nla_get_be32(tb[IFA_BROADCAST]);
550
551 if (tb[IFA_ANYCAST])
552 ifa->ifa_anycast = nla_get_be32(tb[IFA_ANYCAST]);
553
554 if (tb[IFA_LABEL])
555 nla_strlcpy(ifa->ifa_label, tb[IFA_LABEL], IFNAMSIZ);
556 else
557 memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
558
559 return ifa;
560
561errout:
562 return ERR_PTR(err);
563}
564
565static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
566{
567 struct net *net = skb->sk->sk_net;
568 struct in_ifaddr *ifa;
569
570 ASSERT_RTNL();
571
572 if (net != &init_net)
573 return -EINVAL;
574
575 ifa = rtm_to_ifaddr(nlh);
576 if (IS_ERR(ifa))
577 return PTR_ERR(ifa);
578
579 return __inet_insert_ifa(ifa, nlh, NETLINK_CB(skb).pid);
580}
581
582/*
583 * Determine a default network mask, based on the IP address.
584 */
585
586static __inline__ int inet_abc_len(__be32 addr)
587{
588 int rc = -1; /* Something else, probably a multicast. */
589
590 if (ZERONET(addr))
591 rc = 0;
592 else {
593 __u32 haddr = ntohl(addr);
594
595 if (IN_CLASSA(haddr))
596 rc = 8;
597 else if (IN_CLASSB(haddr))
598 rc = 16;
599 else if (IN_CLASSC(haddr))
600 rc = 24;
601 }
602
603 return rc;
604}
605
606
607int devinet_ioctl(unsigned int cmd, void __user *arg)
608{
609 struct ifreq ifr;
610 struct sockaddr_in sin_orig;
611 struct sockaddr_in *sin = (struct sockaddr_in *)&ifr.ifr_addr;
612 struct in_device *in_dev;
613 struct in_ifaddr **ifap = NULL;
614 struct in_ifaddr *ifa = NULL;
615 struct net_device *dev;
616 char *colon;
617 int ret = -EFAULT;
618 int tryaddrmatch = 0;
619
620 /*
621 * Fetch the caller's info block into kernel space
622 */
623
624 if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))
625 goto out;
626 ifr.ifr_name[IFNAMSIZ - 1] = 0;
627
628 /* save original address for comparison */
629 memcpy(&sin_orig, sin, sizeof(*sin));
630
631 colon = strchr(ifr.ifr_name, ':');
632 if (colon)
633 *colon = 0;
634
635#ifdef CONFIG_KMOD
636 dev_load(&init_net, ifr.ifr_name);
637#endif
638
639 switch (cmd) {
640 case SIOCGIFADDR: /* Get interface address */
641 case SIOCGIFBRDADDR: /* Get the broadcast address */
642 case SIOCGIFDSTADDR: /* Get the destination address */
643 case SIOCGIFNETMASK: /* Get the netmask for the interface */
644 /* Note that these ioctls will not sleep,
645 so that we do not impose a lock.
646 One day we will be forced to put shlock here (I mean SMP)
647 */
648 tryaddrmatch = (sin_orig.sin_family == AF_INET);
649 memset(sin, 0, sizeof(*sin));
650 sin->sin_family = AF_INET;
651 break;
652
653 case SIOCSIFFLAGS:
654 ret = -EACCES;
655 if (!capable(CAP_NET_ADMIN))
656 goto out;
657 break;
658 case SIOCSIFADDR: /* Set interface address (and family) */
659 case SIOCSIFBRDADDR: /* Set the broadcast address */
660 case SIOCSIFDSTADDR: /* Set the destination address */
661 case SIOCSIFNETMASK: /* Set the netmask for the interface */
662 ret = -EACCES;
663 if (!capable(CAP_NET_ADMIN))
664 goto out;
665 ret = -EINVAL;
666 if (sin->sin_family != AF_INET)
667 goto out;
668 break;
669 default:
670 ret = -EINVAL;
671 goto out;
672 }
673
674 rtnl_lock();
675
676 ret = -ENODEV;
677 if ((dev = __dev_get_by_name(&init_net, ifr.ifr_name)) == NULL)
678 goto done;
679
680 if (colon)
681 *colon = ':';
682
683 if ((in_dev = __in_dev_get_rtnl(dev)) != NULL) {
684 if (tryaddrmatch) {
685 /* Matthias Andree */
686 /* compare label and address (4.4BSD style) */
687 /* note: we only do this for a limited set of ioctls
688 and only if the original address family was AF_INET.
689 This is checked above. */
690 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
691 ifap = &ifa->ifa_next) {
692 if (!strcmp(ifr.ifr_name, ifa->ifa_label) &&
693 sin_orig.sin_addr.s_addr ==
694 ifa->ifa_address) {
695 break; /* found */
696 }
697 }
698 }
699 /* we didn't get a match, maybe the application is
700 4.3BSD-style and passed in junk so we fall back to
701 comparing just the label */
702 if (!ifa) {
703 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
704 ifap = &ifa->ifa_next)
705 if (!strcmp(ifr.ifr_name, ifa->ifa_label))
706 break;
707 }
708 }
709
710 ret = -EADDRNOTAVAIL;
711 if (!ifa && cmd != SIOCSIFADDR && cmd != SIOCSIFFLAGS)
712 goto done;
713
714 switch (cmd) {
715 case SIOCGIFADDR: /* Get interface address */
716 sin->sin_addr.s_addr = ifa->ifa_local;
717 goto rarok;
718
719 case SIOCGIFBRDADDR: /* Get the broadcast address */
720 sin->sin_addr.s_addr = ifa->ifa_broadcast;
721 goto rarok;
722
723 case SIOCGIFDSTADDR: /* Get the destination address */
724 sin->sin_addr.s_addr = ifa->ifa_address;
725 goto rarok;
726
727 case SIOCGIFNETMASK: /* Get the netmask for the interface */
728 sin->sin_addr.s_addr = ifa->ifa_mask;
729 goto rarok;
730
731 case SIOCSIFFLAGS:
732 if (colon) {
733 ret = -EADDRNOTAVAIL;
734 if (!ifa)
735 break;
736 ret = 0;
737 if (!(ifr.ifr_flags & IFF_UP))
738 inet_del_ifa(in_dev, ifap, 1);
739 break;
740 }
741 ret = dev_change_flags(dev, ifr.ifr_flags);
742 break;
743
744 case SIOCSIFADDR: /* Set interface address (and family) */
745 ret = -EINVAL;
746 if (inet_abc_len(sin->sin_addr.s_addr) < 0)
747 break;
748
749 if (!ifa) {
750 ret = -ENOBUFS;
751 if ((ifa = inet_alloc_ifa()) == NULL)
752 break;
753 if (colon)
754 memcpy(ifa->ifa_label, ifr.ifr_name, IFNAMSIZ);
755 else
756 memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
757 } else {
758 ret = 0;
759 if (ifa->ifa_local == sin->sin_addr.s_addr)
760 break;
761 inet_del_ifa(in_dev, ifap, 0);
762 ifa->ifa_broadcast = 0;
763 ifa->ifa_anycast = 0;
764 }
765
766 ifa->ifa_address = ifa->ifa_local = sin->sin_addr.s_addr;
767
768 if (!(dev->flags & IFF_POINTOPOINT)) {
769 ifa->ifa_prefixlen = inet_abc_len(ifa->ifa_address);
770 ifa->ifa_mask = inet_make_mask(ifa->ifa_prefixlen);
771 if ((dev->flags & IFF_BROADCAST) &&
772 ifa->ifa_prefixlen < 31)
773 ifa->ifa_broadcast = ifa->ifa_address |
774 ~ifa->ifa_mask;
775 } else {
776 ifa->ifa_prefixlen = 32;
777 ifa->ifa_mask = inet_make_mask(32);
778 }
779 ret = inet_set_ifa(dev, ifa);
780 break;
781
782 case SIOCSIFBRDADDR: /* Set the broadcast address */
783 ret = 0;
784 if (ifa->ifa_broadcast != sin->sin_addr.s_addr) {
785 inet_del_ifa(in_dev, ifap, 0);
786 ifa->ifa_broadcast = sin->sin_addr.s_addr;
787 inet_insert_ifa(ifa);
788 }
789 break;
790
791 case SIOCSIFDSTADDR: /* Set the destination address */
792 ret = 0;
793 if (ifa->ifa_address == sin->sin_addr.s_addr)
794 break;
795 ret = -EINVAL;
796 if (inet_abc_len(sin->sin_addr.s_addr) < 0)
797 break;
798 ret = 0;
799 inet_del_ifa(in_dev, ifap, 0);
800 ifa->ifa_address = sin->sin_addr.s_addr;
801 inet_insert_ifa(ifa);
802 break;
803
804 case SIOCSIFNETMASK: /* Set the netmask for the interface */
805
806 /*
807 * The mask we set must be legal.
808 */
809 ret = -EINVAL;
810 if (bad_mask(sin->sin_addr.s_addr, 0))
811 break;
812 ret = 0;
813 if (ifa->ifa_mask != sin->sin_addr.s_addr) {
814 __be32 old_mask = ifa->ifa_mask;
815 inet_del_ifa(in_dev, ifap, 0);
816 ifa->ifa_mask = sin->sin_addr.s_addr;
817 ifa->ifa_prefixlen = inet_mask_len(ifa->ifa_mask);
818
819 /* See if current broadcast address matches
820 * with current netmask, then recalculate
821 * the broadcast address. Otherwise it's a
822 * funny address, so don't touch it since
823 * the user seems to know what (s)he's doing...
824 */
825 if ((dev->flags & IFF_BROADCAST) &&
826 (ifa->ifa_prefixlen < 31) &&
827 (ifa->ifa_broadcast ==
828 (ifa->ifa_local|~old_mask))) {
829 ifa->ifa_broadcast = (ifa->ifa_local |
830 ~sin->sin_addr.s_addr);
831 }
832 inet_insert_ifa(ifa);
833 }
834 break;
835 }
836done:
837 rtnl_unlock();
838out:
839 return ret;
840rarok:
841 rtnl_unlock();
842 ret = copy_to_user(arg, &ifr, sizeof(struct ifreq)) ? -EFAULT : 0;
843 goto out;
844}
845
846static int inet_gifconf(struct net_device *dev, char __user *buf, int len)
847{
848 struct in_device *in_dev = __in_dev_get_rtnl(dev);
849 struct in_ifaddr *ifa;
850 struct ifreq ifr;
851 int done = 0;
852
853 if (!in_dev || (ifa = in_dev->ifa_list) == NULL)
854 goto out;
855
856 for (; ifa; ifa = ifa->ifa_next) {
857 if (!buf) {
858 done += sizeof(ifr);
859 continue;
860 }
861 if (len < (int) sizeof(ifr))
862 break;
863 memset(&ifr, 0, sizeof(struct ifreq));
864 if (ifa->ifa_label)
865 strcpy(ifr.ifr_name, ifa->ifa_label);
866 else
867 strcpy(ifr.ifr_name, dev->name);
868
869 (*(struct sockaddr_in *)&ifr.ifr_addr).sin_family = AF_INET;
870 (*(struct sockaddr_in *)&ifr.ifr_addr).sin_addr.s_addr =
871 ifa->ifa_local;
872
873 if (copy_to_user(buf, &ifr, sizeof(struct ifreq))) {
874 done = -EFAULT;
875 break;
876 }
877 buf += sizeof(struct ifreq);
878 len -= sizeof(struct ifreq);
879 done += sizeof(struct ifreq);
880 }
881out:
882 return done;
883}
884
885__be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope)
886{
887 __be32 addr = 0;
888 struct in_device *in_dev;
889
890 rcu_read_lock();
891 in_dev = __in_dev_get_rcu(dev);
892 if (!in_dev)
893 goto no_in_dev;
894
895 for_primary_ifa(in_dev) {
896 if (ifa->ifa_scope > scope)
897 continue;
898 if (!dst || inet_ifa_match(dst, ifa)) {
899 addr = ifa->ifa_local;
900 break;
901 }
902 if (!addr)
903 addr = ifa->ifa_local;
904 } endfor_ifa(in_dev);
905no_in_dev:
906 rcu_read_unlock();
907
908 if (addr)
909 goto out;
910
911 /* Not loopback addresses on loopback should be preferred
912 in this case. It is importnat that lo is the first interface
913 in dev_base list.
914 */
915 read_lock(&dev_base_lock);
916 rcu_read_lock();
917 for_each_netdev(&init_net, dev) {
918 if ((in_dev = __in_dev_get_rcu(dev)) == NULL)
919 continue;
920
921 for_primary_ifa(in_dev) {
922 if (ifa->ifa_scope != RT_SCOPE_LINK &&
923 ifa->ifa_scope <= scope) {
924 addr = ifa->ifa_local;
925 goto out_unlock_both;
926 }
927 } endfor_ifa(in_dev);
928 }
929out_unlock_both:
930 read_unlock(&dev_base_lock);
931 rcu_read_unlock();
932out:
933 return addr;
934}
935
936static __be32 confirm_addr_indev(struct in_device *in_dev, __be32 dst,
937 __be32 local, int scope)
938{
939 int same = 0;
940 __be32 addr = 0;
941
942 for_ifa(in_dev) {
943 if (!addr &&
944 (local == ifa->ifa_local || !local) &&
945 ifa->ifa_scope <= scope) {
946 addr = ifa->ifa_local;
947 if (same)
948 break;
949 }
950 if (!same) {
951 same = (!local || inet_ifa_match(local, ifa)) &&
952 (!dst || inet_ifa_match(dst, ifa));
953 if (same && addr) {
954 if (local || !dst)
955 break;
956 /* Is the selected addr into dst subnet? */
957 if (inet_ifa_match(addr, ifa))
958 break;
959 /* No, then can we use new local src? */
960 if (ifa->ifa_scope <= scope) {
961 addr = ifa->ifa_local;
962 break;
963 }
964 /* search for large dst subnet for addr */
965 same = 0;
966 }
967 }
968 } endfor_ifa(in_dev);
969
970 return same? addr : 0;
971}
972
973/*
974 * Confirm that local IP address exists using wildcards:
975 * - dev: only on this interface, 0=any interface
976 * - dst: only in the same subnet as dst, 0=any dst
977 * - local: address, 0=autoselect the local address
978 * - scope: maximum allowed scope value for the local address
979 */
980__be32 inet_confirm_addr(const struct net_device *dev, __be32 dst, __be32 local, int scope)
981{
982 __be32 addr = 0;
983 struct in_device *in_dev;
984
985 if (dev) {
986 rcu_read_lock();
987 if ((in_dev = __in_dev_get_rcu(dev)))
988 addr = confirm_addr_indev(in_dev, dst, local, scope);
989 rcu_read_unlock();
990
991 return addr;
992 }
993
994 read_lock(&dev_base_lock);
995 rcu_read_lock();
996 for_each_netdev(&init_net, dev) {
997 if ((in_dev = __in_dev_get_rcu(dev))) {
998 addr = confirm_addr_indev(in_dev, dst, local, scope);
999 if (addr)
1000 break;
1001 }
1002 }
1003 rcu_read_unlock();
1004 read_unlock(&dev_base_lock);
1005
1006 return addr;
1007}
1008
1009/*
1010 * Device notifier
1011 */
1012
1013int register_inetaddr_notifier(struct notifier_block *nb)
1014{
1015 return blocking_notifier_chain_register(&inetaddr_chain, nb);
1016}
1017
1018int unregister_inetaddr_notifier(struct notifier_block *nb)
1019{
1020 return blocking_notifier_chain_unregister(&inetaddr_chain, nb);
1021}
1022
1023/* Rename ifa_labels for a device name change. Make some effort to preserve existing
1024 * alias numbering and to create unique labels if possible.
1025*/
1026static void inetdev_changename(struct net_device *dev, struct in_device *in_dev)
1027{
1028 struct in_ifaddr *ifa;
1029 int named = 0;
1030
1031 for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) {
1032 char old[IFNAMSIZ], *dot;
1033
1034 memcpy(old, ifa->ifa_label, IFNAMSIZ);
1035 memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
1036 if (named++ == 0)
1037 continue;
1038 dot = strchr(old, ':');
1039 if (dot == NULL) {
1040 sprintf(old, ":%d", named);
1041 dot = old;
1042 }
1043 if (strlen(dot) + strlen(dev->name) < IFNAMSIZ) {
1044 strcat(ifa->ifa_label, dot);
1045 } else {
1046 strcpy(ifa->ifa_label + (IFNAMSIZ - strlen(dot) - 1), dot);
1047 }
1048 }
1049}
1050
1051/* Called only under RTNL semaphore */
1052
1053static int inetdev_event(struct notifier_block *this, unsigned long event,
1054 void *ptr)
1055{
1056 struct net_device *dev = ptr;
1057 struct in_device *in_dev = __in_dev_get_rtnl(dev);
1058
1059 if (dev->nd_net != &init_net)
1060 return NOTIFY_DONE;
1061
1062 ASSERT_RTNL();
1063
1064 if (!in_dev) {
1065 if (event == NETDEV_REGISTER) {
1066 in_dev = inetdev_init(dev);
1067 if (!in_dev)
1068 return notifier_from_errno(-ENOMEM);
1069 if (dev->flags & IFF_LOOPBACK) {
1070 IN_DEV_CONF_SET(in_dev, NOXFRM, 1);
1071 IN_DEV_CONF_SET(in_dev, NOPOLICY, 1);
1072 }
1073 }
1074 goto out;
1075 }
1076
1077 switch (event) {
1078 case NETDEV_REGISTER:
1079 printk(KERN_DEBUG "inetdev_event: bug\n");
1080 dev->ip_ptr = NULL;
1081 break;
1082 case NETDEV_UP:
1083 if (dev->mtu < 68)
1084 break;
1085 if (dev->flags & IFF_LOOPBACK) {
1086 struct in_ifaddr *ifa;
1087 if ((ifa = inet_alloc_ifa()) != NULL) {
1088 ifa->ifa_local =
1089 ifa->ifa_address = htonl(INADDR_LOOPBACK);
1090 ifa->ifa_prefixlen = 8;
1091 ifa->ifa_mask = inet_make_mask(8);
1092 in_dev_hold(in_dev);
1093 ifa->ifa_dev = in_dev;
1094 ifa->ifa_scope = RT_SCOPE_HOST;
1095 memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
1096 inet_insert_ifa(ifa);
1097 }
1098 }
1099 ip_mc_up(in_dev);
1100 break;
1101 case NETDEV_DOWN:
1102 ip_mc_down(in_dev);
1103 break;
1104 case NETDEV_CHANGEMTU:
1105 if (dev->mtu >= 68)
1106 break;
1107 /* MTU falled under 68, disable IP */
1108 case NETDEV_UNREGISTER:
1109 inetdev_destroy(in_dev);
1110 break;
1111 case NETDEV_CHANGENAME:
1112 /* Do not notify about label change, this event is
1113 * not interesting to applications using netlink.
1114 */
1115 inetdev_changename(dev, in_dev);
1116
1117#ifdef CONFIG_SYSCTL
1118 devinet_sysctl_unregister(&in_dev->cnf);
1119 neigh_sysctl_unregister(in_dev->arp_parms);
1120 neigh_sysctl_register(dev, in_dev->arp_parms, NET_IPV4,
1121 NET_IPV4_NEIGH, "ipv4", NULL, NULL);
1122 devinet_sysctl_register(in_dev, &in_dev->cnf);
1123#endif
1124 break;
1125 }
1126out:
1127 return NOTIFY_DONE;
1128}
1129
1130static struct notifier_block ip_netdev_notifier = {
1131 .notifier_call =inetdev_event,
1132};
1133
1134static inline size_t inet_nlmsg_size(void)
1135{
1136 return NLMSG_ALIGN(sizeof(struct ifaddrmsg))
1137 + nla_total_size(4) /* IFA_ADDRESS */
1138 + nla_total_size(4) /* IFA_LOCAL */
1139 + nla_total_size(4) /* IFA_BROADCAST */
1140 + nla_total_size(4) /* IFA_ANYCAST */
1141 + nla_total_size(IFNAMSIZ); /* IFA_LABEL */
1142}
1143
1144static int inet_fill_ifaddr(struct sk_buff *skb, struct in_ifaddr *ifa,
1145 u32 pid, u32 seq, int event, unsigned int flags)
1146{
1147 struct ifaddrmsg *ifm;
1148 struct nlmsghdr *nlh;
1149
1150 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*ifm), flags);
1151 if (nlh == NULL)
1152 return -EMSGSIZE;
1153
1154 ifm = nlmsg_data(nlh);
1155 ifm->ifa_family = AF_INET;
1156 ifm->ifa_prefixlen = ifa->ifa_prefixlen;
1157 ifm->ifa_flags = ifa->ifa_flags|IFA_F_PERMANENT;
1158 ifm->ifa_scope = ifa->ifa_scope;
1159 ifm->ifa_index = ifa->ifa_dev->dev->ifindex;
1160
1161 if (ifa->ifa_address)
1162 NLA_PUT_BE32(skb, IFA_ADDRESS, ifa->ifa_address);
1163
1164 if (ifa->ifa_local)
1165 NLA_PUT_BE32(skb, IFA_LOCAL, ifa->ifa_local);
1166
1167 if (ifa->ifa_broadcast)
1168 NLA_PUT_BE32(skb, IFA_BROADCAST, ifa->ifa_broadcast);
1169
1170 if (ifa->ifa_anycast)
1171 NLA_PUT_BE32(skb, IFA_ANYCAST, ifa->ifa_anycast);
1172
1173 if (ifa->ifa_label[0])
1174 NLA_PUT_STRING(skb, IFA_LABEL, ifa->ifa_label);
1175
1176 return nlmsg_end(skb, nlh);
1177
1178nla_put_failure:
1179 nlmsg_cancel(skb, nlh);
1180 return -EMSGSIZE;
1181}
1182
1183static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
1184{
1185 struct net *net = skb->sk->sk_net;
1186 int idx, ip_idx;
1187 struct net_device *dev;
1188 struct in_device *in_dev;
1189 struct in_ifaddr *ifa;
1190 int s_ip_idx, s_idx = cb->args[0];
1191
1192 if (net != &init_net)
1193 return 0;
1194
1195 s_ip_idx = ip_idx = cb->args[1];
1196 idx = 0;
1197 for_each_netdev(&init_net, dev) {
1198 if (idx < s_idx)
1199 goto cont;
1200 if (idx > s_idx)
1201 s_ip_idx = 0;
1202 if ((in_dev = __in_dev_get_rtnl(dev)) == NULL)
1203 goto cont;
1204
1205 for (ifa = in_dev->ifa_list, ip_idx = 0; ifa;
1206 ifa = ifa->ifa_next, ip_idx++) {
1207 if (ip_idx < s_ip_idx)
1208 continue;
1209 if (inet_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid,
1210 cb->nlh->nlmsg_seq,
1211 RTM_NEWADDR, NLM_F_MULTI) <= 0)
1212 goto done;
1213 }
1214cont:
1215 idx++;
1216 }
1217
1218done:
1219 cb->args[0] = idx;
1220 cb->args[1] = ip_idx;
1221
1222 return skb->len;
1223}
1224
1225static void rtmsg_ifa(int event, struct in_ifaddr* ifa, struct nlmsghdr *nlh,
1226 u32 pid)
1227{
1228 struct sk_buff *skb;
1229 u32 seq = nlh ? nlh->nlmsg_seq : 0;
1230 int err = -ENOBUFS;
1231
1232 skb = nlmsg_new(inet_nlmsg_size(), GFP_KERNEL);
1233 if (skb == NULL)
1234 goto errout;
1235
1236 err = inet_fill_ifaddr(skb, ifa, pid, seq, event, 0);
1237 if (err < 0) {
1238 /* -EMSGSIZE implies BUG in inet_nlmsg_size() */
1239 WARN_ON(err == -EMSGSIZE);
1240 kfree_skb(skb);
1241 goto errout;
1242 }
1243 err = rtnl_notify(skb, &init_net, pid, RTNLGRP_IPV4_IFADDR, nlh, GFP_KERNEL);
1244errout:
1245 if (err < 0)
1246 rtnl_set_sk_err(&init_net, RTNLGRP_IPV4_IFADDR, err);
1247}
1248
1249#ifdef CONFIG_SYSCTL
1250
1251static void devinet_copy_dflt_conf(int i)
1252{
1253 struct net_device *dev;
1254
1255 read_lock(&dev_base_lock);
1256 for_each_netdev(&init_net, dev) {
1257 struct in_device *in_dev;
1258 rcu_read_lock();
1259 in_dev = __in_dev_get_rcu(dev);
1260 if (in_dev && !test_bit(i, in_dev->cnf.state))
1261 in_dev->cnf.data[i] = ipv4_devconf_dflt.data[i];
1262 rcu_read_unlock();
1263 }
1264 read_unlock(&dev_base_lock);
1265}
1266
1267static int devinet_conf_proc(ctl_table *ctl, int write,
1268 struct file* filp, void __user *buffer,
1269 size_t *lenp, loff_t *ppos)
1270{
1271 int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
1272
1273 if (write) {
1274 struct ipv4_devconf *cnf = ctl->extra1;
1275 int i = (int *)ctl->data - cnf->data;
1276
1277 set_bit(i, cnf->state);
1278
1279 if (cnf == &ipv4_devconf_dflt)
1280 devinet_copy_dflt_conf(i);
1281 }
1282
1283 return ret;
1284}
1285
1286static int devinet_conf_sysctl(ctl_table *table, int __user *name, int nlen,
1287 void __user *oldval, size_t __user *oldlenp,
1288 void __user *newval, size_t newlen)
1289{
1290 struct ipv4_devconf *cnf;
1291 int *valp = table->data;
1292 int new;
1293 int i;
1294
1295 if (!newval || !newlen)
1296 return 0;
1297
1298 if (newlen != sizeof(int))
1299 return -EINVAL;
1300
1301 if (get_user(new, (int __user *)newval))
1302 return -EFAULT;
1303
1304 if (new == *valp)
1305 return 0;
1306
1307 if (oldval && oldlenp) {
1308 size_t len;
1309
1310 if (get_user(len, oldlenp))
1311 return -EFAULT;
1312
1313 if (len) {
1314 if (len > table->maxlen)
1315 len = table->maxlen;
1316 if (copy_to_user(oldval, valp, len))
1317 return -EFAULT;
1318 if (put_user(len, oldlenp))
1319 return -EFAULT;
1320 }
1321 }
1322
1323 *valp = new;
1324
1325 cnf = table->extra1;
1326 i = (int *)table->data - cnf->data;
1327
1328 set_bit(i, cnf->state);
1329
1330 if (cnf == &ipv4_devconf_dflt)
1331 devinet_copy_dflt_conf(i);
1332
1333 return 1;
1334}
1335
1336void inet_forward_change(void)
1337{
1338 struct net_device *dev;
1339 int on = IPV4_DEVCONF_ALL(FORWARDING);
1340
1341 IPV4_DEVCONF_ALL(ACCEPT_REDIRECTS) = !on;
1342 IPV4_DEVCONF_DFLT(FORWARDING) = on;
1343
1344 read_lock(&dev_base_lock);
1345 for_each_netdev(&init_net, dev) {
1346 struct in_device *in_dev;
1347 rcu_read_lock();
1348 in_dev = __in_dev_get_rcu(dev);
1349 if (in_dev)
1350 IN_DEV_CONF_SET(in_dev, FORWARDING, on);
1351 rcu_read_unlock();
1352 }
1353 read_unlock(&dev_base_lock);
1354
1355 rt_cache_flush(0);
1356}
1357
1358static int devinet_sysctl_forward(ctl_table *ctl, int write,
1359 struct file* filp, void __user *buffer,
1360 size_t *lenp, loff_t *ppos)
1361{
1362 int *valp = ctl->data;
1363 int val = *valp;
1364 int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
1365
1366 if (write && *valp != val) {
1367 if (valp == &IPV4_DEVCONF_ALL(FORWARDING))
1368 inet_forward_change();
1369 else if (valp != &IPV4_DEVCONF_DFLT(FORWARDING))
1370 rt_cache_flush(0);
1371 }
1372
1373 return ret;
1374}
1375
1376int ipv4_doint_and_flush(ctl_table *ctl, int write,
1377 struct file* filp, void __user *buffer,
1378 size_t *lenp, loff_t *ppos)
1379{
1380 int *valp = ctl->data;
1381 int val = *valp;
1382 int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
1383
1384 if (write && *valp != val)
1385 rt_cache_flush(0);
1386
1387 return ret;
1388}
1389
1390int ipv4_doint_and_flush_strategy(ctl_table *table, int __user *name, int nlen,
1391 void __user *oldval, size_t __user *oldlenp,
1392 void __user *newval, size_t newlen)
1393{
1394 int ret = devinet_conf_sysctl(table, name, nlen, oldval, oldlenp,
1395 newval, newlen);
1396
1397 if (ret == 1)
1398 rt_cache_flush(0);
1399
1400 return ret;
1401}
1402
1403
1404#define DEVINET_SYSCTL_ENTRY(attr, name, mval, proc, sysctl) \
1405 { \
1406 .ctl_name = NET_IPV4_CONF_ ## attr, \
1407 .procname = name, \
1408 .data = ipv4_devconf.data + \
1409 NET_IPV4_CONF_ ## attr - 1, \
1410 .maxlen = sizeof(int), \
1411 .mode = mval, \
1412 .proc_handler = proc, \
1413 .strategy = sysctl, \
1414 .extra1 = &ipv4_devconf, \
1415 }
1416
1417#define DEVINET_SYSCTL_RW_ENTRY(attr, name) \
1418 DEVINET_SYSCTL_ENTRY(attr, name, 0644, devinet_conf_proc, \
1419 devinet_conf_sysctl)
1420
1421#define DEVINET_SYSCTL_RO_ENTRY(attr, name) \
1422 DEVINET_SYSCTL_ENTRY(attr, name, 0444, devinet_conf_proc, \
1423 devinet_conf_sysctl)
1424
1425#define DEVINET_SYSCTL_COMPLEX_ENTRY(attr, name, proc, sysctl) \
1426 DEVINET_SYSCTL_ENTRY(attr, name, 0644, proc, sysctl)
1427
1428#define DEVINET_SYSCTL_FLUSHING_ENTRY(attr, name) \
1429 DEVINET_SYSCTL_COMPLEX_ENTRY(attr, name, ipv4_doint_and_flush, \
1430 ipv4_doint_and_flush_strategy)
1431
1432static struct devinet_sysctl_table {
1433 struct ctl_table_header *sysctl_header;
1434 ctl_table devinet_vars[__NET_IPV4_CONF_MAX];
1435 ctl_table devinet_dev[2];
1436 ctl_table devinet_conf_dir[2];
1437 ctl_table devinet_proto_dir[2];
1438 ctl_table devinet_root_dir[2];
1439} devinet_sysctl = {
1440 .devinet_vars = {
1441 DEVINET_SYSCTL_COMPLEX_ENTRY(FORWARDING, "forwarding",
1442 devinet_sysctl_forward,
1443 devinet_conf_sysctl),
1444 DEVINET_SYSCTL_RO_ENTRY(MC_FORWARDING, "mc_forwarding"),
1445
1446 DEVINET_SYSCTL_RW_ENTRY(ACCEPT_REDIRECTS, "accept_redirects"),
1447 DEVINET_SYSCTL_RW_ENTRY(SECURE_REDIRECTS, "secure_redirects"),
1448 DEVINET_SYSCTL_RW_ENTRY(SHARED_MEDIA, "shared_media"),
1449 DEVINET_SYSCTL_RW_ENTRY(RP_FILTER, "rp_filter"),
1450 DEVINET_SYSCTL_RW_ENTRY(SEND_REDIRECTS, "send_redirects"),
1451 DEVINET_SYSCTL_RW_ENTRY(ACCEPT_SOURCE_ROUTE,
1452 "accept_source_route"),
1453 DEVINET_SYSCTL_RW_ENTRY(PROXY_ARP, "proxy_arp"),
1454 DEVINET_SYSCTL_RW_ENTRY(MEDIUM_ID, "medium_id"),
1455 DEVINET_SYSCTL_RW_ENTRY(BOOTP_RELAY, "bootp_relay"),
1456 DEVINET_SYSCTL_RW_ENTRY(LOG_MARTIANS, "log_martians"),
1457 DEVINET_SYSCTL_RW_ENTRY(TAG, "tag"),
1458 DEVINET_SYSCTL_RW_ENTRY(ARPFILTER, "arp_filter"),
1459 DEVINET_SYSCTL_RW_ENTRY(ARP_ANNOUNCE, "arp_announce"),
1460 DEVINET_SYSCTL_RW_ENTRY(ARP_IGNORE, "arp_ignore"),
1461 DEVINET_SYSCTL_RW_ENTRY(ARP_ACCEPT, "arp_accept"),
1462
1463 DEVINET_SYSCTL_FLUSHING_ENTRY(NOXFRM, "disable_xfrm"),
1464 DEVINET_SYSCTL_FLUSHING_ENTRY(NOPOLICY, "disable_policy"),
1465 DEVINET_SYSCTL_FLUSHING_ENTRY(FORCE_IGMP_VERSION,
1466 "force_igmp_version"),
1467 DEVINET_SYSCTL_FLUSHING_ENTRY(PROMOTE_SECONDARIES,
1468 "promote_secondaries"),
1469 },
1470 .devinet_dev = {
1471 {
1472 .ctl_name = NET_PROTO_CONF_ALL,
1473 .procname = "all",
1474 .mode = 0555,
1475 .child = devinet_sysctl.devinet_vars,
1476 },
1477 },
1478 .devinet_conf_dir = {
1479 {
1480 .ctl_name = NET_IPV4_CONF,
1481 .procname = "conf",
1482 .mode = 0555,
1483 .child = devinet_sysctl.devinet_dev,
1484 },
1485 },
1486 .devinet_proto_dir = {
1487 {
1488 .ctl_name = NET_IPV4,
1489 .procname = "ipv4",
1490 .mode = 0555,
1491 .child = devinet_sysctl.devinet_conf_dir,
1492 },
1493 },
1494 .devinet_root_dir = {
1495 {
1496 .ctl_name = CTL_NET,
1497 .procname = "net",
1498 .mode = 0555,
1499 .child = devinet_sysctl.devinet_proto_dir,
1500 },
1501 },
1502};
1503
1504static void devinet_sysctl_register(struct in_device *in_dev,
1505 struct ipv4_devconf *p)
1506{
1507 int i;
1508 struct net_device *dev = in_dev ? in_dev->dev : NULL;
1509 struct devinet_sysctl_table *t;
1510 char *dev_name = NULL;
1511
1512 t = kmemdup(&devinet_sysctl, sizeof(*t), GFP_KERNEL);
1513 if (!t)
1514 goto out;
1515
1516 for (i = 0; i < ARRAY_SIZE(t->devinet_vars) - 1; i++) {
1517 t->devinet_vars[i].data += (char *)p - (char *)&ipv4_devconf;
1518 t->devinet_vars[i].extra1 = p;
1519 }
1520
1521 if (dev) {
1522 dev_name = dev->name;
1523 t->devinet_dev[0].ctl_name = dev->ifindex;
1524 } else {
1525 dev_name = "default";
1526 t->devinet_dev[0].ctl_name = NET_PROTO_CONF_DEFAULT;
1527 }
1528
1529 /*
1530 * Make a copy of dev_name, because '.procname' is regarded as const
1531 * by sysctl and we wouldn't want anyone to change it under our feet
1532 * (see SIOCSIFNAME).
1533 */
1534 dev_name = kstrdup(dev_name, GFP_KERNEL);
1535 if (!dev_name)
1536 goto free;
1537
1538 t->devinet_dev[0].procname = dev_name;
1539 t->devinet_dev[0].child = t->devinet_vars;
1540 t->devinet_conf_dir[0].child = t->devinet_dev;
1541 t->devinet_proto_dir[0].child = t->devinet_conf_dir;
1542 t->devinet_root_dir[0].child = t->devinet_proto_dir;
1543
1544 t->sysctl_header = register_sysctl_table(t->devinet_root_dir);
1545 if (!t->sysctl_header)
1546 goto free_procname;
1547
1548 p->sysctl = t;
1549 return;
1550
1551free_procname:
1552 kfree(dev_name);
1553free:
1554 kfree(t);
1555out:
1556 return;
1557}
1558
1559static void devinet_sysctl_unregister(struct ipv4_devconf *p)
1560{
1561 if (p->sysctl) {
1562 struct devinet_sysctl_table *t = p->sysctl;
1563 p->sysctl = NULL;
1564 unregister_sysctl_table(t->sysctl_header);
1565 kfree(t->devinet_dev[0].procname);
1566 kfree(t);
1567 }
1568}
1569#endif
1570
1571void __init devinet_init(void)
1572{
1573 register_gifconf(PF_INET, inet_gifconf);
1574 register_netdevice_notifier(&ip_netdev_notifier);
1575
1576 rtnl_register(PF_INET, RTM_NEWADDR, inet_rtm_newaddr, NULL);
1577 rtnl_register(PF_INET, RTM_DELADDR, inet_rtm_deladdr, NULL);
1578 rtnl_register(PF_INET, RTM_GETADDR, NULL, inet_dump_ifaddr);
1579#ifdef CONFIG_SYSCTL
1580 devinet_sysctl.sysctl_header =
1581 register_sysctl_table(devinet_sysctl.devinet_root_dir);
1582 devinet_sysctl_register(NULL, &ipv4_devconf_dflt);
1583#endif
1584}
1585
1586EXPORT_SYMBOL(in_dev_finish_destroy);
1587EXPORT_SYMBOL(inet_select_addr);
1588EXPORT_SYMBOL(inetdev_by_index);
1589EXPORT_SYMBOL(register_inetaddr_notifier);
1590EXPORT_SYMBOL(unregister_inetaddr_notifier);