Branch data Line data Source code
1 : : /*
2 : : * NET3 IP device support routines.
3 : : *
4 : : * This program is free software; you can redistribute it and/or
5 : : * modify it under the terms of the GNU General Public License
6 : : * as published by the Free Software Foundation; either version
7 : : * 2 of the License, or (at your option) any later version.
8 : : *
9 : : * Derived from the IP parts of dev.c 1.0.19
10 : : * Authors: Ross Biro
11 : : * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
12 : : * Mark Evans, <evansmp@uhura.aston.ac.uk>
13 : : *
14 : : * Additional Authors:
15 : : * Alan Cox, <gw4pts@gw4pts.ampr.org>
16 : : * Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
17 : : *
18 : : * Changes:
19 : : * Alexey Kuznetsov: pa_* fields are replaced with ifaddr
20 : : * lists.
21 : : * Cyrus Durgin: updated for kmod
22 : : * Matthias Andree: in devinet_ioctl, compare label and
23 : : * address (4.4BSD alias style support),
24 : : * fall back to comparing just the label
25 : : * if no match found.
26 : : */
27 : :
28 : :
29 : : #include <asm/uaccess.h>
30 : : #include <linux/bitops.h>
31 : : #include <linux/capability.h>
32 : : #include <linux/module.h>
33 : : #include <linux/types.h>
34 : : #include <linux/kernel.h>
35 : : #include <linux/string.h>
36 : : #include <linux/mm.h>
37 : : #include <linux/socket.h>
38 : : #include <linux/sockios.h>
39 : : #include <linux/in.h>
40 : : #include <linux/errno.h>
41 : : #include <linux/interrupt.h>
42 : : #include <linux/if_addr.h>
43 : : #include <linux/if_ether.h>
44 : : #include <linux/inet.h>
45 : : #include <linux/netdevice.h>
46 : : #include <linux/etherdevice.h>
47 : : #include <linux/skbuff.h>
48 : : #include <linux/init.h>
49 : : #include <linux/notifier.h>
50 : : #include <linux/inetdevice.h>
51 : : #include <linux/igmp.h>
52 : : #include <linux/slab.h>
53 : : #include <linux/hash.h>
54 : : #ifdef CONFIG_SYSCTL
55 : : #include <linux/sysctl.h>
56 : : #endif
57 : : #include <linux/kmod.h>
58 : : #include <linux/netconf.h>
59 : :
60 : : #include <net/arp.h>
61 : : #include <net/ip.h>
62 : : #include <net/tcp.h>
63 : : #include <net/route.h>
64 : : #include <net/ip_fib.h>
65 : : #include <net/rtnetlink.h>
66 : : #include <net/net_namespace.h>
67 : : #include <net/addrconf.h>
68 : :
69 : : #include "fib_lookup.h"
70 : :
71 : : static struct ipv4_devconf ipv4_devconf = {
72 : : .data = {
73 : : [IPV4_DEVCONF_ACCEPT_REDIRECTS - 1] = 1,
74 : : [IPV4_DEVCONF_SEND_REDIRECTS - 1] = 1,
75 : : [IPV4_DEVCONF_SECURE_REDIRECTS - 1] = 1,
76 : : [IPV4_DEVCONF_SHARED_MEDIA - 1] = 1,
77 : : [IPV4_DEVCONF_IGMPV2_UNSOLICITED_REPORT_INTERVAL - 1] = 10000 /*ms*/,
78 : : [IPV4_DEVCONF_IGMPV3_UNSOLICITED_REPORT_INTERVAL - 1] = 1000 /*ms*/,
79 : : },
80 : : };
81 : :
82 : : static struct ipv4_devconf ipv4_devconf_dflt = {
83 : : .data = {
84 : : [IPV4_DEVCONF_ACCEPT_REDIRECTS - 1] = 1,
85 : : [IPV4_DEVCONF_SEND_REDIRECTS - 1] = 1,
86 : : [IPV4_DEVCONF_SECURE_REDIRECTS - 1] = 1,
87 : : [IPV4_DEVCONF_SHARED_MEDIA - 1] = 1,
88 : : [IPV4_DEVCONF_ACCEPT_SOURCE_ROUTE - 1] = 1,
89 : : [IPV4_DEVCONF_IGMPV2_UNSOLICITED_REPORT_INTERVAL - 1] = 10000 /*ms*/,
90 : : [IPV4_DEVCONF_IGMPV3_UNSOLICITED_REPORT_INTERVAL - 1] = 1000 /*ms*/,
91 : : },
92 : : };
93 : :
94 : : #define IPV4_DEVCONF_DFLT(net, attr) \
95 : : IPV4_DEVCONF((*net->ipv4.devconf_dflt), attr)
96 : :
97 : : static const struct nla_policy ifa_ipv4_policy[IFA_MAX+1] = {
98 : : [IFA_LOCAL] = { .type = NLA_U32 },
99 : : [IFA_ADDRESS] = { .type = NLA_U32 },
100 : : [IFA_BROADCAST] = { .type = NLA_U32 },
101 : : [IFA_LABEL] = { .type = NLA_STRING, .len = IFNAMSIZ - 1 },
102 : : [IFA_CACHEINFO] = { .len = sizeof(struct ifa_cacheinfo) },
103 : : [IFA_FLAGS] = { .type = NLA_U32 },
104 : : };
105 : :
106 : : #define IN4_ADDR_HSIZE_SHIFT 8
107 : : #define IN4_ADDR_HSIZE (1U << IN4_ADDR_HSIZE_SHIFT)
108 : :
109 : : static struct hlist_head inet_addr_lst[IN4_ADDR_HSIZE];
110 : : static DEFINE_SPINLOCK(inet_addr_hash_lock);
111 : :
112 : : static u32 inet_addr_hash(struct net *net, __be32 addr)
113 : : {
114 : : u32 val = (__force u32) addr ^ net_hash_mix(net);
115 : :
116 : : return hash_32(val, IN4_ADDR_HSIZE_SHIFT);
117 : : }
118 : :
119 : 0 : static void inet_hash_insert(struct net *net, struct in_ifaddr *ifa)
120 : : {
121 : 0 : u32 hash = inet_addr_hash(net, ifa->ifa_local);
122 : :
123 : : spin_lock(&inet_addr_hash_lock);
124 : 0 : hlist_add_head_rcu(&ifa->hash, &inet_addr_lst[hash]);
125 : : spin_unlock(&inet_addr_hash_lock);
126 : 0 : }
127 : :
128 : 0 : static void inet_hash_remove(struct in_ifaddr *ifa)
129 : : {
130 : : spin_lock(&inet_addr_hash_lock);
131 : : hlist_del_init_rcu(&ifa->hash);
132 : : spin_unlock(&inet_addr_hash_lock);
133 : 0 : }
134 : :
135 : : /**
136 : : * __ip_dev_find - find the first device with a given source address.
137 : : * @net: the net namespace
138 : : * @addr: the source address
139 : : * @devref: if true, take a reference on the found device
140 : : *
141 : : * If a caller uses devref=false, it should be protected by RCU, or RTNL
142 : : */
143 : 0 : struct net_device *__ip_dev_find(struct net *net, __be32 addr, bool devref)
144 : : {
145 : : u32 hash = inet_addr_hash(net, addr);
146 : : struct net_device *result = NULL;
147 : : struct in_ifaddr *ifa;
148 : :
149 : : rcu_read_lock();
150 [ + - ][ # # ]: 145 : hlist_for_each_entry_rcu(ifa, &inet_addr_lst[hash], hash) {
[ + - ]
151 [ + - ]: 145 : if (ifa->ifa_local == addr) {
152 : 145 : struct net_device *dev = ifa->ifa_dev->dev;
153 : :
154 : : if (!net_eq(dev_net(dev), net))
155 : : continue;
156 : : result = dev;
157 : 145 : break;
158 : : }
159 : : }
160 [ - - ]: 145 : if (!result) {
161 : 0 : struct flowi4 fl4 = { .daddr = addr };
162 : 0 : struct fib_result res = { 0 };
163 : : struct fib_table *local;
164 : :
165 : : /* Fallback to FIB local table so that communication
166 : : * over loopback subnets work.
167 : : */
168 : : local = fib_get_table(net, RT_TABLE_LOCAL);
169 [ # # # # ]: 0 : if (local &&
170 [ # # ]: 0 : !fib_table_lookup(local, &fl4, &res, FIB_LOOKUP_NOREF) &&
171 : 0 : res.type == RTN_LOCAL)
172 : 0 : result = FIB_RES_DEV(res);
173 : : }
174 [ # # ]: 0 : if (result && devref)
175 : : dev_hold(result);
176 : : rcu_read_unlock();
177 : 145 : return result;
178 : : }
179 : : EXPORT_SYMBOL(__ip_dev_find);
180 : :
181 : : static void rtmsg_ifa(int event, struct in_ifaddr *, struct nlmsghdr *, u32);
182 : :
183 : : static BLOCKING_NOTIFIER_HEAD(inetaddr_chain);
184 : : static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
185 : : int destroy);
186 : : #ifdef CONFIG_SYSCTL
187 : : static void devinet_sysctl_register(struct in_device *idev);
188 : : static void devinet_sysctl_unregister(struct in_device *idev);
189 : : #else
190 : : static void devinet_sysctl_register(struct in_device *idev)
191 : : {
192 : : }
193 : : static void devinet_sysctl_unregister(struct in_device *idev)
194 : : {
195 : : }
196 : : #endif
197 : :
198 : : /* Locks all the inet devices. */
199 : :
200 : : static struct in_ifaddr *inet_alloc_ifa(void)
201 : : {
202 : : return kzalloc(sizeof(struct in_ifaddr), GFP_KERNEL);
203 : : }
204 : :
205 : 0 : static void inet_rcu_free_ifa(struct rcu_head *head)
206 : : {
207 : 0 : struct in_ifaddr *ifa = container_of(head, struct in_ifaddr, rcu_head);
208 [ # # ]: 0 : if (ifa->ifa_dev)
209 : : in_dev_put(ifa->ifa_dev);
210 : 0 : kfree(ifa);
211 : 0 : }
212 : :
213 : : static void inet_free_ifa(struct in_ifaddr *ifa)
214 : : {
215 : 0 : call_rcu(&ifa->rcu_head, inet_rcu_free_ifa);
216 : : }
217 : :
218 : 0 : void in_dev_finish_destroy(struct in_device *idev)
219 : : {
220 : 0 : struct net_device *dev = idev->dev;
221 : :
222 [ # # ]: 0 : WARN_ON(idev->ifa_list);
223 [ # # ]: 0 : WARN_ON(idev->mc_list);
224 : 0 : kfree(rcu_dereference_protected(idev->mc_hash, 1));
225 : : #ifdef NET_REFCNT_DEBUG
226 : : pr_debug("%s: %p=%s\n", __func__, idev, dev ? dev->name : "NIL");
227 : : #endif
228 : : dev_put(dev);
229 [ # # ]: 0 : if (!idev->dead)
230 : 0 : pr_err("Freeing alive in_device %p\n", idev);
231 : : else
232 : 0 : kfree(idev);
233 : 0 : }
234 : : EXPORT_SYMBOL(in_dev_finish_destroy);
235 : :
236 : 0 : static struct in_device *inetdev_init(struct net_device *dev)
237 : : {
238 : : struct in_device *in_dev;
239 : :
240 [ # # ]: 0 : ASSERT_RTNL();
241 : :
242 : : in_dev = kzalloc(sizeof(*in_dev), GFP_KERNEL);
243 [ # # ]: 0 : if (!in_dev)
244 : : goto out;
245 : 0 : memcpy(&in_dev->cnf, dev_net(dev)->ipv4.devconf_dflt,
246 : : sizeof(in_dev->cnf));
247 : 0 : in_dev->cnf.sysctl = NULL;
248 : 0 : in_dev->dev = dev;
249 : 0 : in_dev->arp_parms = neigh_parms_alloc(dev, &arp_tbl);
250 [ # # ]: 0 : if (!in_dev->arp_parms)
251 : : goto out_kfree;
252 [ # # ]: 0 : if (IPV4_DEVCONF(in_dev->cnf, FORWARDING))
253 : 0 : dev_disable_lro(dev);
254 : : /* Reference in_dev->dev */
255 : : dev_hold(dev);
256 : : /* Account for reference dev->ip_ptr (below) */
257 : 0 : in_dev_hold(in_dev);
258 : :
259 : 0 : devinet_sysctl_register(in_dev);
260 : 0 : ip_mc_init_dev(in_dev);
261 [ # # ]: 0 : if (dev->flags & IFF_UP)
262 : 0 : ip_mc_up(in_dev);
263 : :
264 : : /* we can receive as soon as ip_ptr is set -- do this last */
265 : 0 : rcu_assign_pointer(dev->ip_ptr, in_dev);
266 : : out:
267 : 0 : return in_dev;
268 : : out_kfree:
269 : 0 : kfree(in_dev);
270 : : in_dev = NULL;
271 : 0 : goto out;
272 : : }
273 : :
274 : 0 : static void in_dev_rcu_put(struct rcu_head *head)
275 : : {
276 : 0 : struct in_device *idev = container_of(head, struct in_device, rcu_head);
277 : : in_dev_put(idev);
278 : 0 : }
279 : :
280 : 0 : static void inetdev_destroy(struct in_device *in_dev)
281 : : {
282 : : struct in_ifaddr *ifa;
283 : : struct net_device *dev;
284 : :
285 [ # # ]: 0 : ASSERT_RTNL();
286 : :
287 : 0 : dev = in_dev->dev;
288 : :
289 : 0 : in_dev->dead = 1;
290 : :
291 : 0 : ip_mc_destroy_dev(in_dev);
292 : :
293 [ # # ]: 0 : while ((ifa = in_dev->ifa_list) != NULL) {
294 : 0 : inet_del_ifa(in_dev, &in_dev->ifa_list, 0);
295 : : inet_free_ifa(ifa);
296 : : }
297 : :
298 : 0 : RCU_INIT_POINTER(dev->ip_ptr, NULL);
299 : :
300 : : devinet_sysctl_unregister(in_dev);
301 : 0 : neigh_parms_release(&arp_tbl, in_dev->arp_parms);
302 : 0 : arp_ifdown(dev);
303 : :
304 : 0 : call_rcu(&in_dev->rcu_head, in_dev_rcu_put);
305 : 0 : }
306 : :
307 : 0 : int inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b)
308 : : {
309 : : rcu_read_lock();
310 [ # # ][ # # ]: 0 : for_primary_ifa(in_dev) {
311 [ # # ]: 0 : if (inet_ifa_match(a, ifa)) {
312 [ # # ][ # # ]: 0 : if (!b || inet_ifa_match(b, ifa)) {
313 : : rcu_read_unlock();
314 : 0 : return 1;
315 : : }
316 : : }
317 : : } endfor_ifa(in_dev);
318 : : rcu_read_unlock();
319 : 0 : return 0;
320 : : }
321 : :
322 : 0 : static void __inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
323 : : int destroy, struct nlmsghdr *nlh, u32 portid)
324 : : {
325 : : struct in_ifaddr *promote = NULL;
326 : 0 : struct in_ifaddr *ifa, *ifa1 = *ifap;
327 : 0 : struct in_ifaddr *last_prim = in_dev->ifa_list;
328 : : struct in_ifaddr *prev_prom = NULL;
329 [ # # ][ # # ]: 0 : int do_promote = IN_DEV_PROMOTE_SECONDARIES(in_dev);
330 : :
331 [ # # ]: 0 : ASSERT_RTNL();
332 : :
333 : : /* 1. Deleting primary ifaddr forces deletion all secondaries
334 : : * unless alias promotion is set
335 : : **/
336 : :
337 [ # # ]: 0 : if (!(ifa1->ifa_flags & IFA_F_SECONDARY)) {
338 : 0 : struct in_ifaddr **ifap1 = &ifa1->ifa_next;
339 : :
340 [ # # ]: 0 : while ((ifa = *ifap1) != NULL) {
341 [ # # ][ # # ]: 0 : if (!(ifa->ifa_flags & IFA_F_SECONDARY) &&
342 : 0 : ifa1->ifa_scope <= ifa->ifa_scope)
343 : : last_prim = ifa;
344 : :
345 [ # # ][ # # ]: 0 : if (!(ifa->ifa_flags & IFA_F_SECONDARY) ||
346 [ # # ]: 0 : ifa1->ifa_mask != ifa->ifa_mask ||
347 : 0 : !inet_ifa_match(ifa1->ifa_address, ifa)) {
348 : 0 : ifap1 = &ifa->ifa_next;
349 : : prev_prom = ifa;
350 : 0 : continue;
351 : : }
352 : :
353 [ # # ]: 0 : if (!do_promote) {
354 : 0 : inet_hash_remove(ifa);
355 : 0 : *ifap1 = ifa->ifa_next;
356 : :
357 : 0 : rtmsg_ifa(RTM_DELADDR, ifa, nlh, portid);
358 : 0 : blocking_notifier_call_chain(&inetaddr_chain,
359 : : NETDEV_DOWN, ifa);
360 : : inet_free_ifa(ifa);
361 : : } else {
362 : : promote = ifa;
363 : : break;
364 : : }
365 : : }
366 : : }
367 : :
368 : : /* On promotion all secondaries from subnet are changing
369 : : * the primary IP, we must remove all their routes silently
370 : : * and later to add them back with new prefsrc. Do this
371 : : * while all addresses are on the device list.
372 : : */
373 [ # # ]: 0 : for (ifa = promote; ifa; ifa = ifa->ifa_next) {
374 [ # # ][ # # ]: 0 : if (ifa1->ifa_mask == ifa->ifa_mask &&
375 : 0 : inet_ifa_match(ifa1->ifa_address, ifa))
376 : 0 : fib_del_ifaddr(ifa, ifa1);
377 : : }
378 : :
379 : : /* 2. Unlink it */
380 : :
381 : 0 : *ifap = ifa1->ifa_next;
382 : 0 : inet_hash_remove(ifa1);
383 : :
384 : : /* 3. Announce address deletion */
385 : :
386 : : /* Send message first, then call notifier.
387 : : At first sight, FIB update triggered by notifier
388 : : will refer to already deleted ifaddr, that could confuse
389 : : netlink listeners. It is not true: look, gated sees
390 : : that route deleted and if it still thinks that ifaddr
391 : : is valid, it will try to restore deleted routes... Grr.
392 : : So that, this order is correct.
393 : : */
394 : 0 : rtmsg_ifa(RTM_DELADDR, ifa1, nlh, portid);
395 : 0 : blocking_notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa1);
396 : :
397 [ # # ]: 0 : if (promote) {
398 : 0 : struct in_ifaddr *next_sec = promote->ifa_next;
399 : :
400 [ # # ]: 0 : if (prev_prom) {
401 : 0 : prev_prom->ifa_next = promote->ifa_next;
402 : 0 : promote->ifa_next = last_prim->ifa_next;
403 : 0 : last_prim->ifa_next = promote;
404 : : }
405 : :
406 : 0 : promote->ifa_flags &= ~IFA_F_SECONDARY;
407 : 0 : rtmsg_ifa(RTM_NEWADDR, promote, nlh, portid);
408 : 0 : blocking_notifier_call_chain(&inetaddr_chain,
409 : : NETDEV_UP, promote);
410 [ # # ]: 0 : for (ifa = next_sec; ifa; ifa = ifa->ifa_next) {
411 [ # # ][ # # ]: 0 : if (ifa1->ifa_mask != ifa->ifa_mask ||
412 : 0 : !inet_ifa_match(ifa1->ifa_address, ifa))
413 : 0 : continue;
414 : 0 : fib_add_ifaddr(ifa);
415 : : }
416 : :
417 : : }
418 [ # # ]: 0 : if (destroy)
419 : : inet_free_ifa(ifa1);
420 : 0 : }
421 : :
422 : 0 : static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
423 : : int destroy)
424 : : {
425 : 0 : __inet_del_ifa(in_dev, ifap, destroy, NULL, 0);
426 : : }
427 : :
428 : : static void check_lifetime(struct work_struct *work);
429 : :
430 : : static DECLARE_DELAYED_WORK(check_lifetime_work, check_lifetime);
431 : :
432 : 0 : static int __inet_insert_ifa(struct in_ifaddr *ifa, struct nlmsghdr *nlh,
433 : : u32 portid)
434 : : {
435 : 0 : struct in_device *in_dev = ifa->ifa_dev;
436 : : struct in_ifaddr *ifa1, **ifap, **last_primary;
437 : :
438 [ # # ]: 0 : ASSERT_RTNL();
439 : :
440 [ # # ]: 0 : if (!ifa->ifa_local) {
441 : : inet_free_ifa(ifa);
442 : 0 : return 0;
443 : : }
444 : :
445 : 0 : ifa->ifa_flags &= ~IFA_F_SECONDARY;
446 : 0 : last_primary = &in_dev->ifa_list;
447 : :
448 [ # # ]: 0 : for (ifap = &in_dev->ifa_list; (ifa1 = *ifap) != NULL;
449 : 0 : ifap = &ifa1->ifa_next) {
450 [ # # ][ # # ]: 0 : if (!(ifa1->ifa_flags & IFA_F_SECONDARY) &&
451 : 0 : ifa->ifa_scope <= ifa1->ifa_scope)
452 : 0 : last_primary = &ifa1->ifa_next;
453 [ # # ][ # # ]: 0 : if (ifa1->ifa_mask == ifa->ifa_mask &&
454 : 0 : inet_ifa_match(ifa1->ifa_address, ifa)) {
455 [ # # ]: 0 : if (ifa1->ifa_local == ifa->ifa_local) {
456 : : inet_free_ifa(ifa);
457 : 0 : return -EEXIST;
458 : : }
459 [ # # ]: 0 : if (ifa1->ifa_scope != ifa->ifa_scope) {
460 : : inet_free_ifa(ifa);
461 : 0 : return -EINVAL;
462 : : }
463 : 0 : ifa->ifa_flags |= IFA_F_SECONDARY;
464 : : }
465 : : }
466 : :
467 [ # # ]: 0 : if (!(ifa->ifa_flags & IFA_F_SECONDARY)) {
468 : 0 : prandom_seed((__force u32) ifa->ifa_local);
469 : : ifap = last_primary;
470 : : }
471 : :
472 : 0 : ifa->ifa_next = *ifap;
473 : 0 : *ifap = ifa;
474 : :
475 : 0 : inet_hash_insert(dev_net(in_dev->dev), ifa);
476 : :
477 : 0 : cancel_delayed_work(&check_lifetime_work);
478 : 0 : queue_delayed_work(system_power_efficient_wq, &check_lifetime_work, 0);
479 : :
480 : : /* Send message first, then call notifier.
481 : : Notifier will trigger FIB update, so that
482 : : listeners of netlink will know about new ifaddr */
483 : 0 : rtmsg_ifa(RTM_NEWADDR, ifa, nlh, portid);
484 : 0 : blocking_notifier_call_chain(&inetaddr_chain, NETDEV_UP, ifa);
485 : :
486 : 0 : return 0;
487 : : }
488 : :
489 : : static int inet_insert_ifa(struct in_ifaddr *ifa)
490 : : {
491 : 0 : return __inet_insert_ifa(ifa, NULL, 0);
492 : : }
493 : :
494 : 0 : static int inet_set_ifa(struct net_device *dev, struct in_ifaddr *ifa)
495 : : {
496 : : struct in_device *in_dev = __in_dev_get_rtnl(dev);
497 : :
498 [ # # ]: 0 : ASSERT_RTNL();
499 : :
500 [ # # ]: 0 : if (!in_dev) {
501 : : inet_free_ifa(ifa);
502 : 0 : return -ENOBUFS;
503 : : }
504 : : ipv4_devconf_setall(in_dev);
505 : 0 : neigh_parms_data_state_setall(in_dev->arp_parms);
506 [ # # ]: 0 : if (ifa->ifa_dev != in_dev) {
507 [ # # ]: 0 : WARN_ON(ifa->ifa_dev);
508 : 0 : in_dev_hold(in_dev);
509 : 0 : ifa->ifa_dev = in_dev;
510 : : }
511 [ # # ]: 0 : if (ipv4_is_loopback(ifa->ifa_local))
512 : 0 : ifa->ifa_scope = RT_SCOPE_HOST;
513 : 0 : return inet_insert_ifa(ifa);
514 : : }
515 : :
516 : : /* Caller must hold RCU or RTNL :
517 : : * We dont take a reference on found in_device
518 : : */
519 : 0 : struct in_device *inetdev_by_index(struct net *net, int ifindex)
520 : : {
521 : : struct net_device *dev;
522 : : struct in_device *in_dev = NULL;
523 : :
524 : : rcu_read_lock();
525 : 0 : dev = dev_get_by_index_rcu(net, ifindex);
526 [ # # # # ]: 0 : if (dev)
527 : 0 : in_dev = rcu_dereference_rtnl(dev->ip_ptr);
528 : : rcu_read_unlock();
529 : 0 : return in_dev;
530 : : }
531 : : EXPORT_SYMBOL(inetdev_by_index);
532 : :
533 : : /* Called only from RTNL semaphored context. No locks. */
534 : :
535 : 0 : struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, __be32 prefix,
536 : : __be32 mask)
537 : : {
538 [ # # ]: 0 : ASSERT_RTNL();
539 : :
540 [ # # ][ # # ]: 0 : for_primary_ifa(in_dev) {
541 [ # # ][ # # ]: 0 : if (ifa->ifa_mask == mask && inet_ifa_match(prefix, ifa))
542 : : return ifa;
543 : : } endfor_ifa(in_dev);
544 : : return NULL;
545 : : }
546 : :
547 : 0 : static int inet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh)
548 : : {
549 : : struct net *net = sock_net(skb->sk);
550 : : struct nlattr *tb[IFA_MAX+1];
551 : 0 : struct in_device *in_dev;
552 : : struct ifaddrmsg *ifm;
553 : 0 : struct in_ifaddr *ifa, **ifap;
554 : : int err = -EINVAL;
555 : :
556 [ # # ]: 0 : ASSERT_RTNL();
557 : :
558 : : err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv4_policy);
559 [ # # ]: 0 : if (err < 0)
560 : : goto errout;
561 : :
562 : : ifm = nlmsg_data(nlh);
563 : 0 : in_dev = inetdev_by_index(net, ifm->ifa_index);
564 [ # # ]: 0 : if (in_dev == NULL) {
565 : : err = -ENODEV;
566 : : goto errout;
567 : : }
568 : :
569 [ # # ]: 0 : for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
570 : 0 : ifap = &ifa->ifa_next) {
571 [ # # ][ # # ]: 0 : if (tb[IFA_LOCAL] &&
572 : 0 : ifa->ifa_local != nla_get_be32(tb[IFA_LOCAL]))
573 : 0 : continue;
574 : :
575 [ # # ][ # # ]: 0 : if (tb[IFA_LABEL] && nla_strcmp(tb[IFA_LABEL], ifa->ifa_label))
576 : 0 : continue;
577 : :
578 [ # # ][ # # ]: 0 : if (tb[IFA_ADDRESS] &&
579 [ # # ]: 0 : (ifm->ifa_prefixlen != ifa->ifa_prefixlen ||
580 : : !inet_ifa_match(nla_get_be32(tb[IFA_ADDRESS]), ifa)))
581 : 0 : continue;
582 : :
583 : 0 : __inet_del_ifa(in_dev, ifap, 1, nlh, NETLINK_CB(skb).portid);
584 : 0 : return 0;
585 : : }
586 : :
587 : : err = -EADDRNOTAVAIL;
588 : : errout:
589 : 0 : return err;
590 : : }
591 : :
592 : : #define INFINITY_LIFE_TIME 0xFFFFFFFF
593 : :
594 : 0 : static void check_lifetime(struct work_struct *work)
595 : : {
596 : : unsigned long now, next, next_sec, next_sched;
597 : : struct in_ifaddr *ifa;
598 : : struct hlist_node *n;
599 : : int i;
600 : :
601 : 272 : now = jiffies;
602 : 272 : next = round_jiffies_up(now + ADDR_CHECK_FREQUENCY);
603 : :
604 [ + + ]: 69904 : for (i = 0; i < IN4_ADDR_HSIZE; i++) {
605 : : bool change_needed = false;
606 : :
607 : : rcu_read_lock();
608 [ + + ][ - + ]: 70448 : hlist_for_each_entry_rcu(ifa, &inet_addr_lst[i], hash) {
[ + + ]
609 : : unsigned long age;
610 : :
611 [ + - ]: 544 : if (ifa->ifa_flags & IFA_F_PERMANENT)
612 : 544 : continue;
613 : :
614 : : /* We try to batch several events at once. */
615 : 0 : age = (now - ifa->ifa_tstamp +
616 : : ADDRCONF_TIMER_FUZZ_MINUS) / HZ;
617 : :
618 [ # # ][ # # ]: 0 : if (ifa->ifa_valid_lft != INFINITY_LIFE_TIME &&
619 : : age >= ifa->ifa_valid_lft) {
620 : : change_needed = true;
621 [ # # ]: 0 : } else if (ifa->ifa_preferred_lft ==
622 : : INFINITY_LIFE_TIME) {
623 : 0 : continue;
624 [ # # ]: 0 : } else if (age >= ifa->ifa_preferred_lft) {
625 [ # # ]: 0 : if (time_before(ifa->ifa_tstamp +
626 : : ifa->ifa_valid_lft * HZ, next))
627 : : next = ifa->ifa_tstamp +
628 : : ifa->ifa_valid_lft * HZ;
629 : :
630 [ # # ]: 0 : if (!(ifa->ifa_flags & IFA_F_DEPRECATED))
631 : : change_needed = true;
632 [ # # ]: 0 : } else if (time_before(ifa->ifa_tstamp +
633 : : ifa->ifa_preferred_lft * HZ,
634 : : next)) {
635 : : next = ifa->ifa_tstamp +
636 : : ifa->ifa_preferred_lft * HZ;
637 : : }
638 : : }
639 : : rcu_read_unlock();
640 [ + - ]: 69632 : if (!change_needed)
641 : 69632 : continue;
642 : 0 : rtnl_lock();
643 [ # # ][ # # ]: 0 : hlist_for_each_entry_safe(ifa, n, &inet_addr_lst[i], hash) {
[ # # ]
644 : : unsigned long age;
645 : :
646 [ # # ]: 0 : if (ifa->ifa_flags & IFA_F_PERMANENT)
647 : 0 : continue;
648 : :
649 : : /* We try to batch several events at once. */
650 : 0 : age = (now - ifa->ifa_tstamp +
651 : : ADDRCONF_TIMER_FUZZ_MINUS) / HZ;
652 : :
653 [ # # ][ # # ]: 0 : if (ifa->ifa_valid_lft != INFINITY_LIFE_TIME &&
654 : : age >= ifa->ifa_valid_lft) {
655 : : struct in_ifaddr **ifap;
656 : :
657 [ # # ]: 0 : for (ifap = &ifa->ifa_dev->ifa_list;
658 : 0 : *ifap != NULL; ifap = &(*ifap)->ifa_next) {
659 [ # # ]: 0 : if (*ifap == ifa) {
660 : : inet_del_ifa(ifa->ifa_dev,
661 : : ifap, 1);
662 : : break;
663 : : }
664 : : }
665 [ # # ]: 0 : } else if (ifa->ifa_preferred_lft !=
666 [ # # ]: 0 : INFINITY_LIFE_TIME &&
667 [ # # ]: 0 : age >= ifa->ifa_preferred_lft &&
668 : 0 : !(ifa->ifa_flags & IFA_F_DEPRECATED)) {
669 : 0 : ifa->ifa_flags |= IFA_F_DEPRECATED;
670 : 0 : rtmsg_ifa(RTM_NEWADDR, ifa, NULL, 0);
671 : : }
672 : : }
673 : 0 : rtnl_unlock();
674 : : }
675 : :
676 : 272 : next_sec = round_jiffies_up(next);
677 : : next_sched = next;
678 : :
679 : : /* If rounded timeout is accurate enough, accept it. */
680 [ - + ]: 272 : if (time_before(next_sec, next + ADDRCONF_TIMER_FUZZ))
681 : : next_sched = next_sec;
682 : :
683 : 272 : now = jiffies;
684 : : /* And minimum interval is ADDRCONF_TIMER_FUZZ_MAX. */
685 [ - + ]: 272 : if (time_before(next_sched, now + ADDRCONF_TIMER_FUZZ_MAX))
686 : 0 : next_sched = now + ADDRCONF_TIMER_FUZZ_MAX;
687 : :
688 : 272 : queue_delayed_work(system_power_efficient_wq, &check_lifetime_work,
689 : : next_sched - now);
690 : 272 : }
691 : :
692 : 0 : static void set_ifa_lifetime(struct in_ifaddr *ifa, __u32 valid_lft,
693 : : __u32 prefered_lft)
694 : : {
695 : : unsigned long timeout;
696 : :
697 : 0 : ifa->ifa_flags &= ~(IFA_F_PERMANENT | IFA_F_DEPRECATED);
698 : :
699 : : timeout = addrconf_timeout_fixup(valid_lft, HZ);
700 [ # # ]: 0 : if (addrconf_finite_timeout(timeout))
701 : 0 : ifa->ifa_valid_lft = timeout;
702 : : else
703 : 0 : ifa->ifa_flags |= IFA_F_PERMANENT;
704 : :
705 : : timeout = addrconf_timeout_fixup(prefered_lft, HZ);
706 [ # # ]: 0 : if (addrconf_finite_timeout(timeout)) {
707 [ # # ]: 0 : if (timeout == 0)
708 : 0 : ifa->ifa_flags |= IFA_F_DEPRECATED;
709 : 0 : ifa->ifa_preferred_lft = timeout;
710 : : }
711 : 0 : ifa->ifa_tstamp = jiffies;
712 [ # # ]: 0 : if (!ifa->ifa_cstamp)
713 : 0 : ifa->ifa_cstamp = ifa->ifa_tstamp;
714 : 0 : }
715 : :
716 : 0 : static struct in_ifaddr *rtm_to_ifaddr(struct net *net, struct nlmsghdr *nlh,
717 : : __u32 *pvalid_lft, __u32 *pprefered_lft)
718 : : {
719 : : struct nlattr *tb[IFA_MAX+1];
720 : : struct in_ifaddr *ifa;
721 : : struct ifaddrmsg *ifm;
722 : 0 : struct net_device *dev;
723 : : struct in_device *in_dev;
724 : : int err;
725 : :
726 : : err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv4_policy);
727 [ # # ]: 0 : if (err < 0)
728 : : goto errout;
729 : :
730 : : ifm = nlmsg_data(nlh);
731 : : err = -EINVAL;
732 [ # # ][ # # ]: 0 : if (ifm->ifa_prefixlen > 32 || tb[IFA_LOCAL] == NULL)
733 : : goto errout;
734 : :
735 : 0 : dev = __dev_get_by_index(net, ifm->ifa_index);
736 : : err = -ENODEV;
737 [ # # ]: 0 : if (dev == NULL)
738 : : goto errout;
739 : :
740 : : in_dev = __in_dev_get_rtnl(dev);
741 : : err = -ENOBUFS;
742 [ # # ]: 0 : if (in_dev == NULL)
743 : : goto errout;
744 : :
745 : : ifa = inet_alloc_ifa();
746 [ # # ]: 0 : if (ifa == NULL)
747 : : /*
748 : : * A potential indev allocation can be left alive, it stays
749 : : * assigned to its device and is destroy with it.
750 : : */
751 : : goto errout;
752 : :
753 : : ipv4_devconf_setall(in_dev);
754 : 0 : neigh_parms_data_state_setall(in_dev->arp_parms);
755 : 0 : in_dev_hold(in_dev);
756 : :
757 [ # # ]: 0 : if (tb[IFA_ADDRESS] == NULL)
758 : 0 : tb[IFA_ADDRESS] = tb[IFA_LOCAL];
759 : :
760 : : INIT_HLIST_NODE(&ifa->hash);
761 : 0 : ifa->ifa_prefixlen = ifm->ifa_prefixlen;
762 : 0 : ifa->ifa_mask = inet_make_mask(ifm->ifa_prefixlen);
763 [ # # ]: 0 : ifa->ifa_flags = tb[IFA_FLAGS] ? nla_get_u32(tb[IFA_FLAGS]) :
764 : 0 : ifm->ifa_flags;
765 : 0 : ifa->ifa_scope = ifm->ifa_scope;
766 : 0 : ifa->ifa_dev = in_dev;
767 : :
768 : 0 : ifa->ifa_local = nla_get_be32(tb[IFA_LOCAL]);
769 : 0 : ifa->ifa_address = nla_get_be32(tb[IFA_ADDRESS]);
770 : :
771 [ # # ]: 0 : if (tb[IFA_BROADCAST])
772 : 0 : ifa->ifa_broadcast = nla_get_be32(tb[IFA_BROADCAST]);
773 : :
774 [ # # ]: 0 : if (tb[IFA_LABEL])
775 : 0 : nla_strlcpy(ifa->ifa_label, tb[IFA_LABEL], IFNAMSIZ);
776 : : else
777 : 0 : memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
778 : :
779 [ # # ]: 0 : if (tb[IFA_CACHEINFO]) {
780 : : struct ifa_cacheinfo *ci;
781 : :
782 : : ci = nla_data(tb[IFA_CACHEINFO]);
783 [ # # ][ # # ]: 0 : if (!ci->ifa_valid || ci->ifa_prefered > ci->ifa_valid) {
784 : : err = -EINVAL;
785 : : goto errout_free;
786 : : }
787 : 0 : *pvalid_lft = ci->ifa_valid;
788 : 0 : *pprefered_lft = ci->ifa_prefered;
789 : : }
790 : :
791 : 0 : return ifa;
792 : :
793 : : errout_free:
794 : : inet_free_ifa(ifa);
795 : : errout:
796 : 0 : return ERR_PTR(err);
797 : : }
798 : :
799 : 0 : static struct in_ifaddr *find_matching_ifa(struct in_ifaddr *ifa)
800 : : {
801 : 0 : struct in_device *in_dev = ifa->ifa_dev;
802 : : struct in_ifaddr *ifa1, **ifap;
803 : :
804 [ # # ]: 0 : if (!ifa->ifa_local)
805 : : return NULL;
806 : :
807 [ # # ]: 0 : for (ifap = &in_dev->ifa_list; (ifa1 = *ifap) != NULL;
808 : 0 : ifap = &ifa1->ifa_next) {
809 [ # # ][ # # ]: 0 : if (ifa1->ifa_mask == ifa->ifa_mask &&
810 [ # # ]: 0 : inet_ifa_match(ifa1->ifa_address, ifa) &&
811 : 0 : ifa1->ifa_local == ifa->ifa_local)
812 : : return ifa1;
813 : : }
814 : : return NULL;
815 : : }
816 : :
817 : 0 : static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh)
818 : : {
819 : : struct net *net = sock_net(skb->sk);
820 : : struct in_ifaddr *ifa;
821 : : struct in_ifaddr *ifa_existing;
822 : 0 : __u32 valid_lft = INFINITY_LIFE_TIME;
823 : 0 : __u32 prefered_lft = INFINITY_LIFE_TIME;
824 : :
825 [ # # ]: 0 : ASSERT_RTNL();
826 : :
827 : 0 : ifa = rtm_to_ifaddr(net, nlh, &valid_lft, &prefered_lft);
828 [ # # ]: 0 : if (IS_ERR(ifa))
829 : 0 : return PTR_ERR(ifa);
830 : :
831 : 0 : ifa_existing = find_matching_ifa(ifa);
832 [ # # ]: 0 : if (!ifa_existing) {
833 : : /* It would be best to check for !NLM_F_CREATE here but
834 : : * userspace alreay relies on not having to provide this.
835 : : */
836 : 0 : set_ifa_lifetime(ifa, valid_lft, prefered_lft);
837 : 0 : return __inet_insert_ifa(ifa, nlh, NETLINK_CB(skb).portid);
838 : : } else {
839 : : inet_free_ifa(ifa);
840 : :
841 [ # # ]: 0 : if (nlh->nlmsg_flags & NLM_F_EXCL ||
842 : : !(nlh->nlmsg_flags & NLM_F_REPLACE))
843 : : return -EEXIST;
844 : : ifa = ifa_existing;
845 : 0 : set_ifa_lifetime(ifa, valid_lft, prefered_lft);
846 : 0 : cancel_delayed_work(&check_lifetime_work);
847 : 0 : queue_delayed_work(system_power_efficient_wq,
848 : : &check_lifetime_work, 0);
849 : 0 : rtmsg_ifa(RTM_NEWADDR, ifa, nlh, NETLINK_CB(skb).portid);
850 : 0 : blocking_notifier_call_chain(&inetaddr_chain, NETDEV_UP, ifa);
851 : : }
852 : 0 : return 0;
853 : : }
854 : :
855 : : /*
856 : : * Determine a default network mask, based on the IP address.
857 : : */
858 : :
859 : 0 : static int inet_abc_len(__be32 addr)
860 : : {
861 : : int rc = -1; /* Something else, probably a multicast. */
862 : :
863 [ # # ]: 0 : if (ipv4_is_zeronet(addr))
864 : : rc = 0;
865 : : else {
866 [ # # ]: 0 : __u32 haddr = ntohl(addr);
867 : :
868 [ # # ]: 0 : if (IN_CLASSA(haddr))
869 : : rc = 8;
870 [ # # ]: 0 : else if (IN_CLASSB(haddr))
871 : : rc = 16;
872 [ # # ]: 0 : else if (IN_CLASSC(haddr))
873 : : rc = 24;
874 : : }
875 : :
876 : 0 : return rc;
877 : : }
878 : :
879 : :
880 : 0 : int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg)
881 : : {
882 : : struct ifreq ifr;
883 : : struct sockaddr_in sin_orig;
884 : : struct sockaddr_in *sin = (struct sockaddr_in *)&ifr.ifr_addr;
885 : : struct in_device *in_dev;
886 : : struct in_ifaddr **ifap = NULL;
887 : : struct in_ifaddr *ifa = NULL;
888 : 0 : struct net_device *dev;
889 : : char *colon;
890 : : int ret = -EFAULT;
891 : : int tryaddrmatch = 0;
892 : :
893 : : /*
894 : : * Fetch the caller's info block into kernel space
895 : : */
896 : :
897 [ - + ]: 1 : if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))
898 : : goto out;
899 : 0 : ifr.ifr_name[IFNAMSIZ - 1] = 0;
900 : :
901 : : /* save original address for comparison */
902 : 0 : memcpy(&sin_orig, sin, sizeof(*sin));
903 : :
904 : 0 : colon = strchr(ifr.ifr_name, ':');
905 [ # # ]: 0 : if (colon)
906 : 0 : *colon = 0;
907 : :
908 : 0 : dev_load(net, ifr.ifr_name);
909 : :
910 [ # # # # ]: 0 : switch (cmd) {
911 : : case SIOCGIFADDR: /* Get interface address */
912 : : case SIOCGIFBRDADDR: /* Get the broadcast address */
913 : : case SIOCGIFDSTADDR: /* Get the destination address */
914 : : case SIOCGIFNETMASK: /* Get the netmask for the interface */
915 : : /* Note that these ioctls will not sleep,
916 : : so that we do not impose a lock.
917 : : One day we will be forced to put shlock here (I mean SMP)
918 : : */
919 : 0 : tryaddrmatch = (sin_orig.sin_family == AF_INET);
920 : 0 : memset(sin, 0, sizeof(*sin));
921 : 0 : sin->sin_family = AF_INET;
922 : 0 : break;
923 : :
924 : : case SIOCSIFFLAGS:
925 : : ret = -EPERM;
926 [ # # ]: 0 : if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
927 : : goto out;
928 : : break;
929 : : case SIOCSIFADDR: /* Set interface address (and family) */
930 : : case SIOCSIFBRDADDR: /* Set the broadcast address */
931 : : case SIOCSIFDSTADDR: /* Set the destination address */
932 : : case SIOCSIFNETMASK: /* Set the netmask for the interface */
933 : : case SIOCKILLADDR: /* Nuke all sockets on this address */
934 : : ret = -EPERM;
935 [ # # ]: 0 : if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
936 : : goto out;
937 : : ret = -EINVAL;
938 [ # # ]: 0 : if (sin->sin_family != AF_INET)
939 : : goto out;
940 : : break;
941 : : default:
942 : : ret = -EINVAL;
943 : : goto out;
944 : : }
945 : :
946 : 0 : rtnl_lock();
947 : :
948 : : ret = -ENODEV;
949 : 0 : dev = __dev_get_by_name(net, ifr.ifr_name);
950 [ # # ]: 0 : if (!dev)
951 : : goto done;
952 : :
953 [ # # ]: 0 : if (colon)
954 : 0 : *colon = ':';
955 : :
956 : : in_dev = __in_dev_get_rtnl(dev);
957 [ # # ]: 0 : if (in_dev) {
958 [ # # ]: 0 : if (tryaddrmatch) {
959 : : /* Matthias Andree */
960 : : /* compare label and address (4.4BSD style) */
961 : : /* note: we only do this for a limited set of ioctls
962 : : and only if the original address family was AF_INET.
963 : : This is checked above. */
964 [ # # ]: 0 : for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
965 : 0 : ifap = &ifa->ifa_next) {
966 [ # # ][ # # ]: 0 : if (!strcmp(ifr.ifr_name, ifa->ifa_label) &&
967 : : sin_orig.sin_addr.s_addr ==
968 : 0 : ifa->ifa_local) {
969 : : break; /* found */
970 : : }
971 : : }
972 : : }
973 : : /* we didn't get a match, maybe the application is
974 : : 4.3BSD-style and passed in junk so we fall back to
975 : : comparing just the label */
976 [ # # ]: 0 : if (!ifa) {
977 [ # # ]: 0 : for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
978 : 0 : ifap = &ifa->ifa_next)
979 [ # # ]: 0 : if (!strcmp(ifr.ifr_name, ifa->ifa_label))
980 : : break;
981 : : }
982 : : }
983 : :
984 : : ret = -EADDRNOTAVAIL;
985 [ # # ]: 0 : if (!ifa && cmd != SIOCSIFADDR && cmd != SIOCSIFFLAGS
986 [ # # ]: 0 : && cmd != SIOCKILLADDR)
987 : : goto done;
988 : :
989 [ # # # # : 0 : switch (cmd) {
# # # # #
# # ]
990 : : case SIOCGIFADDR: /* Get interface address */
991 : 0 : sin->sin_addr.s_addr = ifa->ifa_local;
992 : 0 : goto rarok;
993 : :
994 : : case SIOCGIFBRDADDR: /* Get the broadcast address */
995 : 0 : sin->sin_addr.s_addr = ifa->ifa_broadcast;
996 : 0 : goto rarok;
997 : :
998 : : case SIOCGIFDSTADDR: /* Get the destination address */
999 : 0 : sin->sin_addr.s_addr = ifa->ifa_address;
1000 : 0 : goto rarok;
1001 : :
1002 : : case SIOCGIFNETMASK: /* Get the netmask for the interface */
1003 : 0 : sin->sin_addr.s_addr = ifa->ifa_mask;
1004 : 0 : goto rarok;
1005 : :
1006 : : case SIOCSIFFLAGS:
1007 [ # # ]: 0 : if (colon) {
1008 : : ret = -EADDRNOTAVAIL;
1009 [ # # ]: 0 : if (!ifa)
1010 : : break;
1011 : : ret = 0;
1012 [ # # ]: 0 : if (!(ifr.ifr_flags & IFF_UP))
1013 : : inet_del_ifa(in_dev, ifap, 1);
1014 : : break;
1015 : : }
1016 : 0 : ret = dev_change_flags(dev, ifr.ifr_flags);
1017 : 0 : break;
1018 : :
1019 : : case SIOCSIFADDR: /* Set interface address (and family) */
1020 : : ret = -EINVAL;
1021 [ # # ]: 0 : if (inet_abc_len(sin->sin_addr.s_addr) < 0)
1022 : : break;
1023 : :
1024 [ # # ]: 0 : if (!ifa) {
1025 : : ret = -ENOBUFS;
1026 : : ifa = inet_alloc_ifa();
1027 [ # # ]: 0 : if (!ifa)
1028 : : break;
1029 : : INIT_HLIST_NODE(&ifa->hash);
1030 [ # # ]: 0 : if (colon)
1031 : 0 : memcpy(ifa->ifa_label, ifr.ifr_name, IFNAMSIZ);
1032 : : else
1033 : 0 : memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
1034 : : } else {
1035 : : ret = 0;
1036 [ # # ]: 0 : if (ifa->ifa_local == sin->sin_addr.s_addr)
1037 : : break;
1038 : : inet_del_ifa(in_dev, ifap, 0);
1039 : 0 : ifa->ifa_broadcast = 0;
1040 : 0 : ifa->ifa_scope = 0;
1041 : : }
1042 : :
1043 : 0 : ifa->ifa_address = ifa->ifa_local = sin->sin_addr.s_addr;
1044 : :
1045 [ # # ]: 0 : if (!(dev->flags & IFF_POINTOPOINT)) {
1046 : 0 : ifa->ifa_prefixlen = inet_abc_len(ifa->ifa_address);
1047 : 0 : ifa->ifa_mask = inet_make_mask(ifa->ifa_prefixlen);
1048 [ # # ][ # # ]: 0 : if ((dev->flags & IFF_BROADCAST) &&
1049 : : ifa->ifa_prefixlen < 31)
1050 : 0 : ifa->ifa_broadcast = ifa->ifa_address |
1051 : 0 : ~ifa->ifa_mask;
1052 : : } else {
1053 : 0 : ifa->ifa_prefixlen = 32;
1054 : 0 : ifa->ifa_mask = inet_make_mask(32);
1055 : : }
1056 : 0 : set_ifa_lifetime(ifa, INFINITY_LIFE_TIME, INFINITY_LIFE_TIME);
1057 : 0 : ret = inet_set_ifa(dev, ifa);
1058 : 0 : break;
1059 : :
1060 : : case SIOCSIFBRDADDR: /* Set the broadcast address */
1061 : : ret = 0;
1062 [ # # ]: 0 : if (ifa->ifa_broadcast != sin->sin_addr.s_addr) {
1063 : : inet_del_ifa(in_dev, ifap, 0);
1064 : 0 : ifa->ifa_broadcast = sin->sin_addr.s_addr;
1065 : : inet_insert_ifa(ifa);
1066 : : }
1067 : : break;
1068 : :
1069 : : case SIOCSIFDSTADDR: /* Set the destination address */
1070 : : ret = 0;
1071 [ # # ]: 0 : if (ifa->ifa_address == sin->sin_addr.s_addr)
1072 : : break;
1073 : : ret = -EINVAL;
1074 [ # # ]: 0 : if (inet_abc_len(sin->sin_addr.s_addr) < 0)
1075 : : break;
1076 : : ret = 0;
1077 : : inet_del_ifa(in_dev, ifap, 0);
1078 : 0 : ifa->ifa_address = sin->sin_addr.s_addr;
1079 : : inet_insert_ifa(ifa);
1080 : : break;
1081 : :
1082 : : case SIOCSIFNETMASK: /* Set the netmask for the interface */
1083 : :
1084 : : /*
1085 : : * The mask we set must be legal.
1086 : : */
1087 : : ret = -EINVAL;
1088 [ # # ]: 0 : if (bad_mask(sin->sin_addr.s_addr, 0))
1089 : : break;
1090 : : ret = 0;
1091 [ # # ]: 0 : if (ifa->ifa_mask != sin->sin_addr.s_addr) {
1092 : : __be32 old_mask = ifa->ifa_mask;
1093 : : inet_del_ifa(in_dev, ifap, 0);
1094 : 0 : ifa->ifa_mask = sin->sin_addr.s_addr;
1095 : 0 : ifa->ifa_prefixlen = inet_mask_len(ifa->ifa_mask);
1096 : :
1097 : : /* See if current broadcast address matches
1098 : : * with current netmask, then recalculate
1099 : : * the broadcast address. Otherwise it's a
1100 : : * funny address, so don't touch it since
1101 : : * the user seems to know what (s)he's doing...
1102 : : */
1103 [ - ][ # # ]: 0 : if ((dev->flags & IFF_BROADCAST) &&
1104 [ # # ]: 0 : (ifa->ifa_prefixlen < 31) &&
1105 : 0 : (ifa->ifa_broadcast ==
1106 : 0 : (ifa->ifa_local|~old_mask))) {
1107 : 0 : ifa->ifa_broadcast = (ifa->ifa_local |
1108 : 0 : ~sin->sin_addr.s_addr);
1109 : : }
1110 : : inet_insert_ifa(ifa);
1111 : : }
1112 : : break;
1113 : : case SIOCKILLADDR: /* Nuke all connections on this address */
1114 : 0 : ret = tcp_nuke_addr(net, (struct sockaddr *) sin);
1115 : 0 : break;
1116 : : }
1117 : : done:
1118 : 0 : rtnl_unlock();
1119 : : out:
1120 : 1 : return ret;
1121 : : rarok:
1122 : 0 : rtnl_unlock();
1123 [ # # ]: 0 : ret = copy_to_user(arg, &ifr, sizeof(struct ifreq)) ? -EFAULT : 0;
1124 : : goto out;
1125 : : }
1126 : :
1127 : 0 : static int inet_gifconf(struct net_device *dev, char __user *buf, int len)
1128 : : {
1129 : : struct in_device *in_dev = __in_dev_get_rtnl(dev);
1130 : : struct in_ifaddr *ifa;
1131 : : struct ifreq ifr;
1132 : : int done = 0;
1133 : :
1134 [ + - ]: 12 : if (!in_dev)
1135 : : goto out;
1136 : :
1137 [ + + ]: 20 : for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) {
1138 [ - + ]: 8 : if (!buf) {
1139 : 0 : done += sizeof(ifr);
1140 : 0 : continue;
1141 : : }
1142 [ + ]: 8 : if (len < (int) sizeof(ifr))
1143 : : break;
1144 : 8 : memset(&ifr, 0, sizeof(struct ifreq));
1145 : 8 : strcpy(ifr.ifr_name, ifa->ifa_label);
1146 : :
1147 : 8 : (*(struct sockaddr_in *)&ifr.ifr_addr).sin_family = AF_INET;
1148 : 8 : (*(struct sockaddr_in *)&ifr.ifr_addr).sin_addr.s_addr =
1149 : 8 : ifa->ifa_local;
1150 : :
1151 [ + - ]: 8 : if (copy_to_user(buf, &ifr, sizeof(struct ifreq))) {
1152 : : done = -EFAULT;
1153 : : break;
1154 : : }
1155 : 8 : buf += sizeof(struct ifreq);
1156 : 8 : len -= sizeof(struct ifreq);
1157 : 8 : done += sizeof(struct ifreq);
1158 : : }
1159 : : out:
1160 : 0 : return done;
1161 : : }
1162 : :
1163 : 0 : __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope)
1164 : : {
1165 : : __be32 addr = 0;
1166 : : struct in_device *in_dev;
1167 : : struct net *net = dev_net(dev);
1168 : :
1169 : : rcu_read_lock();
1170 : : in_dev = __in_dev_get_rcu(dev);
1171 [ + - ]: 22 : if (!in_dev)
1172 : : goto no_in_dev;
1173 : :
1174 [ + - ][ + - ]: 22 : for_primary_ifa(in_dev) {
1175 [ - + ]: 22 : if (ifa->ifa_scope > scope)
1176 : 0 : continue;
1177 [ + - ][ + - ]: 22 : if (!dst || inet_ifa_match(dst, ifa)) {
1178 : 22 : addr = ifa->ifa_local;
1179 : 22 : break;
1180 : : }
1181 [ # # ]: 0 : if (!addr)
1182 : 0 : addr = ifa->ifa_local;
1183 : : } endfor_ifa(in_dev);
1184 : :
1185 [ - + ]: 22 : if (addr)
1186 : : goto out_unlock;
1187 : : no_in_dev:
1188 : :
1189 : : /* Not loopback addresses on loopback should be preferred
1190 : : in this case. It is importnat that lo is the first interface
1191 : : in dev_base list.
1192 : : */
1193 [ # # ]: 0 : for_each_netdev_rcu(net, dev) {
1194 : : in_dev = __in_dev_get_rcu(dev);
1195 [ # # ]: 0 : if (!in_dev)
1196 : 0 : continue;
1197 : :
1198 [ # # ][ # # ]: 0 : for_primary_ifa(in_dev) {
1199 [ # # ][ # # ]: 0 : if (ifa->ifa_scope != RT_SCOPE_LINK &&
1200 : 0 : ifa->ifa_scope <= scope) {
1201 : 0 : addr = ifa->ifa_local;
1202 : 0 : goto out_unlock;
1203 : : }
1204 : : } endfor_ifa(in_dev);
1205 : : }
1206 : : out_unlock:
1207 : : rcu_read_unlock();
1208 : 22 : return addr;
1209 : : }
1210 : : EXPORT_SYMBOL(inet_select_addr);
1211 : :
1212 : 0 : static __be32 confirm_addr_indev(struct in_device *in_dev, __be32 dst,
1213 : : __be32 local, int scope)
1214 : : {
1215 : : int same = 0;
1216 : : __be32 addr = 0;
1217 : :
1218 [ # # ]: 0 : for_ifa(in_dev) {
1219 [ # # ][ # # ]: 0 : if (!addr &&
1220 [ # # ][ # # ]: 0 : (local == ifa->ifa_local || !local) &&
1221 : 0 : ifa->ifa_scope <= scope) {
1222 : : addr = ifa->ifa_local;
1223 [ # # ]: 0 : if (same)
1224 : : break;
1225 : : }
1226 [ # # ]: 0 : if (!same) {
1227 [ # # ][ # # ]: 0 : same = (!local || inet_ifa_match(local, ifa)) &&
[ # # ]
1228 [ # # ]: 0 : (!dst || inet_ifa_match(dst, ifa));
1229 [ # # ]: 0 : if (same && addr) {
1230 [ # # ]: 0 : if (local || !dst)
1231 : : break;
1232 : : /* Is the selected addr into dst subnet? */
1233 [ # # ]: 0 : if (inet_ifa_match(addr, ifa))
1234 : : break;
1235 : : /* No, then can we use new local src? */
1236 [ # # ]: 0 : if (ifa->ifa_scope <= scope) {
1237 : 0 : addr = ifa->ifa_local;
1238 : : break;
1239 : : }
1240 : : /* search for large dst subnet for addr */
1241 : : same = 0;
1242 : : }
1243 : : }
1244 : : } endfor_ifa(in_dev);
1245 : :
1246 [ # # ]: 0 : return same ? addr : 0;
1247 : : }
1248 : :
1249 : : /*
1250 : : * Confirm that local IP address exists using wildcards:
1251 : : * - net: netns to check, cannot be NULL
1252 : : * - in_dev: only on this interface, NULL=any interface
1253 : : * - dst: only in the same subnet as dst, 0=any dst
1254 : : * - local: address, 0=autoselect the local address
1255 : : * - scope: maximum allowed scope value for the local address
1256 : : */
1257 : 0 : __be32 inet_confirm_addr(struct net *net, struct in_device *in_dev,
1258 : : __be32 dst, __be32 local, int scope)
1259 : : {
1260 : : __be32 addr = 0;
1261 : 0 : struct net_device *dev;
1262 : :
1263 [ # # ]: 0 : if (in_dev != NULL)
1264 : 0 : return confirm_addr_indev(in_dev, dst, local, scope);
1265 : :
1266 : : rcu_read_lock();
1267 [ # # ]: 0 : for_each_netdev_rcu(net, dev) {
1268 : : in_dev = __in_dev_get_rcu(dev);
1269 [ # # ]: 0 : if (in_dev) {
1270 : 0 : addr = confirm_addr_indev(in_dev, dst, local, scope);
1271 [ # # ]: 0 : if (addr)
1272 : : break;
1273 : : }
1274 : : }
1275 : : rcu_read_unlock();
1276 : :
1277 : 0 : return addr;
1278 : : }
1279 : : EXPORT_SYMBOL(inet_confirm_addr);
1280 : :
1281 : : /*
1282 : : * Device notifier
1283 : : */
1284 : :
1285 : 0 : int register_inetaddr_notifier(struct notifier_block *nb)
1286 : : {
1287 : 0 : return blocking_notifier_chain_register(&inetaddr_chain, nb);
1288 : : }
1289 : : EXPORT_SYMBOL(register_inetaddr_notifier);
1290 : :
1291 : 0 : int unregister_inetaddr_notifier(struct notifier_block *nb)
1292 : : {
1293 : 0 : return blocking_notifier_chain_unregister(&inetaddr_chain, nb);
1294 : : }
1295 : : EXPORT_SYMBOL(unregister_inetaddr_notifier);
1296 : :
1297 : : /* Rename ifa_labels for a device name change. Make some effort to preserve
1298 : : * existing alias numbering and to create unique labels if possible.
1299 : : */
1300 : 0 : static void inetdev_changename(struct net_device *dev, struct in_device *in_dev)
1301 : : {
1302 : : struct in_ifaddr *ifa;
1303 : : int named = 0;
1304 : :
1305 [ # # ]: 0 : for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) {
1306 : : char old[IFNAMSIZ], *dot;
1307 : :
1308 : 0 : memcpy(old, ifa->ifa_label, IFNAMSIZ);
1309 : 0 : memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
1310 [ # # ]: 0 : if (named++ == 0)
1311 : : goto skip;
1312 : 0 : dot = strchr(old, ':');
1313 [ # # ]: 0 : if (dot == NULL) {
1314 : 0 : sprintf(old, ":%d", named);
1315 : : dot = old;
1316 : : }
1317 [ # # ]: 0 : if (strlen(dot) + strlen(dev->name) < IFNAMSIZ)
1318 : 0 : strcat(ifa->ifa_label, dot);
1319 : : else
1320 : 0 : strcpy(ifa->ifa_label + (IFNAMSIZ - strlen(dot) - 1), dot);
1321 : : skip:
1322 : 0 : rtmsg_ifa(RTM_NEWADDR, ifa, NULL, 0);
1323 : : }
1324 : 0 : }
1325 : :
1326 : : static bool inetdev_valid_mtu(unsigned int mtu)
1327 : : {
1328 : : return mtu >= 68;
1329 : : }
1330 : :
1331 : 0 : static void inetdev_send_gratuitous_arp(struct net_device *dev,
1332 : : struct in_device *in_dev)
1333 : :
1334 : : {
1335 : : struct in_ifaddr *ifa;
1336 : :
1337 [ # # ]: 0 : for (ifa = in_dev->ifa_list; ifa;
1338 : 0 : ifa = ifa->ifa_next) {
1339 : 0 : arp_send(ARPOP_REQUEST, ETH_P_ARP,
1340 : : ifa->ifa_local, dev,
1341 : : ifa->ifa_local, NULL,
1342 : 0 : dev->dev_addr, NULL);
1343 : : }
1344 : 0 : }
1345 : :
1346 : : /* Called only under RTNL semaphore */
1347 : :
1348 : 0 : static int inetdev_event(struct notifier_block *this, unsigned long event,
1349 : : void *ptr)
1350 : : {
1351 : 0 : struct net_device *dev = netdev_notifier_info_to_dev(ptr);
1352 : 0 : struct in_device *in_dev = __in_dev_get_rtnl(dev);
1353 : :
1354 [ # # ]: 0 : ASSERT_RTNL();
1355 : :
1356 [ # # ]: 0 : if (!in_dev) {
1357 [ # # ]: 0 : if (event == NETDEV_REGISTER) {
1358 : 0 : in_dev = inetdev_init(dev);
1359 [ # # ]: 0 : if (!in_dev)
1360 : : return notifier_from_errno(-ENOMEM);
1361 [ # # ]: 0 : if (dev->flags & IFF_LOOPBACK) {
1362 : : IN_DEV_CONF_SET(in_dev, NOXFRM, 1);
1363 : : IN_DEV_CONF_SET(in_dev, NOPOLICY, 1);
1364 : : }
1365 [ # # ]: 0 : } else if (event == NETDEV_CHANGEMTU) {
1366 : : /* Re-enabling IP */
1367 [ # # ]: 0 : if (inetdev_valid_mtu(dev->mtu))
1368 : 0 : in_dev = inetdev_init(dev);
1369 : : }
1370 : : goto out;
1371 : : }
1372 : :
1373 [ # # # # : 0 : switch (event) {
# # # # #
# # ]
1374 : : case NETDEV_REGISTER:
1375 : : pr_debug("%s: bug\n", __func__);
1376 : 0 : RCU_INIT_POINTER(dev->ip_ptr, NULL);
1377 : 0 : break;
1378 : : case NETDEV_UP:
1379 [ # # ]: 0 : if (!inetdev_valid_mtu(dev->mtu))
1380 : : break;
1381 [ # # ]: 0 : if (dev->flags & IFF_LOOPBACK) {
1382 : : struct in_ifaddr *ifa = inet_alloc_ifa();
1383 : :
1384 [ # # ]: 0 : if (ifa) {
1385 : : INIT_HLIST_NODE(&ifa->hash);
1386 : 0 : ifa->ifa_local =
1387 : 0 : ifa->ifa_address = htonl(INADDR_LOOPBACK);
1388 : 0 : ifa->ifa_prefixlen = 8;
1389 : 0 : ifa->ifa_mask = inet_make_mask(8);
1390 : 0 : in_dev_hold(in_dev);
1391 : 0 : ifa->ifa_dev = in_dev;
1392 : 0 : ifa->ifa_scope = RT_SCOPE_HOST;
1393 : 0 : memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
1394 : 0 : set_ifa_lifetime(ifa, INFINITY_LIFE_TIME,
1395 : : INFINITY_LIFE_TIME);
1396 : : ipv4_devconf_setall(in_dev);
1397 : 0 : neigh_parms_data_state_setall(in_dev->arp_parms);
1398 : : inet_insert_ifa(ifa);
1399 : : }
1400 : : }
1401 : 0 : ip_mc_up(in_dev);
1402 : : /* fall through */
1403 : : case NETDEV_CHANGEADDR:
1404 [ # # ]: 0 : if (!IN_DEV_ARP_NOTIFY(in_dev))
1405 : : break;
1406 : : /* fall through */
1407 : : case NETDEV_NOTIFY_PEERS:
1408 : : /* Send gratuitous ARP to notify of link change */
1409 : 0 : inetdev_send_gratuitous_arp(dev, in_dev);
1410 : 0 : break;
1411 : : case NETDEV_DOWN:
1412 : 0 : ip_mc_down(in_dev);
1413 : 0 : break;
1414 : : case NETDEV_PRE_TYPE_CHANGE:
1415 : 0 : ip_mc_unmap(in_dev);
1416 : 0 : break;
1417 : : case NETDEV_POST_TYPE_CHANGE:
1418 : 0 : ip_mc_remap(in_dev);
1419 : 0 : break;
1420 : : case NETDEV_CHANGEMTU:
1421 [ # # ]: 0 : if (inetdev_valid_mtu(dev->mtu))
1422 : : break;
1423 : : /* disable IP when MTU is not enough */
1424 : : case NETDEV_UNREGISTER:
1425 : 0 : inetdev_destroy(in_dev);
1426 : 0 : break;
1427 : : case NETDEV_CHANGENAME:
1428 : : /* Do not notify about label change, this event is
1429 : : * not interesting to applications using netlink.
1430 : : */
1431 : 0 : inetdev_changename(dev, in_dev);
1432 : :
1433 : : devinet_sysctl_unregister(in_dev);
1434 : 0 : devinet_sysctl_register(in_dev);
1435 : 0 : break;
1436 : : }
1437 : : out:
1438 : : return NOTIFY_DONE;
1439 : : }
1440 : :
1441 : : static struct notifier_block ip_netdev_notifier = {
1442 : : .notifier_call = inetdev_event,
1443 : : };
1444 : :
1445 : : static size_t inet_nlmsg_size(void)
1446 : : {
1447 : : return NLMSG_ALIGN(sizeof(struct ifaddrmsg))
1448 : : + nla_total_size(4) /* IFA_ADDRESS */
1449 : : + nla_total_size(4) /* IFA_LOCAL */
1450 : : + nla_total_size(4) /* IFA_BROADCAST */
1451 : : + nla_total_size(IFNAMSIZ) /* IFA_LABEL */
1452 : : + nla_total_size(4) /* IFA_FLAGS */
1453 : : + nla_total_size(sizeof(struct ifa_cacheinfo)); /* IFA_CACHEINFO */
1454 : : }
1455 : :
1456 : : static inline u32 cstamp_delta(unsigned long cstamp)
1457 : : {
1458 : 2216 : return (cstamp - INITIAL_JIFFIES) * 100UL / HZ;
1459 : : }
1460 : :
1461 : 0 : static int put_cacheinfo(struct sk_buff *skb, unsigned long cstamp,
1462 : : unsigned long tstamp, u32 preferred, u32 valid)
1463 : : {
1464 : : struct ifa_cacheinfo ci;
1465 : :
1466 : 1108 : ci.cstamp = cstamp_delta(cstamp);
1467 : 1108 : ci.tstamp = cstamp_delta(tstamp);
1468 : 1108 : ci.ifa_prefered = preferred;
1469 : 1108 : ci.ifa_valid = valid;
1470 : :
1471 : 1108 : return nla_put(skb, IFA_CACHEINFO, sizeof(ci), &ci);
1472 : : }
1473 : :
1474 : 0 : static int inet_fill_ifaddr(struct sk_buff *skb, struct in_ifaddr *ifa,
1475 : : u32 portid, u32 seq, int event, unsigned int flags)
1476 : : {
1477 : : struct ifaddrmsg *ifm;
1478 : : struct nlmsghdr *nlh;
1479 : : u32 preferred, valid;
1480 : :
1481 : 1108 : nlh = nlmsg_put(skb, portid, seq, event, sizeof(*ifm), flags);
1482 [ + - ]: 1108 : if (nlh == NULL)
1483 : : return -EMSGSIZE;
1484 : :
1485 : : ifm = nlmsg_data(nlh);
1486 : 1108 : ifm->ifa_family = AF_INET;
1487 : 1108 : ifm->ifa_prefixlen = ifa->ifa_prefixlen;
1488 : 1108 : ifm->ifa_flags = ifa->ifa_flags;
1489 : 1108 : ifm->ifa_scope = ifa->ifa_scope;
1490 : 1108 : ifm->ifa_index = ifa->ifa_dev->dev->ifindex;
1491 : :
1492 [ - + ]: 1108 : if (!(ifm->ifa_flags & IFA_F_PERMANENT)) {
1493 : 0 : preferred = ifa->ifa_preferred_lft;
1494 : 0 : valid = ifa->ifa_valid_lft;
1495 [ # # ]: 0 : if (preferred != INFINITY_LIFE_TIME) {
1496 : 0 : long tval = (jiffies - ifa->ifa_tstamp) / HZ;
1497 : :
1498 [ # # ]: 0 : if (preferred > tval)
1499 : 0 : preferred -= tval;
1500 : : else
1501 : : preferred = 0;
1502 [ # # ]: 0 : if (valid != INFINITY_LIFE_TIME) {
1503 [ # # ]: 0 : if (valid > tval)
1504 : 0 : valid -= tval;
1505 : : else
1506 : : valid = 0;
1507 : : }
1508 : : }
1509 : : } else {
1510 : : preferred = INFINITY_LIFE_TIME;
1511 : : valid = INFINITY_LIFE_TIME;
1512 : : }
1513 [ + - + - ]: 2216 : if ((ifa->ifa_address &&
1514 [ + - ]: 1108 : nla_put_be32(skb, IFA_ADDRESS, ifa->ifa_address)) ||
1515 [ + - ]: 1108 : (ifa->ifa_local &&
1516 [ # # ]: 1108 : nla_put_be32(skb, IFA_LOCAL, ifa->ifa_local)) ||
1517 [ + - ]: 554 : (ifa->ifa_broadcast &&
1518 [ # # ]: 0 : nla_put_be32(skb, IFA_BROADCAST, ifa->ifa_broadcast)) ||
1519 [ + - ]: 1108 : (ifa->ifa_label[0] &&
1520 [ + - ]: 1108 : nla_put_string(skb, IFA_LABEL, ifa->ifa_label)) ||
1521 [ + - ]: 1108 : nla_put_u32(skb, IFA_FLAGS, ifa->ifa_flags) ||
1522 : 1108 : put_cacheinfo(skb, ifa->ifa_cstamp, ifa->ifa_tstamp,
1523 : : preferred, valid))
1524 : : goto nla_put_failure;
1525 : :
1526 : 1108 : return nlmsg_end(skb, nlh);
1527 : :
1528 : : nla_put_failure:
1529 : : nlmsg_cancel(skb, nlh);
1530 : : return -EMSGSIZE;
1531 : : }
1532 : :
1533 : 0 : static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
1534 : : {
1535 : : struct net *net = sock_net(skb->sk);
1536 : : int h, s_h;
1537 : : int idx, s_idx;
1538 : : int ip_idx, s_ip_idx;
1539 : 1662 : struct net_device *dev;
1540 : : struct in_device *in_dev;
1541 : : struct in_ifaddr *ifa;
1542 : : struct hlist_head *head;
1543 : :
1544 : 1108 : s_h = cb->args[0];
1545 : 1108 : s_idx = idx = cb->args[1];
1546 : 1108 : s_ip_idx = ip_idx = cb->args[2];
1547 : :
1548 [ + + ]: 142932 : for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
1549 : : idx = 0;
1550 : 141824 : head = &net->dev_index_head[h];
1551 : : rcu_read_lock();
1552 : 283648 : cb->seq = atomic_read(&net->ipv4.dev_addr_genid) ^
1553 : 141824 : net->dev_base_seq;
1554 [ + + ][ - + ]: 143486 : hlist_for_each_entry_rcu(dev, head, index_hlist) {
[ + + ]
1555 [ + - ]: 1662 : if (idx < s_idx)
1556 : : goto cont;
1557 [ + - ]: 1662 : if (h > s_h || idx > s_idx)
1558 : : s_ip_idx = 0;
1559 : : in_dev = __in_dev_get_rcu(dev);
1560 [ + - ]: 1662 : if (!in_dev)
1561 : : goto cont;
1562 : :
1563 [ + + ]: 2770 : for (ifa = in_dev->ifa_list, ip_idx = 0; ifa;
1564 : 1108 : ifa = ifa->ifa_next, ip_idx++) {
1565 [ + - ]: 1108 : if (ip_idx < s_ip_idx)
1566 : 1108 : continue;
1567 [ - + ]: 0 : if (inet_fill_ifaddr(skb, ifa,
1568 : 0 : NETLINK_CB(cb->skb).portid,
1569 : 0 : cb->nlh->nlmsg_seq,
1570 : : RTM_NEWADDR, NLM_F_MULTI) <= 0) {
1571 : : rcu_read_unlock();
1572 : : goto done;
1573 : : }
1574 : : nl_dump_check_consistent(cb, nlmsg_hdr(skb));
1575 : : }
1576 : : cont:
1577 : 1662 : idx++;
1578 : : }
1579 : : rcu_read_unlock();
1580 : : }
1581 : :
1582 : : done:
1583 : 1108 : cb->args[0] = h;
1584 : 1108 : cb->args[1] = idx;
1585 : 1108 : cb->args[2] = ip_idx;
1586 : :
1587 : 1108 : return skb->len;
1588 : : }
1589 : :
1590 : 0 : static void rtmsg_ifa(int event, struct in_ifaddr *ifa, struct nlmsghdr *nlh,
1591 : : u32 portid)
1592 : : {
1593 : : struct sk_buff *skb;
1594 [ # # ]: 0 : u32 seq = nlh ? nlh->nlmsg_seq : 0;
1595 : : int err = -ENOBUFS;
1596 : : struct net *net;
1597 : :
1598 : : net = dev_net(ifa->ifa_dev->dev);
1599 : : skb = nlmsg_new(inet_nlmsg_size(), GFP_KERNEL);
1600 [ # # ]: 0 : if (skb == NULL)
1601 : : goto errout;
1602 : :
1603 : 0 : err = inet_fill_ifaddr(skb, ifa, portid, seq, event, 0);
1604 [ # # ]: 0 : if (err < 0) {
1605 : : /* -EMSGSIZE implies BUG in inet_nlmsg_size() */
1606 [ # # ]: 0 : WARN_ON(err == -EMSGSIZE);
1607 : 0 : kfree_skb(skb);
1608 : 0 : goto errout;
1609 : : }
1610 : 0 : rtnl_notify(skb, net, portid, RTNLGRP_IPV4_IFADDR, nlh, GFP_KERNEL);
1611 : 0 : return;
1612 : : errout:
1613 [ # # ]: 0 : if (err < 0)
1614 : 0 : rtnl_set_sk_err(net, RTNLGRP_IPV4_IFADDR, err);
1615 : : }
1616 : :
1617 : 0 : static size_t inet_get_link_af_size(const struct net_device *dev)
1618 : : {
1619 : 0 : struct in_device *in_dev = rcu_dereference_rtnl(dev->ip_ptr);
1620 : :
1621 [ # # ]: 0 : if (!in_dev)
1622 : : return 0;
1623 : :
1624 : 0 : return nla_total_size(IPV4_DEVCONF_MAX * 4); /* IFLA_INET_CONF */
1625 : : }
1626 : :
1627 : 0 : static int inet_fill_link_af(struct sk_buff *skb, const struct net_device *dev)
1628 : : {
1629 : 1665 : struct in_device *in_dev = rcu_dereference_rtnl(dev->ip_ptr);
1630 : : struct nlattr *nla;
1631 : : int i;
1632 : :
1633 [ + - ]: 1665 : if (!in_dev)
1634 : : return -ENODATA;
1635 : :
1636 : 1665 : nla = nla_reserve(skb, IFLA_INET_CONF, IPV4_DEVCONF_MAX * 4);
1637 [ + - ]: 1665 : if (nla == NULL)
1638 : : return -EMSGSIZE;
1639 : :
1640 [ + - ]: 48285 : for (i = 0; i < IPV4_DEVCONF_MAX; i++)
1641 : 46620 : ((u32 *) nla_data(nla))[i] = in_dev->cnf.data[i];
1642 : :
1643 : : return 0;
1644 : : }
1645 : :
1646 : : static const struct nla_policy inet_af_policy[IFLA_INET_MAX+1] = {
1647 : : [IFLA_INET_CONF] = { .type = NLA_NESTED },
1648 : : };
1649 : :
1650 : 0 : static int inet_validate_link_af(const struct net_device *dev,
1651 : : const struct nlattr *nla)
1652 : : {
1653 : 0 : struct nlattr *a, *tb[IFLA_INET_MAX+1];
1654 : : int err, rem;
1655 : :
1656 [ # # ][ # # ]: 0 : if (dev && !__in_dev_get_rtnl(dev))
1657 : : return -EAFNOSUPPORT;
1658 : :
1659 : : err = nla_parse_nested(tb, IFLA_INET_MAX, nla, inet_af_policy);
1660 [ # # ]: 0 : if (err < 0)
1661 : : return err;
1662 : :
1663 [ # # ]: 0 : if (tb[IFLA_INET_CONF]) {
1664 [ # # ]: 0 : nla_for_each_nested(a, tb[IFLA_INET_CONF], rem) {
1665 : : int cfgid = nla_type(a);
1666 : :
1667 [ # # ]: 0 : if (nla_len(a) < 4)
1668 : : return -EINVAL;
1669 : :
1670 [ # # ]: 0 : if (cfgid <= 0 || cfgid > IPV4_DEVCONF_MAX)
1671 : : return -EINVAL;
1672 : : }
1673 : : }
1674 : :
1675 : : return 0;
1676 : : }
1677 : :
1678 : 0 : static int inet_set_link_af(struct net_device *dev, const struct nlattr *nla)
1679 : : {
1680 : : struct in_device *in_dev = __in_dev_get_rtnl(dev);
1681 : 0 : struct nlattr *a, *tb[IFLA_INET_MAX+1];
1682 : : int rem;
1683 : :
1684 [ # # ]: 0 : if (!in_dev)
1685 : : return -EAFNOSUPPORT;
1686 : :
1687 [ # # ]: 0 : if (nla_parse_nested(tb, IFLA_INET_MAX, nla, NULL) < 0)
1688 : 0 : BUG();
1689 : :
1690 [ # # ]: 0 : if (tb[IFLA_INET_CONF]) {
1691 [ # # ]: 0 : nla_for_each_nested(a, tb[IFLA_INET_CONF], rem)
1692 : 0 : ipv4_devconf_set(in_dev, nla_type(a), nla_get_u32(a));
1693 : : }
1694 : :
1695 : : return 0;
1696 : : }
1697 : :
1698 : 0 : static int inet_netconf_msgsize_devconf(int type)
1699 : : {
1700 : : int size = NLMSG_ALIGN(sizeof(struct netconfmsg))
1701 : : + nla_total_size(4); /* NETCONFA_IFINDEX */
1702 : :
1703 : : /* type -1 is used for ALL */
1704 [ # # ]: 0 : if (type == -1 || type == NETCONFA_FORWARDING)
1705 : : size += nla_total_size(4);
1706 [ # # ]: 0 : if (type == -1 || type == NETCONFA_RP_FILTER)
1707 : 0 : size += nla_total_size(4);
1708 [ # # ]: 0 : if (type == -1 || type == NETCONFA_MC_FORWARDING)
1709 : 0 : size += nla_total_size(4);
1710 [ # # ]: 0 : if (type == -1 || type == NETCONFA_PROXY_NEIGH)
1711 : 0 : size += nla_total_size(4);
1712 : :
1713 : 0 : return size;
1714 : : }
1715 : :
1716 : 0 : static int inet_netconf_fill_devconf(struct sk_buff *skb, int ifindex,
1717 : : struct ipv4_devconf *devconf, u32 portid,
1718 : : u32 seq, int event, unsigned int flags,
1719 : : int type)
1720 : : {
1721 : : struct nlmsghdr *nlh;
1722 : : struct netconfmsg *ncm;
1723 : :
1724 : 0 : nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct netconfmsg),
1725 : : flags);
1726 [ # # ]: 0 : if (nlh == NULL)
1727 : : return -EMSGSIZE;
1728 : :
1729 : : ncm = nlmsg_data(nlh);
1730 : 0 : ncm->ncm_family = AF_INET;
1731 : :
1732 [ # # ]: 0 : if (nla_put_s32(skb, NETCONFA_IFINDEX, ifindex) < 0)
1733 : : goto nla_put_failure;
1734 : :
1735 : : /* type -1 is used for ALL */
1736 [ # # # # ]: 0 : if ((type == -1 || type == NETCONFA_FORWARDING) &&
1737 : 0 : nla_put_s32(skb, NETCONFA_FORWARDING,
1738 : : IPV4_DEVCONF(*devconf, FORWARDING)) < 0)
1739 : : goto nla_put_failure;
1740 [ # # # # ]: 0 : if ((type == -1 || type == NETCONFA_RP_FILTER) &&
1741 : 0 : nla_put_s32(skb, NETCONFA_RP_FILTER,
1742 : : IPV4_DEVCONF(*devconf, RP_FILTER)) < 0)
1743 : : goto nla_put_failure;
1744 [ # # # # ]: 0 : if ((type == -1 || type == NETCONFA_MC_FORWARDING) &&
1745 : 0 : nla_put_s32(skb, NETCONFA_MC_FORWARDING,
1746 : : IPV4_DEVCONF(*devconf, MC_FORWARDING)) < 0)
1747 : : goto nla_put_failure;
1748 [ # # # # ]: 0 : if ((type == -1 || type == NETCONFA_PROXY_NEIGH) &&
1749 : 0 : nla_put_s32(skb, NETCONFA_PROXY_NEIGH,
1750 : : IPV4_DEVCONF(*devconf, PROXY_ARP)) < 0)
1751 : : goto nla_put_failure;
1752 : :
1753 : 0 : return nlmsg_end(skb, nlh);
1754 : :
1755 : : nla_put_failure:
1756 : : nlmsg_cancel(skb, nlh);
1757 : : return -EMSGSIZE;
1758 : : }
1759 : :
1760 : 0 : void inet_netconf_notify_devconf(struct net *net, int type, int ifindex,
1761 : : struct ipv4_devconf *devconf)
1762 : : {
1763 : : struct sk_buff *skb;
1764 : : int err = -ENOBUFS;
1765 : :
1766 : 0 : skb = nlmsg_new(inet_netconf_msgsize_devconf(type), GFP_ATOMIC);
1767 [ # # ]: 0 : if (skb == NULL)
1768 : : goto errout;
1769 : :
1770 : 0 : err = inet_netconf_fill_devconf(skb, ifindex, devconf, 0, 0,
1771 : : RTM_NEWNETCONF, 0, type);
1772 [ # # ]: 0 : if (err < 0) {
1773 : : /* -EMSGSIZE implies BUG in inet_netconf_msgsize_devconf() */
1774 [ # # ]: 0 : WARN_ON(err == -EMSGSIZE);
1775 : 0 : kfree_skb(skb);
1776 : 0 : goto errout;
1777 : : }
1778 : 0 : rtnl_notify(skb, net, 0, RTNLGRP_IPV4_NETCONF, NULL, GFP_ATOMIC);
1779 : 0 : return;
1780 : : errout:
1781 [ # # ]: 0 : if (err < 0)
1782 : 0 : rtnl_set_sk_err(net, RTNLGRP_IPV4_NETCONF, err);
1783 : : }
1784 : :
1785 : : static const struct nla_policy devconf_ipv4_policy[NETCONFA_MAX+1] = {
1786 : : [NETCONFA_IFINDEX] = { .len = sizeof(int) },
1787 : : [NETCONFA_FORWARDING] = { .len = sizeof(int) },
1788 : : [NETCONFA_RP_FILTER] = { .len = sizeof(int) },
1789 : : [NETCONFA_PROXY_NEIGH] = { .len = sizeof(int) },
1790 : : };
1791 : :
1792 : 0 : static int inet_netconf_get_devconf(struct sk_buff *in_skb,
1793 : : struct nlmsghdr *nlh)
1794 : : {
1795 : : struct net *net = sock_net(in_skb->sk);
1796 : : struct nlattr *tb[NETCONFA_MAX+1];
1797 : : struct netconfmsg *ncm;
1798 : : struct sk_buff *skb;
1799 : : struct ipv4_devconf *devconf;
1800 : : struct in_device *in_dev;
1801 : 0 : struct net_device *dev;
1802 : : int ifindex;
1803 : : int err;
1804 : :
1805 : : err = nlmsg_parse(nlh, sizeof(*ncm), tb, NETCONFA_MAX,
1806 : : devconf_ipv4_policy);
1807 [ # # ]: 0 : if (err < 0)
1808 : : goto errout;
1809 : :
1810 : : err = EINVAL;
1811 [ # # ]: 0 : if (!tb[NETCONFA_IFINDEX])
1812 : : goto errout;
1813 : :
1814 : : ifindex = nla_get_s32(tb[NETCONFA_IFINDEX]);
1815 [ # # # ]: 0 : switch (ifindex) {
1816 : : case NETCONFA_IFINDEX_ALL:
1817 : 0 : devconf = net->ipv4.devconf_all;
1818 : 0 : break;
1819 : : case NETCONFA_IFINDEX_DEFAULT:
1820 : 0 : devconf = net->ipv4.devconf_dflt;
1821 : 0 : break;
1822 : : default:
1823 : 0 : dev = __dev_get_by_index(net, ifindex);
1824 [ # # ]: 0 : if (dev == NULL)
1825 : : goto errout;
1826 : : in_dev = __in_dev_get_rtnl(dev);
1827 [ # # ]: 0 : if (in_dev == NULL)
1828 : : goto errout;
1829 : 0 : devconf = &in_dev->cnf;
1830 : 0 : break;
1831 : : }
1832 : :
1833 : : err = -ENOBUFS;
1834 : 0 : skb = nlmsg_new(inet_netconf_msgsize_devconf(-1), GFP_ATOMIC);
1835 [ # # ]: 0 : if (skb == NULL)
1836 : : goto errout;
1837 : :
1838 : 0 : err = inet_netconf_fill_devconf(skb, ifindex, devconf,
1839 : : NETLINK_CB(in_skb).portid,
1840 : : nlh->nlmsg_seq, RTM_NEWNETCONF, 0,
1841 : : -1);
1842 [ # # ]: 0 : if (err < 0) {
1843 : : /* -EMSGSIZE implies BUG in inet_netconf_msgsize_devconf() */
1844 [ # # ]: 0 : WARN_ON(err == -EMSGSIZE);
1845 : 0 : kfree_skb(skb);
1846 : 0 : goto errout;
1847 : : }
1848 : 0 : err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).portid);
1849 : : errout:
1850 : 0 : return err;
1851 : : }
1852 : :
1853 : 0 : static int inet_netconf_dump_devconf(struct sk_buff *skb,
1854 : : struct netlink_callback *cb)
1855 : : {
1856 : : struct net *net = sock_net(skb->sk);
1857 : : int h, s_h;
1858 : : int idx, s_idx;
1859 : 0 : struct net_device *dev;
1860 : : struct in_device *in_dev;
1861 : : struct hlist_head *head;
1862 : :
1863 : 0 : s_h = cb->args[0];
1864 : 0 : s_idx = idx = cb->args[1];
1865 : :
1866 [ # # ]: 0 : for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
1867 : : idx = 0;
1868 : 0 : head = &net->dev_index_head[h];
1869 : : rcu_read_lock();
1870 : 0 : cb->seq = atomic_read(&net->ipv4.dev_addr_genid) ^
1871 : 0 : net->dev_base_seq;
1872 [ # # ][ # # ]: 0 : hlist_for_each_entry_rcu(dev, head, index_hlist) {
[ # # ]
1873 [ # # ]: 0 : if (idx < s_idx)
1874 : : goto cont;
1875 : : in_dev = __in_dev_get_rcu(dev);
1876 [ # # ]: 0 : if (!in_dev)
1877 : : goto cont;
1878 : :
1879 [ # # ]: 0 : if (inet_netconf_fill_devconf(skb, dev->ifindex,
1880 : : &in_dev->cnf,
1881 : 0 : NETLINK_CB(cb->skb).portid,
1882 : 0 : cb->nlh->nlmsg_seq,
1883 : : RTM_NEWNETCONF,
1884 : : NLM_F_MULTI,
1885 : : -1) <= 0) {
1886 : : rcu_read_unlock();
1887 : : goto done;
1888 : : }
1889 : : nl_dump_check_consistent(cb, nlmsg_hdr(skb));
1890 : : cont:
1891 : 0 : idx++;
1892 : : }
1893 : : rcu_read_unlock();
1894 : : }
1895 [ # # ]: 0 : if (h == NETDEV_HASHENTRIES) {
1896 [ # # ]: 0 : if (inet_netconf_fill_devconf(skb, NETCONFA_IFINDEX_ALL,
1897 : : net->ipv4.devconf_all,
1898 : 0 : NETLINK_CB(cb->skb).portid,
1899 : 0 : cb->nlh->nlmsg_seq,
1900 : : RTM_NEWNETCONF, NLM_F_MULTI,
1901 : : -1) <= 0)
1902 : : goto done;
1903 : : else
1904 : 0 : h++;
1905 : : }
1906 [ # # ]: 0 : if (h == NETDEV_HASHENTRIES + 1) {
1907 [ # # ]: 0 : if (inet_netconf_fill_devconf(skb, NETCONFA_IFINDEX_DEFAULT,
1908 : : net->ipv4.devconf_dflt,
1909 : 0 : NETLINK_CB(cb->skb).portid,
1910 : 0 : cb->nlh->nlmsg_seq,
1911 : : RTM_NEWNETCONF, NLM_F_MULTI,
1912 : : -1) <= 0)
1913 : : goto done;
1914 : : else
1915 : 0 : h++;
1916 : : }
1917 : : done:
1918 : 0 : cb->args[0] = h;
1919 : 0 : cb->args[1] = idx;
1920 : :
1921 : 0 : return skb->len;
1922 : : }
1923 : :
1924 : : #ifdef CONFIG_SYSCTL
1925 : :
1926 : 0 : static void devinet_copy_dflt_conf(struct net *net, int i)
1927 : : {
1928 : 0 : struct net_device *dev;
1929 : :
1930 : : rcu_read_lock();
1931 [ # # ]: 0 : for_each_netdev_rcu(net, dev) {
1932 : : struct in_device *in_dev;
1933 : :
1934 : : in_dev = __in_dev_get_rcu(dev);
1935 [ # # ][ # # ]: 0 : if (in_dev && !test_bit(i, in_dev->cnf.state))
1936 : 0 : in_dev->cnf.data[i] = net->ipv4.devconf_dflt->data[i];
1937 : : }
1938 : : rcu_read_unlock();
1939 : 0 : }
1940 : :
1941 : : /* called with RTNL locked */
1942 : 0 : static void inet_forward_change(struct net *net)
1943 : : {
1944 : 0 : struct net_device *dev;
1945 : 0 : int on = IPV4_DEVCONF_ALL(net, FORWARDING);
1946 : :
1947 : 0 : IPV4_DEVCONF_ALL(net, ACCEPT_REDIRECTS) = !on;
1948 : 0 : IPV4_DEVCONF_DFLT(net, FORWARDING) = on;
1949 : 0 : inet_netconf_notify_devconf(net, NETCONFA_FORWARDING,
1950 : : NETCONFA_IFINDEX_ALL,
1951 : : net->ipv4.devconf_all);
1952 : 0 : inet_netconf_notify_devconf(net, NETCONFA_FORWARDING,
1953 : : NETCONFA_IFINDEX_DEFAULT,
1954 : : net->ipv4.devconf_dflt);
1955 : :
1956 [ # # ]: 0 : for_each_netdev(net, dev) {
1957 : : struct in_device *in_dev;
1958 [ # # ]: 0 : if (on)
1959 : 0 : dev_disable_lro(dev);
1960 : : rcu_read_lock();
1961 : : in_dev = __in_dev_get_rcu(dev);
1962 [ # # ]: 0 : if (in_dev) {
1963 : : IN_DEV_CONF_SET(in_dev, FORWARDING, on);
1964 : 0 : inet_netconf_notify_devconf(net, NETCONFA_FORWARDING,
1965 : : dev->ifindex, &in_dev->cnf);
1966 : : }
1967 : : rcu_read_unlock();
1968 : : }
1969 : 0 : }
1970 : :
1971 : : static int devinet_conf_ifindex(struct net *net, struct ipv4_devconf *cnf)
1972 : : {
1973 [ # # ][ # # ]: 0 : if (cnf == net->ipv4.devconf_dflt)
1974 : : return NETCONFA_IFINDEX_DEFAULT;
1975 [ # # ][ # # ]: 0 : else if (cnf == net->ipv4.devconf_all)
1976 : : return NETCONFA_IFINDEX_ALL;
1977 : : else {
1978 : : struct in_device *idev
1979 : : = container_of(cnf, struct in_device, cnf);
1980 : 0 : return idev->dev->ifindex;
1981 : : }
1982 : : }
1983 : :
1984 : 0 : static int devinet_conf_proc(struct ctl_table *ctl, int write,
1985 : : void __user *buffer,
1986 : : size_t *lenp, loff_t *ppos)
1987 : : {
1988 : 230 : int old_value = *(int *)ctl->data;
1989 : 230 : int ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
1990 : 230 : int new_value = *(int *)ctl->data;
1991 : :
1992 [ - + ]: 230 : if (write) {
1993 : 0 : struct ipv4_devconf *cnf = ctl->extra1;
1994 : 0 : struct net *net = ctl->extra2;
1995 : 0 : int i = (int *)ctl->data - cnf->data;
1996 : : int ifindex;
1997 : :
1998 : 0 : set_bit(i, cnf->state);
1999 : :
2000 [ # # ]: 0 : if (cnf == net->ipv4.devconf_dflt)
2001 : 0 : devinet_copy_dflt_conf(net, i);
2002 [ # # ]: 230 : if (i == IPV4_DEVCONF_ACCEPT_LOCAL - 1 ||
2003 : 0 : i == IPV4_DEVCONF_ROUTE_LOCALNET - 1)
2004 [ # # ]: 0 : if ((new_value == 0) && (old_value != 0))
2005 : 0 : rt_cache_flush(net);
2006 : :
2007 [ # # ]: 0 : if (i == IPV4_DEVCONF_RP_FILTER - 1 &&
2008 : 0 : new_value != old_value) {
2009 : : ifindex = devinet_conf_ifindex(net, cnf);
2010 : 0 : inet_netconf_notify_devconf(net, NETCONFA_RP_FILTER,
2011 : : ifindex, cnf);
2012 : : }
2013 [ # # ]: 0 : if (i == IPV4_DEVCONF_PROXY_ARP - 1 &&
2014 : : new_value != old_value) {
2015 : : ifindex = devinet_conf_ifindex(net, cnf);
2016 : 0 : inet_netconf_notify_devconf(net, NETCONFA_PROXY_NEIGH,
2017 : : ifindex, cnf);
2018 : : }
2019 : : }
2020 : :
2021 : 230 : return ret;
2022 : : }
2023 : :
2024 : 0 : static int devinet_sysctl_forward(struct ctl_table *ctl, int write,
2025 : : void __user *buffer,
2026 : : size_t *lenp, loff_t *ppos)
2027 : : {
2028 : 12 : int *valp = ctl->data;
2029 : 12 : int val = *valp;
2030 : 12 : loff_t pos = *ppos;
2031 : 12 : int ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
2032 : :
2033 [ - + ][ # # ]: 12 : if (write && *valp != val) {
2034 : 0 : struct net *net = ctl->extra2;
2035 : :
2036 [ # # ]: 0 : if (valp != &IPV4_DEVCONF_DFLT(net, FORWARDING)) {
2037 [ # # ]: 0 : if (!rtnl_trylock()) {
2038 : : /* Restore the original values before restarting */
2039 : 0 : *valp = val;
2040 : 0 : *ppos = pos;
2041 : 0 : return restart_syscall();
2042 : : }
2043 [ # # ]: 0 : if (valp == &IPV4_DEVCONF_ALL(net, FORWARDING)) {
2044 : 0 : inet_forward_change(net);
2045 : : } else {
2046 : 0 : struct ipv4_devconf *cnf = ctl->extra1;
2047 : : struct in_device *idev =
2048 : : container_of(cnf, struct in_device, cnf);
2049 [ # # ]: 0 : if (*valp)
2050 : 0 : dev_disable_lro(idev->dev);
2051 : 0 : inet_netconf_notify_devconf(net,
2052 : : NETCONFA_FORWARDING,
2053 : 0 : idev->dev->ifindex,
2054 : : cnf);
2055 : : }
2056 : 0 : rtnl_unlock();
2057 : 0 : rt_cache_flush(net);
2058 : : } else
2059 : 0 : inet_netconf_notify_devconf(net, NETCONFA_FORWARDING,
2060 : : NETCONFA_IFINDEX_DEFAULT,
2061 : : net->ipv4.devconf_dflt);
2062 : : }
2063 : :
2064 : 12 : return ret;
2065 : : }
2066 : :
2067 : 0 : static int ipv4_doint_and_flush(struct ctl_table *ctl, int write,
2068 : : void __user *buffer,
2069 : : size_t *lenp, loff_t *ppos)
2070 : : {
2071 : 40 : int *valp = ctl->data;
2072 : 40 : int val = *valp;
2073 : 40 : int ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
2074 : 40 : struct net *net = ctl->extra2;
2075 : :
2076 [ - + ][ # # ]: 40 : if (write && *valp != val)
2077 : 0 : rt_cache_flush(net);
2078 : :
2079 : 0 : return ret;
2080 : : }
2081 : :
2082 : : #define DEVINET_SYSCTL_ENTRY(attr, name, mval, proc) \
2083 : : { \
2084 : : .procname = name, \
2085 : : .data = ipv4_devconf.data + \
2086 : : IPV4_DEVCONF_ ## attr - 1, \
2087 : : .maxlen = sizeof(int), \
2088 : : .mode = mval, \
2089 : : .proc_handler = proc, \
2090 : : .extra1 = &ipv4_devconf, \
2091 : : }
2092 : :
2093 : : #define DEVINET_SYSCTL_RW_ENTRY(attr, name) \
2094 : : DEVINET_SYSCTL_ENTRY(attr, name, 0644, devinet_conf_proc)
2095 : :
2096 : : #define DEVINET_SYSCTL_RO_ENTRY(attr, name) \
2097 : : DEVINET_SYSCTL_ENTRY(attr, name, 0444, devinet_conf_proc)
2098 : :
2099 : : #define DEVINET_SYSCTL_COMPLEX_ENTRY(attr, name, proc) \
2100 : : DEVINET_SYSCTL_ENTRY(attr, name, 0644, proc)
2101 : :
2102 : : #define DEVINET_SYSCTL_FLUSHING_ENTRY(attr, name) \
2103 : : DEVINET_SYSCTL_COMPLEX_ENTRY(attr, name, ipv4_doint_and_flush)
2104 : :
2105 : : static struct devinet_sysctl_table {
2106 : : struct ctl_table_header *sysctl_header;
2107 : : struct ctl_table devinet_vars[__IPV4_DEVCONF_MAX];
2108 : : } devinet_sysctl = {
2109 : : .devinet_vars = {
2110 : : DEVINET_SYSCTL_COMPLEX_ENTRY(FORWARDING, "forwarding",
2111 : : devinet_sysctl_forward),
2112 : : DEVINET_SYSCTL_RO_ENTRY(MC_FORWARDING, "mc_forwarding"),
2113 : :
2114 : : DEVINET_SYSCTL_RW_ENTRY(ACCEPT_REDIRECTS, "accept_redirects"),
2115 : : DEVINET_SYSCTL_RW_ENTRY(SECURE_REDIRECTS, "secure_redirects"),
2116 : : DEVINET_SYSCTL_RW_ENTRY(SHARED_MEDIA, "shared_media"),
2117 : : DEVINET_SYSCTL_RW_ENTRY(RP_FILTER, "rp_filter"),
2118 : : DEVINET_SYSCTL_RW_ENTRY(SEND_REDIRECTS, "send_redirects"),
2119 : : DEVINET_SYSCTL_RW_ENTRY(ACCEPT_SOURCE_ROUTE,
2120 : : "accept_source_route"),
2121 : : DEVINET_SYSCTL_RW_ENTRY(ACCEPT_LOCAL, "accept_local"),
2122 : : DEVINET_SYSCTL_RW_ENTRY(SRC_VMARK, "src_valid_mark"),
2123 : : DEVINET_SYSCTL_RW_ENTRY(PROXY_ARP, "proxy_arp"),
2124 : : DEVINET_SYSCTL_RW_ENTRY(MEDIUM_ID, "medium_id"),
2125 : : DEVINET_SYSCTL_RW_ENTRY(BOOTP_RELAY, "bootp_relay"),
2126 : : DEVINET_SYSCTL_RW_ENTRY(LOG_MARTIANS, "log_martians"),
2127 : : DEVINET_SYSCTL_RW_ENTRY(TAG, "tag"),
2128 : : DEVINET_SYSCTL_RW_ENTRY(ARPFILTER, "arp_filter"),
2129 : : DEVINET_SYSCTL_RW_ENTRY(ARP_ANNOUNCE, "arp_announce"),
2130 : : DEVINET_SYSCTL_RW_ENTRY(ARP_IGNORE, "arp_ignore"),
2131 : : DEVINET_SYSCTL_RW_ENTRY(ARP_ACCEPT, "arp_accept"),
2132 : : DEVINET_SYSCTL_RW_ENTRY(ARP_NOTIFY, "arp_notify"),
2133 : : DEVINET_SYSCTL_RW_ENTRY(PROXY_ARP_PVLAN, "proxy_arp_pvlan"),
2134 : : DEVINET_SYSCTL_RW_ENTRY(FORCE_IGMP_VERSION,
2135 : : "force_igmp_version"),
2136 : : DEVINET_SYSCTL_RW_ENTRY(IGMPV2_UNSOLICITED_REPORT_INTERVAL,
2137 : : "igmpv2_unsolicited_report_interval"),
2138 : : DEVINET_SYSCTL_RW_ENTRY(IGMPV3_UNSOLICITED_REPORT_INTERVAL,
2139 : : "igmpv3_unsolicited_report_interval"),
2140 : :
2141 : : DEVINET_SYSCTL_FLUSHING_ENTRY(NOXFRM, "disable_xfrm"),
2142 : : DEVINET_SYSCTL_FLUSHING_ENTRY(NOPOLICY, "disable_policy"),
2143 : : DEVINET_SYSCTL_FLUSHING_ENTRY(PROMOTE_SECONDARIES,
2144 : : "promote_secondaries"),
2145 : : DEVINET_SYSCTL_FLUSHING_ENTRY(ROUTE_LOCALNET,
2146 : : "route_localnet"),
2147 : : },
2148 : : };
2149 : :
2150 : 0 : static int __devinet_sysctl_register(struct net *net, char *dev_name,
2151 : : struct ipv4_devconf *p)
2152 : : {
2153 : : int i;
2154 : : struct devinet_sysctl_table *t;
2155 : : char path[sizeof("net/ipv4/conf/") + IFNAMSIZ];
2156 : :
2157 : 0 : t = kmemdup(&devinet_sysctl, sizeof(*t), GFP_KERNEL);
2158 [ # # ]: 0 : if (!t)
2159 : : goto out;
2160 : :
2161 [ # # ]: 0 : for (i = 0; i < ARRAY_SIZE(t->devinet_vars) - 1; i++) {
2162 : 0 : t->devinet_vars[i].data += (char *)p - (char *)&ipv4_devconf;
2163 : 0 : t->devinet_vars[i].extra1 = p;
2164 : 0 : t->devinet_vars[i].extra2 = net;
2165 : : }
2166 : :
2167 : 0 : snprintf(path, sizeof(path), "net/ipv4/conf/%s", dev_name);
2168 : :
2169 : 0 : t->sysctl_header = register_net_sysctl(net, path, t->devinet_vars);
2170 [ # # ]: 0 : if (!t->sysctl_header)
2171 : : goto free;
2172 : :
2173 : 0 : p->sysctl = t;
2174 : 0 : return 0;
2175 : :
2176 : : free:
2177 : 0 : kfree(t);
2178 : : out:
2179 : : return -ENOBUFS;
2180 : : }
2181 : :
2182 : 0 : static void __devinet_sysctl_unregister(struct ipv4_devconf *cnf)
2183 : : {
2184 : 0 : struct devinet_sysctl_table *t = cnf->sysctl;
2185 : :
2186 [ # # ]: 0 : if (t == NULL)
2187 : 0 : return;
2188 : :
2189 : 0 : cnf->sysctl = NULL;
2190 : 0 : unregister_net_sysctl_table(t->sysctl_header);
2191 : 0 : kfree(t);
2192 : : }
2193 : :
2194 : 0 : static void devinet_sysctl_register(struct in_device *idev)
2195 : : {
2196 : 0 : neigh_sysctl_register(idev->dev, idev->arp_parms, NULL);
2197 : 0 : __devinet_sysctl_register(dev_net(idev->dev), idev->dev->name,
2198 : : &idev->cnf);
2199 : 0 : }
2200 : :
2201 : : static void devinet_sysctl_unregister(struct in_device *idev)
2202 : : {
2203 : 0 : __devinet_sysctl_unregister(&idev->cnf);
2204 : 0 : neigh_sysctl_unregister(idev->arp_parms);
2205 : : }
2206 : :
2207 : : static struct ctl_table ctl_forward_entry[] = {
2208 : : {
2209 : : .procname = "ip_forward",
2210 : : .data = &ipv4_devconf.data[
2211 : : IPV4_DEVCONF_FORWARDING - 1],
2212 : : .maxlen = sizeof(int),
2213 : : .mode = 0644,
2214 : : .proc_handler = devinet_sysctl_forward,
2215 : : .extra1 = &ipv4_devconf,
2216 : : .extra2 = &init_net,
2217 : : },
2218 : : { },
2219 : : };
2220 : : #endif
2221 : :
2222 : 0 : static __net_init int devinet_init_net(struct net *net)
2223 : : {
2224 : : int err;
2225 : : struct ipv4_devconf *all, *dflt;
2226 : : #ifdef CONFIG_SYSCTL
2227 : : struct ctl_table *tbl = ctl_forward_entry;
2228 : : struct ctl_table_header *forw_hdr;
2229 : : #endif
2230 : :
2231 : : err = -ENOMEM;
2232 : : all = &ipv4_devconf;
2233 : : dflt = &ipv4_devconf_dflt;
2234 : :
2235 : : if (!net_eq(net, &init_net)) {
2236 : : all = kmemdup(all, sizeof(ipv4_devconf), GFP_KERNEL);
2237 : : if (all == NULL)
2238 : : goto err_alloc_all;
2239 : :
2240 : : dflt = kmemdup(dflt, sizeof(ipv4_devconf_dflt), GFP_KERNEL);
2241 : : if (dflt == NULL)
2242 : : goto err_alloc_dflt;
2243 : :
2244 : : #ifdef CONFIG_SYSCTL
2245 : : tbl = kmemdup(tbl, sizeof(ctl_forward_entry), GFP_KERNEL);
2246 : : if (tbl == NULL)
2247 : : goto err_alloc_ctl;
2248 : :
2249 : : tbl[0].data = &all->data[IPV4_DEVCONF_FORWARDING - 1];
2250 : : tbl[0].extra1 = all;
2251 : : tbl[0].extra2 = net;
2252 : : #endif
2253 : : }
2254 : :
2255 : : #ifdef CONFIG_SYSCTL
2256 : 0 : err = __devinet_sysctl_register(net, "all", all);
2257 [ # # ]: 0 : if (err < 0)
2258 : : goto err_reg_all;
2259 : :
2260 : 0 : err = __devinet_sysctl_register(net, "default", dflt);
2261 [ # # ]: 0 : if (err < 0)
2262 : : goto err_reg_dflt;
2263 : :
2264 : : err = -ENOMEM;
2265 : 0 : forw_hdr = register_net_sysctl(net, "net/ipv4", tbl);
2266 [ # # ]: 0 : if (forw_hdr == NULL)
2267 : : goto err_reg_ctl;
2268 : 0 : net->ipv4.forw_hdr = forw_hdr;
2269 : : #endif
2270 : :
2271 : 0 : net->ipv4.devconf_all = all;
2272 : 0 : net->ipv4.devconf_dflt = dflt;
2273 : 0 : return 0;
2274 : :
2275 : : #ifdef CONFIG_SYSCTL
2276 : : err_reg_ctl:
2277 : 0 : __devinet_sysctl_unregister(dflt);
2278 : : err_reg_dflt:
2279 : 0 : __devinet_sysctl_unregister(all);
2280 : : err_reg_all:
2281 : : if (tbl != ctl_forward_entry)
2282 : : kfree(tbl);
2283 : : err_alloc_ctl:
2284 : : #endif
2285 : : if (dflt != &ipv4_devconf_dflt)
2286 : : kfree(dflt);
2287 : : err_alloc_dflt:
2288 : : if (all != &ipv4_devconf)
2289 : : kfree(all);
2290 : : err_alloc_all:
2291 : 0 : return err;
2292 : : }
2293 : :
2294 : 0 : static __net_exit void devinet_exit_net(struct net *net)
2295 : : {
2296 : : #ifdef CONFIG_SYSCTL
2297 : : struct ctl_table *tbl;
2298 : :
2299 : 0 : tbl = net->ipv4.forw_hdr->ctl_table_arg;
2300 : 0 : unregister_net_sysctl_table(net->ipv4.forw_hdr);
2301 : 0 : __devinet_sysctl_unregister(net->ipv4.devconf_dflt);
2302 : 0 : __devinet_sysctl_unregister(net->ipv4.devconf_all);
2303 : 0 : kfree(tbl);
2304 : : #endif
2305 : 0 : kfree(net->ipv4.devconf_dflt);
2306 : 0 : kfree(net->ipv4.devconf_all);
2307 : 0 : }
2308 : :
2309 : : static __net_initdata struct pernet_operations devinet_ops = {
2310 : : .init = devinet_init_net,
2311 : : .exit = devinet_exit_net,
2312 : : };
2313 : :
2314 : : static struct rtnl_af_ops inet_af_ops = {
2315 : : .family = AF_INET,
2316 : : .fill_link_af = inet_fill_link_af,
2317 : : .get_link_af_size = inet_get_link_af_size,
2318 : : .validate_link_af = inet_validate_link_af,
2319 : : .set_link_af = inet_set_link_af,
2320 : : };
2321 : :
2322 : 0 : void __init devinet_init(void)
2323 : : {
2324 : : int i;
2325 : :
2326 [ # # ]: 0 : for (i = 0; i < IN4_ADDR_HSIZE; i++)
2327 : 0 : INIT_HLIST_HEAD(&inet_addr_lst[i]);
2328 : :
2329 : 0 : register_pernet_subsys(&devinet_ops);
2330 : :
2331 : 0 : register_gifconf(PF_INET, inet_gifconf);
2332 : 0 : register_netdevice_notifier(&ip_netdev_notifier);
2333 : :
2334 : 0 : queue_delayed_work(system_power_efficient_wq, &check_lifetime_work, 0);
2335 : :
2336 : 0 : rtnl_af_register(&inet_af_ops);
2337 : :
2338 : 0 : rtnl_register(PF_INET, RTM_NEWADDR, inet_rtm_newaddr, NULL, NULL);
2339 : 0 : rtnl_register(PF_INET, RTM_DELADDR, inet_rtm_deladdr, NULL, NULL);
2340 : 0 : rtnl_register(PF_INET, RTM_GETADDR, NULL, inet_dump_ifaddr, NULL);
2341 : 0 : rtnl_register(PF_INET, RTM_GETNETCONF, inet_netconf_get_devconf,
2342 : : inet_netconf_dump_devconf, NULL);
2343 : 0 : }
2344 : :
|