hc
2024-05-16 8d2a02b24d66aa359e83eebc1ed3c0f85367a1cb
kernel/net/ipv4/devinet.c
....@@ -1,10 +1,6 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * 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.
84 *
95 * Derived from the IP parts of dev.c 1.0.19
106 * Authors: Ross Biro
....@@ -105,6 +101,16 @@
105101 [IFA_CACHEINFO] = { .len = sizeof(struct ifa_cacheinfo) },
106102 [IFA_FLAGS] = { .type = NLA_U32 },
107103 [IFA_RT_PRIORITY] = { .type = NLA_U32 },
104
+ [IFA_TARGET_NETNSID] = { .type = NLA_S32 },
105
+};
106
+
107
+struct inet_fill_args {
108
+ u32 portid;
109
+ u32 seq;
110
+ int event;
111
+ unsigned int flags;
112
+ int netnsid;
113
+ int ifindex;
108114 };
109115
110116 #define IN4_ADDR_HSIZE_SHIFT 8
....@@ -189,7 +195,8 @@
189195
190196 static BLOCKING_NOTIFIER_HEAD(inetaddr_chain);
191197 static BLOCKING_NOTIFIER_HEAD(inetaddr_validator_chain);
192
-static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
198
+static void inet_del_ifa(struct in_device *in_dev,
199
+ struct in_ifaddr __rcu **ifap,
193200 int destroy);
194201 #ifdef CONFIG_SYSCTL
195202 static int devinet_sysctl_register(struct in_device *idev);
....@@ -296,8 +303,8 @@
296303
297304 static void inetdev_destroy(struct in_device *in_dev)
298305 {
299
- struct in_ifaddr *ifa;
300306 struct net_device *dev;
307
+ struct in_ifaddr *ifa;
301308
302309 ASSERT_RTNL();
303310
....@@ -307,7 +314,7 @@
307314
308315 ip_mc_destroy_dev(in_dev);
309316
310
- while ((ifa = in_dev->ifa_list) != NULL) {
317
+ while ((ifa = rtnl_dereference(in_dev->ifa_list)) != NULL) {
311318 inet_del_ifa(in_dev, &in_dev->ifa_list, 0);
312319 inet_free_ifa(ifa);
313320 }
....@@ -323,30 +330,35 @@
323330
324331 int inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b)
325332 {
333
+ const struct in_ifaddr *ifa;
334
+
326335 rcu_read_lock();
327
- for_primary_ifa(in_dev) {
336
+ in_dev_for_each_ifa_rcu(ifa, in_dev) {
328337 if (inet_ifa_match(a, ifa)) {
329338 if (!b || inet_ifa_match(b, ifa)) {
330339 rcu_read_unlock();
331340 return 1;
332341 }
333342 }
334
- } endfor_ifa(in_dev);
343
+ }
335344 rcu_read_unlock();
336345 return 0;
337346 }
338347
339
-static void __inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
340
- int destroy, struct nlmsghdr *nlh, u32 portid)
348
+static void __inet_del_ifa(struct in_device *in_dev,
349
+ struct in_ifaddr __rcu **ifap,
350
+ int destroy, struct nlmsghdr *nlh, u32 portid)
341351 {
342352 struct in_ifaddr *promote = NULL;
343
- struct in_ifaddr *ifa, *ifa1 = *ifap;
344
- struct in_ifaddr *last_prim = in_dev->ifa_list;
353
+ struct in_ifaddr *ifa, *ifa1;
354
+ struct in_ifaddr __rcu **last_prim;
345355 struct in_ifaddr *prev_prom = NULL;
346356 int do_promote = IN_DEV_PROMOTE_SECONDARIES(in_dev);
347357
348358 ASSERT_RTNL();
349359
360
+ ifa1 = rtnl_dereference(*ifap);
361
+ last_prim = ifap;
350362 if (in_dev->dead)
351363 goto no_promotions;
352364
....@@ -355,12 +367,12 @@
355367 **/
356368
357369 if (!(ifa1->ifa_flags & IFA_F_SECONDARY)) {
358
- struct in_ifaddr **ifap1 = &ifa1->ifa_next;
370
+ struct in_ifaddr __rcu **ifap1 = &ifa1->ifa_next;
359371
360
- while ((ifa = *ifap1) != NULL) {
372
+ while ((ifa = rtnl_dereference(*ifap1)) != NULL) {
361373 if (!(ifa->ifa_flags & IFA_F_SECONDARY) &&
362374 ifa1->ifa_scope <= ifa->ifa_scope)
363
- last_prim = ifa;
375
+ last_prim = &ifa->ifa_next;
364376
365377 if (!(ifa->ifa_flags & IFA_F_SECONDARY) ||
366378 ifa1->ifa_mask != ifa->ifa_mask ||
....@@ -390,7 +402,7 @@
390402 * and later to add them back with new prefsrc. Do this
391403 * while all addresses are on the device list.
392404 */
393
- for (ifa = promote; ifa; ifa = ifa->ifa_next) {
405
+ for (ifa = promote; ifa; ifa = rtnl_dereference(ifa->ifa_next)) {
394406 if (ifa1->ifa_mask == ifa->ifa_mask &&
395407 inet_ifa_match(ifa1->ifa_address, ifa))
396408 fib_del_ifaddr(ifa, ifa1);
....@@ -416,19 +428,25 @@
416428 blocking_notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa1);
417429
418430 if (promote) {
419
- struct in_ifaddr *next_sec = promote->ifa_next;
431
+ struct in_ifaddr *next_sec;
420432
433
+ next_sec = rtnl_dereference(promote->ifa_next);
421434 if (prev_prom) {
422
- prev_prom->ifa_next = promote->ifa_next;
423
- promote->ifa_next = last_prim->ifa_next;
424
- last_prim->ifa_next = promote;
435
+ struct in_ifaddr *last_sec;
436
+
437
+ rcu_assign_pointer(prev_prom->ifa_next, next_sec);
438
+
439
+ last_sec = rtnl_dereference(*last_prim);
440
+ rcu_assign_pointer(promote->ifa_next, last_sec);
441
+ rcu_assign_pointer(*last_prim, promote);
425442 }
426443
427444 promote->ifa_flags &= ~IFA_F_SECONDARY;
428445 rtmsg_ifa(RTM_NEWADDR, promote, nlh, portid);
429446 blocking_notifier_call_chain(&inetaddr_chain,
430447 NETDEV_UP, promote);
431
- for (ifa = next_sec; ifa; ifa = ifa->ifa_next) {
448
+ for (ifa = next_sec; ifa;
449
+ ifa = rtnl_dereference(ifa->ifa_next)) {
432450 if (ifa1->ifa_mask != ifa->ifa_mask ||
433451 !inet_ifa_match(ifa1->ifa_address, ifa))
434452 continue;
....@@ -440,7 +458,8 @@
440458 inet_free_ifa(ifa1);
441459 }
442460
443
-static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
461
+static void inet_del_ifa(struct in_device *in_dev,
462
+ struct in_ifaddr __rcu **ifap,
444463 int destroy)
445464 {
446465 __inet_del_ifa(in_dev, ifap, destroy, NULL, 0);
....@@ -453,9 +472,10 @@
453472 static int __inet_insert_ifa(struct in_ifaddr *ifa, struct nlmsghdr *nlh,
454473 u32 portid, struct netlink_ext_ack *extack)
455474 {
475
+ struct in_ifaddr __rcu **last_primary, **ifap;
456476 struct in_device *in_dev = ifa->ifa_dev;
457
- struct in_ifaddr *ifa1, **ifap, **last_primary;
458477 struct in_validator_info ivi;
478
+ struct in_ifaddr *ifa1;
459479 int ret;
460480
461481 ASSERT_RTNL();
....@@ -471,8 +491,10 @@
471491 /* Don't set IPv6 only flags to IPv4 addresses */
472492 ifa->ifa_flags &= ~IPV6ONLY_FLAGS;
473493
474
- for (ifap = &in_dev->ifa_list; (ifa1 = *ifap) != NULL;
475
- ifap = &ifa1->ifa_next) {
494
+ ifap = &in_dev->ifa_list;
495
+ ifa1 = rtnl_dereference(*ifap);
496
+
497
+ while (ifa1) {
476498 if (!(ifa1->ifa_flags & IFA_F_SECONDARY) &&
477499 ifa->ifa_scope <= ifa1->ifa_scope)
478500 last_primary = &ifa1->ifa_next;
....@@ -488,6 +510,9 @@
488510 }
489511 ifa->ifa_flags |= IFA_F_SECONDARY;
490512 }
513
+
514
+ ifap = &ifa1->ifa_next;
515
+ ifa1 = rtnl_dereference(*ifap);
491516 }
492517
493518 /* Allow any devices that wish to register ifaddr validtors to weigh
....@@ -513,8 +538,8 @@
513538 ifap = last_primary;
514539 }
515540
516
- ifa->ifa_next = *ifap;
517
- *ifap = ifa;
541
+ rcu_assign_pointer(ifa->ifa_next, *ifap);
542
+ rcu_assign_pointer(*ifap, ifa);
518543
519544 inet_hash_insert(dev_net(in_dev->dev), ifa);
520545
....@@ -579,12 +604,14 @@
579604 struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, __be32 prefix,
580605 __be32 mask)
581606 {
607
+ struct in_ifaddr *ifa;
608
+
582609 ASSERT_RTNL();
583610
584
- for_primary_ifa(in_dev) {
611
+ in_dev_for_each_ifa_rtnl(ifa, in_dev) {
585612 if (ifa->ifa_mask == mask && inet_ifa_match(prefix, ifa))
586613 return ifa;
587
- } endfor_ifa(in_dev);
614
+ }
588615 return NULL;
589616 }
590617
....@@ -618,16 +645,18 @@
618645 struct netlink_ext_ack *extack)
619646 {
620647 struct net *net = sock_net(skb->sk);
648
+ struct in_ifaddr __rcu **ifap;
621649 struct nlattr *tb[IFA_MAX+1];
622650 struct in_device *in_dev;
623651 struct ifaddrmsg *ifm;
624
- struct in_ifaddr *ifa, **ifap;
652
+ struct in_ifaddr *ifa;
653
+
625654 int err = -EINVAL;
626655
627656 ASSERT_RTNL();
628657
629
- err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv4_policy,
630
- extack);
658
+ err = nlmsg_parse_deprecated(nlh, sizeof(*ifm), tb, IFA_MAX,
659
+ ifa_ipv4_policy, extack);
631660 if (err < 0)
632661 goto errout;
633662
....@@ -638,7 +667,7 @@
638667 goto errout;
639668 }
640669
641
- for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
670
+ for (ifap = &in_dev->ifa_list; (ifa = rtnl_dereference(*ifap)) != NULL;
642671 ifap = &ifa->ifa_next) {
643672 if (tb[IFA_LOCAL] &&
644673 ifa->ifa_local != nla_get_in_addr(tb[IFA_LOCAL]))
....@@ -726,15 +755,19 @@
726755
727756 if (ifa->ifa_valid_lft != INFINITY_LIFE_TIME &&
728757 age >= ifa->ifa_valid_lft) {
729
- struct in_ifaddr **ifap;
758
+ struct in_ifaddr __rcu **ifap;
759
+ struct in_ifaddr *tmp;
730760
731
- for (ifap = &ifa->ifa_dev->ifa_list;
732
- *ifap != NULL; ifap = &(*ifap)->ifa_next) {
733
- if (*ifap == ifa) {
761
+ ifap = &ifa->ifa_dev->ifa_list;
762
+ tmp = rtnl_dereference(*ifap);
763
+ while (tmp) {
764
+ if (tmp == ifa) {
734765 inet_del_ifa(ifa->ifa_dev,
735766 ifap, 1);
736767 break;
737768 }
769
+ ifap = &tmp->ifa_next;
770
+ tmp = rtnl_dereference(*ifap);
738771 }
739772 } else if (ifa->ifa_preferred_lft !=
740773 INFINITY_LIFE_TIME &&
....@@ -788,7 +821,8 @@
788821 }
789822
790823 static struct in_ifaddr *rtm_to_ifaddr(struct net *net, struct nlmsghdr *nlh,
791
- __u32 *pvalid_lft, __u32 *pprefered_lft)
824
+ __u32 *pvalid_lft, __u32 *pprefered_lft,
825
+ struct netlink_ext_ack *extack)
792826 {
793827 struct nlattr *tb[IFA_MAX+1];
794828 struct in_ifaddr *ifa;
....@@ -797,8 +831,8 @@
797831 struct in_device *in_dev;
798832 int err;
799833
800
- err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv4_policy,
801
- NULL);
834
+ err = nlmsg_parse_deprecated(nlh, sizeof(*ifm), tb, IFA_MAX,
835
+ ifa_ipv4_policy, extack);
802836 if (err < 0)
803837 goto errout;
804838
....@@ -877,13 +911,12 @@
877911 static struct in_ifaddr *find_matching_ifa(struct in_ifaddr *ifa)
878912 {
879913 struct in_device *in_dev = ifa->ifa_dev;
880
- struct in_ifaddr *ifa1, **ifap;
914
+ struct in_ifaddr *ifa1;
881915
882916 if (!ifa->ifa_local)
883917 return NULL;
884918
885
- for (ifap = &in_dev->ifa_list; (ifa1 = *ifap) != NULL;
886
- ifap = &ifa1->ifa_next) {
919
+ in_dev_for_each_ifa_rtnl(ifa1, in_dev) {
887920 if (ifa1->ifa_mask == ifa->ifa_mask &&
888921 inet_ifa_match(ifa1->ifa_address, ifa) &&
889922 ifa1->ifa_local == ifa->ifa_local)
....@@ -903,7 +936,7 @@
903936
904937 ASSERT_RTNL();
905938
906
- ifa = rtm_to_ifaddr(net, nlh, &valid_lft, &prefered_lft);
939
+ ifa = rtm_to_ifaddr(net, nlh, &valid_lft, &prefered_lft, extack);
907940 if (IS_ERR(ifa))
908941 return PTR_ERR(ifa);
909942
....@@ -955,17 +988,18 @@
955988 {
956989 int rc = -1; /* Something else, probably a multicast. */
957990
958
- if (ipv4_is_zeronet(addr))
991
+ if (ipv4_is_zeronet(addr) || ipv4_is_lbcast(addr))
959992 rc = 0;
960993 else {
961994 __u32 haddr = ntohl(addr);
962
-
963995 if (IN_CLASSA(haddr))
964996 rc = 8;
965997 else if (IN_CLASSB(haddr))
966998 rc = 16;
967999 else if (IN_CLASSC(haddr))
9681000 rc = 24;
1001
+ else if (IN_CLASSE(haddr))
1002
+ rc = 32;
9691003 }
9701004
9711005 return rc;
....@@ -976,8 +1010,8 @@
9761010 {
9771011 struct sockaddr_in sin_orig;
9781012 struct sockaddr_in *sin = (struct sockaddr_in *)&ifr->ifr_addr;
1013
+ struct in_ifaddr __rcu **ifap = NULL;
9791014 struct in_device *in_dev;
980
- struct in_ifaddr **ifap = NULL;
9811015 struct in_ifaddr *ifa = NULL;
9821016 struct net_device *dev;
9831017 char *colon;
....@@ -1048,7 +1082,9 @@
10481082 /* note: we only do this for a limited set of ioctls
10491083 and only if the original address family was AF_INET.
10501084 This is checked above. */
1051
- for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
1085
+
1086
+ for (ifap = &in_dev->ifa_list;
1087
+ (ifa = rtnl_dereference(*ifap)) != NULL;
10521088 ifap = &ifa->ifa_next) {
10531089 if (!strcmp(ifr->ifr_name, ifa->ifa_label) &&
10541090 sin_orig.sin_addr.s_addr ==
....@@ -1061,7 +1097,8 @@
10611097 4.3BSD-style and passed in junk so we fall back to
10621098 comparing just the label */
10631099 if (!ifa) {
1064
- for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
1100
+ for (ifap = &in_dev->ifa_list;
1101
+ (ifa = rtnl_dereference(*ifap)) != NULL;
10651102 ifap = &ifa->ifa_next)
10661103 if (!strcmp(ifr->ifr_name, ifa->ifa_label))
10671104 break;
....@@ -1103,7 +1140,7 @@
11031140 inet_del_ifa(in_dev, ifap, 1);
11041141 break;
11051142 }
1106
- ret = dev_change_flags(dev, ifr->ifr_flags);
1143
+ ret = dev_change_flags(dev, ifr->ifr_flags, NULL);
11071144 break;
11081145
11091146 case SIOCSIFADDR: /* Set interface address (and family) */
....@@ -1207,10 +1244,10 @@
12071244 return ret;
12081245 }
12091246
1210
-static int inet_gifconf(struct net_device *dev, char __user *buf, int len, int size)
1247
+int inet_gifconf(struct net_device *dev, char __user *buf, int len, int size)
12111248 {
12121249 struct in_device *in_dev = __in_dev_get_rtnl(dev);
1213
- struct in_ifaddr *ifa;
1250
+ const struct in_ifaddr *ifa;
12141251 struct ifreq ifr;
12151252 int done = 0;
12161253
....@@ -1220,7 +1257,7 @@
12201257 if (!in_dev)
12211258 goto out;
12221259
1223
- for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) {
1260
+ in_dev_for_each_ifa_rtnl(ifa, in_dev) {
12241261 if (!buf) {
12251262 done += size;
12261263 continue;
....@@ -1248,18 +1285,24 @@
12481285 static __be32 in_dev_select_addr(const struct in_device *in_dev,
12491286 int scope)
12501287 {
1251
- for_primary_ifa(in_dev) {
1288
+ const struct in_ifaddr *ifa;
1289
+
1290
+ in_dev_for_each_ifa_rcu(ifa, in_dev) {
1291
+ if (ifa->ifa_flags & IFA_F_SECONDARY)
1292
+ continue;
12521293 if (ifa->ifa_scope != RT_SCOPE_LINK &&
12531294 ifa->ifa_scope <= scope)
12541295 return ifa->ifa_local;
1255
- } endfor_ifa(in_dev);
1296
+ }
12561297
12571298 return 0;
12581299 }
12591300
12601301 __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope)
12611302 {
1303
+ const struct in_ifaddr *ifa;
12621304 __be32 addr = 0;
1305
+ unsigned char localnet_scope = RT_SCOPE_HOST;
12631306 struct in_device *in_dev;
12641307 struct net *net = dev_net(dev);
12651308 int master_idx;
....@@ -1269,8 +1312,13 @@
12691312 if (!in_dev)
12701313 goto no_in_dev;
12711314
1272
- for_primary_ifa(in_dev) {
1273
- if (ifa->ifa_scope > scope)
1315
+ if (unlikely(IN_DEV_ROUTE_LOCALNET(in_dev)))
1316
+ localnet_scope = RT_SCOPE_LINK;
1317
+
1318
+ in_dev_for_each_ifa_rcu(ifa, in_dev) {
1319
+ if (ifa->ifa_flags & IFA_F_SECONDARY)
1320
+ continue;
1321
+ if (min(ifa->ifa_scope, localnet_scope) > scope)
12741322 continue;
12751323 if (!dst || inet_ifa_match(dst, ifa)) {
12761324 addr = ifa->ifa_local;
....@@ -1278,7 +1326,7 @@
12781326 }
12791327 if (!addr)
12801328 addr = ifa->ifa_local;
1281
- } endfor_ifa(in_dev);
1329
+ }
12821330
12831331 if (addr)
12841332 goto out_unlock;
....@@ -1323,13 +1371,20 @@
13231371 static __be32 confirm_addr_indev(struct in_device *in_dev, __be32 dst,
13241372 __be32 local, int scope)
13251373 {
1326
- int same = 0;
1374
+ unsigned char localnet_scope = RT_SCOPE_HOST;
1375
+ const struct in_ifaddr *ifa;
13271376 __be32 addr = 0;
1377
+ int same = 0;
13281378
1329
- for_ifa(in_dev) {
1379
+ if (unlikely(IN_DEV_ROUTE_LOCALNET(in_dev)))
1380
+ localnet_scope = RT_SCOPE_LINK;
1381
+
1382
+ in_dev_for_each_ifa_rcu(ifa, in_dev) {
1383
+ unsigned char min_scope = min(ifa->ifa_scope, localnet_scope);
1384
+
13301385 if (!addr &&
13311386 (local == ifa->ifa_local || !local) &&
1332
- ifa->ifa_scope <= scope) {
1387
+ min_scope <= scope) {
13331388 addr = ifa->ifa_local;
13341389 if (same)
13351390 break;
....@@ -1344,7 +1399,7 @@
13441399 if (inet_ifa_match(addr, ifa))
13451400 break;
13461401 /* No, then can we use new local src? */
1347
- if (ifa->ifa_scope <= scope) {
1402
+ if (min_scope <= scope) {
13481403 addr = ifa->ifa_local;
13491404 break;
13501405 }
....@@ -1352,7 +1407,7 @@
13521407 same = 0;
13531408 }
13541409 }
1355
- } endfor_ifa(in_dev);
1410
+ }
13561411
13571412 return same ? addr : 0;
13581413 }
....@@ -1426,7 +1481,7 @@
14261481 struct in_ifaddr *ifa;
14271482 int named = 0;
14281483
1429
- for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) {
1484
+ in_dev_for_each_ifa_rtnl(ifa, in_dev) {
14301485 char old[IFNAMSIZ], *dot;
14311486
14321487 memcpy(old, ifa->ifa_label, IFNAMSIZ);
....@@ -1451,10 +1506,9 @@
14511506 struct in_device *in_dev)
14521507
14531508 {
1454
- struct in_ifaddr *ifa;
1509
+ const struct in_ifaddr *ifa;
14551510
1456
- for (ifa = in_dev->ifa_list; ifa;
1457
- ifa = ifa->ifa_next) {
1511
+ in_dev_for_each_ifa_rtnl(ifa, in_dev) {
14581512 arp_send(ARPOP_REQUEST, ETH_P_ARP,
14591513 ifa->ifa_local, dev,
14601514 ifa->ifa_local, NULL,
....@@ -1518,11 +1572,11 @@
15181572 }
15191573 }
15201574 ip_mc_up(in_dev);
1521
- /* fall through */
1575
+ fallthrough;
15221576 case NETDEV_CHANGEADDR:
15231577 if (!IN_DEV_ARP_NOTIFY(in_dev))
15241578 break;
1525
- /* fall through */
1579
+ fallthrough;
15261580 case NETDEV_NOTIFY_PEERS:
15271581 /* Send gratuitous ARP to notify of link change */
15281582 inetdev_send_gratuitous_arp(dev, in_dev);
....@@ -1540,7 +1594,7 @@
15401594 if (inetdev_valid_mtu(dev->mtu))
15411595 break;
15421596 /* disable IP when MTU is not enough */
1543
- /* fall through */
1597
+ fallthrough;
15441598 case NETDEV_UNREGISTER:
15451599 inetdev_destroy(in_dev);
15461600 break;
....@@ -1593,13 +1647,14 @@
15931647 }
15941648
15951649 static int inet_fill_ifaddr(struct sk_buff *skb, struct in_ifaddr *ifa,
1596
- u32 portid, u32 seq, int event, unsigned int flags)
1650
+ struct inet_fill_args *args)
15971651 {
15981652 struct ifaddrmsg *ifm;
15991653 struct nlmsghdr *nlh;
16001654 u32 preferred, valid;
16011655
1602
- nlh = nlmsg_put(skb, portid, seq, event, sizeof(*ifm), flags);
1656
+ nlh = nlmsg_put(skb, args->portid, args->seq, args->event, sizeof(*ifm),
1657
+ args->flags);
16031658 if (!nlh)
16041659 return -EMSGSIZE;
16051660
....@@ -1609,6 +1664,10 @@
16091664 ifm->ifa_flags = ifa->ifa_flags;
16101665 ifm->ifa_scope = ifa->ifa_scope;
16111666 ifm->ifa_index = ifa->ifa_dev->dev->ifindex;
1667
+
1668
+ if (args->netnsid >= 0 &&
1669
+ nla_put_s32(skb, IFA_TARGET_NETNSID, args->netnsid))
1670
+ goto nla_put_failure;
16121671
16131672 if (!(ifm->ifa_flags & IFA_F_PERMANENT)) {
16141673 preferred = ifa->ifa_preferred_lft;
....@@ -1654,27 +1713,144 @@
16541713 return -EMSGSIZE;
16551714 }
16561715
1716
+static int inet_valid_dump_ifaddr_req(const struct nlmsghdr *nlh,
1717
+ struct inet_fill_args *fillargs,
1718
+ struct net **tgt_net, struct sock *sk,
1719
+ struct netlink_callback *cb)
1720
+{
1721
+ struct netlink_ext_ack *extack = cb->extack;
1722
+ struct nlattr *tb[IFA_MAX+1];
1723
+ struct ifaddrmsg *ifm;
1724
+ int err, i;
1725
+
1726
+ if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*ifm))) {
1727
+ NL_SET_ERR_MSG(extack, "ipv4: Invalid header for address dump request");
1728
+ return -EINVAL;
1729
+ }
1730
+
1731
+ ifm = nlmsg_data(nlh);
1732
+ if (ifm->ifa_prefixlen || ifm->ifa_flags || ifm->ifa_scope) {
1733
+ NL_SET_ERR_MSG(extack, "ipv4: Invalid values in header for address dump request");
1734
+ return -EINVAL;
1735
+ }
1736
+
1737
+ fillargs->ifindex = ifm->ifa_index;
1738
+ if (fillargs->ifindex) {
1739
+ cb->answer_flags |= NLM_F_DUMP_FILTERED;
1740
+ fillargs->flags |= NLM_F_DUMP_FILTERED;
1741
+ }
1742
+
1743
+ err = nlmsg_parse_deprecated_strict(nlh, sizeof(*ifm), tb, IFA_MAX,
1744
+ ifa_ipv4_policy, extack);
1745
+ if (err < 0)
1746
+ return err;
1747
+
1748
+ for (i = 0; i <= IFA_MAX; ++i) {
1749
+ if (!tb[i])
1750
+ continue;
1751
+
1752
+ if (i == IFA_TARGET_NETNSID) {
1753
+ struct net *net;
1754
+
1755
+ fillargs->netnsid = nla_get_s32(tb[i]);
1756
+
1757
+ net = rtnl_get_net_ns_capable(sk, fillargs->netnsid);
1758
+ if (IS_ERR(net)) {
1759
+ fillargs->netnsid = -1;
1760
+ NL_SET_ERR_MSG(extack, "ipv4: Invalid target network namespace id");
1761
+ return PTR_ERR(net);
1762
+ }
1763
+ *tgt_net = net;
1764
+ } else {
1765
+ NL_SET_ERR_MSG(extack, "ipv4: Unsupported attribute in dump request");
1766
+ return -EINVAL;
1767
+ }
1768
+ }
1769
+
1770
+ return 0;
1771
+}
1772
+
1773
+static int in_dev_dump_addr(struct in_device *in_dev, struct sk_buff *skb,
1774
+ struct netlink_callback *cb, int s_ip_idx,
1775
+ struct inet_fill_args *fillargs)
1776
+{
1777
+ struct in_ifaddr *ifa;
1778
+ int ip_idx = 0;
1779
+ int err;
1780
+
1781
+ in_dev_for_each_ifa_rtnl(ifa, in_dev) {
1782
+ if (ip_idx < s_ip_idx) {
1783
+ ip_idx++;
1784
+ continue;
1785
+ }
1786
+ err = inet_fill_ifaddr(skb, ifa, fillargs);
1787
+ if (err < 0)
1788
+ goto done;
1789
+
1790
+ nl_dump_check_consistent(cb, nlmsg_hdr(skb));
1791
+ ip_idx++;
1792
+ }
1793
+ err = 0;
1794
+
1795
+done:
1796
+ cb->args[2] = ip_idx;
1797
+
1798
+ return err;
1799
+}
1800
+
16571801 static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
16581802 {
1803
+ const struct nlmsghdr *nlh = cb->nlh;
1804
+ struct inet_fill_args fillargs = {
1805
+ .portid = NETLINK_CB(cb->skb).portid,
1806
+ .seq = nlh->nlmsg_seq,
1807
+ .event = RTM_NEWADDR,
1808
+ .flags = NLM_F_MULTI,
1809
+ .netnsid = -1,
1810
+ };
16591811 struct net *net = sock_net(skb->sk);
1812
+ struct net *tgt_net = net;
16601813 int h, s_h;
16611814 int idx, s_idx;
1662
- int ip_idx, s_ip_idx;
1815
+ int s_ip_idx;
16631816 struct net_device *dev;
16641817 struct in_device *in_dev;
1665
- struct in_ifaddr *ifa;
16661818 struct hlist_head *head;
1819
+ int err = 0;
16671820
16681821 s_h = cb->args[0];
16691822 s_idx = idx = cb->args[1];
1670
- s_ip_idx = ip_idx = cb->args[2];
1823
+ s_ip_idx = cb->args[2];
1824
+
1825
+ if (cb->strict_check) {
1826
+ err = inet_valid_dump_ifaddr_req(nlh, &fillargs, &tgt_net,
1827
+ skb->sk, cb);
1828
+ if (err < 0)
1829
+ goto put_tgt_net;
1830
+
1831
+ err = 0;
1832
+ if (fillargs.ifindex) {
1833
+ dev = __dev_get_by_index(tgt_net, fillargs.ifindex);
1834
+ if (!dev) {
1835
+ err = -ENODEV;
1836
+ goto put_tgt_net;
1837
+ }
1838
+
1839
+ in_dev = __in_dev_get_rtnl(dev);
1840
+ if (in_dev) {
1841
+ err = in_dev_dump_addr(in_dev, skb, cb, s_ip_idx,
1842
+ &fillargs);
1843
+ }
1844
+ goto put_tgt_net;
1845
+ }
1846
+ }
16711847
16721848 for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
16731849 idx = 0;
1674
- head = &net->dev_index_head[h];
1850
+ head = &tgt_net->dev_index_head[h];
16751851 rcu_read_lock();
1676
- cb->seq = atomic_read(&net->ipv4.dev_addr_genid) ^
1677
- net->dev_base_seq;
1852
+ cb->seq = atomic_read(&tgt_net->ipv4.dev_addr_genid) ^
1853
+ tgt_net->dev_base_seq;
16781854 hlist_for_each_entry_rcu(dev, head, index_hlist) {
16791855 if (idx < s_idx)
16801856 goto cont;
....@@ -1684,18 +1860,11 @@
16841860 if (!in_dev)
16851861 goto cont;
16861862
1687
- for (ifa = in_dev->ifa_list, ip_idx = 0; ifa;
1688
- ifa = ifa->ifa_next, ip_idx++) {
1689
- if (ip_idx < s_ip_idx)
1690
- continue;
1691
- if (inet_fill_ifaddr(skb, ifa,
1692
- NETLINK_CB(cb->skb).portid,
1693
- cb->nlh->nlmsg_seq,
1694
- RTM_NEWADDR, NLM_F_MULTI) < 0) {
1695
- rcu_read_unlock();
1696
- goto done;
1697
- }
1698
- nl_dump_check_consistent(cb, nlmsg_hdr(skb));
1863
+ err = in_dev_dump_addr(in_dev, skb, cb, s_ip_idx,
1864
+ &fillargs);
1865
+ if (err < 0) {
1866
+ rcu_read_unlock();
1867
+ goto done;
16991868 }
17001869 cont:
17011870 idx++;
....@@ -1706,16 +1875,24 @@
17061875 done:
17071876 cb->args[0] = h;
17081877 cb->args[1] = idx;
1709
- cb->args[2] = ip_idx;
1878
+put_tgt_net:
1879
+ if (fillargs.netnsid >= 0)
1880
+ put_net(tgt_net);
17101881
1711
- return skb->len;
1882
+ return skb->len ? : err;
17121883 }
17131884
17141885 static void rtmsg_ifa(int event, struct in_ifaddr *ifa, struct nlmsghdr *nlh,
17151886 u32 portid)
17161887 {
1888
+ struct inet_fill_args fillargs = {
1889
+ .portid = portid,
1890
+ .seq = nlh ? nlh->nlmsg_seq : 0,
1891
+ .event = event,
1892
+ .flags = 0,
1893
+ .netnsid = -1,
1894
+ };
17171895 struct sk_buff *skb;
1718
- u32 seq = nlh ? nlh->nlmsg_seq : 0;
17191896 int err = -ENOBUFS;
17201897 struct net *net;
17211898
....@@ -1724,7 +1901,7 @@
17241901 if (!skb)
17251902 goto errout;
17261903
1727
- err = inet_fill_ifaddr(skb, ifa, portid, seq, event, 0);
1904
+ err = inet_fill_ifaddr(skb, ifa, &fillargs);
17281905 if (err < 0) {
17291906 /* -EMSGSIZE implies BUG in inet_nlmsg_size() */
17301907 WARN_ON(err == -EMSGSIZE);
....@@ -1782,7 +1959,8 @@
17821959 if (dev && !__in_dev_get_rcu(dev))
17831960 return -EAFNOSUPPORT;
17841961
1785
- err = nla_parse_nested(tb, IFLA_INET_MAX, nla, inet_af_policy, NULL);
1962
+ err = nla_parse_nested_deprecated(tb, IFLA_INET_MAX, nla,
1963
+ inet_af_policy, NULL);
17861964 if (err < 0)
17871965 return err;
17881966
....@@ -1810,8 +1988,8 @@
18101988 if (!in_dev)
18111989 return -EAFNOSUPPORT;
18121990
1813
- if (nla_parse_nested(tb, IFLA_INET_MAX, nla, NULL, NULL) < 0)
1814
- BUG();
1991
+ if (nla_parse_nested_deprecated(tb, IFLA_INET_MAX, nla, NULL, NULL) < 0)
1992
+ return -EINVAL;
18151993
18161994 if (tb[IFLA_INET_CONF]) {
18171995 nla_for_each_nested(a, tb[IFLA_INET_CONF], rem)
....@@ -1939,13 +2117,51 @@
19392117 [NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN] = { .len = sizeof(int) },
19402118 };
19412119
2120
+static int inet_netconf_valid_get_req(struct sk_buff *skb,
2121
+ const struct nlmsghdr *nlh,
2122
+ struct nlattr **tb,
2123
+ struct netlink_ext_ack *extack)
2124
+{
2125
+ int i, err;
2126
+
2127
+ if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(struct netconfmsg))) {
2128
+ NL_SET_ERR_MSG(extack, "ipv4: Invalid header for netconf get request");
2129
+ return -EINVAL;
2130
+ }
2131
+
2132
+ if (!netlink_strict_get_check(skb))
2133
+ return nlmsg_parse_deprecated(nlh, sizeof(struct netconfmsg),
2134
+ tb, NETCONFA_MAX,
2135
+ devconf_ipv4_policy, extack);
2136
+
2137
+ err = nlmsg_parse_deprecated_strict(nlh, sizeof(struct netconfmsg),
2138
+ tb, NETCONFA_MAX,
2139
+ devconf_ipv4_policy, extack);
2140
+ if (err)
2141
+ return err;
2142
+
2143
+ for (i = 0; i <= NETCONFA_MAX; i++) {
2144
+ if (!tb[i])
2145
+ continue;
2146
+
2147
+ switch (i) {
2148
+ case NETCONFA_IFINDEX:
2149
+ break;
2150
+ default:
2151
+ NL_SET_ERR_MSG(extack, "ipv4: Unsupported attribute in netconf get request");
2152
+ return -EINVAL;
2153
+ }
2154
+ }
2155
+
2156
+ return 0;
2157
+}
2158
+
19422159 static int inet_netconf_get_devconf(struct sk_buff *in_skb,
19432160 struct nlmsghdr *nlh,
19442161 struct netlink_ext_ack *extack)
19452162 {
19462163 struct net *net = sock_net(in_skb->sk);
19472164 struct nlattr *tb[NETCONFA_MAX+1];
1948
- struct netconfmsg *ncm;
19492165 struct sk_buff *skb;
19502166 struct ipv4_devconf *devconf;
19512167 struct in_device *in_dev;
....@@ -1953,9 +2169,8 @@
19532169 int ifindex;
19542170 int err;
19552171
1956
- err = nlmsg_parse(nlh, sizeof(*ncm), tb, NETCONFA_MAX,
1957
- devconf_ipv4_policy, extack);
1958
- if (err < 0)
2172
+ err = inet_netconf_valid_get_req(in_skb, nlh, tb, extack);
2173
+ if (err)
19592174 goto errout;
19602175
19612176 err = -EINVAL;
....@@ -2004,12 +2219,28 @@
20042219 static int inet_netconf_dump_devconf(struct sk_buff *skb,
20052220 struct netlink_callback *cb)
20062221 {
2222
+ const struct nlmsghdr *nlh = cb->nlh;
20072223 struct net *net = sock_net(skb->sk);
20082224 int h, s_h;
20092225 int idx, s_idx;
20102226 struct net_device *dev;
20112227 struct in_device *in_dev;
20122228 struct hlist_head *head;
2229
+
2230
+ if (cb->strict_check) {
2231
+ struct netlink_ext_ack *extack = cb->extack;
2232
+ struct netconfmsg *ncm;
2233
+
2234
+ if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*ncm))) {
2235
+ NL_SET_ERR_MSG(extack, "ipv4: Invalid header for netconf dump request");
2236
+ return -EINVAL;
2237
+ }
2238
+
2239
+ if (nlmsg_attrlen(nlh, sizeof(*ncm))) {
2240
+ NL_SET_ERR_MSG(extack, "ipv4: Invalid data after header in netconf dump request");
2241
+ return -EINVAL;
2242
+ }
2243
+ }
20132244
20142245 s_h = cb->args[0];
20152246 s_idx = idx = cb->args[1];
....@@ -2030,7 +2261,7 @@
20302261 if (inet_netconf_fill_devconf(skb, dev->ifindex,
20312262 &in_dev->cnf,
20322263 NETLINK_CB(cb->skb).portid,
2033
- cb->nlh->nlmsg_seq,
2264
+ nlh->nlmsg_seq,
20342265 RTM_NEWNETCONF,
20352266 NLM_F_MULTI,
20362267 NETCONFA_ALL) < 0) {
....@@ -2047,7 +2278,7 @@
20472278 if (inet_netconf_fill_devconf(skb, NETCONFA_IFINDEX_ALL,
20482279 net->ipv4.devconf_all,
20492280 NETLINK_CB(cb->skb).portid,
2050
- cb->nlh->nlmsg_seq,
2281
+ nlh->nlmsg_seq,
20512282 RTM_NEWNETCONF, NLM_F_MULTI,
20522283 NETCONFA_ALL) < 0)
20532284 goto done;
....@@ -2058,7 +2289,7 @@
20582289 if (inet_netconf_fill_devconf(skb, NETCONFA_IFINDEX_DEFAULT,
20592290 net->ipv4.devconf_dflt,
20602291 NETLINK_CB(cb->skb).portid,
2061
- cb->nlh->nlmsg_seq,
2292
+ nlh->nlmsg_seq,
20622293 RTM_NEWNETCONF, NLM_F_MULTI,
20632294 NETCONFA_ALL) < 0)
20642295 goto done;
....@@ -2136,8 +2367,7 @@
21362367 }
21372368
21382369 static int devinet_conf_proc(struct ctl_table *ctl, int write,
2139
- void __user *buffer,
2140
- size_t *lenp, loff_t *ppos)
2370
+ void *buffer, size_t *lenp, loff_t *ppos)
21412371 {
21422372 int old_value = *(int *)ctl->data;
21432373 int ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
....@@ -2189,8 +2419,7 @@
21892419 }
21902420
21912421 static int devinet_sysctl_forward(struct ctl_table *ctl, int write,
2192
- void __user *buffer,
2193
- size_t *lenp, loff_t *ppos)
2422
+ void *buffer, size_t *lenp, loff_t *ppos)
21942423 {
21952424 int *valp = ctl->data;
21962425 int val = *valp;
....@@ -2233,8 +2462,7 @@
22332462 }
22342463
22352464 static int ipv4_doint_and_flush(struct ctl_table *ctl, int write,
2236
- void __user *buffer,
2237
- size_t *lenp, loff_t *ppos)
2465
+ void *buffer, size_t *lenp, loff_t *ppos)
22382466 {
22392467 int *valp = ctl->data;
22402468 int val = *valp;
....@@ -2416,32 +2644,51 @@
24162644 int err;
24172645 struct ipv4_devconf *all, *dflt;
24182646 #ifdef CONFIG_SYSCTL
2419
- struct ctl_table *tbl = ctl_forward_entry;
2647
+ struct ctl_table *tbl;
24202648 struct ctl_table_header *forw_hdr;
24212649 #endif
24222650
24232651 err = -ENOMEM;
2424
- all = &ipv4_devconf;
2425
- dflt = &ipv4_devconf_dflt;
2652
+ all = kmemdup(&ipv4_devconf, sizeof(ipv4_devconf), GFP_KERNEL);
2653
+ if (!all)
2654
+ goto err_alloc_all;
24262655
2427
- if (!net_eq(net, &init_net)) {
2428
- all = kmemdup(all, sizeof(ipv4_devconf), GFP_KERNEL);
2429
- if (!all)
2430
- goto err_alloc_all;
2431
-
2432
- dflt = kmemdup(dflt, sizeof(ipv4_devconf_dflt), GFP_KERNEL);
2433
- if (!dflt)
2434
- goto err_alloc_dflt;
2656
+ dflt = kmemdup(&ipv4_devconf_dflt, sizeof(ipv4_devconf_dflt), GFP_KERNEL);
2657
+ if (!dflt)
2658
+ goto err_alloc_dflt;
24352659
24362660 #ifdef CONFIG_SYSCTL
2437
- tbl = kmemdup(tbl, sizeof(ctl_forward_entry), GFP_KERNEL);
2438
- if (!tbl)
2439
- goto err_alloc_ctl;
2661
+ tbl = kmemdup(ctl_forward_entry, sizeof(ctl_forward_entry), GFP_KERNEL);
2662
+ if (!tbl)
2663
+ goto err_alloc_ctl;
24402664
2441
- tbl[0].data = &all->data[IPV4_DEVCONF_FORWARDING - 1];
2442
- tbl[0].extra1 = all;
2443
- tbl[0].extra2 = net;
2665
+ tbl[0].data = &all->data[IPV4_DEVCONF_FORWARDING - 1];
2666
+ tbl[0].extra1 = all;
2667
+ tbl[0].extra2 = net;
24442668 #endif
2669
+
2670
+ if (!net_eq(net, &init_net)) {
2671
+ switch (net_inherit_devconf()) {
2672
+ case 3:
2673
+ /* copy from the current netns */
2674
+ memcpy(all, current->nsproxy->net_ns->ipv4.devconf_all,
2675
+ sizeof(ipv4_devconf));
2676
+ memcpy(dflt,
2677
+ current->nsproxy->net_ns->ipv4.devconf_dflt,
2678
+ sizeof(ipv4_devconf_dflt));
2679
+ break;
2680
+ case 0:
2681
+ case 1:
2682
+ /* copy from init_net */
2683
+ memcpy(all, init_net.ipv4.devconf_all,
2684
+ sizeof(ipv4_devconf));
2685
+ memcpy(dflt, init_net.ipv4.devconf_dflt,
2686
+ sizeof(ipv4_devconf_dflt));
2687
+ break;
2688
+ case 2:
2689
+ /* use compiled values */
2690
+ break;
2691
+ }
24452692 }
24462693
24472694 #ifdef CONFIG_SYSCTL
....@@ -2471,15 +2718,12 @@
24712718 err_reg_dflt:
24722719 __devinet_sysctl_unregister(net, all, NETCONFA_IFINDEX_ALL);
24732720 err_reg_all:
2474
- if (tbl != ctl_forward_entry)
2475
- kfree(tbl);
2721
+ kfree(tbl);
24762722 err_alloc_ctl:
24772723 #endif
2478
- if (dflt != &ipv4_devconf_dflt)
2479
- kfree(dflt);
2724
+ kfree(dflt);
24802725 err_alloc_dflt:
2481
- if (all != &ipv4_devconf)
2482
- kfree(all);
2726
+ kfree(all);
24832727 err_alloc_all:
24842728 return err;
24852729 }
....@@ -2522,8 +2766,6 @@
25222766 INIT_HLIST_HEAD(&inet_addr_lst[i]);
25232767
25242768 register_pernet_subsys(&devinet_ops);
2525
-
2526
- register_gifconf(PF_INET, inet_gifconf);
25272769 register_netdevice_notifier(&ip_netdev_notifier);
25282770
25292771 queue_delayed_work(system_power_efficient_wq, &check_lifetime_work, 0);