forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/net/ipv6/addrconf.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * IPv6 Address [auto]configuration
34 * Linux INET6 implementation
....@@ -5,11 +6,6 @@
56 * Authors:
67 * Pedro Roque <roque@di.fc.ul.pt>
78 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
8
- *
9
- * This program is free software; you can redistribute it and/or
10
- * modify it under the terms of the GNU General Public License
11
- * as published by the Free Software Foundation; either version
12
- * 2 of the License, or (at your option) any later version.
139 */
1410
1511 /*
....@@ -94,6 +90,8 @@
9490 #include <linux/seq_file.h>
9591 #include <linux/export.h>
9692
93
+#include <trace/hooks/ipv6.h>
94
+
9795 #define INFINITY_LIFE_TIME 0xFFFFFFFF
9896
9997 #define IPV6_MAX_STRLEN \
....@@ -139,8 +137,7 @@
139137 }
140138 #endif
141139
142
-static void ipv6_regen_rndid(struct inet6_dev *idev);
143
-static void ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr);
140
+static void ipv6_gen_rnd_iid(struct in6_addr *addr);
144141
145142 static int ipv6_generate_eui64(u8 *eui, struct net_device *dev);
146143 static int ipv6_count_addresses(const struct inet6_dev *idev);
....@@ -168,12 +165,13 @@
168165
169166 static void addrconf_type_change(struct net_device *dev,
170167 unsigned long event);
171
-static int addrconf_ifdown(struct net_device *dev, int how);
168
+static int addrconf_ifdown(struct net_device *dev, bool unregister);
172169
173170 static struct fib6_info *addrconf_get_prefix_route(const struct in6_addr *pfx,
174171 int plen,
175172 const struct net_device *dev,
176
- u32 flags, u32 noflags);
173
+ u32 flags, u32 noflags,
174
+ bool no_gw);
177175
178176 static void addrconf_dad_start(struct inet6_ifaddr *ifp);
179177 static void addrconf_dad_work(struct work_struct *w);
....@@ -240,6 +238,7 @@
240238 .enhanced_dad = 1,
241239 .addr_gen_mode = IN6_ADDR_GEN_MODE_EUI64,
242240 .disable_policy = 0,
241
+ .rpl_seg_enabled = 0,
243242 };
244243
245244 static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
....@@ -295,6 +294,7 @@
295294 .enhanced_dad = 1,
296295 .addr_gen_mode = IN6_ADDR_GEN_MODE_EUI64,
297296 .disable_policy = 0,
297
+ .rpl_seg_enabled = 0,
298298 };
299299
300300 /* Check if link is ready: is it up and is a valid qdisc available */
....@@ -435,8 +435,7 @@
435435 dev->type == ARPHRD_SIT ||
436436 dev->type == ARPHRD_NONE) {
437437 ndev->cnf.use_tempaddr = -1;
438
- } else
439
- ipv6_regen_rndid(ndev);
438
+ }
440439
441440 ndev->token = in6addr_any;
442441
....@@ -483,7 +482,7 @@
483482 if (!idev) {
484483 idev = ipv6_add_dev(dev);
485484 if (IS_ERR(idev))
486
- return NULL;
485
+ return idev;
487486 }
488487
489488 if (dev->flags&IFF_UP)
....@@ -547,7 +546,7 @@
547546 #ifdef CONFIG_IPV6_MROUTE
548547 if ((all || type == NETCONFA_MC_FORWARDING) &&
549548 nla_put_s32(skb, NETCONFA_MC_FORWARDING,
550
- devconf->mc_forwarding) < 0)
549
+ atomic_read(&devconf->mc_forwarding)) < 0)
551550 goto nla_put_failure;
552551 #endif
553552 if ((all || type == NETCONFA_PROXY_NEIGH) &&
....@@ -599,6 +598,45 @@
599598 [NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN] = { .len = sizeof(int) },
600599 };
601600
601
+static int inet6_netconf_valid_get_req(struct sk_buff *skb,
602
+ const struct nlmsghdr *nlh,
603
+ struct nlattr **tb,
604
+ struct netlink_ext_ack *extack)
605
+{
606
+ int i, err;
607
+
608
+ if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(struct netconfmsg))) {
609
+ NL_SET_ERR_MSG_MOD(extack, "Invalid header for netconf get request");
610
+ return -EINVAL;
611
+ }
612
+
613
+ if (!netlink_strict_get_check(skb))
614
+ return nlmsg_parse_deprecated(nlh, sizeof(struct netconfmsg),
615
+ tb, NETCONFA_MAX,
616
+ devconf_ipv6_policy, extack);
617
+
618
+ err = nlmsg_parse_deprecated_strict(nlh, sizeof(struct netconfmsg),
619
+ tb, NETCONFA_MAX,
620
+ devconf_ipv6_policy, extack);
621
+ if (err)
622
+ return err;
623
+
624
+ for (i = 0; i <= NETCONFA_MAX; i++) {
625
+ if (!tb[i])
626
+ continue;
627
+
628
+ switch (i) {
629
+ case NETCONFA_IFINDEX:
630
+ break;
631
+ default:
632
+ NL_SET_ERR_MSG_MOD(extack, "Unsupported attribute in netconf get request");
633
+ return -EINVAL;
634
+ }
635
+ }
636
+
637
+ return 0;
638
+}
639
+
602640 static int inet6_netconf_get_devconf(struct sk_buff *in_skb,
603641 struct nlmsghdr *nlh,
604642 struct netlink_ext_ack *extack)
....@@ -607,14 +645,12 @@
607645 struct nlattr *tb[NETCONFA_MAX+1];
608646 struct inet6_dev *in6_dev = NULL;
609647 struct net_device *dev = NULL;
610
- struct netconfmsg *ncm;
611648 struct sk_buff *skb;
612649 struct ipv6_devconf *devconf;
613650 int ifindex;
614651 int err;
615652
616
- err = nlmsg_parse(nlh, sizeof(*ncm), tb, NETCONFA_MAX,
617
- devconf_ipv6_policy, extack);
653
+ err = inet6_netconf_valid_get_req(in_skb, nlh, tb, extack);
618654 if (err < 0)
619655 return err;
620656
....@@ -668,12 +704,28 @@
668704 static int inet6_netconf_dump_devconf(struct sk_buff *skb,
669705 struct netlink_callback *cb)
670706 {
707
+ const struct nlmsghdr *nlh = cb->nlh;
671708 struct net *net = sock_net(skb->sk);
672709 int h, s_h;
673710 int idx, s_idx;
674711 struct net_device *dev;
675712 struct inet6_dev *idev;
676713 struct hlist_head *head;
714
+
715
+ if (cb->strict_check) {
716
+ struct netlink_ext_ack *extack = cb->extack;
717
+ struct netconfmsg *ncm;
718
+
719
+ if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*ncm))) {
720
+ NL_SET_ERR_MSG_MOD(extack, "Invalid header for netconf dump request");
721
+ return -EINVAL;
722
+ }
723
+
724
+ if (nlmsg_attrlen(nlh, sizeof(*ncm))) {
725
+ NL_SET_ERR_MSG_MOD(extack, "Invalid data after header in netconf dump request");
726
+ return -EINVAL;
727
+ }
728
+ }
677729
678730 s_h = cb->args[0];
679731 s_idx = idx = cb->args[1];
....@@ -694,7 +746,7 @@
694746 if (inet6_netconf_fill_devconf(skb, dev->ifindex,
695747 &idev->cnf,
696748 NETLINK_CB(cb->skb).portid,
697
- cb->nlh->nlmsg_seq,
749
+ nlh->nlmsg_seq,
698750 RTM_NEWNETCONF,
699751 NLM_F_MULTI,
700752 NETCONFA_ALL) < 0) {
....@@ -711,7 +763,7 @@
711763 if (inet6_netconf_fill_devconf(skb, NETCONFA_IFINDEX_ALL,
712764 net->ipv6.devconf_all,
713765 NETLINK_CB(cb->skb).portid,
714
- cb->nlh->nlmsg_seq,
766
+ nlh->nlmsg_seq,
715767 RTM_NEWNETCONF, NLM_F_MULTI,
716768 NETCONFA_ALL) < 0)
717769 goto done;
....@@ -722,7 +774,7 @@
722774 if (inet6_netconf_fill_devconf(skb, NETCONFA_IFINDEX_DEFAULT,
723775 net->ipv6.devconf_dflt,
724776 NETLINK_CB(cb->skb).portid,
725
- cb->nlh->nlmsg_seq,
777
+ nlh->nlmsg_seq,
726778 RTM_NEWNETCONF, NLM_F_MULTI,
727779 NETCONFA_ALL) < 0)
728780 goto done;
....@@ -741,6 +793,7 @@
741793 {
742794 struct net_device *dev;
743795 struct inet6_ifaddr *ifa;
796
+ LIST_HEAD(tmp_addr_list);
744797
745798 if (!idev)
746799 return;
....@@ -759,14 +812,24 @@
759812 }
760813 }
761814
815
+ read_lock_bh(&idev->lock);
762816 list_for_each_entry(ifa, &idev->addr_list, if_list) {
763817 if (ifa->flags&IFA_F_TENTATIVE)
764818 continue;
819
+ list_add_tail(&ifa->if_list_aux, &tmp_addr_list);
820
+ }
821
+ read_unlock_bh(&idev->lock);
822
+
823
+ while (!list_empty(&tmp_addr_list)) {
824
+ ifa = list_first_entry(&tmp_addr_list,
825
+ struct inet6_ifaddr, if_list_aux);
826
+ list_del(&ifa->if_list_aux);
765827 if (idev->cnf.forwarding)
766828 addrconf_join_anycast(ifa);
767829 else
768830 addrconf_leave_anycast(ifa);
769831 }
832
+
770833 inet6_netconf_notify_devconf(dev_net(dev), RTM_NEWNETCONF,
771834 NETCONFA_FORWARDING,
772835 dev->ifindex, &idev->cnf);
....@@ -1000,6 +1063,7 @@
10001063 (addr_type & IPV6_ADDR_MULTICAST &&
10011064 !(cfg->ifa_flags & IFA_F_MCAUTOJOIN)) ||
10021065 (!(idev->dev->flags & IFF_LOOPBACK) &&
1066
+ !netif_is_l3_master(idev->dev) &&
10031067 addr_type & IPV6_ADDR_LOOPBACK))
10041068 return ERR_PTR(-EADDRNOTAVAIL);
10051069
....@@ -1041,10 +1105,6 @@
10411105 f6i = NULL;
10421106 goto out;
10431107 }
1044
-
1045
- if (net->ipv6.devconf_all->disable_policy ||
1046
- idev->cnf.disable_policy)
1047
- f6i->dst_nopolicy = true;
10481108
10491109 neigh_parms_data_state_setall(idev->nd_parms);
10501110
....@@ -1183,12 +1243,11 @@
11831243 struct fib6_info *f6i;
11841244
11851245 f6i = addrconf_get_prefix_route(del_peer ? &ifp->peer_addr : &ifp->addr,
1186
- ifp->prefix_len,
1187
- ifp->idev->dev,
1188
- 0, RTF_GATEWAY | RTF_DEFAULT);
1246
+ ifp->prefix_len,
1247
+ ifp->idev->dev, 0, RTF_DEFAULT, true);
11891248 if (f6i) {
11901249 if (del_rt)
1191
- ip6_del_rt(dev_net(ifp->idev->dev), f6i);
1250
+ ip6_del_rt(dev_net(ifp->idev->dev), f6i, false);
11921251 else {
11931252 if (!(f6i->fib6_flags & RTF_EXPIRES))
11941253 fib6_set_expires(f6i, expires);
....@@ -1256,29 +1315,21 @@
12561315 in6_ifa_put(ifp);
12571316 }
12581317
1259
-static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp,
1260
- struct inet6_ifaddr *ift,
1261
- bool block)
1318
+static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, bool block)
12621319 {
12631320 struct inet6_dev *idev = ifp->idev;
1264
- struct in6_addr addr, *tmpaddr;
12651321 unsigned long tmp_tstamp, age;
12661322 unsigned long regen_advance;
1267
- struct ifa6_config cfg;
1268
- int ret = 0;
12691323 unsigned long now = jiffies;
1270
- long max_desync_factor;
12711324 s32 cnf_temp_preferred_lft;
1325
+ struct inet6_ifaddr *ift;
1326
+ struct ifa6_config cfg;
1327
+ long max_desync_factor;
1328
+ struct in6_addr addr;
1329
+ int ret = 0;
12721330
12731331 write_lock_bh(&idev->lock);
1274
- if (ift) {
1275
- spin_lock_bh(&ift->lock);
1276
- memcpy(&addr.s6_addr[8], &ift->addr.s6_addr[8], 8);
1277
- spin_unlock_bh(&ift->lock);
1278
- tmpaddr = &addr;
1279
- } else {
1280
- tmpaddr = NULL;
1281
- }
1332
+
12821333 retry:
12831334 in6_dev_hold(idev);
12841335 if (idev->cnf.use_tempaddr <= 0) {
....@@ -1301,13 +1352,13 @@
13011352 }
13021353 in6_ifa_hold(ifp);
13031354 memcpy(addr.s6_addr, ifp->addr.s6_addr, 8);
1304
- ipv6_try_regen_rndid(idev, tmpaddr);
1305
- memcpy(&addr.s6_addr[8], idev->rndid, 8);
1355
+ ipv6_gen_rnd_iid(&addr);
1356
+
13061357 age = (now - ifp->tstamp) / HZ;
13071358
13081359 regen_advance = idev->cnf.regen_max_retry *
13091360 idev->cnf.dad_transmits *
1310
- NEIGH_VAR(idev->nd_parms, RETRANS_TIME) / HZ;
1361
+ max(NEIGH_VAR(idev->nd_parms, RETRANS_TIME), HZ/100) / HZ;
13111362
13121363 /* recalculate max_desync_factor each time and update
13131364 * idev->desync_factor if it's larger
....@@ -1367,7 +1418,6 @@
13671418 in6_ifa_put(ifp);
13681419 in6_dev_put(idev);
13691420 pr_info("%s: retry temporary address regeneration\n", __func__);
1370
- tmpaddr = &addr;
13711421 write_lock_bh(&idev->lock);
13721422 goto retry;
13731423 }
....@@ -1854,12 +1904,13 @@
18541904 * 2. does the address exist on the specific device
18551905 * (skip_dev_check = false)
18561906 */
1857
-int ipv6_chk_addr_and_flags(struct net *net, const struct in6_addr *addr,
1858
- const struct net_device *dev, bool skip_dev_check,
1859
- int strict, u32 banned_flags)
1907
+static struct net_device *
1908
+__ipv6_chk_addr_and_flags(struct net *net, const struct in6_addr *addr,
1909
+ const struct net_device *dev, bool skip_dev_check,
1910
+ int strict, u32 banned_flags)
18601911 {
18611912 unsigned int hash = inet6_addr_hash(net, addr);
1862
- const struct net_device *l3mdev;
1913
+ struct net_device *l3mdev, *ndev;
18631914 struct inet6_ifaddr *ifp;
18641915 u32 ifp_flags;
18651916
....@@ -1870,10 +1921,11 @@
18701921 dev = NULL;
18711922
18721923 hlist_for_each_entry_rcu(ifp, &inet6_addr_lst[hash], addr_lst) {
1873
- if (!net_eq(dev_net(ifp->idev->dev), net))
1924
+ ndev = ifp->idev->dev;
1925
+ if (!net_eq(dev_net(ndev), net))
18741926 continue;
18751927
1876
- if (l3mdev_master_dev_rcu(ifp->idev->dev) != l3mdev)
1928
+ if (l3mdev_master_dev_rcu(ndev) != l3mdev)
18771929 continue;
18781930
18791931 /* Decouple optimistic from tentative for evaluation here.
....@@ -1884,15 +1936,23 @@
18841936 : ifp->flags;
18851937 if (ipv6_addr_equal(&ifp->addr, addr) &&
18861938 !(ifp_flags&banned_flags) &&
1887
- (!dev || ifp->idev->dev == dev ||
1939
+ (!dev || ndev == dev ||
18881940 !(ifp->scope&(IFA_LINK|IFA_HOST) || strict))) {
18891941 rcu_read_unlock();
1890
- return 1;
1942
+ return ndev;
18911943 }
18921944 }
18931945
18941946 rcu_read_unlock();
1895
- return 0;
1947
+ return NULL;
1948
+}
1949
+
1950
+int ipv6_chk_addr_and_flags(struct net *net, const struct in6_addr *addr,
1951
+ const struct net_device *dev, bool skip_dev_check,
1952
+ int strict, u32 banned_flags)
1953
+{
1954
+ return __ipv6_chk_addr_and_flags(net, addr, dev, skip_dev_check,
1955
+ strict, banned_flags) ? 1 : 0;
18961956 }
18971957 EXPORT_SYMBOL(ipv6_chk_addr_and_flags);
18981958
....@@ -1944,6 +2004,21 @@
19442004 }
19452005 EXPORT_SYMBOL(ipv6_chk_prefix);
19462006
2007
+/**
2008
+ * ipv6_dev_find - find the first device with a given source address.
2009
+ * @net: the net namespace
2010
+ * @addr: the source address
2011
+ *
2012
+ * The caller should be protected by RCU, or RTNL.
2013
+ */
2014
+struct net_device *ipv6_dev_find(struct net *net, const struct in6_addr *addr,
2015
+ struct net_device *dev)
2016
+{
2017
+ return __ipv6_chk_addr_and_flags(net, addr, dev, !dev, 1,
2018
+ IFA_F_TENTATIVE);
2019
+}
2020
+EXPORT_SYMBOL(ipv6_dev_find);
2021
+
19472022 struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net, const struct in6_addr *addr,
19482023 struct net_device *dev, int strict)
19492024 {
....@@ -1982,7 +2057,7 @@
19822057 if (ifpub) {
19832058 in6_ifa_hold(ifpub);
19842059 spin_unlock_bh(&ifp->lock);
1985
- ipv6_create_tempaddr(ifpub, ifp, true);
2060
+ ipv6_create_tempaddr(ifpub, true);
19862061 in6_ifa_put(ifpub);
19872062 } else {
19882063 spin_unlock_bh(&ifp->lock);
....@@ -2279,40 +2354,38 @@
22792354 return err;
22802355 }
22812356
2282
-/* (re)generation of randomized interface identifier (RFC 3041 3.2, 3.5) */
2283
-static void ipv6_regen_rndid(struct inet6_dev *idev)
2357
+/* Generation of a randomized Interface Identifier
2358
+ * draft-ietf-6man-rfc4941bis, Section 3.3.1
2359
+ */
2360
+
2361
+static void ipv6_gen_rnd_iid(struct in6_addr *addr)
22842362 {
22852363 regen:
2286
- get_random_bytes(idev->rndid, sizeof(idev->rndid));
2287
- idev->rndid[0] &= ~0x02;
2364
+ get_random_bytes(&addr->s6_addr[8], 8);
22882365
2289
- /*
2290
- * <draft-ietf-ipngwg-temp-addresses-v2-00.txt>:
2291
- * check if generated address is not inappropriate
2366
+ /* <draft-ietf-6man-rfc4941bis-08.txt>, Section 3.3.1:
2367
+ * check if generated address is not inappropriate:
22922368 *
2293
- * - Reserved subnet anycast (RFC 2526)
2294
- * 11111101 11....11 1xxxxxxx
2295
- * - ISATAP (RFC4214) 6.1
2296
- * 00-00-5E-FE-xx-xx-xx-xx
2297
- * - value 0
2298
- * - XXX: already assigned to an address on the device
2369
+ * - Reserved IPv6 Interface Identifers
2370
+ * - XXX: already assigned to an address on the device
22992371 */
2300
- if (idev->rndid[0] == 0xfd &&
2301
- (idev->rndid[1]&idev->rndid[2]&idev->rndid[3]&idev->rndid[4]&idev->rndid[5]&idev->rndid[6]) == 0xff &&
2302
- (idev->rndid[7]&0x80))
2303
- goto regen;
2304
- if ((idev->rndid[0]|idev->rndid[1]) == 0) {
2305
- if (idev->rndid[2] == 0x5e && idev->rndid[3] == 0xfe)
2306
- goto regen;
2307
- if ((idev->rndid[2]|idev->rndid[3]|idev->rndid[4]|idev->rndid[5]|idev->rndid[6]|idev->rndid[7]) == 0x00)
2308
- goto regen;
2309
- }
2310
-}
23112372
2312
-static void ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr)
2313
-{
2314
- if (tmpaddr && memcmp(idev->rndid, &tmpaddr->s6_addr[8], 8) == 0)
2315
- ipv6_regen_rndid(idev);
2373
+ /* Subnet-router anycast: 0000:0000:0000:0000 */
2374
+ if (!(addr->s6_addr32[2] | addr->s6_addr32[3]))
2375
+ goto regen;
2376
+
2377
+ /* IANA Ethernet block: 0200:5EFF:FE00:0000-0200:5EFF:FE00:5212
2378
+ * Proxy Mobile IPv6: 0200:5EFF:FE00:5213
2379
+ * IANA Ethernet block: 0200:5EFF:FE00:5214-0200:5EFF:FEFF:FFFF
2380
+ */
2381
+ if (ntohl(addr->s6_addr32[2]) == 0x02005eff &&
2382
+ (ntohl(addr->s6_addr32[3]) & 0Xff000000) == 0xfe000000)
2383
+ goto regen;
2384
+
2385
+ /* Reserved subnet anycast addresses */
2386
+ if (ntohl(addr->s6_addr32[2]) == 0xfdffffff &&
2387
+ ntohl(addr->s6_addr32[3]) >= 0Xffffff80)
2388
+ goto regen;
23162389 }
23172390
23182391 u32 addrconf_rt_table(const struct net_device *dev, u32 default_table)
....@@ -2374,7 +2447,8 @@
23742447 static struct fib6_info *addrconf_get_prefix_route(const struct in6_addr *pfx,
23752448 int plen,
23762449 const struct net_device *dev,
2377
- u32 flags, u32 noflags)
2450
+ u32 flags, u32 noflags,
2451
+ bool no_gw)
23782452 {
23792453 struct fib6_node *fn;
23802454 struct fib6_info *rt = NULL;
....@@ -2391,7 +2465,13 @@
23912465 goto out;
23922466
23932467 for_each_fib6_node_rt_rcu(fn) {
2394
- if (rt->fib6_nh.nh_dev->ifindex != dev->ifindex)
2468
+ /* prefix routes only use builtin fib6_nh */
2469
+ if (rt->nh)
2470
+ continue;
2471
+
2472
+ if (rt->fib6_nh->fib_nh_dev->ifindex != dev->ifindex)
2473
+ continue;
2474
+ if (no_gw && rt->fib6_nh->fib_nh_gw_family)
23952475 continue;
23962476 if ((rt->fib6_flags & flags) != flags)
23972477 continue;
....@@ -2434,8 +2514,8 @@
24342514 ASSERT_RTNL();
24352515
24362516 idev = ipv6_find_idev(dev);
2437
- if (!idev)
2438
- return ERR_PTR(-ENOBUFS);
2517
+ if (IS_ERR(idev))
2518
+ return idev;
24392519
24402520 if (idev->cnf.disable_ipv6)
24412521 return ERR_PTR(-EACCES);
....@@ -2508,7 +2588,7 @@
25082588 * no temporary address currently exists.
25092589 */
25102590 read_unlock_bh(&idev->lock);
2511
- ipv6_create_tempaddr(ifp, NULL, false);
2591
+ ipv6_create_tempaddr(ifp, false);
25122592 } else {
25132593 read_unlock_bh(&idev->lock);
25142594 }
....@@ -2690,12 +2770,12 @@
26902770 pinfo->prefix_len,
26912771 dev,
26922772 RTF_ADDRCONF | RTF_PREFIX_RT,
2693
- RTF_GATEWAY | RTF_DEFAULT);
2773
+ RTF_DEFAULT, true);
26942774
26952775 if (rt) {
26962776 /* Autoconf prefix route */
26972777 if (valid_lft == 0) {
2698
- ip6_del_rt(net, rt);
2778
+ ip6_del_rt(net, rt, false);
26992779 rt = NULL;
27002780 } else if (addrconf_finite_timeout(rt_expires)) {
27012781 /* not infinity */
....@@ -2773,6 +2853,33 @@
27732853 in6_dev_put(in6_dev);
27742854 }
27752855
2856
+static int addrconf_set_sit_dstaddr(struct net *net, struct net_device *dev,
2857
+ struct in6_ifreq *ireq)
2858
+{
2859
+ struct ip_tunnel_parm p = { };
2860
+ int err;
2861
+
2862
+ if (!(ipv6_addr_type(&ireq->ifr6_addr) & IPV6_ADDR_COMPATv4))
2863
+ return -EADDRNOTAVAIL;
2864
+
2865
+ p.iph.daddr = ireq->ifr6_addr.s6_addr32[3];
2866
+ p.iph.version = 4;
2867
+ p.iph.ihl = 5;
2868
+ p.iph.protocol = IPPROTO_IPV6;
2869
+ p.iph.ttl = 64;
2870
+
2871
+ if (!dev->netdev_ops->ndo_tunnel_ctl)
2872
+ return -EOPNOTSUPP;
2873
+ err = dev->netdev_ops->ndo_tunnel_ctl(dev, &p, SIOCADDTUNNEL);
2874
+ if (err)
2875
+ return err;
2876
+
2877
+ dev = __dev_get_by_name(net, p.name);
2878
+ if (!dev)
2879
+ return -ENOBUFS;
2880
+ return dev_open(dev, NULL);
2881
+}
2882
+
27762883 /*
27772884 * Set destination address.
27782885 * Special case for SIT interfaces where we create a new "virtual"
....@@ -2780,61 +2887,19 @@
27802887 */
27812888 int addrconf_set_dstaddr(struct net *net, void __user *arg)
27822889 {
2783
- struct in6_ifreq ireq;
27842890 struct net_device *dev;
2785
- int err = -EINVAL;
2891
+ struct in6_ifreq ireq;
2892
+ int err = -ENODEV;
2893
+
2894
+ if (!IS_ENABLED(CONFIG_IPV6_SIT))
2895
+ return -ENODEV;
2896
+ if (copy_from_user(&ireq, arg, sizeof(struct in6_ifreq)))
2897
+ return -EFAULT;
27862898
27872899 rtnl_lock();
2788
-
2789
- err = -EFAULT;
2790
- if (copy_from_user(&ireq, arg, sizeof(struct in6_ifreq)))
2791
- goto err_exit;
2792
-
27932900 dev = __dev_get_by_index(net, ireq.ifr6_ifindex);
2794
-
2795
- err = -ENODEV;
2796
- if (!dev)
2797
- goto err_exit;
2798
-
2799
-#if IS_ENABLED(CONFIG_IPV6_SIT)
2800
- if (dev->type == ARPHRD_SIT) {
2801
- const struct net_device_ops *ops = dev->netdev_ops;
2802
- struct ifreq ifr;
2803
- struct ip_tunnel_parm p;
2804
-
2805
- err = -EADDRNOTAVAIL;
2806
- if (!(ipv6_addr_type(&ireq.ifr6_addr) & IPV6_ADDR_COMPATv4))
2807
- goto err_exit;
2808
-
2809
- memset(&p, 0, sizeof(p));
2810
- p.iph.daddr = ireq.ifr6_addr.s6_addr32[3];
2811
- p.iph.saddr = 0;
2812
- p.iph.version = 4;
2813
- p.iph.ihl = 5;
2814
- p.iph.protocol = IPPROTO_IPV6;
2815
- p.iph.ttl = 64;
2816
- ifr.ifr_ifru.ifru_data = (__force void __user *)&p;
2817
-
2818
- if (ops->ndo_do_ioctl) {
2819
- mm_segment_t oldfs = get_fs();
2820
-
2821
- set_fs(KERNEL_DS);
2822
- err = ops->ndo_do_ioctl(dev, &ifr, SIOCADDTUNNEL);
2823
- set_fs(oldfs);
2824
- } else
2825
- err = -EOPNOTSUPP;
2826
-
2827
- if (err == 0) {
2828
- err = -ENOBUFS;
2829
- dev = __dev_get_by_name(net, p.name);
2830
- if (!dev)
2831
- goto err_exit;
2832
- err = dev_open(dev);
2833
- }
2834
- }
2835
-#endif
2836
-
2837
-err_exit:
2901
+ if (dev && dev->type == ARPHRD_SIT)
2902
+ err = addrconf_set_sit_dstaddr(net, dev, &ireq);
28382903 rtnl_unlock();
28392904 return err;
28402905 }
....@@ -3099,11 +3164,9 @@
30993164 struct in_device *in_dev = __in_dev_get_rtnl(dev);
31003165 if (in_dev && (dev->flags & IFF_UP)) {
31013166 struct in_ifaddr *ifa;
3102
-
31033167 int flag = scope;
31043168
3105
- for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) {
3106
-
3169
+ in_dev_for_each_ifa_rtnl(ifa, in_dev) {
31073170 addr.s6_addr32[3] = ifa->ifa_local;
31083171
31093172 if (ifa->ifa_scope == RT_SCOPE_LINK)
....@@ -3132,7 +3195,7 @@
31323195 ASSERT_RTNL();
31333196
31343197 idev = ipv6_find_idev(dev);
3135
- if (!idev) {
3198
+ if (IS_ERR(idev)) {
31363199 pr_debug("%s: add_dev failed\n", __func__);
31373200 return;
31383201 }
....@@ -3191,11 +3254,11 @@
31913254 const struct inet6_dev *idev)
31923255 {
31933256 static DEFINE_SPINLOCK(lock);
3194
- static __u32 digest[SHA_DIGEST_WORDS];
3195
- static __u32 workspace[SHA_WORKSPACE_WORDS];
3257
+ static __u32 digest[SHA1_DIGEST_WORDS];
3258
+ static __u32 workspace[SHA1_WORKSPACE_WORDS];
31963259
31973260 static union {
3198
- char __data[SHA_MESSAGE_BYTES];
3261
+ char __data[SHA1_BLOCK_SIZE];
31993262 struct {
32003263 struct in6_addr secret;
32013264 __be32 prefix[2];
....@@ -3220,7 +3283,7 @@
32203283 retry:
32213284 spin_lock_bh(&lock);
32223285
3223
- sha_init(digest);
3286
+ sha1_init(digest);
32243287 memset(&data, 0, sizeof(data));
32253288 memset(workspace, 0, sizeof(workspace));
32263289 memcpy(data.hwaddr, idev->dev->perm_addr, idev->dev->addr_len);
....@@ -3229,7 +3292,7 @@
32293292 data.secret = secret;
32303293 data.dad_count = dad_count;
32313294
3232
- sha_transform(digest, data.__data, workspace);
3295
+ sha1_transform(digest, data.__data, workspace);
32333296
32343297 temp = *address;
32353298 temp.s6_addr32[2] = (__force __be32)digest[0];
....@@ -3276,7 +3339,7 @@
32763339 switch (idev->cnf.addr_gen_mode) {
32773340 case IN6_ADDR_GEN_MODE_RANDOM:
32783341 ipv6_gen_mode_random_init(idev);
3279
- /* fallthrough */
3342
+ fallthrough;
32803343 case IN6_ADDR_GEN_MODE_STABLE_PRIVACY:
32813344 if (!ipv6_generate_stable_address(&addr, 0, idev))
32823345 addrconf_add_linklocal(idev, &addr,
....@@ -3306,6 +3369,7 @@
33063369 static void addrconf_dev_config(struct net_device *dev)
33073370 {
33083371 struct inet6_dev *idev;
3372
+ bool ret = false;
33093373
33103374 ASSERT_RTNL();
33113375
....@@ -3333,6 +3397,10 @@
33333397 if (IS_ERR(idev))
33343398 return;
33353399
3400
+ trace_android_vh_ipv6_gen_linklocal_addr(dev, &ret);
3401
+ if (ret)
3402
+ return;
3403
+
33363404 /* this device type has no EUI support */
33373405 if (dev->type == ARPHRD_NONE &&
33383406 idev->cnf.addr_gen_mode == IN6_ADDR_GEN_MODE_EUI64)
....@@ -3355,7 +3423,7 @@
33553423 */
33563424
33573425 idev = ipv6_find_idev(dev);
3358
- if (!idev) {
3426
+ if (IS_ERR(idev)) {
33593427 pr_debug("%s: add_dev failed\n", __func__);
33603428 return;
33613429 }
....@@ -3380,7 +3448,7 @@
33803448 ASSERT_RTNL();
33813449
33823450 idev = ipv6_find_idev(dev);
3383
- if (!idev) {
3451
+ if (IS_ERR(idev)) {
33843452 pr_debug("%s: add_dev failed\n", __func__);
33853453 return;
33863454 }
....@@ -3498,9 +3566,7 @@
34983566 break;
34993567
35003568 run_pending = 1;
3501
-
3502
- /* fall through */
3503
-
3569
+ fallthrough;
35043570 case NETDEV_UP:
35053571 case NETDEV_CHANGE:
35063572 if (dev->flags & IFF_SLAVE)
....@@ -3515,8 +3581,8 @@
35153581
35163582 if (!addrconf_link_ready(dev)) {
35173583 /* device is not ready yet. */
3518
- pr_info("ADDRCONF(NETDEV_UP): %s: link is not ready\n",
3519
- dev->name);
3584
+ pr_debug("ADDRCONF(NETDEV_UP): %s: link is not ready\n",
3585
+ dev->name);
35203586 break;
35213587 }
35223588
....@@ -3642,7 +3708,7 @@
36423708 * an L3 master device (e.g., VRF)
36433709 */
36443710 if (info->upper_dev && netif_is_l3_master(info->upper_dev))
3645
- addrconf_ifdown(dev, 0);
3711
+ addrconf_ifdown(dev, false);
36463712 }
36473713
36483714 return NOTIFY_OK;
....@@ -3675,13 +3741,15 @@
36753741 (IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK);
36763742 }
36773743
3678
-static int addrconf_ifdown(struct net_device *dev, int how)
3744
+static int addrconf_ifdown(struct net_device *dev, bool unregister)
36793745 {
3680
- unsigned long event = how ? NETDEV_UNREGISTER : NETDEV_DOWN;
3746
+ unsigned long event = unregister ? NETDEV_UNREGISTER : NETDEV_DOWN;
36813747 struct net *net = dev_net(dev);
36823748 struct inet6_dev *idev;
3683
- struct inet6_ifaddr *ifa, *tmp;
3749
+ struct inet6_ifaddr *ifa;
3750
+ LIST_HEAD(tmp_addr_list);
36843751 bool keep_addr = false;
3752
+ bool was_ready;
36853753 int state, i;
36863754
36873755 ASSERT_RTNL();
....@@ -3696,7 +3764,7 @@
36963764 * Step 1: remove reference to ipv6 device from parent device.
36973765 * Do not dev_put!
36983766 */
3699
- if (how) {
3767
+ if (unregister) {
37003768 idev->dead = 1;
37013769
37023770 /* protected by rtnl_lock */
....@@ -3710,7 +3778,7 @@
37103778 /* combine the user config with event to determine if permanent
37113779 * addresses are to be removed from address hash table
37123780 */
3713
- if (!how && !idev->cnf.disable_ipv6) {
3781
+ if (!unregister && !idev->cnf.disable_ipv6) {
37143782 /* aggregate the system setting and interface setting */
37153783 int _keep_addr = net->ipv6.devconf_all->keep_addr_on_down;
37163784
....@@ -3747,8 +3815,11 @@
37473815
37483816 addrconf_del_rs_timer(idev);
37493817
3750
- /* Step 2: clear flags for stateless addrconf */
3751
- if (!how)
3818
+ /* Step 2: clear flags for stateless addrconf, repeated down
3819
+ * detection
3820
+ */
3821
+ was_ready = idev->if_flags & IF_READY;
3822
+ if (!unregister)
37523823 idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD|IF_READY);
37533824
37543825 /* Step 3: clear tempaddr list */
....@@ -3768,16 +3839,23 @@
37683839 write_lock_bh(&idev->lock);
37693840 }
37703841
3771
- list_for_each_entry_safe(ifa, tmp, &idev->addr_list, if_list) {
3842
+ list_for_each_entry(ifa, &idev->addr_list, if_list)
3843
+ list_add_tail(&ifa->if_list_aux, &tmp_addr_list);
3844
+ write_unlock_bh(&idev->lock);
3845
+
3846
+ while (!list_empty(&tmp_addr_list)) {
37723847 struct fib6_info *rt = NULL;
37733848 bool keep;
3849
+
3850
+ ifa = list_first_entry(&tmp_addr_list,
3851
+ struct inet6_ifaddr, if_list_aux);
3852
+ list_del(&ifa->if_list_aux);
37743853
37753854 addrconf_del_dad_work(ifa);
37763855
37773856 keep = keep_addr && (ifa->flags & IFA_F_PERMANENT) &&
37783857 !addr_is_local(&ifa->addr);
37793858
3780
- write_unlock_bh(&idev->lock);
37813859 spin_lock_bh(&ifa->lock);
37823860
37833861 if (keep) {
....@@ -3797,7 +3875,7 @@
37973875 spin_unlock_bh(&ifa->lock);
37983876
37993877 if (rt)
3800
- ip6_del_rt(net, rt);
3878
+ ip6_del_rt(net, rt, false);
38013879
38023880 if (state != INET6_IFADDR_STATE_DEAD) {
38033881 __ipv6_ifa_notify(RTM_DELADDR, ifa);
....@@ -3808,27 +3886,26 @@
38083886 addrconf_leave_solict(ifa->idev, &ifa->addr);
38093887 }
38103888
3811
- write_lock_bh(&idev->lock);
38123889 if (!keep) {
3890
+ write_lock_bh(&idev->lock);
38133891 list_del_rcu(&ifa->if_list);
3892
+ write_unlock_bh(&idev->lock);
38143893 in6_ifa_put(ifa);
38153894 }
38163895 }
38173896
3818
- write_unlock_bh(&idev->lock);
3819
-
38203897 /* Step 5: Discard anycast and multicast list */
3821
- if (how) {
3898
+ if (unregister) {
38223899 ipv6_ac_destroy_dev(idev);
38233900 ipv6_mc_destroy_dev(idev);
3824
- } else {
3901
+ } else if (was_ready) {
38253902 ipv6_mc_down(idev);
38263903 }
38273904
38283905 idev->tstamp = jiffies;
38293906
38303907 /* Last: Shot the device (if unregistered) */
3831
- if (how) {
3908
+ if (unregister) {
38323909 addrconf_sysctl_unregister(idev);
38333910 neigh_parms_release(&nd_tbl, idev->nd_parms);
38343911 neigh_ifdown(&nd_tbl, dev);
....@@ -4050,7 +4127,7 @@
40504127 in6_ifa_hold(ifp);
40514128 addrconf_dad_stop(ifp, 1);
40524129 if (disable_ipv6)
4053
- addrconf_ifdown(idev->dev, 0);
4130
+ addrconf_ifdown(idev->dev, false);
40544131 goto out;
40554132 }
40564133
....@@ -4092,7 +4169,8 @@
40924169
40934170 ifp->dad_probes--;
40944171 addrconf_mod_dad_work(ifp,
4095
- NEIGH_VAR(ifp->idev->nd_parms, RETRANS_TIME));
4172
+ max(NEIGH_VAR(ifp->idev->nd_parms, RETRANS_TIME),
4173
+ HZ/100));
40964174 spin_unlock(&ifp->lock);
40974175 write_unlock_bh(&idev->lock);
40984176
....@@ -4147,7 +4225,8 @@
41474225 send_rs = send_mld &&
41484226 ipv6_accept_ra(ifp->idev) &&
41494227 ifp->idev->cnf.rtr_solicits != 0 &&
4150
- (dev->flags&IFF_LOOPBACK) == 0;
4228
+ (dev->flags & IFF_LOOPBACK) == 0 &&
4229
+ (dev->type != ARPHRD_TUNNEL);
41514230 read_unlock_bh(&ifp->idev->lock);
41524231
41534232 /* While dad is in progress mld report's source address is in6_addrany.
....@@ -4375,6 +4454,59 @@
43754454 }
43764455 #endif
43774456
4457
+/* RFC6554 has some algorithm to avoid loops in segment routing by
4458
+ * checking if the segments contains any of a local interface address.
4459
+ *
4460
+ * Quote:
4461
+ *
4462
+ * To detect loops in the SRH, a router MUST determine if the SRH
4463
+ * includes multiple addresses assigned to any interface on that router.
4464
+ * If such addresses appear more than once and are separated by at least
4465
+ * one address not assigned to that router.
4466
+ */
4467
+int ipv6_chk_rpl_srh_loop(struct net *net, const struct in6_addr *segs,
4468
+ unsigned char nsegs)
4469
+{
4470
+ const struct in6_addr *addr;
4471
+ int i, ret = 0, found = 0;
4472
+ struct inet6_ifaddr *ifp;
4473
+ bool separated = false;
4474
+ unsigned int hash;
4475
+ bool hash_found;
4476
+
4477
+ rcu_read_lock();
4478
+ for (i = 0; i < nsegs; i++) {
4479
+ addr = &segs[i];
4480
+ hash = inet6_addr_hash(net, addr);
4481
+
4482
+ hash_found = false;
4483
+ hlist_for_each_entry_rcu(ifp, &inet6_addr_lst[hash], addr_lst) {
4484
+ if (!net_eq(dev_net(ifp->idev->dev), net))
4485
+ continue;
4486
+
4487
+ if (ipv6_addr_equal(&ifp->addr, addr)) {
4488
+ hash_found = true;
4489
+ break;
4490
+ }
4491
+ }
4492
+
4493
+ if (hash_found) {
4494
+ if (found > 1 && separated) {
4495
+ ret = 1;
4496
+ break;
4497
+ }
4498
+
4499
+ separated = false;
4500
+ found++;
4501
+ } else {
4502
+ separated = true;
4503
+ }
4504
+ }
4505
+ rcu_read_unlock();
4506
+
4507
+ return ret;
4508
+}
4509
+
43784510 /*
43794511 * Periodic address status verification
43804512 */
....@@ -4445,7 +4577,7 @@
44454577 !(ifp->flags&IFA_F_TENTATIVE)) {
44464578 unsigned long regen_advance = ifp->idev->cnf.regen_max_retry *
44474579 ifp->idev->cnf.dad_transmits *
4448
- NEIGH_VAR(ifp->idev->nd_parms, RETRANS_TIME) / HZ;
4580
+ max(NEIGH_VAR(ifp->idev->nd_parms, RETRANS_TIME), HZ/100) / HZ;
44494581
44504582 if (age >= ifp->prefered_lft - regen_advance) {
44514583 struct inet6_ifaddr *ifpub = ifp->ifpub;
....@@ -4461,7 +4593,7 @@
44614593 ifpub->regen_count = 0;
44624594 spin_unlock(&ifpub->lock);
44634595 rcu_read_unlock_bh();
4464
- ipv6_create_tempaddr(ifpub, ifp, true);
4596
+ ipv6_create_tempaddr(ifpub, true);
44654597 in6_ifa_put(ifpub);
44664598 in6_ifa_put(ifp);
44674599 rcu_read_lock_bh();
....@@ -4533,6 +4665,7 @@
45334665 [IFA_CACHEINFO] = { .len = sizeof(struct ifa_cacheinfo) },
45344666 [IFA_FLAGS] = { .len = sizeof(u32) },
45354667 [IFA_RT_PRIORITY] = { .len = sizeof(u32) },
4668
+ [IFA_TARGET_NETNSID] = { .type = NLA_S32 },
45364669 };
45374670
45384671 static int
....@@ -4546,8 +4679,8 @@
45464679 u32 ifa_flags;
45474680 int err;
45484681
4549
- err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy,
4550
- extack);
4682
+ err = nlmsg_parse_deprecated(nlh, sizeof(*ifm), tb, IFA_MAX,
4683
+ ifa_ipv6_policy, extack);
45514684 if (err < 0)
45524685 return err;
45534686
....@@ -4574,15 +4707,14 @@
45744707
45754708 f6i = addrconf_get_prefix_route(modify_peer ? &ifp->peer_addr : &ifp->addr,
45764709 ifp->prefix_len,
4577
- ifp->idev->dev,
4578
- 0, RTF_GATEWAY | RTF_DEFAULT);
4710
+ ifp->idev->dev, 0, RTF_DEFAULT, true);
45794711 if (!f6i)
45804712 return -ENOENT;
45814713
45824714 prio = ifp->rt_priority ? : IP6_RT_PRIO_ADDRCONF;
45834715 if (f6i->fib6_metric != prio) {
45844716 /* delete old one */
4585
- ip6_del_rt(dev_net(ifp->idev->dev), f6i);
4717
+ ip6_del_rt(dev_net(ifp->idev->dev), f6i, false);
45864718
45874719 /* add new one */
45884720 addrconf_prefix_route(modify_peer ? &ifp->peer_addr : &ifp->addr,
....@@ -4734,8 +4866,8 @@
47344866 struct ifa6_config cfg;
47354867 int err;
47364868
4737
- err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy,
4738
- extack);
4869
+ err = nlmsg_parse_deprecated(nlh, sizeof(*ifm), tb, IFA_MAX,
4870
+ ifa_ipv6_policy, extack);
47394871 if (err < 0)
47404872 return err;
47414873
....@@ -4777,8 +4909,8 @@
47774909 IFA_F_MCAUTOJOIN | IFA_F_OPTIMISTIC;
47784910
47794911 idev = ipv6_find_idev(dev);
4780
- if (!idev)
4781
- return -ENOBUFS;
4912
+ if (IS_ERR(idev))
4913
+ return PTR_ERR(idev);
47824914
47834915 if (!ipv6_allow_optimistic_dad(net, idev))
47844916 cfg.ifa_flags &= ~IFA_F_OPTIMISTIC;
....@@ -4857,19 +4989,41 @@
48574989 + nla_total_size(4) /* IFA_RT_PRIORITY */;
48584990 }
48594991
4992
+enum addr_type_t {
4993
+ UNICAST_ADDR,
4994
+ MULTICAST_ADDR,
4995
+ ANYCAST_ADDR,
4996
+};
4997
+
4998
+struct inet6_fill_args {
4999
+ u32 portid;
5000
+ u32 seq;
5001
+ int event;
5002
+ unsigned int flags;
5003
+ int netnsid;
5004
+ int ifindex;
5005
+ enum addr_type_t type;
5006
+};
5007
+
48605008 static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
4861
- u32 portid, u32 seq, int event, unsigned int flags)
5009
+ struct inet6_fill_args *args)
48625010 {
48635011 struct nlmsghdr *nlh;
48645012 u32 preferred, valid;
48655013
4866
- nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct ifaddrmsg), flags);
5014
+ nlh = nlmsg_put(skb, args->portid, args->seq, args->event,
5015
+ sizeof(struct ifaddrmsg), args->flags);
48675016 if (!nlh)
48685017 return -EMSGSIZE;
48695018
48705019 put_ifaddrmsg(nlh, ifa->prefix_len, ifa->flags, rt_scope(ifa->scope),
48715020 ifa->idev->dev->ifindex);
48725021
5022
+ if (args->netnsid >= 0 &&
5023
+ nla_put_s32(skb, IFA_TARGET_NETNSID, args->netnsid))
5024
+ goto error;
5025
+
5026
+ spin_lock_bh(&ifa->lock);
48735027 if (!((ifa->flags&IFA_F_PERMANENT) &&
48745028 (ifa->prefered_lft == INFINITY_LIFE_TIME))) {
48755029 preferred = ifa->prefered_lft;
....@@ -4891,6 +5045,7 @@
48915045 preferred = INFINITY_LIFE_TIME;
48925046 valid = INFINITY_LIFE_TIME;
48935047 }
5048
+ spin_unlock_bh(&ifa->lock);
48945049
48955050 if (!ipv6_addr_any(&ifa->peer_addr)) {
48965051 if (nla_put_in6_addr(skb, IFA_LOCAL, &ifa->addr) < 0 ||
....@@ -4919,7 +5074,7 @@
49195074 }
49205075
49215076 static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca,
4922
- u32 portid, u32 seq, int event, u16 flags)
5077
+ struct inet6_fill_args *args)
49235078 {
49245079 struct nlmsghdr *nlh;
49255080 u8 scope = RT_SCOPE_UNIVERSE;
....@@ -4928,9 +5083,16 @@
49285083 if (ipv6_addr_scope(&ifmca->mca_addr) & IFA_SITE)
49295084 scope = RT_SCOPE_SITE;
49305085
4931
- nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct ifaddrmsg), flags);
5086
+ nlh = nlmsg_put(skb, args->portid, args->seq, args->event,
5087
+ sizeof(struct ifaddrmsg), args->flags);
49325088 if (!nlh)
49335089 return -EMSGSIZE;
5090
+
5091
+ if (args->netnsid >= 0 &&
5092
+ nla_put_s32(skb, IFA_TARGET_NETNSID, args->netnsid)) {
5093
+ nlmsg_cancel(skb, nlh);
5094
+ return -EMSGSIZE;
5095
+ }
49345096
49355097 put_ifaddrmsg(nlh, 128, IFA_F_PERMANENT, scope, ifindex);
49365098 if (nla_put_in6_addr(skb, IFA_MULTICAST, &ifmca->mca_addr) < 0 ||
....@@ -4945,7 +5107,7 @@
49455107 }
49465108
49475109 static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca,
4948
- u32 portid, u32 seq, int event, unsigned int flags)
5110
+ struct inet6_fill_args *args)
49495111 {
49505112 struct net_device *dev = fib6_info_nh_dev(ifaca->aca_rt);
49515113 int ifindex = dev ? dev->ifindex : 1;
....@@ -4955,9 +5117,16 @@
49555117 if (ipv6_addr_scope(&ifaca->aca_addr) & IFA_SITE)
49565118 scope = RT_SCOPE_SITE;
49575119
4958
- nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct ifaddrmsg), flags);
5120
+ nlh = nlmsg_put(skb, args->portid, args->seq, args->event,
5121
+ sizeof(struct ifaddrmsg), args->flags);
49595122 if (!nlh)
49605123 return -EMSGSIZE;
5124
+
5125
+ if (args->netnsid >= 0 &&
5126
+ nla_put_s32(skb, IFA_TARGET_NETNSID, args->netnsid)) {
5127
+ nlmsg_cancel(skb, nlh);
5128
+ return -EMSGSIZE;
5129
+ }
49615130
49625131 put_ifaddrmsg(nlh, 128, IFA_F_PERMANENT, scope, ifindex);
49635132 if (nla_put_in6_addr(skb, IFA_ANYCAST, &ifaca->aca_addr) < 0 ||
....@@ -4971,36 +5140,27 @@
49715140 return 0;
49725141 }
49735142
4974
-enum addr_type_t {
4975
- UNICAST_ADDR,
4976
- MULTICAST_ADDR,
4977
- ANYCAST_ADDR,
4978
-};
4979
-
49805143 /* called with rcu_read_lock() */
49815144 static int in6_dump_addrs(struct inet6_dev *idev, struct sk_buff *skb,
4982
- struct netlink_callback *cb, enum addr_type_t type,
4983
- int s_ip_idx, int *p_ip_idx)
5145
+ struct netlink_callback *cb, int s_ip_idx,
5146
+ struct inet6_fill_args *fillargs)
49845147 {
49855148 struct ifmcaddr6 *ifmca;
49865149 struct ifacaddr6 *ifaca;
5150
+ int ip_idx = 0;
49875151 int err = 1;
4988
- int ip_idx = *p_ip_idx;
49895152
49905153 read_lock_bh(&idev->lock);
4991
- switch (type) {
5154
+ switch (fillargs->type) {
49925155 case UNICAST_ADDR: {
49935156 struct inet6_ifaddr *ifa;
5157
+ fillargs->event = RTM_NEWADDR;
49945158
49955159 /* unicast address incl. temp addr */
49965160 list_for_each_entry(ifa, &idev->addr_list, if_list) {
49975161 if (ip_idx < s_ip_idx)
49985162 goto next;
4999
- err = inet6_fill_ifaddr(skb, ifa,
5000
- NETLINK_CB(cb->skb).portid,
5001
- cb->nlh->nlmsg_seq,
5002
- RTM_NEWADDR,
5003
- NLM_F_MULTI);
5163
+ err = inet6_fill_ifaddr(skb, ifa, fillargs);
50045164 if (err < 0)
50055165 break;
50065166 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
....@@ -5010,31 +5170,26 @@
50105170 break;
50115171 }
50125172 case MULTICAST_ADDR:
5173
+ fillargs->event = RTM_GETMULTICAST;
5174
+
50135175 /* multicast address */
50145176 for (ifmca = idev->mc_list; ifmca;
50155177 ifmca = ifmca->next, ip_idx++) {
50165178 if (ip_idx < s_ip_idx)
50175179 continue;
5018
- err = inet6_fill_ifmcaddr(skb, ifmca,
5019
- NETLINK_CB(cb->skb).portid,
5020
- cb->nlh->nlmsg_seq,
5021
- RTM_GETMULTICAST,
5022
- NLM_F_MULTI);
5180
+ err = inet6_fill_ifmcaddr(skb, ifmca, fillargs);
50235181 if (err < 0)
50245182 break;
50255183 }
50265184 break;
50275185 case ANYCAST_ADDR:
5186
+ fillargs->event = RTM_GETANYCAST;
50285187 /* anycast address */
50295188 for (ifaca = idev->ac_list; ifaca;
50305189 ifaca = ifaca->aca_next, ip_idx++) {
50315190 if (ip_idx < s_ip_idx)
50325191 continue;
5033
- err = inet6_fill_ifacaddr(skb, ifaca,
5034
- NETLINK_CB(cb->skb).portid,
5035
- cb->nlh->nlmsg_seq,
5036
- RTM_GETANYCAST,
5037
- NLM_F_MULTI);
5192
+ err = inet6_fill_ifacaddr(skb, ifaca, fillargs);
50385193 if (err < 0)
50395194 break;
50405195 }
....@@ -5043,42 +5198,130 @@
50435198 break;
50445199 }
50455200 read_unlock_bh(&idev->lock);
5046
- *p_ip_idx = ip_idx;
5201
+ cb->args[2] = ip_idx;
50475202 return err;
5203
+}
5204
+
5205
+static int inet6_valid_dump_ifaddr_req(const struct nlmsghdr *nlh,
5206
+ struct inet6_fill_args *fillargs,
5207
+ struct net **tgt_net, struct sock *sk,
5208
+ struct netlink_callback *cb)
5209
+{
5210
+ struct netlink_ext_ack *extack = cb->extack;
5211
+ struct nlattr *tb[IFA_MAX+1];
5212
+ struct ifaddrmsg *ifm;
5213
+ int err, i;
5214
+
5215
+ if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*ifm))) {
5216
+ NL_SET_ERR_MSG_MOD(extack, "Invalid header for address dump request");
5217
+ return -EINVAL;
5218
+ }
5219
+
5220
+ ifm = nlmsg_data(nlh);
5221
+ if (ifm->ifa_prefixlen || ifm->ifa_flags || ifm->ifa_scope) {
5222
+ NL_SET_ERR_MSG_MOD(extack, "Invalid values in header for address dump request");
5223
+ return -EINVAL;
5224
+ }
5225
+
5226
+ fillargs->ifindex = ifm->ifa_index;
5227
+ if (fillargs->ifindex) {
5228
+ cb->answer_flags |= NLM_F_DUMP_FILTERED;
5229
+ fillargs->flags |= NLM_F_DUMP_FILTERED;
5230
+ }
5231
+
5232
+ err = nlmsg_parse_deprecated_strict(nlh, sizeof(*ifm), tb, IFA_MAX,
5233
+ ifa_ipv6_policy, extack);
5234
+ if (err < 0)
5235
+ return err;
5236
+
5237
+ for (i = 0; i <= IFA_MAX; ++i) {
5238
+ if (!tb[i])
5239
+ continue;
5240
+
5241
+ if (i == IFA_TARGET_NETNSID) {
5242
+ struct net *net;
5243
+
5244
+ fillargs->netnsid = nla_get_s32(tb[i]);
5245
+ net = rtnl_get_net_ns_capable(sk, fillargs->netnsid);
5246
+ if (IS_ERR(net)) {
5247
+ fillargs->netnsid = -1;
5248
+ NL_SET_ERR_MSG_MOD(extack, "Invalid target network namespace id");
5249
+ return PTR_ERR(net);
5250
+ }
5251
+ *tgt_net = net;
5252
+ } else {
5253
+ NL_SET_ERR_MSG_MOD(extack, "Unsupported attribute in dump request");
5254
+ return -EINVAL;
5255
+ }
5256
+ }
5257
+
5258
+ return 0;
50485259 }
50495260
50505261 static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
50515262 enum addr_type_t type)
50525263 {
5264
+ const struct nlmsghdr *nlh = cb->nlh;
5265
+ struct inet6_fill_args fillargs = {
5266
+ .portid = NETLINK_CB(cb->skb).portid,
5267
+ .seq = cb->nlh->nlmsg_seq,
5268
+ .flags = NLM_F_MULTI,
5269
+ .netnsid = -1,
5270
+ .type = type,
5271
+ };
50535272 struct net *net = sock_net(skb->sk);
5273
+ struct net *tgt_net = net;
5274
+ int idx, s_idx, s_ip_idx;
50545275 int h, s_h;
5055
- int idx, ip_idx;
5056
- int s_idx, s_ip_idx;
50575276 struct net_device *dev;
50585277 struct inet6_dev *idev;
50595278 struct hlist_head *head;
5279
+ int err = 0;
50605280
50615281 s_h = cb->args[0];
50625282 s_idx = idx = cb->args[1];
5063
- s_ip_idx = ip_idx = cb->args[2];
5283
+ s_ip_idx = cb->args[2];
5284
+
5285
+ if (cb->strict_check) {
5286
+ err = inet6_valid_dump_ifaddr_req(nlh, &fillargs, &tgt_net,
5287
+ skb->sk, cb);
5288
+ if (err < 0)
5289
+ goto put_tgt_net;
5290
+
5291
+ err = 0;
5292
+ if (fillargs.ifindex) {
5293
+ dev = __dev_get_by_index(tgt_net, fillargs.ifindex);
5294
+ if (!dev) {
5295
+ err = -ENODEV;
5296
+ goto put_tgt_net;
5297
+ }
5298
+ idev = __in6_dev_get(dev);
5299
+ if (idev) {
5300
+ err = in6_dump_addrs(idev, skb, cb, s_ip_idx,
5301
+ &fillargs);
5302
+ if (err > 0)
5303
+ err = 0;
5304
+ }
5305
+ goto put_tgt_net;
5306
+ }
5307
+ }
50645308
50655309 rcu_read_lock();
5066
- cb->seq = atomic_read(&net->ipv6.dev_addr_genid) ^ net->dev_base_seq;
5310
+ cb->seq = atomic_read(&tgt_net->ipv6.dev_addr_genid) ^ tgt_net->dev_base_seq;
50675311 for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
50685312 idx = 0;
5069
- head = &net->dev_index_head[h];
5313
+ head = &tgt_net->dev_index_head[h];
50705314 hlist_for_each_entry_rcu(dev, head, index_hlist) {
50715315 if (idx < s_idx)
50725316 goto cont;
50735317 if (h > s_h || idx > s_idx)
50745318 s_ip_idx = 0;
5075
- ip_idx = 0;
50765319 idev = __in6_dev_get(dev);
50775320 if (!idev)
50785321 goto cont;
50795322
5080
- if (in6_dump_addrs(idev, skb, cb, type,
5081
- s_ip_idx, &ip_idx) < 0)
5323
+ if (in6_dump_addrs(idev, skb, cb, s_ip_idx,
5324
+ &fillargs) < 0)
50825325 goto done;
50835326 cont:
50845327 idx++;
....@@ -5088,9 +5331,11 @@
50885331 rcu_read_unlock();
50895332 cb->args[0] = h;
50905333 cb->args[1] = idx;
5091
- cb->args[2] = ip_idx;
5334
+put_tgt_net:
5335
+ if (fillargs.netnsid >= 0)
5336
+ put_net(tgt_net);
50925337
5093
- return skb->len;
5338
+ return skb->len ? : err;
50945339 }
50955340
50965341 static int inet6_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
....@@ -5115,10 +5360,64 @@
51155360 return inet6_dump_addr(skb, cb, type);
51165361 }
51175362
5363
+static int inet6_rtm_valid_getaddr_req(struct sk_buff *skb,
5364
+ const struct nlmsghdr *nlh,
5365
+ struct nlattr **tb,
5366
+ struct netlink_ext_ack *extack)
5367
+{
5368
+ struct ifaddrmsg *ifm;
5369
+ int i, err;
5370
+
5371
+ if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*ifm))) {
5372
+ NL_SET_ERR_MSG_MOD(extack, "Invalid header for get address request");
5373
+ return -EINVAL;
5374
+ }
5375
+
5376
+ if (!netlink_strict_get_check(skb))
5377
+ return nlmsg_parse_deprecated(nlh, sizeof(*ifm), tb, IFA_MAX,
5378
+ ifa_ipv6_policy, extack);
5379
+
5380
+ ifm = nlmsg_data(nlh);
5381
+ if (ifm->ifa_prefixlen || ifm->ifa_flags || ifm->ifa_scope) {
5382
+ NL_SET_ERR_MSG_MOD(extack, "Invalid values in header for get address request");
5383
+ return -EINVAL;
5384
+ }
5385
+
5386
+ err = nlmsg_parse_deprecated_strict(nlh, sizeof(*ifm), tb, IFA_MAX,
5387
+ ifa_ipv6_policy, extack);
5388
+ if (err)
5389
+ return err;
5390
+
5391
+ for (i = 0; i <= IFA_MAX; i++) {
5392
+ if (!tb[i])
5393
+ continue;
5394
+
5395
+ switch (i) {
5396
+ case IFA_TARGET_NETNSID:
5397
+ case IFA_ADDRESS:
5398
+ case IFA_LOCAL:
5399
+ break;
5400
+ default:
5401
+ NL_SET_ERR_MSG_MOD(extack, "Unsupported attribute in get address request");
5402
+ return -EINVAL;
5403
+ }
5404
+ }
5405
+
5406
+ return 0;
5407
+}
5408
+
51185409 static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr *nlh,
51195410 struct netlink_ext_ack *extack)
51205411 {
51215412 struct net *net = sock_net(in_skb->sk);
5413
+ struct inet6_fill_args fillargs = {
5414
+ .portid = NETLINK_CB(in_skb).portid,
5415
+ .seq = nlh->nlmsg_seq,
5416
+ .event = RTM_NEWADDR,
5417
+ .flags = 0,
5418
+ .netnsid = -1,
5419
+ };
5420
+ struct net *tgt_net = net;
51225421 struct ifaddrmsg *ifm;
51235422 struct nlattr *tb[IFA_MAX+1];
51245423 struct in6_addr *addr = NULL, *peer;
....@@ -5127,10 +5426,18 @@
51275426 struct sk_buff *skb;
51285427 int err;
51295428
5130
- err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy,
5131
- extack);
5429
+ err = inet6_rtm_valid_getaddr_req(in_skb, nlh, tb, extack);
51325430 if (err < 0)
51335431 return err;
5432
+
5433
+ if (tb[IFA_TARGET_NETNSID]) {
5434
+ fillargs.netnsid = nla_get_s32(tb[IFA_TARGET_NETNSID]);
5435
+
5436
+ tgt_net = rtnl_get_net_ns_capable(NETLINK_CB(in_skb).sk,
5437
+ fillargs.netnsid);
5438
+ if (IS_ERR(tgt_net))
5439
+ return PTR_ERR(tgt_net);
5440
+ }
51345441
51355442 addr = extract_addr(tb[IFA_ADDRESS], tb[IFA_LOCAL], &peer);
51365443 if (!addr)
....@@ -5138,9 +5445,9 @@
51385445
51395446 ifm = nlmsg_data(nlh);
51405447 if (ifm->ifa_index)
5141
- dev = dev_get_by_index(net, ifm->ifa_index);
5448
+ dev = dev_get_by_index(tgt_net, ifm->ifa_index);
51425449
5143
- ifa = ipv6_get_ifaddr(net, addr, dev, 1);
5450
+ ifa = ipv6_get_ifaddr(tgt_net, addr, dev, 1);
51445451 if (!ifa) {
51455452 err = -EADDRNOTAVAIL;
51465453 goto errout;
....@@ -5152,20 +5459,22 @@
51525459 goto errout_ifa;
51535460 }
51545461
5155
- err = inet6_fill_ifaddr(skb, ifa, NETLINK_CB(in_skb).portid,
5156
- nlh->nlmsg_seq, RTM_NEWADDR, 0);
5462
+ err = inet6_fill_ifaddr(skb, ifa, &fillargs);
51575463 if (err < 0) {
51585464 /* -EMSGSIZE implies BUG in inet6_ifaddr_msgsize() */
51595465 WARN_ON(err == -EMSGSIZE);
51605466 kfree_skb(skb);
51615467 goto errout_ifa;
51625468 }
5163
- err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).portid);
5469
+ err = rtnl_unicast(skb, tgt_net, NETLINK_CB(in_skb).portid);
51645470 errout_ifa:
51655471 in6_ifa_put(ifa);
51665472 errout:
51675473 if (dev)
51685474 dev_put(dev);
5475
+ if (fillargs.netnsid >= 0)
5476
+ put_net(tgt_net);
5477
+
51695478 return err;
51705479 }
51715480
....@@ -5173,13 +5482,20 @@
51735482 {
51745483 struct sk_buff *skb;
51755484 struct net *net = dev_net(ifa->idev->dev);
5485
+ struct inet6_fill_args fillargs = {
5486
+ .portid = 0,
5487
+ .seq = 0,
5488
+ .event = event,
5489
+ .flags = 0,
5490
+ .netnsid = -1,
5491
+ };
51765492 int err = -ENOBUFS;
51775493
51785494 skb = nlmsg_new(inet6_ifaddr_msgsize(), GFP_ATOMIC);
51795495 if (!skb)
51805496 goto errout;
51815497
5182
- err = inet6_fill_ifaddr(skb, ifa, 0, 0, event, 0);
5498
+ err = inet6_fill_ifaddr(skb, ifa, &fillargs);
51835499 if (err < 0) {
51845500 /* -EMSGSIZE implies BUG in inet6_ifaddr_msgsize() */
51855501 WARN_ON(err == -EMSGSIZE);
....@@ -5243,7 +5559,7 @@
52435559 array[DEVCONF_USE_OPTIMISTIC] = cnf->use_optimistic;
52445560 #endif
52455561 #ifdef CONFIG_IPV6_MROUTE
5246
- array[DEVCONF_MC_FORWARDING] = cnf->mc_forwarding;
5562
+ array[DEVCONF_MC_FORWARDING] = atomic_read(&cnf->mc_forwarding);
52475563 #endif
52485564 array[DEVCONF_DISABLE_IPV6] = cnf->disable_ipv6;
52495565 array[DEVCONF_ACCEPT_DAD] = cnf->accept_dad;
....@@ -5266,6 +5582,7 @@
52665582 array[DEVCONF_ADDR_GEN_MODE] = cnf->addr_gen_mode;
52675583 array[DEVCONF_DISABLE_POLICY] = cnf->disable_policy;
52685584 array[DEVCONF_NDISC_TCLASS] = cnf->ndisc_tclass;
5585
+ array[DEVCONF_RPL_SEG_ENABLED] = cnf->rpl_seg_enabled;
52695586 }
52705587
52715588 static inline size_t inet6_ifla6_size(void)
....@@ -5378,13 +5695,12 @@
53785695 nla = nla_reserve(skb, IFLA_INET6_TOKEN, sizeof(struct in6_addr));
53795696 if (!nla)
53805697 goto nla_put_failure;
5381
-
5382
- if (nla_put_u8(skb, IFLA_INET6_ADDR_GEN_MODE, idev->cnf.addr_gen_mode))
5383
- goto nla_put_failure;
5384
-
53855698 read_lock_bh(&idev->lock);
53865699 memcpy(nla_data(nla), idev->token.s6_addr, nla_len(nla));
53875700 read_unlock_bh(&idev->lock);
5701
+
5702
+ if (nla_put_u8(skb, IFLA_INET6_ADDR_GEN_MODE, idev->cnf.addr_gen_mode))
5703
+ goto nla_put_failure;
53885704
53895705 return 0;
53905706
....@@ -5486,18 +5802,6 @@
54865802 [IFLA_INET6_TOKEN] = { .len = sizeof(struct in6_addr) },
54875803 };
54885804
5489
-static int inet6_validate_link_af(const struct net_device *dev,
5490
- const struct nlattr *nla)
5491
-{
5492
- struct nlattr *tb[IFLA_INET6_MAX + 1];
5493
-
5494
- if (dev && !__in6_dev_get(dev))
5495
- return -EAFNOSUPPORT;
5496
-
5497
- return nla_parse_nested(tb, IFLA_INET6_MAX, nla, inet6_af_policy,
5498
- NULL);
5499
-}
5500
-
55015805 static int check_addr_gen_mode(int mode)
55025806 {
55035807 if (mode != IN6_ADDR_GEN_MODE_EUI64 &&
....@@ -5518,17 +5822,50 @@
55185822 return 1;
55195823 }
55205824
5825
+static int inet6_validate_link_af(const struct net_device *dev,
5826
+ const struct nlattr *nla)
5827
+{
5828
+ struct nlattr *tb[IFLA_INET6_MAX + 1];
5829
+ struct inet6_dev *idev = NULL;
5830
+ int err;
5831
+
5832
+ if (dev) {
5833
+ idev = __in6_dev_get(dev);
5834
+ if (!idev)
5835
+ return -EAFNOSUPPORT;
5836
+ }
5837
+
5838
+ err = nla_parse_nested_deprecated(tb, IFLA_INET6_MAX, nla,
5839
+ inet6_af_policy, NULL);
5840
+ if (err)
5841
+ return err;
5842
+
5843
+ if (!tb[IFLA_INET6_TOKEN] && !tb[IFLA_INET6_ADDR_GEN_MODE])
5844
+ return -EINVAL;
5845
+
5846
+ if (tb[IFLA_INET6_ADDR_GEN_MODE]) {
5847
+ u8 mode = nla_get_u8(tb[IFLA_INET6_ADDR_GEN_MODE]);
5848
+
5849
+ if (check_addr_gen_mode(mode) < 0)
5850
+ return -EINVAL;
5851
+ if (dev && check_stable_privacy(idev, dev_net(dev), mode) < 0)
5852
+ return -EINVAL;
5853
+ }
5854
+
5855
+ return 0;
5856
+}
5857
+
55215858 static int inet6_set_link_af(struct net_device *dev, const struct nlattr *nla)
55225859 {
5523
- int err = -EINVAL;
55245860 struct inet6_dev *idev = __in6_dev_get(dev);
55255861 struct nlattr *tb[IFLA_INET6_MAX + 1];
5862
+ int err;
55265863
55275864 if (!idev)
55285865 return -EAFNOSUPPORT;
55295866
5530
- if (nla_parse_nested(tb, IFLA_INET6_MAX, nla, NULL, NULL) < 0)
5531
- BUG();
5867
+ if (nla_parse_nested_deprecated(tb, IFLA_INET6_MAX, nla, NULL, NULL) < 0)
5868
+ return -EINVAL;
55325869
55335870 if (tb[IFLA_INET6_TOKEN]) {
55345871 err = inet6_set_iftoken(idev, nla_data(tb[IFLA_INET6_TOKEN]));
....@@ -5539,15 +5876,10 @@
55395876 if (tb[IFLA_INET6_ADDR_GEN_MODE]) {
55405877 u8 mode = nla_get_u8(tb[IFLA_INET6_ADDR_GEN_MODE]);
55415878
5542
- if (check_addr_gen_mode(mode) < 0 ||
5543
- check_stable_privacy(idev, dev_net(dev), mode) < 0)
5544
- return -EINVAL;
5545
-
55465879 idev->cnf.addr_gen_mode = mode;
5547
- err = 0;
55485880 }
55495881
5550
- return err;
5882
+ return 0;
55515883 }
55525884
55535885 static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
....@@ -5579,7 +5911,7 @@
55795911 nla_put_u8(skb, IFLA_OPERSTATE,
55805912 netif_running(dev) ? dev->operstate : IF_OPER_DOWN))
55815913 goto nla_put_failure;
5582
- protoinfo = nla_nest_start(skb, IFLA_PROTINFO);
5914
+ protoinfo = nla_nest_start_noflag(skb, IFLA_PROTINFO);
55835915 if (!protoinfo)
55845916 goto nla_put_failure;
55855917
....@@ -5595,6 +5927,31 @@
55955927 return -EMSGSIZE;
55965928 }
55975929
5930
+static int inet6_valid_dump_ifinfo(const struct nlmsghdr *nlh,
5931
+ struct netlink_ext_ack *extack)
5932
+{
5933
+ struct ifinfomsg *ifm;
5934
+
5935
+ if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*ifm))) {
5936
+ NL_SET_ERR_MSG_MOD(extack, "Invalid header for link dump request");
5937
+ return -EINVAL;
5938
+ }
5939
+
5940
+ if (nlmsg_attrlen(nlh, sizeof(*ifm))) {
5941
+ NL_SET_ERR_MSG_MOD(extack, "Invalid data after header");
5942
+ return -EINVAL;
5943
+ }
5944
+
5945
+ ifm = nlmsg_data(nlh);
5946
+ if (ifm->__ifi_pad || ifm->ifi_type || ifm->ifi_flags ||
5947
+ ifm->ifi_change || ifm->ifi_index) {
5948
+ NL_SET_ERR_MSG_MOD(extack, "Invalid values in header for dump request");
5949
+ return -EINVAL;
5950
+ }
5951
+
5952
+ return 0;
5953
+}
5954
+
55985955 static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
55995956 {
56005957 struct net *net = sock_net(skb->sk);
....@@ -5603,6 +5960,16 @@
56035960 struct net_device *dev;
56045961 struct inet6_dev *idev;
56055962 struct hlist_head *head;
5963
+
5964
+ /* only requests using strict checking can pass data to
5965
+ * influence the dump
5966
+ */
5967
+ if (cb->strict_check) {
5968
+ int err = inet6_valid_dump_ifinfo(cb->nlh, cb->extack);
5969
+
5970
+ if (err < 0)
5971
+ return err;
5972
+ }
56065973
56075974 s_h = cb->args[0];
56085975 s_idx = cb->args[1];
....@@ -5771,12 +6138,13 @@
57716138 struct fib6_info *rt;
57726139
57736140 rt = addrconf_get_prefix_route(&ifp->peer_addr, 128,
5774
- ifp->idev->dev, 0, 0);
6141
+ ifp->idev->dev, 0, 0,
6142
+ false);
57756143 if (rt)
5776
- ip6_del_rt(net, rt);
6144
+ ip6_del_rt(net, rt, false);
57776145 }
57786146 if (ifp->rt) {
5779
- ip6_del_rt(net, ifp->rt);
6147
+ ip6_del_rt(net, ifp->rt, false);
57806148 ifp->rt = NULL;
57816149 }
57826150 rt_genid_bump_ipv6(net);
....@@ -5795,9 +6163,8 @@
57956163
57966164 #ifdef CONFIG_SYSCTL
57976165
5798
-static
5799
-int addrconf_sysctl_forward(struct ctl_table *ctl, int write,
5800
- void __user *buffer, size_t *lenp, loff_t *ppos)
6166
+static int addrconf_sysctl_forward(struct ctl_table *ctl, int write,
6167
+ void *buffer, size_t *lenp, loff_t *ppos)
58016168 {
58026169 int *valp = ctl->data;
58036170 int val = *valp;
....@@ -5821,9 +6188,8 @@
58216188 return ret;
58226189 }
58236190
5824
-static
5825
-int addrconf_sysctl_mtu(struct ctl_table *ctl, int write,
5826
- void __user *buffer, size_t *lenp, loff_t *ppos)
6191
+static int addrconf_sysctl_mtu(struct ctl_table *ctl, int write,
6192
+ void *buffer, size_t *lenp, loff_t *ppos)
58276193 {
58286194 struct inet6_dev *idev = ctl->extra1;
58296195 int min_mtu = IPV6_MIN_MTU;
....@@ -5893,9 +6259,8 @@
58936259 return 0;
58946260 }
58956261
5896
-static
5897
-int addrconf_sysctl_disable(struct ctl_table *ctl, int write,
5898
- void __user *buffer, size_t *lenp, loff_t *ppos)
6262
+static int addrconf_sysctl_disable(struct ctl_table *ctl, int write,
6263
+ void *buffer, size_t *lenp, loff_t *ppos)
58996264 {
59006265 int *valp = ctl->data;
59016266 int val = *valp;
....@@ -5919,9 +6284,8 @@
59196284 return ret;
59206285 }
59216286
5922
-static
5923
-int addrconf_sysctl_proxy_ndp(struct ctl_table *ctl, int write,
5924
- void __user *buffer, size_t *lenp, loff_t *ppos)
6287
+static int addrconf_sysctl_proxy_ndp(struct ctl_table *ctl, int write,
6288
+ void *buffer, size_t *lenp, loff_t *ppos)
59256289 {
59266290 int *valp = ctl->data;
59276291 int ret;
....@@ -5962,7 +6326,7 @@
59626326 }
59636327
59646328 static int addrconf_sysctl_addr_gen_mode(struct ctl_table *ctl, int write,
5965
- void __user *buffer, size_t *lenp,
6329
+ void *buffer, size_t *lenp,
59666330 loff_t *ppos)
59676331 {
59686332 int ret = 0;
....@@ -6024,7 +6388,7 @@
60246388 }
60256389
60266390 static int addrconf_sysctl_stable_secret(struct ctl_table *ctl, int write,
6027
- void __user *buffer, size_t *lenp,
6391
+ void *buffer, size_t *lenp,
60286392 loff_t *ppos)
60296393 {
60306394 int err;
....@@ -6091,8 +6455,7 @@
60916455
60926456 static
60936457 int addrconf_sysctl_ignore_routes_with_linkdown(struct ctl_table *ctl,
6094
- int write,
6095
- void __user *buffer,
6458
+ int write, void *buffer,
60966459 size_t *lenp,
60976460 loff_t *ppos)
60986461 {
....@@ -6137,16 +6500,17 @@
61376500 list_for_each_entry(ifa, &idev->addr_list, if_list) {
61386501 spin_lock(&ifa->lock);
61396502 if (ifa->rt) {
6140
- struct fib6_info *rt = ifa->rt;
6503
+ /* host routes only use builtin fib6_nh */
6504
+ struct fib6_nh *nh = ifa->rt->fib6_nh;
61416505 int cpu;
61426506
61436507 rcu_read_lock();
61446508 ifa->rt->dst_nopolicy = val ? true : false;
6145
- if (rt->rt6i_pcpu) {
6509
+ if (nh->rt6i_pcpu) {
61466510 for_each_possible_cpu(cpu) {
61476511 struct rt6_info **rtp;
61486512
6149
- rtp = per_cpu_ptr(rt->rt6i_pcpu, cpu);
6513
+ rtp = per_cpu_ptr(nh->rt6i_pcpu, cpu);
61506514 addrconf_set_nopolicy(*rtp, val);
61516515 }
61526516 }
....@@ -6191,10 +6555,8 @@
61916555 return 0;
61926556 }
61936557
6194
-static
6195
-int addrconf_sysctl_disable_policy(struct ctl_table *ctl, int write,
6196
- void __user *buffer, size_t *lenp,
6197
- loff_t *ppos)
6558
+static int addrconf_sysctl_disable_policy(struct ctl_table *ctl, int write,
6559
+ void *buffer, size_t *lenp, loff_t *ppos)
61986560 {
61996561 int *valp = ctl->data;
62006562 int val = *valp;
....@@ -6216,8 +6578,6 @@
62166578 }
62176579
62186580 static int minus_one = -1;
6219
-static const int zero = 0;
6220
-static const int one = 1;
62216581 static const int two_five_five = 255;
62226582
62236583 static const struct ctl_table addrconf_sysctl[] = {
....@@ -6234,7 +6594,7 @@
62346594 .maxlen = sizeof(int),
62356595 .mode = 0644,
62366596 .proc_handler = proc_dointvec_minmax,
6237
- .extra1 = (void *)&one,
6597
+ .extra1 = (void *)SYSCTL_ONE,
62386598 .extra2 = (void *)&two_five_five,
62396599 },
62406600 {
....@@ -6600,8 +6960,15 @@
66006960 .maxlen = sizeof(int),
66016961 .mode = 0644,
66026962 .proc_handler = proc_dointvec_minmax,
6603
- .extra1 = (void *)&zero,
6963
+ .extra1 = (void *)SYSCTL_ZERO,
66046964 .extra2 = (void *)&two_five_five,
6965
+ },
6966
+ {
6967
+ .procname = "rpl_seg_enabled",
6968
+ .data = &ipv6_devconf.rpl_seg_enabled,
6969
+ .maxlen = sizeof(int),
6970
+ .mode = 0644,
6971
+ .proc_handler = proc_dointvec,
66056972 },
66066973 {
66076974 /* sentinel */
....@@ -6710,6 +7077,28 @@
67107077 dflt = kmemdup(&ipv6_devconf_dflt, sizeof(ipv6_devconf_dflt), GFP_KERNEL);
67117078 if (!dflt)
67127079 goto err_alloc_dflt;
7080
+
7081
+ if (!net_eq(net, &init_net)) {
7082
+ switch (net_inherit_devconf()) {
7083
+ case 1: /* copy from init_net */
7084
+ memcpy(all, init_net.ipv6.devconf_all,
7085
+ sizeof(ipv6_devconf));
7086
+ memcpy(dflt, init_net.ipv6.devconf_dflt,
7087
+ sizeof(ipv6_devconf_dflt));
7088
+ break;
7089
+ case 3: /* copy from the current netns */
7090
+ memcpy(all, current->nsproxy->net_ns->ipv6.devconf_all,
7091
+ sizeof(ipv6_devconf));
7092
+ memcpy(dflt,
7093
+ current->nsproxy->net_ns->ipv6.devconf_dflt,
7094
+ sizeof(ipv6_devconf_dflt));
7095
+ break;
7096
+ case 0:
7097
+ case 2:
7098
+ /* use compiled values */
7099
+ break;
7100
+ }
7101
+ }
67137102
67147103 /* these will be inherited by all namespaces */
67157104 dflt->autoconf = ipv6_defaults.autoconf;
....@@ -6900,9 +7289,9 @@
69007289 for_each_netdev(&init_net, dev) {
69017290 if (__in6_dev_get(dev) == NULL)
69027291 continue;
6903
- addrconf_ifdown(dev, 1);
7292
+ addrconf_ifdown(dev, true);
69047293 }
6905
- addrconf_ifdown(init_net.loopback_dev, 2);
7294
+ addrconf_ifdown(init_net.loopback_dev, true);
69067295
69077296 /*
69087297 * Check hash table.