hc
2024-01-31 f9004dbfff8a3fbbd7e2a88c8a4327c7f2f8e5b2
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 */
....@@ -318,9 +318,8 @@
318318 static void addrconf_mod_rs_timer(struct inet6_dev *idev,
319319 unsigned long when)
320320 {
321
- if (!timer_pending(&idev->rs_timer))
321
+ if (!mod_timer(&idev->rs_timer, jiffies + when))
322322 in6_dev_hold(idev);
323
- mod_timer(&idev->rs_timer, jiffies + when);
324323 }
325324
326325 static void addrconf_mod_dad_work(struct inet6_ifaddr *ifp,
....@@ -435,8 +434,7 @@
435434 dev->type == ARPHRD_SIT ||
436435 dev->type == ARPHRD_NONE) {
437436 ndev->cnf.use_tempaddr = -1;
438
- } else
439
- ipv6_regen_rndid(ndev);
437
+ }
440438
441439 ndev->token = in6addr_any;
442440
....@@ -483,7 +481,7 @@
483481 if (!idev) {
484482 idev = ipv6_add_dev(dev);
485483 if (IS_ERR(idev))
486
- return NULL;
484
+ return idev;
487485 }
488486
489487 if (dev->flags&IFF_UP)
....@@ -547,7 +545,7 @@
547545 #ifdef CONFIG_IPV6_MROUTE
548546 if ((all || type == NETCONFA_MC_FORWARDING) &&
549547 nla_put_s32(skb, NETCONFA_MC_FORWARDING,
550
- devconf->mc_forwarding) < 0)
548
+ atomic_read(&devconf->mc_forwarding)) < 0)
551549 goto nla_put_failure;
552550 #endif
553551 if ((all || type == NETCONFA_PROXY_NEIGH) &&
....@@ -599,6 +597,45 @@
599597 [NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN] = { .len = sizeof(int) },
600598 };
601599
600
+static int inet6_netconf_valid_get_req(struct sk_buff *skb,
601
+ const struct nlmsghdr *nlh,
602
+ struct nlattr **tb,
603
+ struct netlink_ext_ack *extack)
604
+{
605
+ int i, err;
606
+
607
+ if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(struct netconfmsg))) {
608
+ NL_SET_ERR_MSG_MOD(extack, "Invalid header for netconf get request");
609
+ return -EINVAL;
610
+ }
611
+
612
+ if (!netlink_strict_get_check(skb))
613
+ return nlmsg_parse_deprecated(nlh, sizeof(struct netconfmsg),
614
+ tb, NETCONFA_MAX,
615
+ devconf_ipv6_policy, extack);
616
+
617
+ err = nlmsg_parse_deprecated_strict(nlh, sizeof(struct netconfmsg),
618
+ tb, NETCONFA_MAX,
619
+ devconf_ipv6_policy, extack);
620
+ if (err)
621
+ return err;
622
+
623
+ for (i = 0; i <= NETCONFA_MAX; i++) {
624
+ if (!tb[i])
625
+ continue;
626
+
627
+ switch (i) {
628
+ case NETCONFA_IFINDEX:
629
+ break;
630
+ default:
631
+ NL_SET_ERR_MSG_MOD(extack, "Unsupported attribute in netconf get request");
632
+ return -EINVAL;
633
+ }
634
+ }
635
+
636
+ return 0;
637
+}
638
+
602639 static int inet6_netconf_get_devconf(struct sk_buff *in_skb,
603640 struct nlmsghdr *nlh,
604641 struct netlink_ext_ack *extack)
....@@ -607,14 +644,12 @@
607644 struct nlattr *tb[NETCONFA_MAX+1];
608645 struct inet6_dev *in6_dev = NULL;
609646 struct net_device *dev = NULL;
610
- struct netconfmsg *ncm;
611647 struct sk_buff *skb;
612648 struct ipv6_devconf *devconf;
613649 int ifindex;
614650 int err;
615651
616
- err = nlmsg_parse(nlh, sizeof(*ncm), tb, NETCONFA_MAX,
617
- devconf_ipv6_policy, extack);
652
+ err = inet6_netconf_valid_get_req(in_skb, nlh, tb, extack);
618653 if (err < 0)
619654 return err;
620655
....@@ -668,12 +703,28 @@
668703 static int inet6_netconf_dump_devconf(struct sk_buff *skb,
669704 struct netlink_callback *cb)
670705 {
706
+ const struct nlmsghdr *nlh = cb->nlh;
671707 struct net *net = sock_net(skb->sk);
672708 int h, s_h;
673709 int idx, s_idx;
674710 struct net_device *dev;
675711 struct inet6_dev *idev;
676712 struct hlist_head *head;
713
+
714
+ if (cb->strict_check) {
715
+ struct netlink_ext_ack *extack = cb->extack;
716
+ struct netconfmsg *ncm;
717
+
718
+ if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*ncm))) {
719
+ NL_SET_ERR_MSG_MOD(extack, "Invalid header for netconf dump request");
720
+ return -EINVAL;
721
+ }
722
+
723
+ if (nlmsg_attrlen(nlh, sizeof(*ncm))) {
724
+ NL_SET_ERR_MSG_MOD(extack, "Invalid data after header in netconf dump request");
725
+ return -EINVAL;
726
+ }
727
+ }
677728
678729 s_h = cb->args[0];
679730 s_idx = idx = cb->args[1];
....@@ -694,7 +745,7 @@
694745 if (inet6_netconf_fill_devconf(skb, dev->ifindex,
695746 &idev->cnf,
696747 NETLINK_CB(cb->skb).portid,
697
- cb->nlh->nlmsg_seq,
748
+ nlh->nlmsg_seq,
698749 RTM_NEWNETCONF,
699750 NLM_F_MULTI,
700751 NETCONFA_ALL) < 0) {
....@@ -711,7 +762,7 @@
711762 if (inet6_netconf_fill_devconf(skb, NETCONFA_IFINDEX_ALL,
712763 net->ipv6.devconf_all,
713764 NETLINK_CB(cb->skb).portid,
714
- cb->nlh->nlmsg_seq,
765
+ nlh->nlmsg_seq,
715766 RTM_NEWNETCONF, NLM_F_MULTI,
716767 NETCONFA_ALL) < 0)
717768 goto done;
....@@ -722,7 +773,7 @@
722773 if (inet6_netconf_fill_devconf(skb, NETCONFA_IFINDEX_DEFAULT,
723774 net->ipv6.devconf_dflt,
724775 NETLINK_CB(cb->skb).portid,
725
- cb->nlh->nlmsg_seq,
776
+ nlh->nlmsg_seq,
726777 RTM_NEWNETCONF, NLM_F_MULTI,
727778 NETCONFA_ALL) < 0)
728779 goto done;
....@@ -741,6 +792,7 @@
741792 {
742793 struct net_device *dev;
743794 struct inet6_ifaddr *ifa;
795
+ LIST_HEAD(tmp_addr_list);
744796
745797 if (!idev)
746798 return;
....@@ -759,14 +811,24 @@
759811 }
760812 }
761813
814
+ read_lock_bh(&idev->lock);
762815 list_for_each_entry(ifa, &idev->addr_list, if_list) {
763816 if (ifa->flags&IFA_F_TENTATIVE)
764817 continue;
818
+ list_add_tail(&ifa->if_list_aux, &tmp_addr_list);
819
+ }
820
+ read_unlock_bh(&idev->lock);
821
+
822
+ while (!list_empty(&tmp_addr_list)) {
823
+ ifa = list_first_entry(&tmp_addr_list,
824
+ struct inet6_ifaddr, if_list_aux);
825
+ list_del(&ifa->if_list_aux);
765826 if (idev->cnf.forwarding)
766827 addrconf_join_anycast(ifa);
767828 else
768829 addrconf_leave_anycast(ifa);
769830 }
831
+
770832 inet6_netconf_notify_devconf(dev_net(dev), RTM_NEWNETCONF,
771833 NETCONFA_FORWARDING,
772834 dev->ifindex, &idev->cnf);
....@@ -1000,6 +1062,7 @@
10001062 (addr_type & IPV6_ADDR_MULTICAST &&
10011063 !(cfg->ifa_flags & IFA_F_MCAUTOJOIN)) ||
10021064 (!(idev->dev->flags & IFF_LOOPBACK) &&
1065
+ !netif_is_l3_master(idev->dev) &&
10031066 addr_type & IPV6_ADDR_LOOPBACK))
10041067 return ERR_PTR(-EADDRNOTAVAIL);
10051068
....@@ -1041,10 +1104,6 @@
10411104 f6i = NULL;
10421105 goto out;
10431106 }
1044
-
1045
- if (net->ipv6.devconf_all->disable_policy ||
1046
- idev->cnf.disable_policy)
1047
- f6i->dst_nopolicy = true;
10481107
10491108 neigh_parms_data_state_setall(idev->nd_parms);
10501109
....@@ -1183,12 +1242,11 @@
11831242 struct fib6_info *f6i;
11841243
11851244 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);
1245
+ ifp->prefix_len,
1246
+ ifp->idev->dev, 0, RTF_DEFAULT, true);
11891247 if (f6i) {
11901248 if (del_rt)
1191
- ip6_del_rt(dev_net(ifp->idev->dev), f6i);
1249
+ ip6_del_rt(dev_net(ifp->idev->dev), f6i, false);
11921250 else {
11931251 if (!(f6i->fib6_flags & RTF_EXPIRES))
11941252 fib6_set_expires(f6i, expires);
....@@ -1256,29 +1314,21 @@
12561314 in6_ifa_put(ifp);
12571315 }
12581316
1259
-static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp,
1260
- struct inet6_ifaddr *ift,
1261
- bool block)
1317
+static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, bool block)
12621318 {
12631319 struct inet6_dev *idev = ifp->idev;
1264
- struct in6_addr addr, *tmpaddr;
12651320 unsigned long tmp_tstamp, age;
12661321 unsigned long regen_advance;
1267
- struct ifa6_config cfg;
1268
- int ret = 0;
12691322 unsigned long now = jiffies;
1270
- long max_desync_factor;
12711323 s32 cnf_temp_preferred_lft;
1324
+ struct inet6_ifaddr *ift;
1325
+ struct ifa6_config cfg;
1326
+ long max_desync_factor;
1327
+ struct in6_addr addr;
1328
+ int ret = 0;
12721329
12731330 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
- }
1331
+
12821332 retry:
12831333 in6_dev_hold(idev);
12841334 if (idev->cnf.use_tempaddr <= 0) {
....@@ -1301,19 +1351,19 @@
13011351 }
13021352 in6_ifa_hold(ifp);
13031353 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);
1354
+ ipv6_gen_rnd_iid(&addr);
1355
+
13061356 age = (now - ifp->tstamp) / HZ;
13071357
13081358 regen_advance = idev->cnf.regen_max_retry *
13091359 idev->cnf.dad_transmits *
1310
- NEIGH_VAR(idev->nd_parms, RETRANS_TIME) / HZ;
1360
+ max(NEIGH_VAR(idev->nd_parms, RETRANS_TIME), HZ/100) / HZ;
13111361
13121362 /* recalculate max_desync_factor each time and update
13131363 * idev->desync_factor if it's larger
13141364 */
13151365 cnf_temp_preferred_lft = READ_ONCE(idev->cnf.temp_prefered_lft);
1316
- max_desync_factor = min_t(__u32,
1366
+ max_desync_factor = min_t(long,
13171367 idev->cnf.max_desync_factor,
13181368 cnf_temp_preferred_lft - regen_advance);
13191369
....@@ -1367,7 +1417,6 @@
13671417 in6_ifa_put(ifp);
13681418 in6_dev_put(idev);
13691419 pr_info("%s: retry temporary address regeneration\n", __func__);
1370
- tmpaddr = &addr;
13711420 write_lock_bh(&idev->lock);
13721421 goto retry;
13731422 }
....@@ -1854,12 +1903,13 @@
18541903 * 2. does the address exist on the specific device
18551904 * (skip_dev_check = false)
18561905 */
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)
1906
+static struct net_device *
1907
+__ipv6_chk_addr_and_flags(struct net *net, const struct in6_addr *addr,
1908
+ const struct net_device *dev, bool skip_dev_check,
1909
+ int strict, u32 banned_flags)
18601910 {
18611911 unsigned int hash = inet6_addr_hash(net, addr);
1862
- const struct net_device *l3mdev;
1912
+ struct net_device *l3mdev, *ndev;
18631913 struct inet6_ifaddr *ifp;
18641914 u32 ifp_flags;
18651915
....@@ -1870,10 +1920,11 @@
18701920 dev = NULL;
18711921
18721922 hlist_for_each_entry_rcu(ifp, &inet6_addr_lst[hash], addr_lst) {
1873
- if (!net_eq(dev_net(ifp->idev->dev), net))
1923
+ ndev = ifp->idev->dev;
1924
+ if (!net_eq(dev_net(ndev), net))
18741925 continue;
18751926
1876
- if (l3mdev_master_dev_rcu(ifp->idev->dev) != l3mdev)
1927
+ if (l3mdev_master_dev_rcu(ndev) != l3mdev)
18771928 continue;
18781929
18791930 /* Decouple optimistic from tentative for evaluation here.
....@@ -1884,15 +1935,23 @@
18841935 : ifp->flags;
18851936 if (ipv6_addr_equal(&ifp->addr, addr) &&
18861937 !(ifp_flags&banned_flags) &&
1887
- (!dev || ifp->idev->dev == dev ||
1938
+ (!dev || ndev == dev ||
18881939 !(ifp->scope&(IFA_LINK|IFA_HOST) || strict))) {
18891940 rcu_read_unlock();
1890
- return 1;
1941
+ return ndev;
18911942 }
18921943 }
18931944
18941945 rcu_read_unlock();
1895
- return 0;
1946
+ return NULL;
1947
+}
1948
+
1949
+int ipv6_chk_addr_and_flags(struct net *net, const struct in6_addr *addr,
1950
+ const struct net_device *dev, bool skip_dev_check,
1951
+ int strict, u32 banned_flags)
1952
+{
1953
+ return __ipv6_chk_addr_and_flags(net, addr, dev, skip_dev_check,
1954
+ strict, banned_flags) ? 1 : 0;
18961955 }
18971956 EXPORT_SYMBOL(ipv6_chk_addr_and_flags);
18981957
....@@ -1944,6 +2003,21 @@
19442003 }
19452004 EXPORT_SYMBOL(ipv6_chk_prefix);
19462005
2006
+/**
2007
+ * ipv6_dev_find - find the first device with a given source address.
2008
+ * @net: the net namespace
2009
+ * @addr: the source address
2010
+ *
2011
+ * The caller should be protected by RCU, or RTNL.
2012
+ */
2013
+struct net_device *ipv6_dev_find(struct net *net, const struct in6_addr *addr,
2014
+ struct net_device *dev)
2015
+{
2016
+ return __ipv6_chk_addr_and_flags(net, addr, dev, !dev, 1,
2017
+ IFA_F_TENTATIVE);
2018
+}
2019
+EXPORT_SYMBOL(ipv6_dev_find);
2020
+
19472021 struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net, const struct in6_addr *addr,
19482022 struct net_device *dev, int strict)
19492023 {
....@@ -1982,7 +2056,7 @@
19822056 if (ifpub) {
19832057 in6_ifa_hold(ifpub);
19842058 spin_unlock_bh(&ifp->lock);
1985
- ipv6_create_tempaddr(ifpub, ifp, true);
2059
+ ipv6_create_tempaddr(ifpub, true);
19862060 in6_ifa_put(ifpub);
19872061 } else {
19882062 spin_unlock_bh(&ifp->lock);
....@@ -2279,40 +2353,38 @@
22792353 return err;
22802354 }
22812355
2282
-/* (re)generation of randomized interface identifier (RFC 3041 3.2, 3.5) */
2283
-static void ipv6_regen_rndid(struct inet6_dev *idev)
2356
+/* Generation of a randomized Interface Identifier
2357
+ * draft-ietf-6man-rfc4941bis, Section 3.3.1
2358
+ */
2359
+
2360
+static void ipv6_gen_rnd_iid(struct in6_addr *addr)
22842361 {
22852362 regen:
2286
- get_random_bytes(idev->rndid, sizeof(idev->rndid));
2287
- idev->rndid[0] &= ~0x02;
2363
+ get_random_bytes(&addr->s6_addr[8], 8);
22882364
2289
- /*
2290
- * <draft-ietf-ipngwg-temp-addresses-v2-00.txt>:
2291
- * check if generated address is not inappropriate
2365
+ /* <draft-ietf-6man-rfc4941bis-08.txt>, Section 3.3.1:
2366
+ * check if generated address is not inappropriate:
22922367 *
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
2368
+ * - Reserved IPv6 Interface Identifers
2369
+ * - XXX: already assigned to an address on the device
22992370 */
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
-}
23112371
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);
2372
+ /* Subnet-router anycast: 0000:0000:0000:0000 */
2373
+ if (!(addr->s6_addr32[2] | addr->s6_addr32[3]))
2374
+ goto regen;
2375
+
2376
+ /* IANA Ethernet block: 0200:5EFF:FE00:0000-0200:5EFF:FE00:5212
2377
+ * Proxy Mobile IPv6: 0200:5EFF:FE00:5213
2378
+ * IANA Ethernet block: 0200:5EFF:FE00:5214-0200:5EFF:FEFF:FFFF
2379
+ */
2380
+ if (ntohl(addr->s6_addr32[2]) == 0x02005eff &&
2381
+ (ntohl(addr->s6_addr32[3]) & 0Xff000000) == 0xfe000000)
2382
+ goto regen;
2383
+
2384
+ /* Reserved subnet anycast addresses */
2385
+ if (ntohl(addr->s6_addr32[2]) == 0xfdffffff &&
2386
+ ntohl(addr->s6_addr32[3]) >= 0Xffffff80)
2387
+ goto regen;
23162388 }
23172389
23182390 u32 addrconf_rt_table(const struct net_device *dev, u32 default_table)
....@@ -2374,7 +2446,8 @@
23742446 static struct fib6_info *addrconf_get_prefix_route(const struct in6_addr *pfx,
23752447 int plen,
23762448 const struct net_device *dev,
2377
- u32 flags, u32 noflags)
2449
+ u32 flags, u32 noflags,
2450
+ bool no_gw)
23782451 {
23792452 struct fib6_node *fn;
23802453 struct fib6_info *rt = NULL;
....@@ -2391,7 +2464,13 @@
23912464 goto out;
23922465
23932466 for_each_fib6_node_rt_rcu(fn) {
2394
- if (rt->fib6_nh.nh_dev->ifindex != dev->ifindex)
2467
+ /* prefix routes only use builtin fib6_nh */
2468
+ if (rt->nh)
2469
+ continue;
2470
+
2471
+ if (rt->fib6_nh->fib_nh_dev->ifindex != dev->ifindex)
2472
+ continue;
2473
+ if (no_gw && rt->fib6_nh->fib_nh_gw_family)
23952474 continue;
23962475 if ((rt->fib6_flags & flags) != flags)
23972476 continue;
....@@ -2434,8 +2513,8 @@
24342513 ASSERT_RTNL();
24352514
24362515 idev = ipv6_find_idev(dev);
2437
- if (!idev)
2438
- return ERR_PTR(-ENOBUFS);
2516
+ if (IS_ERR(idev))
2517
+ return idev;
24392518
24402519 if (idev->cnf.disable_ipv6)
24412520 return ERR_PTR(-EACCES);
....@@ -2500,15 +2579,21 @@
25002579 ipv6_ifa_notify(0, ift);
25012580 }
25022581
2503
- if ((create || list_empty(&idev->tempaddr_list)) &&
2504
- idev->cnf.use_tempaddr > 0) {
2582
+ /* Also create a temporary address if it's enabled but no temporary
2583
+ * address currently exists.
2584
+ * However, we get called with valid_lft == 0, prefered_lft == 0, create == false
2585
+ * as part of cleanup (ie. deleting the mngtmpaddr).
2586
+ * We don't want that to result in creating a new temporary ip address.
2587
+ */
2588
+ if (list_empty(&idev->tempaddr_list) && (valid_lft || prefered_lft))
2589
+ create = true;
2590
+
2591
+ if (create && idev->cnf.use_tempaddr > 0) {
25052592 /* When a new public address is created as described
25062593 * in [ADDRCONF], also create a new temporary address.
2507
- * Also create a temporary address if it's enabled but
2508
- * no temporary address currently exists.
25092594 */
25102595 read_unlock_bh(&idev->lock);
2511
- ipv6_create_tempaddr(ifp, NULL, false);
2596
+ ipv6_create_tempaddr(ifp, false);
25122597 } else {
25132598 read_unlock_bh(&idev->lock);
25142599 }
....@@ -2690,12 +2775,12 @@
26902775 pinfo->prefix_len,
26912776 dev,
26922777 RTF_ADDRCONF | RTF_PREFIX_RT,
2693
- RTF_GATEWAY | RTF_DEFAULT);
2778
+ RTF_DEFAULT, true);
26942779
26952780 if (rt) {
26962781 /* Autoconf prefix route */
26972782 if (valid_lft == 0) {
2698
- ip6_del_rt(net, rt);
2783
+ ip6_del_rt(net, rt, false);
26992784 rt = NULL;
27002785 } else if (addrconf_finite_timeout(rt_expires)) {
27012786 /* not infinity */
....@@ -2773,6 +2858,33 @@
27732858 in6_dev_put(in6_dev);
27742859 }
27752860
2861
+static int addrconf_set_sit_dstaddr(struct net *net, struct net_device *dev,
2862
+ struct in6_ifreq *ireq)
2863
+{
2864
+ struct ip_tunnel_parm p = { };
2865
+ int err;
2866
+
2867
+ if (!(ipv6_addr_type(&ireq->ifr6_addr) & IPV6_ADDR_COMPATv4))
2868
+ return -EADDRNOTAVAIL;
2869
+
2870
+ p.iph.daddr = ireq->ifr6_addr.s6_addr32[3];
2871
+ p.iph.version = 4;
2872
+ p.iph.ihl = 5;
2873
+ p.iph.protocol = IPPROTO_IPV6;
2874
+ p.iph.ttl = 64;
2875
+
2876
+ if (!dev->netdev_ops->ndo_tunnel_ctl)
2877
+ return -EOPNOTSUPP;
2878
+ err = dev->netdev_ops->ndo_tunnel_ctl(dev, &p, SIOCADDTUNNEL);
2879
+ if (err)
2880
+ return err;
2881
+
2882
+ dev = __dev_get_by_name(net, p.name);
2883
+ if (!dev)
2884
+ return -ENOBUFS;
2885
+ return dev_open(dev, NULL);
2886
+}
2887
+
27762888 /*
27772889 * Set destination address.
27782890 * Special case for SIT interfaces where we create a new "virtual"
....@@ -2780,61 +2892,19 @@
27802892 */
27812893 int addrconf_set_dstaddr(struct net *net, void __user *arg)
27822894 {
2783
- struct in6_ifreq ireq;
27842895 struct net_device *dev;
2785
- int err = -EINVAL;
2896
+ struct in6_ifreq ireq;
2897
+ int err = -ENODEV;
2898
+
2899
+ if (!IS_ENABLED(CONFIG_IPV6_SIT))
2900
+ return -ENODEV;
2901
+ if (copy_from_user(&ireq, arg, sizeof(struct in6_ifreq)))
2902
+ return -EFAULT;
27862903
27872904 rtnl_lock();
2788
-
2789
- err = -EFAULT;
2790
- if (copy_from_user(&ireq, arg, sizeof(struct in6_ifreq)))
2791
- goto err_exit;
2792
-
27932905 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:
2906
+ if (dev && dev->type == ARPHRD_SIT)
2907
+ err = addrconf_set_sit_dstaddr(net, dev, &ireq);
28382908 rtnl_unlock();
28392909 return err;
28402910 }
....@@ -3099,11 +3169,9 @@
30993169 struct in_device *in_dev = __in_dev_get_rtnl(dev);
31003170 if (in_dev && (dev->flags & IFF_UP)) {
31013171 struct in_ifaddr *ifa;
3102
-
31033172 int flag = scope;
31043173
3105
- for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) {
3106
-
3174
+ in_dev_for_each_ifa_rtnl(ifa, in_dev) {
31073175 addr.s6_addr32[3] = ifa->ifa_local;
31083176
31093177 if (ifa->ifa_scope == RT_SCOPE_LINK)
....@@ -3132,7 +3200,7 @@
31323200 ASSERT_RTNL();
31333201
31343202 idev = ipv6_find_idev(dev);
3135
- if (!idev) {
3203
+ if (IS_ERR(idev)) {
31363204 pr_debug("%s: add_dev failed\n", __func__);
31373205 return;
31383206 }
....@@ -3191,11 +3259,11 @@
31913259 const struct inet6_dev *idev)
31923260 {
31933261 static DEFINE_SPINLOCK(lock);
3194
- static __u32 digest[SHA_DIGEST_WORDS];
3195
- static __u32 workspace[SHA_WORKSPACE_WORDS];
3262
+ static __u32 digest[SHA1_DIGEST_WORDS];
3263
+ static __u32 workspace[SHA1_WORKSPACE_WORDS];
31963264
31973265 static union {
3198
- char __data[SHA_MESSAGE_BYTES];
3266
+ char __data[SHA1_BLOCK_SIZE];
31993267 struct {
32003268 struct in6_addr secret;
32013269 __be32 prefix[2];
....@@ -3220,7 +3288,7 @@
32203288 retry:
32213289 spin_lock_bh(&lock);
32223290
3223
- sha_init(digest);
3291
+ sha1_init(digest);
32243292 memset(&data, 0, sizeof(data));
32253293 memset(workspace, 0, sizeof(workspace));
32263294 memcpy(data.hwaddr, idev->dev->perm_addr, idev->dev->addr_len);
....@@ -3229,7 +3297,7 @@
32293297 data.secret = secret;
32303298 data.dad_count = dad_count;
32313299
3232
- sha_transform(digest, data.__data, workspace);
3300
+ sha1_transform(digest, data.__data, workspace);
32333301
32343302 temp = *address;
32353303 temp.s6_addr32[2] = (__force __be32)digest[0];
....@@ -3276,7 +3344,7 @@
32763344 switch (idev->cnf.addr_gen_mode) {
32773345 case IN6_ADDR_GEN_MODE_RANDOM:
32783346 ipv6_gen_mode_random_init(idev);
3279
- /* fallthrough */
3347
+ fallthrough;
32803348 case IN6_ADDR_GEN_MODE_STABLE_PRIVACY:
32813349 if (!ipv6_generate_stable_address(&addr, 0, idev))
32823350 addrconf_add_linklocal(idev, &addr,
....@@ -3306,6 +3374,7 @@
33063374 static void addrconf_dev_config(struct net_device *dev)
33073375 {
33083376 struct inet6_dev *idev;
3377
+ bool ret = false;
33093378
33103379 ASSERT_RTNL();
33113380
....@@ -3333,6 +3402,10 @@
33333402 if (IS_ERR(idev))
33343403 return;
33353404
3405
+ trace_android_vh_ipv6_gen_linklocal_addr(dev, &ret);
3406
+ if (ret)
3407
+ return;
3408
+
33363409 /* this device type has no EUI support */
33373410 if (dev->type == ARPHRD_NONE &&
33383411 idev->cnf.addr_gen_mode == IN6_ADDR_GEN_MODE_EUI64)
....@@ -3355,7 +3428,7 @@
33553428 */
33563429
33573430 idev = ipv6_find_idev(dev);
3358
- if (!idev) {
3431
+ if (IS_ERR(idev)) {
33593432 pr_debug("%s: add_dev failed\n", __func__);
33603433 return;
33613434 }
....@@ -3380,7 +3453,7 @@
33803453 ASSERT_RTNL();
33813454
33823455 idev = ipv6_find_idev(dev);
3383
- if (!idev) {
3456
+ if (IS_ERR(idev)) {
33843457 pr_debug("%s: add_dev failed\n", __func__);
33853458 return;
33863459 }
....@@ -3498,9 +3571,7 @@
34983571 break;
34993572
35003573 run_pending = 1;
3501
-
3502
- /* fall through */
3503
-
3574
+ fallthrough;
35043575 case NETDEV_UP:
35053576 case NETDEV_CHANGE:
35063577 if (dev->flags & IFF_SLAVE)
....@@ -3515,8 +3586,8 @@
35153586
35163587 if (!addrconf_link_ready(dev)) {
35173588 /* device is not ready yet. */
3518
- pr_info("ADDRCONF(NETDEV_UP): %s: link is not ready\n",
3519
- dev->name);
3589
+ pr_debug("ADDRCONF(NETDEV_UP): %s: link is not ready\n",
3590
+ dev->name);
35203591 break;
35213592 }
35223593
....@@ -3642,7 +3713,7 @@
36423713 * an L3 master device (e.g., VRF)
36433714 */
36443715 if (info->upper_dev && netif_is_l3_master(info->upper_dev))
3645
- addrconf_ifdown(dev, 0);
3716
+ addrconf_ifdown(dev, false);
36463717 }
36473718
36483719 return NOTIFY_OK;
....@@ -3675,13 +3746,15 @@
36753746 (IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK);
36763747 }
36773748
3678
-static int addrconf_ifdown(struct net_device *dev, int how)
3749
+static int addrconf_ifdown(struct net_device *dev, bool unregister)
36793750 {
3680
- unsigned long event = how ? NETDEV_UNREGISTER : NETDEV_DOWN;
3751
+ unsigned long event = unregister ? NETDEV_UNREGISTER : NETDEV_DOWN;
36813752 struct net *net = dev_net(dev);
36823753 struct inet6_dev *idev;
3683
- struct inet6_ifaddr *ifa, *tmp;
3754
+ struct inet6_ifaddr *ifa;
3755
+ LIST_HEAD(tmp_addr_list);
36843756 bool keep_addr = false;
3757
+ bool was_ready;
36853758 int state, i;
36863759
36873760 ASSERT_RTNL();
....@@ -3696,7 +3769,7 @@
36963769 * Step 1: remove reference to ipv6 device from parent device.
36973770 * Do not dev_put!
36983771 */
3699
- if (how) {
3772
+ if (unregister) {
37003773 idev->dead = 1;
37013774
37023775 /* protected by rtnl_lock */
....@@ -3710,7 +3783,7 @@
37103783 /* combine the user config with event to determine if permanent
37113784 * addresses are to be removed from address hash table
37123785 */
3713
- if (!how && !idev->cnf.disable_ipv6) {
3786
+ if (!unregister && !idev->cnf.disable_ipv6) {
37143787 /* aggregate the system setting and interface setting */
37153788 int _keep_addr = net->ipv6.devconf_all->keep_addr_on_down;
37163789
....@@ -3747,8 +3820,11 @@
37473820
37483821 addrconf_del_rs_timer(idev);
37493822
3750
- /* Step 2: clear flags for stateless addrconf */
3751
- if (!how)
3823
+ /* Step 2: clear flags for stateless addrconf, repeated down
3824
+ * detection
3825
+ */
3826
+ was_ready = idev->if_flags & IF_READY;
3827
+ if (!unregister)
37523828 idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD|IF_READY);
37533829
37543830 /* Step 3: clear tempaddr list */
....@@ -3768,16 +3844,23 @@
37683844 write_lock_bh(&idev->lock);
37693845 }
37703846
3771
- list_for_each_entry_safe(ifa, tmp, &idev->addr_list, if_list) {
3847
+ list_for_each_entry(ifa, &idev->addr_list, if_list)
3848
+ list_add_tail(&ifa->if_list_aux, &tmp_addr_list);
3849
+ write_unlock_bh(&idev->lock);
3850
+
3851
+ while (!list_empty(&tmp_addr_list)) {
37723852 struct fib6_info *rt = NULL;
37733853 bool keep;
3854
+
3855
+ ifa = list_first_entry(&tmp_addr_list,
3856
+ struct inet6_ifaddr, if_list_aux);
3857
+ list_del(&ifa->if_list_aux);
37743858
37753859 addrconf_del_dad_work(ifa);
37763860
37773861 keep = keep_addr && (ifa->flags & IFA_F_PERMANENT) &&
37783862 !addr_is_local(&ifa->addr);
37793863
3780
- write_unlock_bh(&idev->lock);
37813864 spin_lock_bh(&ifa->lock);
37823865
37833866 if (keep) {
....@@ -3797,7 +3880,7 @@
37973880 spin_unlock_bh(&ifa->lock);
37983881
37993882 if (rt)
3800
- ip6_del_rt(net, rt);
3883
+ ip6_del_rt(net, rt, false);
38013884
38023885 if (state != INET6_IFADDR_STATE_DEAD) {
38033886 __ipv6_ifa_notify(RTM_DELADDR, ifa);
....@@ -3808,27 +3891,26 @@
38083891 addrconf_leave_solict(ifa->idev, &ifa->addr);
38093892 }
38103893
3811
- write_lock_bh(&idev->lock);
38123894 if (!keep) {
3895
+ write_lock_bh(&idev->lock);
38133896 list_del_rcu(&ifa->if_list);
3897
+ write_unlock_bh(&idev->lock);
38143898 in6_ifa_put(ifa);
38153899 }
38163900 }
38173901
3818
- write_unlock_bh(&idev->lock);
3819
-
38203902 /* Step 5: Discard anycast and multicast list */
3821
- if (how) {
3903
+ if (unregister) {
38223904 ipv6_ac_destroy_dev(idev);
38233905 ipv6_mc_destroy_dev(idev);
3824
- } else {
3906
+ } else if (was_ready) {
38253907 ipv6_mc_down(idev);
38263908 }
38273909
38283910 idev->tstamp = jiffies;
38293911
38303912 /* Last: Shot the device (if unregistered) */
3831
- if (how) {
3913
+ if (unregister) {
38323914 addrconf_sysctl_unregister(idev);
38333915 neigh_parms_release(&nd_tbl, idev->nd_parms);
38343916 neigh_ifdown(&nd_tbl, dev);
....@@ -4050,7 +4132,7 @@
40504132 in6_ifa_hold(ifp);
40514133 addrconf_dad_stop(ifp, 1);
40524134 if (disable_ipv6)
4053
- addrconf_ifdown(idev->dev, 0);
4135
+ addrconf_ifdown(idev->dev, false);
40544136 goto out;
40554137 }
40564138
....@@ -4092,7 +4174,8 @@
40924174
40934175 ifp->dad_probes--;
40944176 addrconf_mod_dad_work(ifp,
4095
- NEIGH_VAR(ifp->idev->nd_parms, RETRANS_TIME));
4177
+ max(NEIGH_VAR(ifp->idev->nd_parms, RETRANS_TIME),
4178
+ HZ/100));
40964179 spin_unlock(&ifp->lock);
40974180 write_unlock_bh(&idev->lock);
40984181
....@@ -4147,7 +4230,8 @@
41474230 send_rs = send_mld &&
41484231 ipv6_accept_ra(ifp->idev) &&
41494232 ifp->idev->cnf.rtr_solicits != 0 &&
4150
- (dev->flags&IFF_LOOPBACK) == 0;
4233
+ (dev->flags & IFF_LOOPBACK) == 0 &&
4234
+ (dev->type != ARPHRD_TUNNEL);
41514235 read_unlock_bh(&ifp->idev->lock);
41524236
41534237 /* While dad is in progress mld report's source address is in6_addrany.
....@@ -4375,6 +4459,59 @@
43754459 }
43764460 #endif
43774461
4462
+/* RFC6554 has some algorithm to avoid loops in segment routing by
4463
+ * checking if the segments contains any of a local interface address.
4464
+ *
4465
+ * Quote:
4466
+ *
4467
+ * To detect loops in the SRH, a router MUST determine if the SRH
4468
+ * includes multiple addresses assigned to any interface on that router.
4469
+ * If such addresses appear more than once and are separated by at least
4470
+ * one address not assigned to that router.
4471
+ */
4472
+int ipv6_chk_rpl_srh_loop(struct net *net, const struct in6_addr *segs,
4473
+ unsigned char nsegs)
4474
+{
4475
+ const struct in6_addr *addr;
4476
+ int i, ret = 0, found = 0;
4477
+ struct inet6_ifaddr *ifp;
4478
+ bool separated = false;
4479
+ unsigned int hash;
4480
+ bool hash_found;
4481
+
4482
+ rcu_read_lock();
4483
+ for (i = 0; i < nsegs; i++) {
4484
+ addr = &segs[i];
4485
+ hash = inet6_addr_hash(net, addr);
4486
+
4487
+ hash_found = false;
4488
+ hlist_for_each_entry_rcu(ifp, &inet6_addr_lst[hash], addr_lst) {
4489
+ if (!net_eq(dev_net(ifp->idev->dev), net))
4490
+ continue;
4491
+
4492
+ if (ipv6_addr_equal(&ifp->addr, addr)) {
4493
+ hash_found = true;
4494
+ break;
4495
+ }
4496
+ }
4497
+
4498
+ if (hash_found) {
4499
+ if (found > 1 && separated) {
4500
+ ret = 1;
4501
+ break;
4502
+ }
4503
+
4504
+ separated = false;
4505
+ found++;
4506
+ } else {
4507
+ separated = true;
4508
+ }
4509
+ }
4510
+ rcu_read_unlock();
4511
+
4512
+ return ret;
4513
+}
4514
+
43784515 /*
43794516 * Periodic address status verification
43804517 */
....@@ -4445,7 +4582,7 @@
44454582 !(ifp->flags&IFA_F_TENTATIVE)) {
44464583 unsigned long regen_advance = ifp->idev->cnf.regen_max_retry *
44474584 ifp->idev->cnf.dad_transmits *
4448
- NEIGH_VAR(ifp->idev->nd_parms, RETRANS_TIME) / HZ;
4585
+ max(NEIGH_VAR(ifp->idev->nd_parms, RETRANS_TIME), HZ/100) / HZ;
44494586
44504587 if (age >= ifp->prefered_lft - regen_advance) {
44514588 struct inet6_ifaddr *ifpub = ifp->ifpub;
....@@ -4461,7 +4598,7 @@
44614598 ifpub->regen_count = 0;
44624599 spin_unlock(&ifpub->lock);
44634600 rcu_read_unlock_bh();
4464
- ipv6_create_tempaddr(ifpub, ifp, true);
4601
+ ipv6_create_tempaddr(ifpub, true);
44654602 in6_ifa_put(ifpub);
44664603 in6_ifa_put(ifp);
44674604 rcu_read_lock_bh();
....@@ -4533,6 +4670,7 @@
45334670 [IFA_CACHEINFO] = { .len = sizeof(struct ifa_cacheinfo) },
45344671 [IFA_FLAGS] = { .len = sizeof(u32) },
45354672 [IFA_RT_PRIORITY] = { .len = sizeof(u32) },
4673
+ [IFA_TARGET_NETNSID] = { .type = NLA_S32 },
45364674 };
45374675
45384676 static int
....@@ -4546,8 +4684,8 @@
45464684 u32 ifa_flags;
45474685 int err;
45484686
4549
- err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy,
4550
- extack);
4687
+ err = nlmsg_parse_deprecated(nlh, sizeof(*ifm), tb, IFA_MAX,
4688
+ ifa_ipv6_policy, extack);
45514689 if (err < 0)
45524690 return err;
45534691
....@@ -4574,15 +4712,14 @@
45744712
45754713 f6i = addrconf_get_prefix_route(modify_peer ? &ifp->peer_addr : &ifp->addr,
45764714 ifp->prefix_len,
4577
- ifp->idev->dev,
4578
- 0, RTF_GATEWAY | RTF_DEFAULT);
4715
+ ifp->idev->dev, 0, RTF_DEFAULT, true);
45794716 if (!f6i)
45804717 return -ENOENT;
45814718
45824719 prio = ifp->rt_priority ? : IP6_RT_PRIO_ADDRCONF;
45834720 if (f6i->fib6_metric != prio) {
45844721 /* delete old one */
4585
- ip6_del_rt(dev_net(ifp->idev->dev), f6i);
4722
+ ip6_del_rt(dev_net(ifp->idev->dev), f6i, false);
45864723
45874724 /* add new one */
45884725 addrconf_prefix_route(modify_peer ? &ifp->peer_addr : &ifp->addr,
....@@ -4734,8 +4871,8 @@
47344871 struct ifa6_config cfg;
47354872 int err;
47364873
4737
- err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy,
4738
- extack);
4874
+ err = nlmsg_parse_deprecated(nlh, sizeof(*ifm), tb, IFA_MAX,
4875
+ ifa_ipv6_policy, extack);
47394876 if (err < 0)
47404877 return err;
47414878
....@@ -4777,8 +4914,8 @@
47774914 IFA_F_MCAUTOJOIN | IFA_F_OPTIMISTIC;
47784915
47794916 idev = ipv6_find_idev(dev);
4780
- if (!idev)
4781
- return -ENOBUFS;
4917
+ if (IS_ERR(idev))
4918
+ return PTR_ERR(idev);
47824919
47834920 if (!ipv6_allow_optimistic_dad(net, idev))
47844921 cfg.ifa_flags &= ~IFA_F_OPTIMISTIC;
....@@ -4857,19 +4994,41 @@
48574994 + nla_total_size(4) /* IFA_RT_PRIORITY */;
48584995 }
48594996
4997
+enum addr_type_t {
4998
+ UNICAST_ADDR,
4999
+ MULTICAST_ADDR,
5000
+ ANYCAST_ADDR,
5001
+};
5002
+
5003
+struct inet6_fill_args {
5004
+ u32 portid;
5005
+ u32 seq;
5006
+ int event;
5007
+ unsigned int flags;
5008
+ int netnsid;
5009
+ int ifindex;
5010
+ enum addr_type_t type;
5011
+};
5012
+
48605013 static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
4861
- u32 portid, u32 seq, int event, unsigned int flags)
5014
+ struct inet6_fill_args *args)
48625015 {
48635016 struct nlmsghdr *nlh;
48645017 u32 preferred, valid;
48655018
4866
- nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct ifaddrmsg), flags);
5019
+ nlh = nlmsg_put(skb, args->portid, args->seq, args->event,
5020
+ sizeof(struct ifaddrmsg), args->flags);
48675021 if (!nlh)
48685022 return -EMSGSIZE;
48695023
48705024 put_ifaddrmsg(nlh, ifa->prefix_len, ifa->flags, rt_scope(ifa->scope),
48715025 ifa->idev->dev->ifindex);
48725026
5027
+ if (args->netnsid >= 0 &&
5028
+ nla_put_s32(skb, IFA_TARGET_NETNSID, args->netnsid))
5029
+ goto error;
5030
+
5031
+ spin_lock_bh(&ifa->lock);
48735032 if (!((ifa->flags&IFA_F_PERMANENT) &&
48745033 (ifa->prefered_lft == INFINITY_LIFE_TIME))) {
48755034 preferred = ifa->prefered_lft;
....@@ -4891,6 +5050,7 @@
48915050 preferred = INFINITY_LIFE_TIME;
48925051 valid = INFINITY_LIFE_TIME;
48935052 }
5053
+ spin_unlock_bh(&ifa->lock);
48945054
48955055 if (!ipv6_addr_any(&ifa->peer_addr)) {
48965056 if (nla_put_in6_addr(skb, IFA_LOCAL, &ifa->addr) < 0 ||
....@@ -4919,7 +5079,7 @@
49195079 }
49205080
49215081 static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca,
4922
- u32 portid, u32 seq, int event, u16 flags)
5082
+ struct inet6_fill_args *args)
49235083 {
49245084 struct nlmsghdr *nlh;
49255085 u8 scope = RT_SCOPE_UNIVERSE;
....@@ -4928,9 +5088,16 @@
49285088 if (ipv6_addr_scope(&ifmca->mca_addr) & IFA_SITE)
49295089 scope = RT_SCOPE_SITE;
49305090
4931
- nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct ifaddrmsg), flags);
5091
+ nlh = nlmsg_put(skb, args->portid, args->seq, args->event,
5092
+ sizeof(struct ifaddrmsg), args->flags);
49325093 if (!nlh)
49335094 return -EMSGSIZE;
5095
+
5096
+ if (args->netnsid >= 0 &&
5097
+ nla_put_s32(skb, IFA_TARGET_NETNSID, args->netnsid)) {
5098
+ nlmsg_cancel(skb, nlh);
5099
+ return -EMSGSIZE;
5100
+ }
49345101
49355102 put_ifaddrmsg(nlh, 128, IFA_F_PERMANENT, scope, ifindex);
49365103 if (nla_put_in6_addr(skb, IFA_MULTICAST, &ifmca->mca_addr) < 0 ||
....@@ -4945,7 +5112,7 @@
49455112 }
49465113
49475114 static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca,
4948
- u32 portid, u32 seq, int event, unsigned int flags)
5115
+ struct inet6_fill_args *args)
49495116 {
49505117 struct net_device *dev = fib6_info_nh_dev(ifaca->aca_rt);
49515118 int ifindex = dev ? dev->ifindex : 1;
....@@ -4955,9 +5122,16 @@
49555122 if (ipv6_addr_scope(&ifaca->aca_addr) & IFA_SITE)
49565123 scope = RT_SCOPE_SITE;
49575124
4958
- nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct ifaddrmsg), flags);
5125
+ nlh = nlmsg_put(skb, args->portid, args->seq, args->event,
5126
+ sizeof(struct ifaddrmsg), args->flags);
49595127 if (!nlh)
49605128 return -EMSGSIZE;
5129
+
5130
+ if (args->netnsid >= 0 &&
5131
+ nla_put_s32(skb, IFA_TARGET_NETNSID, args->netnsid)) {
5132
+ nlmsg_cancel(skb, nlh);
5133
+ return -EMSGSIZE;
5134
+ }
49615135
49625136 put_ifaddrmsg(nlh, 128, IFA_F_PERMANENT, scope, ifindex);
49635137 if (nla_put_in6_addr(skb, IFA_ANYCAST, &ifaca->aca_addr) < 0 ||
....@@ -4971,36 +5145,27 @@
49715145 return 0;
49725146 }
49735147
4974
-enum addr_type_t {
4975
- UNICAST_ADDR,
4976
- MULTICAST_ADDR,
4977
- ANYCAST_ADDR,
4978
-};
4979
-
49805148 /* called with rcu_read_lock() */
49815149 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)
5150
+ struct netlink_callback *cb, int s_ip_idx,
5151
+ struct inet6_fill_args *fillargs)
49845152 {
49855153 struct ifmcaddr6 *ifmca;
49865154 struct ifacaddr6 *ifaca;
5155
+ int ip_idx = 0;
49875156 int err = 1;
4988
- int ip_idx = *p_ip_idx;
49895157
49905158 read_lock_bh(&idev->lock);
4991
- switch (type) {
5159
+ switch (fillargs->type) {
49925160 case UNICAST_ADDR: {
49935161 struct inet6_ifaddr *ifa;
5162
+ fillargs->event = RTM_NEWADDR;
49945163
49955164 /* unicast address incl. temp addr */
49965165 list_for_each_entry(ifa, &idev->addr_list, if_list) {
49975166 if (ip_idx < s_ip_idx)
49985167 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);
5168
+ err = inet6_fill_ifaddr(skb, ifa, fillargs);
50045169 if (err < 0)
50055170 break;
50065171 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
....@@ -5010,31 +5175,26 @@
50105175 break;
50115176 }
50125177 case MULTICAST_ADDR:
5178
+ fillargs->event = RTM_GETMULTICAST;
5179
+
50135180 /* multicast address */
50145181 for (ifmca = idev->mc_list; ifmca;
50155182 ifmca = ifmca->next, ip_idx++) {
50165183 if (ip_idx < s_ip_idx)
50175184 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);
5185
+ err = inet6_fill_ifmcaddr(skb, ifmca, fillargs);
50235186 if (err < 0)
50245187 break;
50255188 }
50265189 break;
50275190 case ANYCAST_ADDR:
5191
+ fillargs->event = RTM_GETANYCAST;
50285192 /* anycast address */
50295193 for (ifaca = idev->ac_list; ifaca;
50305194 ifaca = ifaca->aca_next, ip_idx++) {
50315195 if (ip_idx < s_ip_idx)
50325196 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);
5197
+ err = inet6_fill_ifacaddr(skb, ifaca, fillargs);
50385198 if (err < 0)
50395199 break;
50405200 }
....@@ -5043,42 +5203,130 @@
50435203 break;
50445204 }
50455205 read_unlock_bh(&idev->lock);
5046
- *p_ip_idx = ip_idx;
5206
+ cb->args[2] = ip_idx;
50475207 return err;
5208
+}
5209
+
5210
+static int inet6_valid_dump_ifaddr_req(const struct nlmsghdr *nlh,
5211
+ struct inet6_fill_args *fillargs,
5212
+ struct net **tgt_net, struct sock *sk,
5213
+ struct netlink_callback *cb)
5214
+{
5215
+ struct netlink_ext_ack *extack = cb->extack;
5216
+ struct nlattr *tb[IFA_MAX+1];
5217
+ struct ifaddrmsg *ifm;
5218
+ int err, i;
5219
+
5220
+ if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*ifm))) {
5221
+ NL_SET_ERR_MSG_MOD(extack, "Invalid header for address dump request");
5222
+ return -EINVAL;
5223
+ }
5224
+
5225
+ ifm = nlmsg_data(nlh);
5226
+ if (ifm->ifa_prefixlen || ifm->ifa_flags || ifm->ifa_scope) {
5227
+ NL_SET_ERR_MSG_MOD(extack, "Invalid values in header for address dump request");
5228
+ return -EINVAL;
5229
+ }
5230
+
5231
+ fillargs->ifindex = ifm->ifa_index;
5232
+ if (fillargs->ifindex) {
5233
+ cb->answer_flags |= NLM_F_DUMP_FILTERED;
5234
+ fillargs->flags |= NLM_F_DUMP_FILTERED;
5235
+ }
5236
+
5237
+ err = nlmsg_parse_deprecated_strict(nlh, sizeof(*ifm), tb, IFA_MAX,
5238
+ ifa_ipv6_policy, extack);
5239
+ if (err < 0)
5240
+ return err;
5241
+
5242
+ for (i = 0; i <= IFA_MAX; ++i) {
5243
+ if (!tb[i])
5244
+ continue;
5245
+
5246
+ if (i == IFA_TARGET_NETNSID) {
5247
+ struct net *net;
5248
+
5249
+ fillargs->netnsid = nla_get_s32(tb[i]);
5250
+ net = rtnl_get_net_ns_capable(sk, fillargs->netnsid);
5251
+ if (IS_ERR(net)) {
5252
+ fillargs->netnsid = -1;
5253
+ NL_SET_ERR_MSG_MOD(extack, "Invalid target network namespace id");
5254
+ return PTR_ERR(net);
5255
+ }
5256
+ *tgt_net = net;
5257
+ } else {
5258
+ NL_SET_ERR_MSG_MOD(extack, "Unsupported attribute in dump request");
5259
+ return -EINVAL;
5260
+ }
5261
+ }
5262
+
5263
+ return 0;
50485264 }
50495265
50505266 static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
50515267 enum addr_type_t type)
50525268 {
5269
+ const struct nlmsghdr *nlh = cb->nlh;
5270
+ struct inet6_fill_args fillargs = {
5271
+ .portid = NETLINK_CB(cb->skb).portid,
5272
+ .seq = cb->nlh->nlmsg_seq,
5273
+ .flags = NLM_F_MULTI,
5274
+ .netnsid = -1,
5275
+ .type = type,
5276
+ };
50535277 struct net *net = sock_net(skb->sk);
5278
+ struct net *tgt_net = net;
5279
+ int idx, s_idx, s_ip_idx;
50545280 int h, s_h;
5055
- int idx, ip_idx;
5056
- int s_idx, s_ip_idx;
50575281 struct net_device *dev;
50585282 struct inet6_dev *idev;
50595283 struct hlist_head *head;
5284
+ int err = 0;
50605285
50615286 s_h = cb->args[0];
50625287 s_idx = idx = cb->args[1];
5063
- s_ip_idx = ip_idx = cb->args[2];
5288
+ s_ip_idx = cb->args[2];
5289
+
5290
+ if (cb->strict_check) {
5291
+ err = inet6_valid_dump_ifaddr_req(nlh, &fillargs, &tgt_net,
5292
+ skb->sk, cb);
5293
+ if (err < 0)
5294
+ goto put_tgt_net;
5295
+
5296
+ err = 0;
5297
+ if (fillargs.ifindex) {
5298
+ dev = __dev_get_by_index(tgt_net, fillargs.ifindex);
5299
+ if (!dev) {
5300
+ err = -ENODEV;
5301
+ goto put_tgt_net;
5302
+ }
5303
+ idev = __in6_dev_get(dev);
5304
+ if (idev) {
5305
+ err = in6_dump_addrs(idev, skb, cb, s_ip_idx,
5306
+ &fillargs);
5307
+ if (err > 0)
5308
+ err = 0;
5309
+ }
5310
+ goto put_tgt_net;
5311
+ }
5312
+ }
50645313
50655314 rcu_read_lock();
5066
- cb->seq = atomic_read(&net->ipv6.dev_addr_genid) ^ net->dev_base_seq;
5315
+ cb->seq = atomic_read(&tgt_net->ipv6.dev_addr_genid) ^ tgt_net->dev_base_seq;
50675316 for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
50685317 idx = 0;
5069
- head = &net->dev_index_head[h];
5318
+ head = &tgt_net->dev_index_head[h];
50705319 hlist_for_each_entry_rcu(dev, head, index_hlist) {
50715320 if (idx < s_idx)
50725321 goto cont;
50735322 if (h > s_h || idx > s_idx)
50745323 s_ip_idx = 0;
5075
- ip_idx = 0;
50765324 idev = __in6_dev_get(dev);
50775325 if (!idev)
50785326 goto cont;
50795327
5080
- if (in6_dump_addrs(idev, skb, cb, type,
5081
- s_ip_idx, &ip_idx) < 0)
5328
+ if (in6_dump_addrs(idev, skb, cb, s_ip_idx,
5329
+ &fillargs) < 0)
50825330 goto done;
50835331 cont:
50845332 idx++;
....@@ -5088,9 +5336,11 @@
50885336 rcu_read_unlock();
50895337 cb->args[0] = h;
50905338 cb->args[1] = idx;
5091
- cb->args[2] = ip_idx;
5339
+put_tgt_net:
5340
+ if (fillargs.netnsid >= 0)
5341
+ put_net(tgt_net);
50925342
5093
- return skb->len;
5343
+ return skb->len ? : err;
50945344 }
50955345
50965346 static int inet6_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
....@@ -5115,10 +5365,64 @@
51155365 return inet6_dump_addr(skb, cb, type);
51165366 }
51175367
5368
+static int inet6_rtm_valid_getaddr_req(struct sk_buff *skb,
5369
+ const struct nlmsghdr *nlh,
5370
+ struct nlattr **tb,
5371
+ struct netlink_ext_ack *extack)
5372
+{
5373
+ struct ifaddrmsg *ifm;
5374
+ int i, err;
5375
+
5376
+ if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*ifm))) {
5377
+ NL_SET_ERR_MSG_MOD(extack, "Invalid header for get address request");
5378
+ return -EINVAL;
5379
+ }
5380
+
5381
+ if (!netlink_strict_get_check(skb))
5382
+ return nlmsg_parse_deprecated(nlh, sizeof(*ifm), tb, IFA_MAX,
5383
+ ifa_ipv6_policy, extack);
5384
+
5385
+ ifm = nlmsg_data(nlh);
5386
+ if (ifm->ifa_prefixlen || ifm->ifa_flags || ifm->ifa_scope) {
5387
+ NL_SET_ERR_MSG_MOD(extack, "Invalid values in header for get address request");
5388
+ return -EINVAL;
5389
+ }
5390
+
5391
+ err = nlmsg_parse_deprecated_strict(nlh, sizeof(*ifm), tb, IFA_MAX,
5392
+ ifa_ipv6_policy, extack);
5393
+ if (err)
5394
+ return err;
5395
+
5396
+ for (i = 0; i <= IFA_MAX; i++) {
5397
+ if (!tb[i])
5398
+ continue;
5399
+
5400
+ switch (i) {
5401
+ case IFA_TARGET_NETNSID:
5402
+ case IFA_ADDRESS:
5403
+ case IFA_LOCAL:
5404
+ break;
5405
+ default:
5406
+ NL_SET_ERR_MSG_MOD(extack, "Unsupported attribute in get address request");
5407
+ return -EINVAL;
5408
+ }
5409
+ }
5410
+
5411
+ return 0;
5412
+}
5413
+
51185414 static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr *nlh,
51195415 struct netlink_ext_ack *extack)
51205416 {
51215417 struct net *net = sock_net(in_skb->sk);
5418
+ struct inet6_fill_args fillargs = {
5419
+ .portid = NETLINK_CB(in_skb).portid,
5420
+ .seq = nlh->nlmsg_seq,
5421
+ .event = RTM_NEWADDR,
5422
+ .flags = 0,
5423
+ .netnsid = -1,
5424
+ };
5425
+ struct net *tgt_net = net;
51225426 struct ifaddrmsg *ifm;
51235427 struct nlattr *tb[IFA_MAX+1];
51245428 struct in6_addr *addr = NULL, *peer;
....@@ -5127,10 +5431,18 @@
51275431 struct sk_buff *skb;
51285432 int err;
51295433
5130
- err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy,
5131
- extack);
5434
+ err = inet6_rtm_valid_getaddr_req(in_skb, nlh, tb, extack);
51325435 if (err < 0)
51335436 return err;
5437
+
5438
+ if (tb[IFA_TARGET_NETNSID]) {
5439
+ fillargs.netnsid = nla_get_s32(tb[IFA_TARGET_NETNSID]);
5440
+
5441
+ tgt_net = rtnl_get_net_ns_capable(NETLINK_CB(in_skb).sk,
5442
+ fillargs.netnsid);
5443
+ if (IS_ERR(tgt_net))
5444
+ return PTR_ERR(tgt_net);
5445
+ }
51345446
51355447 addr = extract_addr(tb[IFA_ADDRESS], tb[IFA_LOCAL], &peer);
51365448 if (!addr)
....@@ -5138,9 +5450,9 @@
51385450
51395451 ifm = nlmsg_data(nlh);
51405452 if (ifm->ifa_index)
5141
- dev = dev_get_by_index(net, ifm->ifa_index);
5453
+ dev = dev_get_by_index(tgt_net, ifm->ifa_index);
51425454
5143
- ifa = ipv6_get_ifaddr(net, addr, dev, 1);
5455
+ ifa = ipv6_get_ifaddr(tgt_net, addr, dev, 1);
51445456 if (!ifa) {
51455457 err = -EADDRNOTAVAIL;
51465458 goto errout;
....@@ -5152,20 +5464,22 @@
51525464 goto errout_ifa;
51535465 }
51545466
5155
- err = inet6_fill_ifaddr(skb, ifa, NETLINK_CB(in_skb).portid,
5156
- nlh->nlmsg_seq, RTM_NEWADDR, 0);
5467
+ err = inet6_fill_ifaddr(skb, ifa, &fillargs);
51575468 if (err < 0) {
51585469 /* -EMSGSIZE implies BUG in inet6_ifaddr_msgsize() */
51595470 WARN_ON(err == -EMSGSIZE);
51605471 kfree_skb(skb);
51615472 goto errout_ifa;
51625473 }
5163
- err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).portid);
5474
+ err = rtnl_unicast(skb, tgt_net, NETLINK_CB(in_skb).portid);
51645475 errout_ifa:
51655476 in6_ifa_put(ifa);
51665477 errout:
51675478 if (dev)
51685479 dev_put(dev);
5480
+ if (fillargs.netnsid >= 0)
5481
+ put_net(tgt_net);
5482
+
51695483 return err;
51705484 }
51715485
....@@ -5173,13 +5487,20 @@
51735487 {
51745488 struct sk_buff *skb;
51755489 struct net *net = dev_net(ifa->idev->dev);
5490
+ struct inet6_fill_args fillargs = {
5491
+ .portid = 0,
5492
+ .seq = 0,
5493
+ .event = event,
5494
+ .flags = 0,
5495
+ .netnsid = -1,
5496
+ };
51765497 int err = -ENOBUFS;
51775498
51785499 skb = nlmsg_new(inet6_ifaddr_msgsize(), GFP_ATOMIC);
51795500 if (!skb)
51805501 goto errout;
51815502
5182
- err = inet6_fill_ifaddr(skb, ifa, 0, 0, event, 0);
5503
+ err = inet6_fill_ifaddr(skb, ifa, &fillargs);
51835504 if (err < 0) {
51845505 /* -EMSGSIZE implies BUG in inet6_ifaddr_msgsize() */
51855506 WARN_ON(err == -EMSGSIZE);
....@@ -5243,7 +5564,7 @@
52435564 array[DEVCONF_USE_OPTIMISTIC] = cnf->use_optimistic;
52445565 #endif
52455566 #ifdef CONFIG_IPV6_MROUTE
5246
- array[DEVCONF_MC_FORWARDING] = cnf->mc_forwarding;
5567
+ array[DEVCONF_MC_FORWARDING] = atomic_read(&cnf->mc_forwarding);
52475568 #endif
52485569 array[DEVCONF_DISABLE_IPV6] = cnf->disable_ipv6;
52495570 array[DEVCONF_ACCEPT_DAD] = cnf->accept_dad;
....@@ -5266,6 +5587,7 @@
52665587 array[DEVCONF_ADDR_GEN_MODE] = cnf->addr_gen_mode;
52675588 array[DEVCONF_DISABLE_POLICY] = cnf->disable_policy;
52685589 array[DEVCONF_NDISC_TCLASS] = cnf->ndisc_tclass;
5590
+ array[DEVCONF_RPL_SEG_ENABLED] = cnf->rpl_seg_enabled;
52695591 }
52705592
52715593 static inline size_t inet6_ifla6_size(void)
....@@ -5378,13 +5700,12 @@
53785700 nla = nla_reserve(skb, IFLA_INET6_TOKEN, sizeof(struct in6_addr));
53795701 if (!nla)
53805702 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
-
53855703 read_lock_bh(&idev->lock);
53865704 memcpy(nla_data(nla), idev->token.s6_addr, nla_len(nla));
53875705 read_unlock_bh(&idev->lock);
5706
+
5707
+ if (nla_put_u8(skb, IFLA_INET6_ADDR_GEN_MODE, idev->cnf.addr_gen_mode))
5708
+ goto nla_put_failure;
53885709
53895710 return 0;
53905711
....@@ -5486,18 +5807,6 @@
54865807 [IFLA_INET6_TOKEN] = { .len = sizeof(struct in6_addr) },
54875808 };
54885809
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
-
55015810 static int check_addr_gen_mode(int mode)
55025811 {
55035812 if (mode != IN6_ADDR_GEN_MODE_EUI64 &&
....@@ -5518,17 +5827,50 @@
55185827 return 1;
55195828 }
55205829
5830
+static int inet6_validate_link_af(const struct net_device *dev,
5831
+ const struct nlattr *nla)
5832
+{
5833
+ struct nlattr *tb[IFLA_INET6_MAX + 1];
5834
+ struct inet6_dev *idev = NULL;
5835
+ int err;
5836
+
5837
+ if (dev) {
5838
+ idev = __in6_dev_get(dev);
5839
+ if (!idev)
5840
+ return -EAFNOSUPPORT;
5841
+ }
5842
+
5843
+ err = nla_parse_nested_deprecated(tb, IFLA_INET6_MAX, nla,
5844
+ inet6_af_policy, NULL);
5845
+ if (err)
5846
+ return err;
5847
+
5848
+ if (!tb[IFLA_INET6_TOKEN] && !tb[IFLA_INET6_ADDR_GEN_MODE])
5849
+ return -EINVAL;
5850
+
5851
+ if (tb[IFLA_INET6_ADDR_GEN_MODE]) {
5852
+ u8 mode = nla_get_u8(tb[IFLA_INET6_ADDR_GEN_MODE]);
5853
+
5854
+ if (check_addr_gen_mode(mode) < 0)
5855
+ return -EINVAL;
5856
+ if (dev && check_stable_privacy(idev, dev_net(dev), mode) < 0)
5857
+ return -EINVAL;
5858
+ }
5859
+
5860
+ return 0;
5861
+}
5862
+
55215863 static int inet6_set_link_af(struct net_device *dev, const struct nlattr *nla)
55225864 {
5523
- int err = -EINVAL;
55245865 struct inet6_dev *idev = __in6_dev_get(dev);
55255866 struct nlattr *tb[IFLA_INET6_MAX + 1];
5867
+ int err;
55265868
55275869 if (!idev)
55285870 return -EAFNOSUPPORT;
55295871
5530
- if (nla_parse_nested(tb, IFLA_INET6_MAX, nla, NULL, NULL) < 0)
5531
- BUG();
5872
+ if (nla_parse_nested_deprecated(tb, IFLA_INET6_MAX, nla, NULL, NULL) < 0)
5873
+ return -EINVAL;
55325874
55335875 if (tb[IFLA_INET6_TOKEN]) {
55345876 err = inet6_set_iftoken(idev, nla_data(tb[IFLA_INET6_TOKEN]));
....@@ -5539,15 +5881,10 @@
55395881 if (tb[IFLA_INET6_ADDR_GEN_MODE]) {
55405882 u8 mode = nla_get_u8(tb[IFLA_INET6_ADDR_GEN_MODE]);
55415883
5542
- if (check_addr_gen_mode(mode) < 0 ||
5543
- check_stable_privacy(idev, dev_net(dev), mode) < 0)
5544
- return -EINVAL;
5545
-
55465884 idev->cnf.addr_gen_mode = mode;
5547
- err = 0;
55485885 }
55495886
5550
- return err;
5887
+ return 0;
55515888 }
55525889
55535890 static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
....@@ -5579,7 +5916,7 @@
55795916 nla_put_u8(skb, IFLA_OPERSTATE,
55805917 netif_running(dev) ? dev->operstate : IF_OPER_DOWN))
55815918 goto nla_put_failure;
5582
- protoinfo = nla_nest_start(skb, IFLA_PROTINFO);
5919
+ protoinfo = nla_nest_start_noflag(skb, IFLA_PROTINFO);
55835920 if (!protoinfo)
55845921 goto nla_put_failure;
55855922
....@@ -5595,6 +5932,31 @@
55955932 return -EMSGSIZE;
55965933 }
55975934
5935
+static int inet6_valid_dump_ifinfo(const struct nlmsghdr *nlh,
5936
+ struct netlink_ext_ack *extack)
5937
+{
5938
+ struct ifinfomsg *ifm;
5939
+
5940
+ if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*ifm))) {
5941
+ NL_SET_ERR_MSG_MOD(extack, "Invalid header for link dump request");
5942
+ return -EINVAL;
5943
+ }
5944
+
5945
+ if (nlmsg_attrlen(nlh, sizeof(*ifm))) {
5946
+ NL_SET_ERR_MSG_MOD(extack, "Invalid data after header");
5947
+ return -EINVAL;
5948
+ }
5949
+
5950
+ ifm = nlmsg_data(nlh);
5951
+ if (ifm->__ifi_pad || ifm->ifi_type || ifm->ifi_flags ||
5952
+ ifm->ifi_change || ifm->ifi_index) {
5953
+ NL_SET_ERR_MSG_MOD(extack, "Invalid values in header for dump request");
5954
+ return -EINVAL;
5955
+ }
5956
+
5957
+ return 0;
5958
+}
5959
+
55985960 static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
55995961 {
56005962 struct net *net = sock_net(skb->sk);
....@@ -5603,6 +5965,16 @@
56035965 struct net_device *dev;
56045966 struct inet6_dev *idev;
56055967 struct hlist_head *head;
5968
+
5969
+ /* only requests using strict checking can pass data to
5970
+ * influence the dump
5971
+ */
5972
+ if (cb->strict_check) {
5973
+ int err = inet6_valid_dump_ifinfo(cb->nlh, cb->extack);
5974
+
5975
+ if (err < 0)
5976
+ return err;
5977
+ }
56065978
56075979 s_h = cb->args[0];
56085980 s_idx = cb->args[1];
....@@ -5771,12 +6143,13 @@
57716143 struct fib6_info *rt;
57726144
57736145 rt = addrconf_get_prefix_route(&ifp->peer_addr, 128,
5774
- ifp->idev->dev, 0, 0);
6146
+ ifp->idev->dev, 0, 0,
6147
+ false);
57756148 if (rt)
5776
- ip6_del_rt(net, rt);
6149
+ ip6_del_rt(net, rt, false);
57776150 }
57786151 if (ifp->rt) {
5779
- ip6_del_rt(net, ifp->rt);
6152
+ ip6_del_rt(net, ifp->rt, false);
57806153 ifp->rt = NULL;
57816154 }
57826155 rt_genid_bump_ipv6(net);
....@@ -5795,9 +6168,8 @@
57956168
57966169 #ifdef CONFIG_SYSCTL
57976170
5798
-static
5799
-int addrconf_sysctl_forward(struct ctl_table *ctl, int write,
5800
- void __user *buffer, size_t *lenp, loff_t *ppos)
6171
+static int addrconf_sysctl_forward(struct ctl_table *ctl, int write,
6172
+ void *buffer, size_t *lenp, loff_t *ppos)
58016173 {
58026174 int *valp = ctl->data;
58036175 int val = *valp;
....@@ -5821,9 +6193,8 @@
58216193 return ret;
58226194 }
58236195
5824
-static
5825
-int addrconf_sysctl_mtu(struct ctl_table *ctl, int write,
5826
- void __user *buffer, size_t *lenp, loff_t *ppos)
6196
+static int addrconf_sysctl_mtu(struct ctl_table *ctl, int write,
6197
+ void *buffer, size_t *lenp, loff_t *ppos)
58276198 {
58286199 struct inet6_dev *idev = ctl->extra1;
58296200 int min_mtu = IPV6_MIN_MTU;
....@@ -5893,9 +6264,8 @@
58936264 return 0;
58946265 }
58956266
5896
-static
5897
-int addrconf_sysctl_disable(struct ctl_table *ctl, int write,
5898
- void __user *buffer, size_t *lenp, loff_t *ppos)
6267
+static int addrconf_sysctl_disable(struct ctl_table *ctl, int write,
6268
+ void *buffer, size_t *lenp, loff_t *ppos)
58996269 {
59006270 int *valp = ctl->data;
59016271 int val = *valp;
....@@ -5919,9 +6289,8 @@
59196289 return ret;
59206290 }
59216291
5922
-static
5923
-int addrconf_sysctl_proxy_ndp(struct ctl_table *ctl, int write,
5924
- void __user *buffer, size_t *lenp, loff_t *ppos)
6292
+static int addrconf_sysctl_proxy_ndp(struct ctl_table *ctl, int write,
6293
+ void *buffer, size_t *lenp, loff_t *ppos)
59256294 {
59266295 int *valp = ctl->data;
59276296 int ret;
....@@ -5962,7 +6331,7 @@
59626331 }
59636332
59646333 static int addrconf_sysctl_addr_gen_mode(struct ctl_table *ctl, int write,
5965
- void __user *buffer, size_t *lenp,
6334
+ void *buffer, size_t *lenp,
59666335 loff_t *ppos)
59676336 {
59686337 int ret = 0;
....@@ -6024,7 +6393,7 @@
60246393 }
60256394
60266395 static int addrconf_sysctl_stable_secret(struct ctl_table *ctl, int write,
6027
- void __user *buffer, size_t *lenp,
6396
+ void *buffer, size_t *lenp,
60286397 loff_t *ppos)
60296398 {
60306399 int err;
....@@ -6091,8 +6460,7 @@
60916460
60926461 static
60936462 int addrconf_sysctl_ignore_routes_with_linkdown(struct ctl_table *ctl,
6094
- int write,
6095
- void __user *buffer,
6463
+ int write, void *buffer,
60966464 size_t *lenp,
60976465 loff_t *ppos)
60986466 {
....@@ -6137,16 +6505,17 @@
61376505 list_for_each_entry(ifa, &idev->addr_list, if_list) {
61386506 spin_lock(&ifa->lock);
61396507 if (ifa->rt) {
6140
- struct fib6_info *rt = ifa->rt;
6508
+ /* host routes only use builtin fib6_nh */
6509
+ struct fib6_nh *nh = ifa->rt->fib6_nh;
61416510 int cpu;
61426511
61436512 rcu_read_lock();
61446513 ifa->rt->dst_nopolicy = val ? true : false;
6145
- if (rt->rt6i_pcpu) {
6514
+ if (nh->rt6i_pcpu) {
61466515 for_each_possible_cpu(cpu) {
61476516 struct rt6_info **rtp;
61486517
6149
- rtp = per_cpu_ptr(rt->rt6i_pcpu, cpu);
6518
+ rtp = per_cpu_ptr(nh->rt6i_pcpu, cpu);
61506519 addrconf_set_nopolicy(*rtp, val);
61516520 }
61526521 }
....@@ -6191,10 +6560,8 @@
61916560 return 0;
61926561 }
61936562
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)
6563
+static int addrconf_sysctl_disable_policy(struct ctl_table *ctl, int write,
6564
+ void *buffer, size_t *lenp, loff_t *ppos)
61986565 {
61996566 int *valp = ctl->data;
62006567 int val = *valp;
....@@ -6216,8 +6583,6 @@
62166583 }
62176584
62186585 static int minus_one = -1;
6219
-static const int zero = 0;
6220
-static const int one = 1;
62216586 static const int two_five_five = 255;
62226587
62236588 static const struct ctl_table addrconf_sysctl[] = {
....@@ -6234,7 +6599,7 @@
62346599 .maxlen = sizeof(int),
62356600 .mode = 0644,
62366601 .proc_handler = proc_dointvec_minmax,
6237
- .extra1 = (void *)&one,
6602
+ .extra1 = (void *)SYSCTL_ONE,
62386603 .extra2 = (void *)&two_five_five,
62396604 },
62406605 {
....@@ -6600,8 +6965,15 @@
66006965 .maxlen = sizeof(int),
66016966 .mode = 0644,
66026967 .proc_handler = proc_dointvec_minmax,
6603
- .extra1 = (void *)&zero,
6968
+ .extra1 = (void *)SYSCTL_ZERO,
66046969 .extra2 = (void *)&two_five_five,
6970
+ },
6971
+ {
6972
+ .procname = "rpl_seg_enabled",
6973
+ .data = &ipv6_devconf.rpl_seg_enabled,
6974
+ .maxlen = sizeof(int),
6975
+ .mode = 0644,
6976
+ .proc_handler = proc_dointvec,
66056977 },
66066978 {
66076979 /* sentinel */
....@@ -6710,6 +7082,28 @@
67107082 dflt = kmemdup(&ipv6_devconf_dflt, sizeof(ipv6_devconf_dflt), GFP_KERNEL);
67117083 if (!dflt)
67127084 goto err_alloc_dflt;
7085
+
7086
+ if (!net_eq(net, &init_net)) {
7087
+ switch (net_inherit_devconf()) {
7088
+ case 1: /* copy from init_net */
7089
+ memcpy(all, init_net.ipv6.devconf_all,
7090
+ sizeof(ipv6_devconf));
7091
+ memcpy(dflt, init_net.ipv6.devconf_dflt,
7092
+ sizeof(ipv6_devconf_dflt));
7093
+ break;
7094
+ case 3: /* copy from the current netns */
7095
+ memcpy(all, current->nsproxy->net_ns->ipv6.devconf_all,
7096
+ sizeof(ipv6_devconf));
7097
+ memcpy(dflt,
7098
+ current->nsproxy->net_ns->ipv6.devconf_dflt,
7099
+ sizeof(ipv6_devconf_dflt));
7100
+ break;
7101
+ case 0:
7102
+ case 2:
7103
+ /* use compiled values */
7104
+ break;
7105
+ }
7106
+ }
67137107
67147108 /* these will be inherited by all namespaces */
67157109 dflt->autoconf = ipv6_defaults.autoconf;
....@@ -6900,9 +7294,9 @@
69007294 for_each_netdev(&init_net, dev) {
69017295 if (__in6_dev_get(dev) == NULL)
69027296 continue;
6903
- addrconf_ifdown(dev, 1);
7297
+ addrconf_ifdown(dev, true);
69047298 }
6905
- addrconf_ifdown(init_net.loopback_dev, 2);
7299
+ addrconf_ifdown(init_net.loopback_dev, true);
69067300
69077301 /*
69087302 * Check hash table.