blob: 2db1acf706102c5cadf21fad5bca1c422c21a1ae [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * IPv6 Address [auto]configuration
3 * Linux INET6 implementation
4 *
5 * Authors:
YOSHIFUJI Hideaki1ab14572007-02-09 23:24:49 +09006 * Pedro Roque <roque@di.fc.ul.pt>
Linus Torvalds1da177e2005-04-16 15:20:36 -07007 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
8 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07009 * 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.
13 */
14
15/*
16 * Changes:
17 *
18 * Janos Farkas : delete timer on ifdown
19 * <chexum@bankinf.banki.hu>
20 * Andi Kleen : kill double kfree on module
21 * unload.
22 * Maciej W. Rozycki : FDDI support
23 * sekiya@USAGI : Don't send too many RS
24 * packets.
25 * yoshfuji@USAGI : Fixed interval between DAD
26 * packets.
27 * YOSHIFUJI Hideaki @USAGI : improved accuracy of
28 * address validation timer.
29 * YOSHIFUJI Hideaki @USAGI : Privacy Extensions (RFC3041)
30 * support.
31 * Yuji SEKIYA @USAGI : Don't assign a same IPv6
32 * address on a same interface.
33 * YOSHIFUJI Hideaki @USAGI : ARCnet support
34 * YOSHIFUJI Hideaki @USAGI : convert /proc/net/if_inet6 to
35 * seq_file.
YOSHIFUJI Hideakib1cacb62005-11-08 09:38:12 -080036 * YOSHIFUJI Hideaki @USAGI : improved source address
37 * selection; consider scope,
38 * status etc.
Linus Torvalds1da177e2005-04-16 15:20:36 -070039 */
40
Joe Perchesf3213832012-05-15 14:11:53 +000041#define pr_fmt(fmt) "IPv6: " fmt
42
Linus Torvalds1da177e2005-04-16 15:20:36 -070043#include <linux/errno.h>
44#include <linux/types.h>
Ilpo Järvinena0bffff2009-03-21 13:36:17 -070045#include <linux/kernel.h>
Ingo Molnar174cd4b2017-02-02 19:15:33 +010046#include <linux/sched/signal.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070047#include <linux/socket.h>
48#include <linux/sockios.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070049#include <linux/net.h>
Hannes Frederic Sowa3d1bec92015-03-23 23:36:00 +010050#include <linux/inet.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070051#include <linux/in6.h>
52#include <linux/netdevice.h>
Thomas Graf18237302006-08-04 23:04:54 -070053#include <linux/if_addr.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070054#include <linux/if_arp.h>
55#include <linux/if_arcnet.h>
56#include <linux/if_infiniband.h>
57#include <linux/route.h>
58#include <linux/inetdevice.h>
59#include <linux/init.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090060#include <linux/slab.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070061#ifdef CONFIG_SYSCTL
62#include <linux/sysctl.h>
63#endif
Randy Dunlap4fc268d2006-01-11 12:17:47 -080064#include <linux/capability.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070065#include <linux/delay.h>
66#include <linux/notifier.h>
Paulo Marques543537b2005-06-23 00:09:02 -070067#include <linux/string.h>
Eric Dumazetddbe5032012-07-18 08:11:12 +000068#include <linux/hash.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070069
Eric W. Biederman457c4cb2007-09-12 12:01:34 +020070#include <net/net_namespace.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070071#include <net/sock.h>
72#include <net/snmp.h>
73
Alexander Aring5241c2d2015-12-14 20:55:22 +010074#include <net/6lowpan.h>
YOSHIFUJI Hideaki / 吉藤英明cb6bf352013-03-25 08:26:24 +000075#include <net/firewire.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070076#include <net/ipv6.h>
77#include <net/protocol.h>
78#include <net/ndisc.h>
79#include <net/ip6_route.h>
80#include <net/addrconf.h>
81#include <net/tcp.h>
82#include <net/ip.h>
Thomas Graf5d620262006-08-15 00:35:02 -070083#include <net/netlink.h>
Mitsuru Chinenf24e3d62007-10-10 02:53:43 -070084#include <net/pkt_sched.h>
David Ahernca254492015-10-12 11:47:10 -070085#include <net/l3mdev.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070086#include <linux/if_tunnel.h>
87#include <linux/rtnetlink.h>
Nicolas Dichtelf3a1bfb2012-10-25 22:28:50 +000088#include <linux/netconf.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070089#include <linux/random.h>
Stephen Hemmingere21e8462010-03-20 16:09:01 -070090#include <linux/uaccess.h>
Herbert Xu7f7d9a62007-04-24 21:54:09 -070091#include <asm/unaligned.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070092
93#include <linux/proc_fs.h>
94#include <linux/seq_file.h>
Paul Gortmakerbc3b2d72011-07-15 11:47:34 -040095#include <linux/export.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070096
Linus Torvalds1da177e2005-04-16 15:20:36 -070097#define INFINITY_LIFE_TIME 0xFFFFFFFF
Thomas Graf18a31e12010-11-17 04:12:02 +000098
Hannes Frederic Sowa3d1bec92015-03-23 23:36:00 +010099#define IPV6_MAX_STRLEN \
100 sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")
101
Thomas Graf18a31e12010-11-17 04:12:02 +0000102static inline u32 cstamp_delta(unsigned long cstamp)
103{
104 return (cstamp - INITIAL_JIFFIES) * 100UL / HZ;
105}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106
Maciej Żenczykowskibd11f072016-09-27 23:57:58 -0700107static inline s32 rfc3315_s14_backoff_init(s32 irt)
108{
109 /* multiply 'initial retransmission time' by 0.9 .. 1.1 */
110 u64 tmp = (900000 + prandom_u32() % 200001) * (u64)irt;
111 do_div(tmp, 1000000);
112 return (s32)tmp;
113}
114
115static inline s32 rfc3315_s14_backoff_update(s32 rt, s32 mrt)
116{
117 /* multiply 'retransmission timeout' by 1.9 .. 2.1 */
118 u64 tmp = (1900000 + prandom_u32() % 200001) * (u64)rt;
119 do_div(tmp, 1000000);
120 if ((s32)tmp > mrt) {
121 /* multiply 'maximum retransmission time' by 0.9 .. 1.1 */
122 tmp = (900000 + prandom_u32() % 200001) * (u64)mrt;
123 do_div(tmp, 1000000);
124 }
125 return (s32)tmp;
126}
127
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128#ifdef CONFIG_SYSCTL
WANG Conga317a2f2014-07-25 15:25:09 -0700129static int addrconf_sysctl_register(struct inet6_dev *idev);
Pavel Emelyanov408c4762008-01-10 17:41:21 -0800130static void addrconf_sysctl_unregister(struct inet6_dev *idev);
131#else
WANG Conga317a2f2014-07-25 15:25:09 -0700132static inline int addrconf_sysctl_register(struct inet6_dev *idev)
Pavel Emelyanov408c4762008-01-10 17:41:21 -0800133{
WANG Conga317a2f2014-07-25 15:25:09 -0700134 return 0;
Pavel Emelyanov408c4762008-01-10 17:41:21 -0800135}
136
137static inline void addrconf_sysctl_unregister(struct inet6_dev *idev)
138{
139}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140#endif
141
Jiri Bohac9d6280d2016-10-13 18:50:02 +0200142static void ipv6_regen_rndid(struct inet6_dev *idev);
143static void ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144
YOSHIFUJI Hideaki1b34be72008-06-28 14:18:38 +0900145static int ipv6_generate_eui64(u8 *eui, struct net_device *dev);
Eric Dumazetd9bf82c2017-10-07 19:30:24 -0700146static int ipv6_count_addresses(const struct inet6_dev *idev);
Hannes Frederic Sowa622c81d52015-03-23 23:36:01 +0100147static int ipv6_generate_stable_address(struct in6_addr *addr,
148 u8 dad_count,
149 const struct inet6_dev *idev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700150
Eric Dumazet27c565a2017-11-04 08:53:27 -0700151#define IN6_ADDR_HSIZE_SHIFT 8
152#define IN6_ADDR_HSIZE (1 << IN6_ADDR_HSIZE_SHIFT)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700153/*
154 * Configured unicast address hash table
155 */
stephen hemmingerc2e21292010-03-17 20:31:10 +0000156static struct hlist_head inet6_addr_lst[IN6_ADDR_HSIZE];
stephen hemminger5c578aed2010-03-17 20:31:11 +0000157static DEFINE_SPINLOCK(addrconf_hash_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700158
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +0100159static void addrconf_verify(void);
160static void addrconf_verify_rtnl(void);
161static void addrconf_verify_work(struct work_struct *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700162
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +0100163static struct workqueue_struct *addrconf_wq;
164static DECLARE_DELAYED_WORK(addr_chk_work, addrconf_verify_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700165
166static void addrconf_join_anycast(struct inet6_ifaddr *ifp);
167static void addrconf_leave_anycast(struct inet6_ifaddr *ifp);
168
Jiri Pirko93d9b7d2010-03-10 10:28:56 +0000169static void addrconf_type_change(struct net_device *dev,
170 unsigned long event);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700171static int addrconf_ifdown(struct net_device *dev, int how);
172
David Ahern8d1c8022018-04-17 17:33:26 -0700173static struct fib6_info *addrconf_get_prefix_route(const struct in6_addr *pfx,
Romain Kuntz21caa662013-01-09 21:06:03 +0000174 int plen,
175 const struct net_device *dev,
176 u32 flags, u32 noflags);
177
David S. Millercf22f9a2012-04-14 21:37:40 -0400178static void addrconf_dad_start(struct inet6_ifaddr *ifp);
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +0100179static void addrconf_dad_work(struct work_struct *w);
David Ahernc76fe2d2018-01-25 20:16:29 -0800180static void addrconf_dad_completed(struct inet6_ifaddr *ifp, bool bump_id,
181 bool send_na);
YOSHIFUJI Hideakic5e33bd2005-12-21 22:57:44 +0900182static void addrconf_dad_run(struct inet6_dev *idev);
Kees Cooke99e88a2017-10-16 14:43:17 -0700183static void addrconf_rs_timer(struct timer_list *t);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700184static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifa);
185static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifa);
186
YOSHIFUJI Hideaki1ab14572007-02-09 23:24:49 +0900187static void inet6_prefix_notify(int event, struct inet6_dev *idev,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700188 struct prefix_info *pinfo);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700189
Adrian Bunk888c8482008-07-22 14:21:58 -0700190static struct ipv6_devconf ipv6_devconf __read_mostly = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700191 .forwarding = 0,
192 .hop_limit = IPV6_DEFAULT_HOPLIMIT,
193 .mtu6 = IPV6_MIN_MTU,
194 .accept_ra = 1,
195 .accept_redirects = 1,
196 .autoconf = 1,
197 .force_mld_version = 0,
Hannes Frederic Sowafc4eba52013-08-14 01:03:46 +0200198 .mldv1_unsolicited_report_interval = 10 * HZ,
199 .mldv2_unsolicited_report_interval = HZ,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700200 .dad_transmits = 1,
201 .rtr_solicits = MAX_RTR_SOLICITATIONS,
202 .rtr_solicit_interval = RTR_SOLICITATION_INTERVAL,
Maciej Żenczykowskibd11f072016-09-27 23:57:58 -0700203 .rtr_solicit_max_interval = RTR_SOLICITATION_MAX_INTERVAL,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700204 .rtr_solicit_delay = MAX_RTR_SOLICITATION_DELAY,
Ian Morris67ba4152014-08-24 21:53:10 +0100205 .use_tempaddr = 0,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700206 .temp_valid_lft = TEMP_VALID_LIFETIME,
207 .temp_prefered_lft = TEMP_PREFERRED_LIFETIME,
208 .regen_max_retry = REGEN_MAX_RETRY,
209 .max_desync_factor = MAX_DESYNC_FACTOR,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700210 .max_addresses = IPV6_MAX_ADDRESSES,
YOSHIFUJI Hideaki65f5c7c2006-03-20 16:55:08 -0800211 .accept_ra_defrtr = 1,
Ben Greeard9333192014-06-25 14:44:53 -0700212 .accept_ra_from_local = 0,
Hangbin Liu8013d1d72015-07-30 14:28:42 +0800213 .accept_ra_min_hop_limit= 1,
YOSHIFUJI Hideakic4fd30e2006-03-20 16:55:26 -0800214 .accept_ra_pinfo = 1,
YOSHIFUJI Hideaki930d6ff2006-03-20 17:05:30 -0800215#ifdef CONFIG_IPV6_ROUTER_PREF
216 .accept_ra_rtr_pref = 1,
YOSHIFUJI Hideaki52e163562006-03-20 17:05:47 -0800217 .rtr_probe_interval = 60 * HZ,
YOSHIFUJI Hideaki09c884d2006-03-20 17:07:03 -0800218#ifdef CONFIG_IPV6_ROUTE_INFO
Joel Scherpelzbbea1242017-03-22 18:19:04 +0900219 .accept_ra_rt_info_min_plen = 0,
YOSHIFUJI Hideaki09c884d2006-03-20 17:07:03 -0800220 .accept_ra_rt_info_max_plen = 0,
221#endif
YOSHIFUJI Hideaki930d6ff2006-03-20 17:05:30 -0800222#endif
YOSHIFUJI Hideakifbea49e2006-09-22 14:43:49 -0700223 .proxy_ndp = 0,
YOSHIFUJI Hideaki0bcbc922007-04-24 14:58:30 -0700224 .accept_source_route = 0, /* we do not accept RH0 by default. */
YOSHIFUJI Hideaki778d80b2008-06-28 14:17:11 +0900225 .disable_ipv6 = 0,
Nicolas Dichtel09400952017-11-14 14:21:32 +0100226 .accept_dad = 0,
Hannes Frederic Sowab800c3b2013-08-27 01:36:51 +0200227 .suppress_frag_ndisc = 1,
Harout Hedeshianc2943f12015-01-20 10:06:05 -0700228 .accept_ra_mtu = 1,
Hannes Frederic Sowa3d1bec92015-03-23 23:36:00 +0100229 .stable_secret = {
230 .initialized = false,
Erik Kline3985e8a2015-07-22 16:38:25 +0900231 },
232 .use_oif_addrs_only = 0,
Andy Gospodarek35103d12015-08-13 10:39:01 -0400233 .ignore_routes_with_linkdown = 0,
David Ahernf1705ec2016-02-24 09:25:37 -0800234 .keep_addr_on_down = 0,
David Lebrun1ababeb2016-11-08 14:57:39 +0100235 .seg6_enabled = 0,
David Lebrunbf355b82016-11-08 14:57:42 +0100236#ifdef CONFIG_IPV6_SEG6_HMAC
237 .seg6_require_hmac = 0,
238#endif
Erik Nordmarkadc176c2016-12-02 14:00:08 -0800239 .enhanced_dad = 1,
Felix Jiad35a00b2017-01-26 16:59:17 +1300240 .addr_gen_mode = IN6_ADDR_GEN_MODE_EUI64,
David Forsterdf789fe2017-02-23 16:27:18 +0000241 .disable_policy = 0,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700242};
243
Brian Haleyab32ea52006-09-22 14:15:41 -0700244static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700245 .forwarding = 0,
246 .hop_limit = IPV6_DEFAULT_HOPLIMIT,
247 .mtu6 = IPV6_MIN_MTU,
248 .accept_ra = 1,
249 .accept_redirects = 1,
250 .autoconf = 1,
Hannes Frederic Sowafc4eba52013-08-14 01:03:46 +0200251 .force_mld_version = 0,
252 .mldv1_unsolicited_report_interval = 10 * HZ,
253 .mldv2_unsolicited_report_interval = HZ,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700254 .dad_transmits = 1,
255 .rtr_solicits = MAX_RTR_SOLICITATIONS,
256 .rtr_solicit_interval = RTR_SOLICITATION_INTERVAL,
Maciej Żenczykowskibd11f072016-09-27 23:57:58 -0700257 .rtr_solicit_max_interval = RTR_SOLICITATION_MAX_INTERVAL,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700258 .rtr_solicit_delay = MAX_RTR_SOLICITATION_DELAY,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700259 .use_tempaddr = 0,
260 .temp_valid_lft = TEMP_VALID_LIFETIME,
261 .temp_prefered_lft = TEMP_PREFERRED_LIFETIME,
262 .regen_max_retry = REGEN_MAX_RETRY,
263 .max_desync_factor = MAX_DESYNC_FACTOR,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700264 .max_addresses = IPV6_MAX_ADDRESSES,
YOSHIFUJI Hideaki65f5c7c2006-03-20 16:55:08 -0800265 .accept_ra_defrtr = 1,
Ben Greeard9333192014-06-25 14:44:53 -0700266 .accept_ra_from_local = 0,
Hangbin Liu8013d1d72015-07-30 14:28:42 +0800267 .accept_ra_min_hop_limit= 1,
YOSHIFUJI Hideakic4fd30e2006-03-20 16:55:26 -0800268 .accept_ra_pinfo = 1,
YOSHIFUJI Hideaki930d6ff2006-03-20 17:05:30 -0800269#ifdef CONFIG_IPV6_ROUTER_PREF
270 .accept_ra_rtr_pref = 1,
YOSHIFUJI Hideaki52e163562006-03-20 17:05:47 -0800271 .rtr_probe_interval = 60 * HZ,
YOSHIFUJI Hideaki09c884d2006-03-20 17:07:03 -0800272#ifdef CONFIG_IPV6_ROUTE_INFO
Joel Scherpelzbbea1242017-03-22 18:19:04 +0900273 .accept_ra_rt_info_min_plen = 0,
YOSHIFUJI Hideaki09c884d2006-03-20 17:07:03 -0800274 .accept_ra_rt_info_max_plen = 0,
275#endif
YOSHIFUJI Hideaki930d6ff2006-03-20 17:05:30 -0800276#endif
YOSHIFUJI Hideakifbea49e2006-09-22 14:43:49 -0700277 .proxy_ndp = 0,
YOSHIFUJI Hideaki0bcbc922007-04-24 14:58:30 -0700278 .accept_source_route = 0, /* we do not accept RH0 by default. */
YOSHIFUJI Hideaki778d80b2008-06-28 14:17:11 +0900279 .disable_ipv6 = 0,
YOSHIFUJI Hideaki1b34be72008-06-28 14:18:38 +0900280 .accept_dad = 1,
Hannes Frederic Sowab800c3b2013-08-27 01:36:51 +0200281 .suppress_frag_ndisc = 1,
Harout Hedeshianc2943f12015-01-20 10:06:05 -0700282 .accept_ra_mtu = 1,
Hannes Frederic Sowa3d1bec92015-03-23 23:36:00 +0100283 .stable_secret = {
284 .initialized = false,
285 },
Erik Kline3985e8a2015-07-22 16:38:25 +0900286 .use_oif_addrs_only = 0,
Andy Gospodarek35103d12015-08-13 10:39:01 -0400287 .ignore_routes_with_linkdown = 0,
David Ahernf1705ec2016-02-24 09:25:37 -0800288 .keep_addr_on_down = 0,
David Lebrun1ababeb2016-11-08 14:57:39 +0100289 .seg6_enabled = 0,
David Lebrunbf355b82016-11-08 14:57:42 +0100290#ifdef CONFIG_IPV6_SEG6_HMAC
291 .seg6_require_hmac = 0,
292#endif
Erik Nordmarkadc176c2016-12-02 14:00:08 -0800293 .enhanced_dad = 1,
Felix Jiad35a00b2017-01-26 16:59:17 +1300294 .addr_gen_mode = IN6_ADDR_GEN_MODE_EUI64,
David Forsterdf789fe2017-02-23 16:27:18 +0000295 .disable_policy = 0,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700296};
297
Mike Manning1f372c72017-09-25 22:01:36 +0100298/* Check if link is ready: is it up and is a valid qdisc available */
299static inline bool addrconf_link_ready(const struct net_device *dev)
Mitsuru Chinenf24e3d62007-10-10 02:53:43 -0700300{
Mike Manning1f372c72017-09-25 22:01:36 +0100301 return netif_oper_up(dev) && !qdisc_tx_is_noop(dev);
Mitsuru Chinenf24e3d62007-10-10 02:53:43 -0700302}
303
Hannes Frederic Sowab7b1bfc2013-06-23 18:39:01 +0200304static void addrconf_del_rs_timer(struct inet6_dev *idev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700305{
Hannes Frederic Sowab7b1bfc2013-06-23 18:39:01 +0200306 if (del_timer(&idev->rs_timer))
307 __in6_dev_put(idev);
308}
309
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +0100310static void addrconf_del_dad_work(struct inet6_ifaddr *ifp)
Hannes Frederic Sowab7b1bfc2013-06-23 18:39:01 +0200311{
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +0100312 if (cancel_delayed_work(&ifp->dad_work))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700313 __in6_ifa_put(ifp);
314}
315
Hannes Frederic Sowab7b1bfc2013-06-23 18:39:01 +0200316static void addrconf_mod_rs_timer(struct inet6_dev *idev,
317 unsigned long when)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700318{
Hannes Frederic Sowab7b1bfc2013-06-23 18:39:01 +0200319 if (!timer_pending(&idev->rs_timer))
320 in6_dev_hold(idev);
321 mod_timer(&idev->rs_timer, jiffies + when);
322}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700323
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +0100324static void addrconf_mod_dad_work(struct inet6_ifaddr *ifp,
325 unsigned long delay)
Hannes Frederic Sowab7b1bfc2013-06-23 18:39:01 +0200326{
Xin Longf8a894b2017-06-15 16:33:58 +0800327 in6_ifa_hold(ifp);
328 if (mod_delayed_work(addrconf_wq, &ifp->dad_work, delay))
329 in6_ifa_put(ifp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700330}
331
Herbert Xu7f7d9a62007-04-24 21:54:09 -0700332static int snmp6_alloc_dev(struct inet6_dev *idev)
333{
John Stultz827da442013-10-07 15:51:58 -0700334 int i;
335
WANG Cong698365f2014-05-05 15:55:55 -0700336 idev->stats.ipv6 = alloc_percpu(struct ipstats_mib);
337 if (!idev->stats.ipv6)
Herbert Xu7f7d9a62007-04-24 21:54:09 -0700338 goto err_ip;
John Stultz827da442013-10-07 15:51:58 -0700339
340 for_each_possible_cpu(i) {
341 struct ipstats_mib *addrconf_stats;
WANG Cong698365f2014-05-05 15:55:55 -0700342 addrconf_stats = per_cpu_ptr(idev->stats.ipv6, i);
John Stultz827da442013-10-07 15:51:58 -0700343 u64_stats_init(&addrconf_stats->syncp);
John Stultz827da442013-10-07 15:51:58 -0700344 }
345
346
Eric Dumazetbe281e52011-05-19 01:14:23 +0000347 idev->stats.icmpv6dev = kzalloc(sizeof(struct icmpv6_mib_device),
348 GFP_KERNEL);
349 if (!idev->stats.icmpv6dev)
Herbert Xu7f7d9a62007-04-24 21:54:09 -0700350 goto err_icmp;
Eric Dumazetbe281e52011-05-19 01:14:23 +0000351 idev->stats.icmpv6msgdev = kzalloc(sizeof(struct icmpv6msg_mib_device),
352 GFP_KERNEL);
353 if (!idev->stats.icmpv6msgdev)
David L Stevens14878f72007-09-16 16:52:35 -0700354 goto err_icmpmsg;
Herbert Xu7f7d9a62007-04-24 21:54:09 -0700355
356 return 0;
357
David L Stevens14878f72007-09-16 16:52:35 -0700358err_icmpmsg:
Eric Dumazetbe281e52011-05-19 01:14:23 +0000359 kfree(idev->stats.icmpv6dev);
Herbert Xu7f7d9a62007-04-24 21:54:09 -0700360err_icmp:
WANG Cong698365f2014-05-05 15:55:55 -0700361 free_percpu(idev->stats.ipv6);
Herbert Xu7f7d9a62007-04-24 21:54:09 -0700362err_ip:
Pavel Emelyanovaaf70ec2007-10-17 21:25:32 -0700363 return -ENOMEM;
Herbert Xu7f7d9a62007-04-24 21:54:09 -0700364}
365
Eldad Zack8e5e8f32012-04-01 07:49:08 +0000366static struct inet6_dev *ipv6_add_dev(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700367{
368 struct inet6_dev *ndev;
WANG Conga317a2f2014-07-25 15:25:09 -0700369 int err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370
371 ASSERT_RTNL();
372
373 if (dev->mtu < IPV6_MIN_MTU)
WANG Conga317a2f2014-07-25 15:25:09 -0700374 return ERR_PTR(-EINVAL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375
YOSHIFUJI Hideaki1ab14572007-02-09 23:24:49 +0900376 ndev = kzalloc(sizeof(struct inet6_dev), GFP_KERNEL);
Ian Morris63159f22015-03-29 14:00:04 +0100377 if (!ndev)
WANG Conga317a2f2014-07-25 15:25:09 -0700378 return ERR_PTR(err);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379
Ingo Oeser322f74a2006-03-20 23:01:47 -0800380 rwlock_init(&ndev->lock);
381 ndev->dev = dev;
stephen hemminger502a2ff2010-03-17 20:31:13 +0000382 INIT_LIST_HEAD(&ndev->addr_list);
Kees Cooke99e88a2017-10-16 14:43:17 -0700383 timer_setup(&ndev->rs_timer, addrconf_rs_timer, 0);
YOSHIFUJI Hideakic346dca2008-03-25 21:47:49 +0900384 memcpy(&ndev->cnf, dev_net(dev)->ipv6.devconf_dflt, sizeof(ndev->cnf));
Hannes Frederic Sowa9b29c692015-12-15 22:59:12 +0100385
386 if (ndev->cnf.stable_secret.initialized)
Felix Jiad35a00b2017-01-26 16:59:17 +1300387 ndev->cnf.addr_gen_mode = IN6_ADDR_GEN_MODE_STABLE_PRIVACY;
Hannes Frederic Sowa9b29c692015-12-15 22:59:12 +0100388 else
Felix Jiad35a00b2017-01-26 16:59:17 +1300389 ndev->cnf.addr_gen_mode = ipv6_devconf_dflt.addr_gen_mode;
Hannes Frederic Sowa9b29c692015-12-15 22:59:12 +0100390
Ingo Oeser322f74a2006-03-20 23:01:47 -0800391 ndev->cnf.mtu6 = dev->mtu;
Ingo Oeser322f74a2006-03-20 23:01:47 -0800392 ndev->nd_parms = neigh_parms_alloc(dev, &nd_tbl);
Ian Morris63159f22015-03-29 14:00:04 +0100393 if (!ndev->nd_parms) {
Ingo Oeser322f74a2006-03-20 23:01:47 -0800394 kfree(ndev);
WANG Conga317a2f2014-07-25 15:25:09 -0700395 return ERR_PTR(err);
Ingo Oeser322f74a2006-03-20 23:01:47 -0800396 }
Ben Hutchings0187bdf2008-06-19 16:15:47 -0700397 if (ndev->cnf.forwarding)
398 dev_disable_lro(dev);
Ingo Oeser322f74a2006-03-20 23:01:47 -0800399 /* We refer to the device */
400 dev_hold(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401
Ingo Oeser322f74a2006-03-20 23:01:47 -0800402 if (snmp6_alloc_dev(ndev) < 0) {
Joe Perchese32ac252018-03-26 08:35:01 -0700403 netdev_dbg(dev, "%s: cannot allocate memory for statistics\n",
404 __func__);
Ingo Oeser322f74a2006-03-20 23:01:47 -0800405 neigh_parms_release(&nd_tbl, ndev->nd_parms);
Roy Li8603e332011-09-20 15:10:16 -0400406 dev_put(dev);
407 kfree(ndev);
WANG Conga317a2f2014-07-25 15:25:09 -0700408 return ERR_PTR(err);
Ingo Oeser322f74a2006-03-20 23:01:47 -0800409 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410
Ingo Oeser322f74a2006-03-20 23:01:47 -0800411 if (snmp6_register_dev(ndev) < 0) {
Joe Perchese32ac252018-03-26 08:35:01 -0700412 netdev_dbg(dev, "%s: cannot create /proc/net/dev_snmp6/%s\n",
413 __func__, dev->name);
WANG Conga317a2f2014-07-25 15:25:09 -0700414 goto err_release;
Ingo Oeser322f74a2006-03-20 23:01:47 -0800415 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416
Jiri Bohac9d6280d2016-10-13 18:50:02 +0200417 /* One reference from device. */
Reshetova, Elena1be92462017-07-04 09:34:55 +0300418 refcount_set(&ndev->refcnt, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419
YOSHIFUJI Hideaki1b34be72008-06-28 14:18:38 +0900420 if (dev->flags & (IFF_NOARP | IFF_LOOPBACK))
421 ndev->cnf.accept_dad = -1;
422
Amerigo Wang07a93622012-10-29 16:23:10 +0000423#if IS_ENABLED(CONFIG_IPV6_SIT)
YOSHIFUJI Hideakib077d7a2008-04-13 23:42:18 -0700424 if (dev->type == ARPHRD_SIT && (dev->priv_flags & IFF_ISATAP)) {
Joe Perchesf3213832012-05-15 14:11:53 +0000425 pr_info("%s: Disabled Multicast RS\n", dev->name);
YOSHIFUJI Hideakib077d7a2008-04-13 23:42:18 -0700426 ndev->cnf.rtr_solicits = 0;
427 }
428#endif
429
stephen hemminger372e6c82010-03-17 20:31:09 +0000430 INIT_LIST_HEAD(&ndev->tempaddr_list);
Jiri Bohac76506a92016-10-13 18:52:15 +0200431 ndev->desync_factor = U32_MAX;
Ingo Oeser322f74a2006-03-20 23:01:47 -0800432 if ((dev->flags&IFF_LOOPBACK) ||
433 dev->type == ARPHRD_TUNNEL ||
YOSHIFUJI Hideaki9625ed72008-04-13 23:47:11 -0700434 dev->type == ARPHRD_TUNNEL6 ||
Joerg Roedel0be669b2006-10-10 14:49:53 -0700435 dev->type == ARPHRD_SIT ||
Joerg Roedel0be669b2006-10-10 14:49:53 -0700436 dev->type == ARPHRD_NONE) {
Ingo Oeser322f74a2006-03-20 23:01:47 -0800437 ndev->cnf.use_tempaddr = -1;
Jiri Bohac9d6280d2016-10-13 18:50:02 +0200438 } else
439 ipv6_regen_rndid(ndev);
David S. Miller5d9efa72013-10-28 20:07:50 -0400440
Daniel Borkmann914faa12013-04-09 03:47:14 +0000441 ndev->token = in6addr_any;
Ingo Oeser322f74a2006-03-20 23:01:47 -0800442
Mike Manning1f372c72017-09-25 22:01:36 +0100443 if (netif_running(dev) && addrconf_link_ready(dev))
Herbert Xu53aadcc2007-03-27 14:31:52 -0700444 ndev->if_flags |= IF_READY;
445
Ingo Oeser322f74a2006-03-20 23:01:47 -0800446 ipv6_mc_init_dev(ndev);
447 ndev->tstamp = jiffies;
WANG Conga317a2f2014-07-25 15:25:09 -0700448 err = addrconf_sysctl_register(ndev);
449 if (err) {
450 ipv6_mc_destroy_dev(ndev);
Sabrina Dubroca2a189f9e2015-11-04 14:47:53 +0100451 snmp6_unregister_dev(ndev);
WANG Conga317a2f2014-07-25 15:25:09 -0700452 goto err_release;
453 }
David L Stevens30c4cf52007-01-04 12:31:14 -0800454 /* protected by rtnl_lock */
Eric Dumazetcf778b02012-01-12 04:41:32 +0000455 rcu_assign_pointer(dev->ip6_ptr, ndev);
YOSHIFUJI Hideakid88ae4c2007-01-14 21:48:40 -0800456
Hannes Frederic Sowa2c5e8932013-02-10 03:50:18 +0000457 /* Join interface-local all-node multicast group */
458 ipv6_dev_mc_inc(dev, &in6addr_interfacelocal_allnodes);
459
YOSHIFUJI Hideakid88ae4c2007-01-14 21:48:40 -0800460 /* Join all-node multicast group */
YOSHIFUJI Hideakif3ee4012008-04-10 15:42:11 +0900461 ipv6_dev_mc_inc(dev, &in6addr_linklocal_allnodes);
YOSHIFUJI Hideakid88ae4c2007-01-14 21:48:40 -0800462
Li Weid6ddef92012-03-05 14:45:17 +0000463 /* Join all-router multicast group if forwarding is set */
Li Wei8b2aaed2012-03-07 14:58:07 +0000464 if (ndev->cnf.forwarding && (dev->flags & IFF_MULTICAST))
Li Weid6ddef92012-03-05 14:45:17 +0000465 ipv6_dev_mc_inc(dev, &in6addr_linklocal_allrouters);
466
Linus Torvalds1da177e2005-04-16 15:20:36 -0700467 return ndev;
WANG Conga317a2f2014-07-25 15:25:09 -0700468
469err_release:
470 neigh_parms_release(&nd_tbl, ndev->nd_parms);
471 ndev->dead = 1;
472 in6_dev_finish_destroy(ndev);
473 return ERR_PTR(err);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700474}
475
Eldad Zack8e5e8f32012-04-01 07:49:08 +0000476static struct inet6_dev *ipv6_find_idev(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700477{
478 struct inet6_dev *idev;
479
480 ASSERT_RTNL();
481
Stephen Hemmingere21e8462010-03-20 16:09:01 -0700482 idev = __in6_dev_get(dev);
483 if (!idev) {
484 idev = ipv6_add_dev(dev);
WANG Conga317a2f2014-07-25 15:25:09 -0700485 if (IS_ERR(idev))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700486 return NULL;
487 }
YOSHIFUJI Hideakic5e33bd2005-12-21 22:57:44 +0900488
Linus Torvalds1da177e2005-04-16 15:20:36 -0700489 if (dev->flags&IFF_UP)
490 ipv6_mc_up(idev);
491 return idev;
492}
493
Nicolas Dichtelf3a1bfb2012-10-25 22:28:50 +0000494static int inet6_netconf_msgsize_devconf(int type)
495{
496 int size = NLMSG_ALIGN(sizeof(struct netconfmsg))
497 + nla_total_size(4); /* NETCONFA_IFINDEX */
Zhang Shengju136ba622016-03-10 08:55:50 +0000498 bool all = false;
Nicolas Dichtelf3a1bfb2012-10-25 22:28:50 +0000499
Zhang Shengju136ba622016-03-10 08:55:50 +0000500 if (type == NETCONFA_ALL)
501 all = true;
502
503 if (all || type == NETCONFA_FORWARDING)
Nicolas Dichtelf3a1bfb2012-10-25 22:28:50 +0000504 size += nla_total_size(4);
David S. Millerb1afce92012-12-04 14:46:34 -0500505#ifdef CONFIG_IPV6_MROUTE
Zhang Shengju136ba622016-03-10 08:55:50 +0000506 if (all || type == NETCONFA_MC_FORWARDING)
Nicolas Dichteld67b8c62012-12-04 01:13:35 +0000507 size += nla_total_size(4);
David S. Millerb1afce92012-12-04 14:46:34 -0500508#endif
Zhang Shengju136ba622016-03-10 08:55:50 +0000509 if (all || type == NETCONFA_PROXY_NEIGH)
stephen hemmingerc92d5492013-12-17 22:37:14 -0800510 size += nla_total_size(4);
Nicolas Dichtelf3a1bfb2012-10-25 22:28:50 +0000511
Zhang Shengju136ba622016-03-10 08:55:50 +0000512 if (all || type == NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN)
Andy Gospodarek35103d12015-08-13 10:39:01 -0400513 size += nla_total_size(4);
514
Nicolas Dichtelf3a1bfb2012-10-25 22:28:50 +0000515 return size;
516}
517
518static int inet6_netconf_fill_devconf(struct sk_buff *skb, int ifindex,
519 struct ipv6_devconf *devconf, u32 portid,
520 u32 seq, int event, unsigned int flags,
521 int type)
522{
523 struct nlmsghdr *nlh;
524 struct netconfmsg *ncm;
Zhang Shengju136ba622016-03-10 08:55:50 +0000525 bool all = false;
Nicolas Dichtelf3a1bfb2012-10-25 22:28:50 +0000526
527 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct netconfmsg),
528 flags);
Ian Morris63159f22015-03-29 14:00:04 +0100529 if (!nlh)
Nicolas Dichtelf3a1bfb2012-10-25 22:28:50 +0000530 return -EMSGSIZE;
531
Zhang Shengju136ba622016-03-10 08:55:50 +0000532 if (type == NETCONFA_ALL)
533 all = true;
534
Nicolas Dichtelf3a1bfb2012-10-25 22:28:50 +0000535 ncm = nlmsg_data(nlh);
536 ncm->ncm_family = AF_INET6;
537
538 if (nla_put_s32(skb, NETCONFA_IFINDEX, ifindex) < 0)
539 goto nla_put_failure;
540
David Ahern23452172017-03-28 14:28:05 -0700541 if (!devconf)
542 goto out;
543
Zhang Shengju136ba622016-03-10 08:55:50 +0000544 if ((all || type == NETCONFA_FORWARDING) &&
Nicolas Dichtelf3a1bfb2012-10-25 22:28:50 +0000545 nla_put_s32(skb, NETCONFA_FORWARDING, devconf->forwarding) < 0)
546 goto nla_put_failure;
David S. Millerb1afce92012-12-04 14:46:34 -0500547#ifdef CONFIG_IPV6_MROUTE
Zhang Shengju136ba622016-03-10 08:55:50 +0000548 if ((all || type == NETCONFA_MC_FORWARDING) &&
Nicolas Dichteld67b8c62012-12-04 01:13:35 +0000549 nla_put_s32(skb, NETCONFA_MC_FORWARDING,
550 devconf->mc_forwarding) < 0)
551 goto nla_put_failure;
David S. Millerb1afce92012-12-04 14:46:34 -0500552#endif
Zhang Shengju136ba622016-03-10 08:55:50 +0000553 if ((all || type == NETCONFA_PROXY_NEIGH) &&
stephen hemmingerc92d5492013-12-17 22:37:14 -0800554 nla_put_s32(skb, NETCONFA_PROXY_NEIGH, devconf->proxy_ndp) < 0)
555 goto nla_put_failure;
556
Zhang Shengju136ba622016-03-10 08:55:50 +0000557 if ((all || type == NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN) &&
Andy Gospodarek35103d12015-08-13 10:39:01 -0400558 nla_put_s32(skb, NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN,
559 devconf->ignore_routes_with_linkdown) < 0)
560 goto nla_put_failure;
561
David Ahern23452172017-03-28 14:28:05 -0700562out:
Johannes Berg053c0952015-01-16 22:09:00 +0100563 nlmsg_end(skb, nlh);
564 return 0;
Nicolas Dichtelf3a1bfb2012-10-25 22:28:50 +0000565
566nla_put_failure:
567 nlmsg_cancel(skb, nlh);
568 return -EMSGSIZE;
569}
570
David Ahern85b3daa2017-03-28 14:28:04 -0700571void inet6_netconf_notify_devconf(struct net *net, int event, int type,
572 int ifindex, struct ipv6_devconf *devconf)
Nicolas Dichtelf3a1bfb2012-10-25 22:28:50 +0000573{
574 struct sk_buff *skb;
575 int err = -ENOBUFS;
576
Eric Dumazet927265b2016-07-08 05:46:04 +0200577 skb = nlmsg_new(inet6_netconf_msgsize_devconf(type), GFP_KERNEL);
Ian Morris63159f22015-03-29 14:00:04 +0100578 if (!skb)
Nicolas Dichtelf3a1bfb2012-10-25 22:28:50 +0000579 goto errout;
580
581 err = inet6_netconf_fill_devconf(skb, ifindex, devconf, 0, 0,
David Ahern85b3daa2017-03-28 14:28:04 -0700582 event, 0, type);
Nicolas Dichtelf3a1bfb2012-10-25 22:28:50 +0000583 if (err < 0) {
584 /* -EMSGSIZE implies BUG in inet6_netconf_msgsize_devconf() */
585 WARN_ON(err == -EMSGSIZE);
586 kfree_skb(skb);
587 goto errout;
588 }
Eric Dumazet927265b2016-07-08 05:46:04 +0200589 rtnl_notify(skb, net, 0, RTNLGRP_IPV6_NETCONF, NULL, GFP_KERNEL);
Nicolas Dichtelf3a1bfb2012-10-25 22:28:50 +0000590 return;
591errout:
Cong Dingbd779022012-12-18 12:08:56 +0000592 rtnl_set_sk_err(net, RTNLGRP_IPV6_NETCONF, err);
Nicolas Dichtelf3a1bfb2012-10-25 22:28:50 +0000593}
594
Nicolas Dichtel76f8f6c2012-10-25 22:28:51 +0000595static const struct nla_policy devconf_ipv6_policy[NETCONFA_MAX+1] = {
596 [NETCONFA_IFINDEX] = { .len = sizeof(int) },
597 [NETCONFA_FORWARDING] = { .len = sizeof(int) },
stephen hemmingerc92d5492013-12-17 22:37:14 -0800598 [NETCONFA_PROXY_NEIGH] = { .len = sizeof(int) },
Andy Gospodarek35103d12015-08-13 10:39:01 -0400599 [NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN] = { .len = sizeof(int) },
Nicolas Dichtel76f8f6c2012-10-25 22:28:51 +0000600};
601
602static int inet6_netconf_get_devconf(struct sk_buff *in_skb,
David Ahernc21ef3e2017-04-16 09:48:24 -0700603 struct nlmsghdr *nlh,
604 struct netlink_ext_ack *extack)
Nicolas Dichtel76f8f6c2012-10-25 22:28:51 +0000605{
606 struct net *net = sock_net(in_skb->sk);
607 struct nlattr *tb[NETCONFA_MAX+1];
Florian Westphal4ea26072017-10-11 10:28:00 +0200608 struct inet6_dev *in6_dev = NULL;
609 struct net_device *dev = NULL;
Nicolas Dichtel76f8f6c2012-10-25 22:28:51 +0000610 struct netconfmsg *ncm;
611 struct sk_buff *skb;
612 struct ipv6_devconf *devconf;
Nicolas Dichtel76f8f6c2012-10-25 22:28:51 +0000613 int ifindex;
614 int err;
615
616 err = nlmsg_parse(nlh, sizeof(*ncm), tb, NETCONFA_MAX,
David Ahernc21ef3e2017-04-16 09:48:24 -0700617 devconf_ipv6_policy, extack);
Nicolas Dichtel76f8f6c2012-10-25 22:28:51 +0000618 if (err < 0)
Florian Westphal4ea26072017-10-11 10:28:00 +0200619 return err;
620
621 if (!tb[NETCONFA_IFINDEX])
622 return -EINVAL;
Nicolas Dichtel76f8f6c2012-10-25 22:28:51 +0000623
Anton Protopopova97eb332016-02-16 21:43:16 -0500624 err = -EINVAL;
Nicolas Dichtel76f8f6c2012-10-25 22:28:51 +0000625 ifindex = nla_get_s32(tb[NETCONFA_IFINDEX]);
626 switch (ifindex) {
627 case NETCONFA_IFINDEX_ALL:
628 devconf = net->ipv6.devconf_all;
629 break;
630 case NETCONFA_IFINDEX_DEFAULT:
631 devconf = net->ipv6.devconf_dflt;
632 break;
633 default:
Florian Westphal4ea26072017-10-11 10:28:00 +0200634 dev = dev_get_by_index(net, ifindex);
Ian Morris63159f22015-03-29 14:00:04 +0100635 if (!dev)
Florian Westphal4ea26072017-10-11 10:28:00 +0200636 return -EINVAL;
637 in6_dev = in6_dev_get(dev);
Ian Morris63159f22015-03-29 14:00:04 +0100638 if (!in6_dev)
Nicolas Dichtel76f8f6c2012-10-25 22:28:51 +0000639 goto errout;
640 devconf = &in6_dev->cnf;
641 break;
642 }
643
644 err = -ENOBUFS;
Florian Westphal4ea26072017-10-11 10:28:00 +0200645 skb = nlmsg_new(inet6_netconf_msgsize_devconf(NETCONFA_ALL), GFP_KERNEL);
Ian Morris63159f22015-03-29 14:00:04 +0100646 if (!skb)
Nicolas Dichtel76f8f6c2012-10-25 22:28:51 +0000647 goto errout;
648
649 err = inet6_netconf_fill_devconf(skb, ifindex, devconf,
650 NETLINK_CB(in_skb).portid,
651 nlh->nlmsg_seq, RTM_NEWNETCONF, 0,
Zhang Shengju136ba622016-03-10 08:55:50 +0000652 NETCONFA_ALL);
Nicolas Dichtel76f8f6c2012-10-25 22:28:51 +0000653 if (err < 0) {
654 /* -EMSGSIZE implies BUG in inet6_netconf_msgsize_devconf() */
655 WARN_ON(err == -EMSGSIZE);
656 kfree_skb(skb);
657 goto errout;
658 }
659 err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).portid);
660errout:
Florian Westphal4ea26072017-10-11 10:28:00 +0200661 if (in6_dev)
662 in6_dev_put(in6_dev);
663 if (dev)
664 dev_put(dev);
Nicolas Dichtel76f8f6c2012-10-25 22:28:51 +0000665 return err;
666}
667
Nicolas Dichtel7a674202013-03-05 23:42:06 +0000668static int inet6_netconf_dump_devconf(struct sk_buff *skb,
669 struct netlink_callback *cb)
670{
671 struct net *net = sock_net(skb->sk);
672 int h, s_h;
673 int idx, s_idx;
674 struct net_device *dev;
675 struct inet6_dev *idev;
676 struct hlist_head *head;
677
678 s_h = cb->args[0];
679 s_idx = idx = cb->args[1];
680
681 for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
682 idx = 0;
683 head = &net->dev_index_head[h];
684 rcu_read_lock();
Nicolas Dichtel63998ac2013-03-22 06:28:43 +0000685 cb->seq = atomic_read(&net->ipv6.dev_addr_genid) ^
686 net->dev_base_seq;
Nicolas Dichtel7a674202013-03-05 23:42:06 +0000687 hlist_for_each_entry_rcu(dev, head, index_hlist) {
688 if (idx < s_idx)
689 goto cont;
690 idev = __in6_dev_get(dev);
691 if (!idev)
692 goto cont;
693
694 if (inet6_netconf_fill_devconf(skb, dev->ifindex,
695 &idev->cnf,
696 NETLINK_CB(cb->skb).portid,
697 cb->nlh->nlmsg_seq,
698 RTM_NEWNETCONF,
699 NLM_F_MULTI,
Zhang Shengju136ba622016-03-10 08:55:50 +0000700 NETCONFA_ALL) < 0) {
Nicolas Dichtel7a674202013-03-05 23:42:06 +0000701 rcu_read_unlock();
702 goto done;
703 }
Nicolas Dichtel63998ac2013-03-22 06:28:43 +0000704 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
Nicolas Dichtel7a674202013-03-05 23:42:06 +0000705cont:
706 idx++;
707 }
708 rcu_read_unlock();
709 }
710 if (h == NETDEV_HASHENTRIES) {
711 if (inet6_netconf_fill_devconf(skb, NETCONFA_IFINDEX_ALL,
712 net->ipv6.devconf_all,
713 NETLINK_CB(cb->skb).portid,
714 cb->nlh->nlmsg_seq,
715 RTM_NEWNETCONF, NLM_F_MULTI,
Zhang Shengju136ba622016-03-10 08:55:50 +0000716 NETCONFA_ALL) < 0)
Nicolas Dichtel7a674202013-03-05 23:42:06 +0000717 goto done;
718 else
719 h++;
720 }
721 if (h == NETDEV_HASHENTRIES + 1) {
722 if (inet6_netconf_fill_devconf(skb, NETCONFA_IFINDEX_DEFAULT,
723 net->ipv6.devconf_dflt,
724 NETLINK_CB(cb->skb).portid,
725 cb->nlh->nlmsg_seq,
726 RTM_NEWNETCONF, NLM_F_MULTI,
Zhang Shengju136ba622016-03-10 08:55:50 +0000727 NETCONFA_ALL) < 0)
Nicolas Dichtel7a674202013-03-05 23:42:06 +0000728 goto done;
729 else
730 h++;
731 }
732done:
733 cb->args[0] = h;
734 cb->args[1] = idx;
735
736 return skb->len;
737}
738
Linus Torvalds1da177e2005-04-16 15:20:36 -0700739#ifdef CONFIG_SYSCTL
740static void dev_forward_change(struct inet6_dev *idev)
741{
742 struct net_device *dev;
743 struct inet6_ifaddr *ifa;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700744
745 if (!idev)
746 return;
747 dev = idev->dev;
Ben Hutchings0187bdf2008-06-19 16:15:47 -0700748 if (idev->cnf.forwarding)
749 dev_disable_lro(dev);
Amerigo Wang1a940832012-10-28 17:43:53 +0000750 if (dev->flags & IFF_MULTICAST) {
Hannes Frederic Sowa2c5e8932013-02-10 03:50:18 +0000751 if (idev->cnf.forwarding) {
YOSHIFUJI Hideakif3ee4012008-04-10 15:42:11 +0900752 ipv6_dev_mc_inc(dev, &in6addr_linklocal_allrouters);
Hannes Frederic Sowa2c5e8932013-02-10 03:50:18 +0000753 ipv6_dev_mc_inc(dev, &in6addr_interfacelocal_allrouters);
754 ipv6_dev_mc_inc(dev, &in6addr_sitelocal_allrouters);
755 } else {
YOSHIFUJI Hideakif3ee4012008-04-10 15:42:11 +0900756 ipv6_dev_mc_dec(dev, &in6addr_linklocal_allrouters);
Hannes Frederic Sowa2c5e8932013-02-10 03:50:18 +0000757 ipv6_dev_mc_dec(dev, &in6addr_interfacelocal_allrouters);
758 ipv6_dev_mc_dec(dev, &in6addr_sitelocal_allrouters);
759 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700760 }
stephen hemminger502a2ff2010-03-17 20:31:13 +0000761
762 list_for_each_entry(ifa, &idev->addr_list, if_list) {
Michal Wrobel2c12a742007-02-26 15:36:10 -0800763 if (ifa->flags&IFA_F_TENTATIVE)
764 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700765 if (idev->cnf.forwarding)
766 addrconf_join_anycast(ifa);
767 else
768 addrconf_leave_anycast(ifa);
769 }
David Ahern85b3daa2017-03-28 14:28:04 -0700770 inet6_netconf_notify_devconf(dev_net(dev), RTM_NEWNETCONF,
771 NETCONFA_FORWARDING,
Nicolas Dichtelf3a1bfb2012-10-25 22:28:50 +0000772 dev->ifindex, &idev->cnf);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700773}
774
775
Pavel Emelyanove1869322008-01-10 17:43:50 -0800776static void addrconf_forward_change(struct net *net, __s32 newf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700777{
778 struct net_device *dev;
779 struct inet6_dev *idev;
780
Ben Hutchings4acd4942012-08-14 08:54:51 +0000781 for_each_netdev(net, dev) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700782 idev = __in6_dev_get(dev);
783 if (idev) {
Pavel Emelyanove1869322008-01-10 17:43:50 -0800784 int changed = (!idev->cnf.forwarding) ^ (!newf);
785 idev->cnf.forwarding = newf;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700786 if (changed)
787 dev_forward_change(idev);
788 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700789 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700790}
Pavel Emelyanovc8fecf22007-12-05 01:50:24 -0800791
Francesco Ruggeri013d97e2012-01-16 10:40:10 +0000792static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int newf)
Pavel Emelyanovc8fecf22007-12-05 01:50:24 -0800793{
Pavel Emelyanovbff16c22008-01-10 17:42:13 -0800794 struct net *net;
Francesco Ruggeri013d97e2012-01-16 10:40:10 +0000795 int old;
796
797 if (!rtnl_trylock())
798 return restart_syscall();
Pavel Emelyanovbff16c22008-01-10 17:42:13 -0800799
800 net = (struct net *)table->extra2;
Francesco Ruggeri013d97e2012-01-16 10:40:10 +0000801 old = *p;
802 *p = newf;
Pavel Emelyanovc8fecf22007-12-05 01:50:24 -0800803
Francesco Ruggeri013d97e2012-01-16 10:40:10 +0000804 if (p == &net->ipv6.devconf_dflt->forwarding) {
Nicolas Dichtelf3a1bfb2012-10-25 22:28:50 +0000805 if ((!newf) ^ (!old))
David Ahern85b3daa2017-03-28 14:28:04 -0700806 inet6_netconf_notify_devconf(net, RTM_NEWNETCONF,
807 NETCONFA_FORWARDING,
Nicolas Dichtelf3a1bfb2012-10-25 22:28:50 +0000808 NETCONFA_IFINDEX_DEFAULT,
809 net->ipv6.devconf_dflt);
Francesco Ruggeri013d97e2012-01-16 10:40:10 +0000810 rtnl_unlock();
811 return 0;
Eric W. Biederman88af1822010-02-19 13:22:59 +0000812 }
Stephen Hemmingerb325fdd2009-02-26 06:55:31 +0000813
Pavel Emelyanove1869322008-01-10 17:43:50 -0800814 if (p == &net->ipv6.devconf_all->forwarding) {
Nicolas Dichteld26c6382016-08-30 10:09:21 +0200815 int old_dflt = net->ipv6.devconf_dflt->forwarding;
816
Pavel Emelyanove1869322008-01-10 17:43:50 -0800817 net->ipv6.devconf_dflt->forwarding = newf;
Nicolas Dichteld26c6382016-08-30 10:09:21 +0200818 if ((!newf) ^ (!old_dflt))
David Ahern85b3daa2017-03-28 14:28:04 -0700819 inet6_netconf_notify_devconf(net, RTM_NEWNETCONF,
820 NETCONFA_FORWARDING,
Nicolas Dichteld26c6382016-08-30 10:09:21 +0200821 NETCONFA_IFINDEX_DEFAULT,
822 net->ipv6.devconf_dflt);
823
Pavel Emelyanove1869322008-01-10 17:43:50 -0800824 addrconf_forward_change(net, newf);
Nicolas Dichtelf3a1bfb2012-10-25 22:28:50 +0000825 if ((!newf) ^ (!old))
David Ahern85b3daa2017-03-28 14:28:04 -0700826 inet6_netconf_notify_devconf(net, RTM_NEWNETCONF,
827 NETCONFA_FORWARDING,
Nicolas Dichtelf3a1bfb2012-10-25 22:28:50 +0000828 NETCONFA_IFINDEX_ALL,
829 net->ipv6.devconf_all);
Francesco Ruggeri013d97e2012-01-16 10:40:10 +0000830 } else if ((!newf) ^ (!old))
Pavel Emelyanovc8fecf22007-12-05 01:50:24 -0800831 dev_forward_change((struct inet6_dev *)table->extra1);
Ben Hutchings0187bdf2008-06-19 16:15:47 -0700832 rtnl_unlock();
Pavel Emelyanovc8fecf22007-12-05 01:50:24 -0800833
Francesco Ruggeri013d97e2012-01-16 10:40:10 +0000834 if (newf)
Daniel Lezcano7b4da532008-03-04 13:47:14 -0800835 rt6_purge_dflt_routers(net);
Stephen Hemmingerb325fdd2009-02-26 06:55:31 +0000836 return 1;
Pavel Emelyanovc8fecf22007-12-05 01:50:24 -0800837}
Andy Gospodarek35103d12015-08-13 10:39:01 -0400838
839static void addrconf_linkdown_change(struct net *net, __s32 newf)
840{
841 struct net_device *dev;
842 struct inet6_dev *idev;
843
844 for_each_netdev(net, dev) {
845 idev = __in6_dev_get(dev);
846 if (idev) {
847 int changed = (!idev->cnf.ignore_routes_with_linkdown) ^ (!newf);
848
849 idev->cnf.ignore_routes_with_linkdown = newf;
850 if (changed)
851 inet6_netconf_notify_devconf(dev_net(dev),
David Ahern85b3daa2017-03-28 14:28:04 -0700852 RTM_NEWNETCONF,
Andy Gospodarek35103d12015-08-13 10:39:01 -0400853 NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN,
854 dev->ifindex,
855 &idev->cnf);
856 }
857 }
858}
859
860static int addrconf_fixup_linkdown(struct ctl_table *table, int *p, int newf)
861{
862 struct net *net;
863 int old;
864
865 if (!rtnl_trylock())
866 return restart_syscall();
867
868 net = (struct net *)table->extra2;
869 old = *p;
870 *p = newf;
871
872 if (p == &net->ipv6.devconf_dflt->ignore_routes_with_linkdown) {
873 if ((!newf) ^ (!old))
874 inet6_netconf_notify_devconf(net,
David Ahern85b3daa2017-03-28 14:28:04 -0700875 RTM_NEWNETCONF,
Andy Gospodarek35103d12015-08-13 10:39:01 -0400876 NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN,
877 NETCONFA_IFINDEX_DEFAULT,
878 net->ipv6.devconf_dflt);
879 rtnl_unlock();
880 return 0;
881 }
882
883 if (p == &net->ipv6.devconf_all->ignore_routes_with_linkdown) {
884 net->ipv6.devconf_dflt->ignore_routes_with_linkdown = newf;
885 addrconf_linkdown_change(net, newf);
886 if ((!newf) ^ (!old))
887 inet6_netconf_notify_devconf(net,
David Ahern85b3daa2017-03-28 14:28:04 -0700888 RTM_NEWNETCONF,
Andy Gospodarek35103d12015-08-13 10:39:01 -0400889 NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN,
890 NETCONFA_IFINDEX_ALL,
891 net->ipv6.devconf_all);
892 }
893 rtnl_unlock();
894
895 return 1;
896}
897
Linus Torvalds1da177e2005-04-16 15:20:36 -0700898#endif
899
stephen hemminger5c578aed2010-03-17 20:31:11 +0000900/* Nobody refers to this ifaddr, destroy it */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700901void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp)
902{
stephen hemmingerc2e21292010-03-17 20:31:10 +0000903 WARN_ON(!hlist_unhashed(&ifp->addr_lst));
Ilpo Järvinen547b7922008-07-25 21:43:18 -0700904
Linus Torvalds1da177e2005-04-16 15:20:36 -0700905#ifdef NET_REFCNT_DEBUG
Joe Perches91df42b2012-05-15 14:11:54 +0000906 pr_debug("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700907#endif
908
909 in6_dev_put(ifp->idev);
910
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +0100911 if (cancel_delayed_work(&ifp->dad_work))
912 pr_notice("delayed DAD work was pending while freeing ifa=%p\n",
913 ifp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700914
Herbert Xue9d3e082010-05-18 15:36:06 -0700915 if (ifp->state != INET6_IFADDR_STATE_DEAD) {
Joe Perchesf3213832012-05-15 14:11:53 +0000916 pr_warn("Freeing alive inet6 address %p\n", ifp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700917 return;
918 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700919
Lai Jiangshane5785982011-03-15 18:00:14 +0800920 kfree_rcu(ifp, rcu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700921}
922
Brian Haleye55ffac2006-07-10 15:25:51 -0700923static void
924ipv6_link_dev_addr(struct inet6_dev *idev, struct inet6_ifaddr *ifp)
925{
stephen hemminger502a2ff2010-03-17 20:31:13 +0000926 struct list_head *p;
YOSHIFUJI Hideaki8a6ce0c2006-07-11 13:05:30 -0700927 int ifp_scope = ipv6_addr_src_scope(&ifp->addr);
Brian Haleye55ffac2006-07-10 15:25:51 -0700928
929 /*
930 * Each device address list is sorted in order of scope -
931 * global before linklocal.
932 */
stephen hemminger502a2ff2010-03-17 20:31:13 +0000933 list_for_each(p, &idev->addr_list) {
934 struct inet6_ifaddr *ifa
935 = list_entry(p, struct inet6_ifaddr, if_list);
YOSHIFUJI Hideaki8a6ce0c2006-07-11 13:05:30 -0700936 if (ifp_scope >= ipv6_addr_src_scope(&ifa->addr))
Brian Haleye55ffac2006-07-10 15:25:51 -0700937 break;
938 }
939
Eric Dumazet8ef802a2017-10-07 19:30:23 -0700940 list_add_tail_rcu(&ifp->if_list, p);
Brian Haleye55ffac2006-07-10 15:25:51 -0700941}
942
Eric Dumazet3f27fb22017-10-23 16:17:47 -0700943static u32 inet6_addr_hash(const struct net *net, const struct in6_addr *addr)
YOSHIFUJI Hideaki3eb84f42008-04-10 15:42:08 +0900944{
Eric Dumazet3f27fb22017-10-23 16:17:47 -0700945 u32 val = ipv6_addr_hash(addr) ^ net_hash_mix(net);
946
947 return hash_32(val, IN6_ADDR_HSIZE_SHIFT);
YOSHIFUJI Hideaki3eb84f42008-04-10 15:42:08 +0900948}
949
Eric Dumazet56fc7092017-10-23 16:17:45 -0700950static bool ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr,
Eric Dumazet752a9292017-10-23 16:17:46 -0700951 struct net_device *dev, unsigned int hash)
Eric Dumazet56fc7092017-10-23 16:17:45 -0700952{
Eric Dumazet56fc7092017-10-23 16:17:45 -0700953 struct inet6_ifaddr *ifp;
954
955 hlist_for_each_entry(ifp, &inet6_addr_lst[hash], addr_lst) {
956 if (!net_eq(dev_net(ifp->idev->dev), net))
957 continue;
958 if (ipv6_addr_equal(&ifp->addr, addr)) {
959 if (!dev || ifp->idev->dev == dev)
960 return true;
961 }
962 }
963 return false;
964}
965
David Ahernf3d98322017-10-18 09:56:52 -0700966static int ipv6_add_addr_hash(struct net_device *dev, struct inet6_ifaddr *ifa)
967{
Eric Dumazet3f27fb22017-10-23 16:17:47 -0700968 unsigned int hash = inet6_addr_hash(dev_net(dev), &ifa->addr);
David Ahernf3d98322017-10-18 09:56:52 -0700969 int err = 0;
970
971 spin_lock(&addrconf_hash_lock);
972
973 /* Ignore adding duplicate addresses on an interface */
Eric Dumazet752a9292017-10-23 16:17:46 -0700974 if (ipv6_chk_same_addr(dev_net(dev), &ifa->addr, dev, hash)) {
Joe Perchese32ac252018-03-26 08:35:01 -0700975 netdev_dbg(dev, "ipv6_add_addr: already assigned\n");
David Ahernf3d98322017-10-18 09:56:52 -0700976 err = -EEXIST;
Eric Dumazet752a9292017-10-23 16:17:46 -0700977 } else {
978 hlist_add_head_rcu(&ifa->addr_lst, &inet6_addr_lst[hash]);
David Ahernf3d98322017-10-18 09:56:52 -0700979 }
980
David Ahernf3d98322017-10-18 09:56:52 -0700981 spin_unlock(&addrconf_hash_lock);
982
983 return err;
984}
985
Linus Torvalds1da177e2005-04-16 15:20:36 -0700986/* On success it returns ifp with increased reference count */
987
988static struct inet6_ifaddr *
David Aherne6464b82018-05-27 08:09:53 -0700989ipv6_add_addr(struct inet6_dev *idev, struct ifa6_config *cfg,
David Ahernde95e042017-10-18 09:56:54 -0700990 bool can_block, struct netlink_ext_ack *extack)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700991{
David Ahernf3d98322017-10-18 09:56:52 -0700992 gfp_t gfp_flags = can_block ? GFP_KERNEL : GFP_ATOMIC;
David Aherne6464b82018-05-27 08:09:53 -0700993 int addr_type = ipv6_addr_type(cfg->pfx);
David Forsterdf789fe2017-02-23 16:27:18 +0000994 struct net *net = dev_net(idev->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700995 struct inet6_ifaddr *ifa = NULL;
David Ahern360a9882018-04-18 15:39:00 -0700996 struct fib6_info *f6i = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700997 int err = 0;
YOSHIFUJI Hideakid68b8272008-06-25 16:26:47 +0900998
999 if (addr_type == IPV6_ADDR_ANY ||
1000 addr_type & IPV6_ADDR_MULTICAST ||
1001 (!(idev->dev->flags & IFF_LOOPBACK) &&
1002 addr_type & IPV6_ADDR_LOOPBACK))
1003 return ERR_PTR(-EADDRNOTAVAIL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001004
Linus Torvalds1da177e2005-04-16 15:20:36 -07001005 if (idev->dead) {
1006 err = -ENODEV; /*XXX*/
David Ahernf3d98322017-10-18 09:56:52 -07001007 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001008 }
1009
Brian Haley56d417b2009-06-01 03:07:33 -07001010 if (idev->cnf.disable_ipv6) {
Brian Haley9bdd8d42009-03-18 18:22:48 -07001011 err = -EACCES;
David Ahernf3d98322017-10-18 09:56:52 -07001012 goto out;
Brian Haley9bdd8d42009-03-18 18:22:48 -07001013 }
1014
David Ahernff7883e2017-10-18 09:56:53 -07001015 /* validator notifier needs to be blocking;
1016 * do not call in atomic context
1017 */
1018 if (can_block) {
1019 struct in6_validator_info i6vi = {
David Aherne6464b82018-05-27 08:09:53 -07001020 .i6vi_addr = *cfg->pfx,
David Ahernff7883e2017-10-18 09:56:53 -07001021 .i6vi_dev = idev,
David Ahernde95e042017-10-18 09:56:54 -07001022 .extack = extack,
David Ahernff7883e2017-10-18 09:56:53 -07001023 };
1024
1025 err = inet6addr_validator_notifier_call_chain(NETDEV_UP, &i6vi);
1026 err = notifier_to_errno(err);
1027 if (err < 0)
1028 goto out;
1029 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001030
David Ahernf3d98322017-10-18 09:56:52 -07001031 ifa = kzalloc(sizeof(*ifa), gfp_flags);
Ian Morris63159f22015-03-29 14:00:04 +01001032 if (!ifa) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001033 err = -ENOBUFS;
1034 goto out;
1035 }
1036
David Aherne6464b82018-05-27 08:09:53 -07001037 f6i = addrconf_f6i_alloc(net, idev, cfg->pfx, false, gfp_flags);
David Ahern360a9882018-04-18 15:39:00 -07001038 if (IS_ERR(f6i)) {
1039 err = PTR_ERR(f6i);
1040 f6i = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001041 goto out;
1042 }
1043
David Forsterdf789fe2017-02-23 16:27:18 +00001044 if (net->ipv6.devconf_all->disable_policy ||
1045 idev->cnf.disable_policy)
David Ahern360a9882018-04-18 15:39:00 -07001046 f6i->dst_nopolicy = true;
David Forsterdf789fe2017-02-23 16:27:18 +00001047
Jiri Pirkobba24892013-12-07 19:26:57 +01001048 neigh_parms_data_state_setall(idev->nd_parms);
1049
David Aherne6464b82018-05-27 08:09:53 -07001050 ifa->addr = *cfg->pfx;
1051 if (cfg->peer_pfx)
1052 ifa->peer_addr = *cfg->peer_pfx;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001053
1054 spin_lock_init(&ifa->lock);
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01001055 INIT_DELAYED_WORK(&ifa->dad_work, addrconf_dad_work);
stephen hemmingerc2e21292010-03-17 20:31:10 +00001056 INIT_HLIST_NODE(&ifa->addr_lst);
David Aherne6464b82018-05-27 08:09:53 -07001057 ifa->scope = cfg->scope;
1058 ifa->prefix_len = cfg->plen;
1059 ifa->flags = cfg->ifa_flags;
Mahesh Bandewar66eb9f82017-05-12 17:03:39 -07001060 /* No need to add the TENTATIVE flag for addresses with NODAD */
David Aherne6464b82018-05-27 08:09:53 -07001061 if (!(cfg->ifa_flags & IFA_F_NODAD))
Mahesh Bandewar66eb9f82017-05-12 17:03:39 -07001062 ifa->flags |= IFA_F_TENTATIVE;
David Aherne6464b82018-05-27 08:09:53 -07001063 ifa->valid_lft = cfg->valid_lft;
1064 ifa->prefered_lft = cfg->preferred_lft;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001065 ifa->cstamp = ifa->tstamp = jiffies;
Daniel Borkmann617fe292013-04-09 03:47:16 +00001066 ifa->tokenized = false;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001067
David Ahern360a9882018-04-18 15:39:00 -07001068 ifa->rt = f6i;
Keir Fraser57f5f542006-08-29 02:43:49 -07001069
Linus Torvalds1da177e2005-04-16 15:20:36 -07001070 ifa->idev = idev;
David Ahernf3d98322017-10-18 09:56:52 -07001071 in6_dev_hold(idev);
1072
Linus Torvalds1da177e2005-04-16 15:20:36 -07001073 /* For caller */
Reshetova, Elena271201c2017-07-04 09:34:56 +03001074 refcount_set(&ifa->refcnt, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001075
David Ahernf3d98322017-10-18 09:56:52 -07001076 rcu_read_lock_bh();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077
David Ahernf3d98322017-10-18 09:56:52 -07001078 err = ipv6_add_addr_hash(idev->dev, ifa);
1079 if (err < 0) {
1080 rcu_read_unlock_bh();
1081 goto out;
1082 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001083
1084 write_lock(&idev->lock);
David Ahernf3d98322017-10-18 09:56:52 -07001085
Linus Torvalds1da177e2005-04-16 15:20:36 -07001086 /* Add to inet6_dev unicast addr list. */
Brian Haleye55ffac2006-07-10 15:25:51 -07001087 ipv6_link_dev_addr(idev, ifa);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001088
Linus Torvalds1da177e2005-04-16 15:20:36 -07001089 if (ifa->flags&IFA_F_TEMPORARY) {
stephen hemminger372e6c82010-03-17 20:31:09 +00001090 list_add(&ifa->tmp_list, &idev->tempaddr_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001091 in6_ifa_hold(ifa);
1092 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001093
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094 in6_ifa_hold(ifa);
1095 write_unlock(&idev->lock);
David Ahernf3d98322017-10-18 09:56:52 -07001096
YOSHIFUJI Hideaki8814c4b2006-09-22 14:44:24 -07001097 rcu_read_unlock_bh();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001098
David Ahernf3d98322017-10-18 09:56:52 -07001099 inet6addr_notifier_call_chain(NETDEV_UP, ifa);
1100out:
1101 if (unlikely(err < 0)) {
David Ahern360a9882018-04-18 15:39:00 -07001102 fib6_info_release(f6i);
David Ahern93531c62018-04-17 17:33:25 -07001103
David Ahernf3d98322017-10-18 09:56:52 -07001104 if (ifa) {
1105 if (ifa->idev)
1106 in6_dev_put(ifa->idev);
1107 kfree(ifa);
1108 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001109 ifa = ERR_PTR(err);
1110 }
1111
1112 return ifa;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001113}
1114
Thomas Haller5b84efe2014-01-15 15:36:59 +01001115enum cleanup_prefix_rt_t {
1116 CLEANUP_PREFIX_RT_NOP, /* no cleanup action for prefix route */
1117 CLEANUP_PREFIX_RT_DEL, /* delete the prefix route */
1118 CLEANUP_PREFIX_RT_EXPIRE, /* update the lifetime of the prefix route */
1119};
1120
1121/*
1122 * Check, whether the prefix for ifp would still need a prefix route
1123 * after deleting ifp. The function returns one of the CLEANUP_PREFIX_RT_*
1124 * constants.
1125 *
1126 * 1) we don't purge prefix if address was not permanent.
1127 * prefix is managed by its own lifetime.
1128 * 2) we also don't purge, if the address was IFA_F_NOPREFIXROUTE.
1129 * 3) if there are no addresses, delete prefix.
1130 * 4) if there are still other permanent address(es),
1131 * corresponding prefix is still permanent.
1132 * 5) if there are still other addresses with IFA_F_NOPREFIXROUTE,
1133 * don't purge the prefix, assume user space is managing it.
1134 * 6) otherwise, update prefix lifetime to the
1135 * longest valid lifetime among the corresponding
1136 * addresses on the device.
1137 * Note: subsequent RA will update lifetime.
1138 **/
1139static enum cleanup_prefix_rt_t
1140check_cleanup_prefix_route(struct inet6_ifaddr *ifp, unsigned long *expires)
1141{
1142 struct inet6_ifaddr *ifa;
1143 struct inet6_dev *idev = ifp->idev;
1144 unsigned long lifetime;
1145 enum cleanup_prefix_rt_t action = CLEANUP_PREFIX_RT_DEL;
1146
1147 *expires = jiffies;
1148
1149 list_for_each_entry(ifa, &idev->addr_list, if_list) {
1150 if (ifa == ifp)
1151 continue;
1152 if (!ipv6_prefix_equal(&ifa->addr, &ifp->addr,
1153 ifp->prefix_len))
1154 continue;
1155 if (ifa->flags & (IFA_F_PERMANENT | IFA_F_NOPREFIXROUTE))
1156 return CLEANUP_PREFIX_RT_NOP;
1157
1158 action = CLEANUP_PREFIX_RT_EXPIRE;
1159
1160 spin_lock(&ifa->lock);
1161
1162 lifetime = addrconf_timeout_fixup(ifa->valid_lft, HZ);
1163 /*
1164 * Note: Because this address is
1165 * not permanent, lifetime <
1166 * LONG_MAX / HZ here.
1167 */
1168 if (time_before(*expires, ifa->tstamp + lifetime * HZ))
1169 *expires = ifa->tstamp + lifetime * HZ;
1170 spin_unlock(&ifa->lock);
1171 }
1172
1173 return action;
1174}
1175
1176static void
1177cleanup_prefix_route(struct inet6_ifaddr *ifp, unsigned long expires, bool del_rt)
1178{
David Ahern93c2fb22018-04-18 15:38:59 -07001179 struct fib6_info *f6i;
Thomas Haller5b84efe2014-01-15 15:36:59 +01001180
David Ahern93c2fb22018-04-18 15:38:59 -07001181 f6i = addrconf_get_prefix_route(&ifp->addr,
Thomas Haller5b84efe2014-01-15 15:36:59 +01001182 ifp->prefix_len,
1183 ifp->idev->dev,
1184 0, RTF_GATEWAY | RTF_DEFAULT);
David Ahern93c2fb22018-04-18 15:38:59 -07001185 if (f6i) {
Thomas Haller5b84efe2014-01-15 15:36:59 +01001186 if (del_rt)
David Ahern93c2fb22018-04-18 15:38:59 -07001187 ip6_del_rt(dev_net(ifp->idev->dev), f6i);
Thomas Haller5b84efe2014-01-15 15:36:59 +01001188 else {
David Ahern93c2fb22018-04-18 15:38:59 -07001189 if (!(f6i->fib6_flags & RTF_EXPIRES))
1190 fib6_set_expires(f6i, expires);
1191 fib6_info_release(f6i);
Thomas Haller5b84efe2014-01-15 15:36:59 +01001192 }
1193 }
1194}
1195
1196
Linus Torvalds1da177e2005-04-16 15:20:36 -07001197/* This function wants to get referenced ifp and releases it before return */
1198
1199static void ipv6_del_addr(struct inet6_ifaddr *ifp)
1200{
Herbert Xu4c5ff6a2010-05-18 15:54:18 -07001201 int state;
Thomas Haller5b84efe2014-01-15 15:36:59 +01001202 enum cleanup_prefix_rt_t action = CLEANUP_PREFIX_RT_NOP;
1203 unsigned long expires;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001204
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01001205 ASSERT_RTNL();
1206
Hannes Frederic Sowa8e8e6762015-03-23 23:36:03 +01001207 spin_lock_bh(&ifp->lock);
Herbert Xu4c5ff6a2010-05-18 15:54:18 -07001208 state = ifp->state;
Herbert Xue9d3e082010-05-18 15:36:06 -07001209 ifp->state = INET6_IFADDR_STATE_DEAD;
Hannes Frederic Sowa8e8e6762015-03-23 23:36:03 +01001210 spin_unlock_bh(&ifp->lock);
Herbert Xu4c5ff6a2010-05-18 15:54:18 -07001211
1212 if (state == INET6_IFADDR_STATE_DEAD)
1213 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001214
stephen hemminger5c578aed2010-03-17 20:31:11 +00001215 spin_lock_bh(&addrconf_hash_lock);
1216 hlist_del_init_rcu(&ifp->addr_lst);
stephen hemminger5c578aed2010-03-17 20:31:11 +00001217 spin_unlock_bh(&addrconf_hash_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218
Thomas Haller5b84efe2014-01-15 15:36:59 +01001219 write_lock_bh(&ifp->idev->lock);
David S. Miller5d9efa72013-10-28 20:07:50 -04001220
Linus Torvalds1da177e2005-04-16 15:20:36 -07001221 if (ifp->flags&IFA_F_TEMPORARY) {
stephen hemminger372e6c82010-03-17 20:31:09 +00001222 list_del(&ifp->tmp_list);
1223 if (ifp->ifpub) {
1224 in6_ifa_put(ifp->ifpub);
1225 ifp->ifpub = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001226 }
stephen hemminger372e6c82010-03-17 20:31:09 +00001227 __in6_ifa_put(ifp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001228 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001229
Thomas Haller5b84efe2014-01-15 15:36:59 +01001230 if (ifp->flags & IFA_F_PERMANENT && !(ifp->flags & IFA_F_NOPREFIXROUTE))
1231 action = check_cleanup_prefix_route(ifp, &expires);
stephen hemminger502a2ff2010-03-17 20:31:13 +00001232
Eric Dumazet8ef802a2017-10-07 19:30:23 -07001233 list_del_rcu(&ifp->if_list);
Thomas Haller5b84efe2014-01-15 15:36:59 +01001234 __in6_ifa_put(ifp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001235
Thomas Haller5b84efe2014-01-15 15:36:59 +01001236 write_unlock_bh(&ifp->idev->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001237
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01001238 addrconf_del_dad_work(ifp);
Andrey Vaginb2238562008-07-08 15:13:31 -07001239
Linus Torvalds1da177e2005-04-16 15:20:36 -07001240 ipv6_ifa_notify(RTM_DELADDR, ifp);
1241
Cong Wangf88c91d2013-04-14 23:18:43 +08001242 inet6addr_notifier_call_chain(NETDEV_DOWN, ifp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001243
Thomas Haller5b84efe2014-01-15 15:36:59 +01001244 if (action != CLEANUP_PREFIX_RT_NOP) {
1245 cleanup_prefix_route(ifp, expires,
1246 action == CLEANUP_PREFIX_RT_DEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001247 }
1248
Daniel Walterc3968a82011-04-13 21:10:57 +00001249 /* clean up prefsrc entries */
1250 rt6_remove_prefsrc(ifp);
Herbert Xu4c5ff6a2010-05-18 15:54:18 -07001251out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001252 in6_ifa_put(ifp);
1253}
1254
Eric Dumazetfffcefe2017-11-06 14:13:29 -08001255static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp,
1256 struct inet6_ifaddr *ift,
1257 bool block)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001258{
1259 struct inet6_dev *idev = ifp->idev;
1260 struct in6_addr addr, *tmpaddr;
David Aherne6464b82018-05-27 08:09:53 -07001261 unsigned long tmp_tstamp, age;
Benoit Boissinoteac55bf2008-04-02 00:01:35 -07001262 unsigned long regen_advance;
David Aherne6464b82018-05-27 08:09:53 -07001263 struct ifa6_config cfg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001264 int ret = 0;
Lorenzo Colitti76f793e2011-07-26 13:50:49 +00001265 unsigned long now = jiffies;
Jiri Bohac76506a92016-10-13 18:52:15 +02001266 long max_desync_factor;
Jiri Bohac7aa8e632016-10-20 12:29:26 +02001267 s32 cnf_temp_preferred_lft;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001268
Jiri Pirko53bd6742013-12-06 09:45:22 +01001269 write_lock_bh(&idev->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001270 if (ift) {
1271 spin_lock_bh(&ift->lock);
1272 memcpy(&addr.s6_addr[8], &ift->addr.s6_addr[8], 8);
1273 spin_unlock_bh(&ift->lock);
1274 tmpaddr = &addr;
1275 } else {
1276 tmpaddr = NULL;
1277 }
1278retry:
1279 in6_dev_hold(idev);
1280 if (idev->cnf.use_tempaddr <= 0) {
Jiri Pirko53bd6742013-12-06 09:45:22 +01001281 write_unlock_bh(&idev->lock);
Joe Perchesf3213832012-05-15 14:11:53 +00001282 pr_info("%s: use_tempaddr is disabled\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001283 in6_dev_put(idev);
1284 ret = -1;
1285 goto out;
1286 }
1287 spin_lock_bh(&ifp->lock);
1288 if (ifp->regen_count++ >= idev->cnf.regen_max_retry) {
1289 idev->cnf.use_tempaddr = -1; /*XXX*/
1290 spin_unlock_bh(&ifp->lock);
Jiri Pirko53bd6742013-12-06 09:45:22 +01001291 write_unlock_bh(&idev->lock);
Joe Perchesf3213832012-05-15 14:11:53 +00001292 pr_warn("%s: regeneration time exceeded - disabled temporary address support\n",
1293 __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001294 in6_dev_put(idev);
1295 ret = -1;
1296 goto out;
1297 }
1298 in6_ifa_hold(ifp);
1299 memcpy(addr.s6_addr, ifp->addr.s6_addr, 8);
Jiri Bohac9d6280d2016-10-13 18:50:02 +02001300 ipv6_try_regen_rndid(idev, tmpaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001301 memcpy(&addr.s6_addr[8], idev->rndid, 8);
Lorenzo Colitti76f793e2011-07-26 13:50:49 +00001302 age = (now - ifp->tstamp) / HZ;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001303
Benoit Boissinoteac55bf2008-04-02 00:01:35 -07001304 regen_advance = idev->cnf.regen_max_retry *
Ian Morris67ba4152014-08-24 21:53:10 +01001305 idev->cnf.dad_transmits *
1306 NEIGH_VAR(idev->nd_parms, RETRANS_TIME) / HZ;
Jiri Bohac76506a92016-10-13 18:52:15 +02001307
1308 /* recalculate max_desync_factor each time and update
1309 * idev->desync_factor if it's larger
1310 */
Jiri Bohac7aa8e632016-10-20 12:29:26 +02001311 cnf_temp_preferred_lft = READ_ONCE(idev->cnf.temp_prefered_lft);
Jiri Bohac76506a92016-10-13 18:52:15 +02001312 max_desync_factor = min_t(__u32,
1313 idev->cnf.max_desync_factor,
Jiri Bohac7aa8e632016-10-20 12:29:26 +02001314 cnf_temp_preferred_lft - regen_advance);
Jiri Bohac76506a92016-10-13 18:52:15 +02001315
1316 if (unlikely(idev->desync_factor > max_desync_factor)) {
1317 if (max_desync_factor > 0) {
1318 get_random_bytes(&idev->desync_factor,
1319 sizeof(idev->desync_factor));
1320 idev->desync_factor %= max_desync_factor;
1321 } else {
1322 idev->desync_factor = 0;
1323 }
1324 }
1325
David Aherne6464b82018-05-27 08:09:53 -07001326 cfg.valid_lft = min_t(__u32, ifp->valid_lft,
Jiri Bohac76506a92016-10-13 18:52:15 +02001327 idev->cnf.temp_valid_lft + age);
David Aherne6464b82018-05-27 08:09:53 -07001328 cfg.preferred_lft = cnf_temp_preferred_lft + age - idev->desync_factor;
1329 cfg.preferred_lft = min_t(__u32, ifp->prefered_lft, cfg.preferred_lft);
1330
1331 cfg.plen = ifp->prefix_len;
Jiri Bohac76506a92016-10-13 18:52:15 +02001332 tmp_tstamp = ifp->tstamp;
1333 spin_unlock_bh(&ifp->lock);
1334
Jiri Pirko53bd6742013-12-06 09:45:22 +01001335 write_unlock_bh(&idev->lock);
Neil Horman95c385b2007-04-25 17:08:10 -07001336
Benoit Boissinoteac55bf2008-04-02 00:01:35 -07001337 /* A temporary address is created only if this calculated Preferred
1338 * Lifetime is greater than REGEN_ADVANCE time units. In particular,
1339 * an implementation must not create a temporary address with a zero
1340 * Preferred Lifetime.
Heiner Kallweitecab6702014-03-12 22:13:19 +01001341 * Use age calculation as in addrconf_verify to avoid unnecessary
1342 * temporary addresses being generated.
Benoit Boissinoteac55bf2008-04-02 00:01:35 -07001343 */
Heiner Kallweitecab6702014-03-12 22:13:19 +01001344 age = (now - tmp_tstamp + ADDRCONF_TIMER_FUZZ_MINUS) / HZ;
David Aherne6464b82018-05-27 08:09:53 -07001345 if (cfg.preferred_lft <= regen_advance + age) {
Benoit Boissinoteac55bf2008-04-02 00:01:35 -07001346 in6_ifa_put(ifp);
1347 in6_dev_put(idev);
1348 ret = -1;
1349 goto out;
1350 }
1351
David Aherne6464b82018-05-27 08:09:53 -07001352 cfg.ifa_flags = IFA_F_TEMPORARY;
Neil Horman95c385b2007-04-25 17:08:10 -07001353 /* set in addrconf_prefix_rcv() */
1354 if (ifp->flags & IFA_F_OPTIMISTIC)
David Aherne6464b82018-05-27 08:09:53 -07001355 cfg.ifa_flags |= IFA_F_OPTIMISTIC;
Neil Horman95c385b2007-04-25 17:08:10 -07001356
David Aherne6464b82018-05-27 08:09:53 -07001357 cfg.pfx = &addr;
1358 cfg.scope = ipv6_addr_scope(cfg.pfx);
1359
1360 ift = ipv6_add_addr(idev, &cfg, block, NULL);
Hannes Frederic Sowa4b08a8f2013-08-16 13:02:27 +02001361 if (IS_ERR(ift)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001362 in6_ifa_put(ifp);
1363 in6_dev_put(idev);
Joe Perchesf3213832012-05-15 14:11:53 +00001364 pr_info("%s: retry temporary address regeneration\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001365 tmpaddr = &addr;
Jiri Pirko53bd6742013-12-06 09:45:22 +01001366 write_lock_bh(&idev->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001367 goto retry;
1368 }
1369
1370 spin_lock_bh(&ift->lock);
1371 ift->ifpub = ifp;
Lorenzo Colitti76f793e2011-07-26 13:50:49 +00001372 ift->cstamp = now;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001373 ift->tstamp = tmp_tstamp;
1374 spin_unlock_bh(&ift->lock);
1375
David S. Millercf22f9a2012-04-14 21:37:40 -04001376 addrconf_dad_start(ift);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001377 in6_ifa_put(ift);
1378 in6_dev_put(idev);
1379out:
1380 return ret;
1381}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001382
1383/*
YOSHIFUJI Hideaki072047e42005-11-08 09:38:30 -08001384 * Choose an appropriate source address (RFC3484)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001385 */
YOSHIFUJI Hideakia9b05722008-03-02 10:48:21 +09001386enum {
1387 IPV6_SADDR_RULE_INIT = 0,
1388 IPV6_SADDR_RULE_LOCAL,
1389 IPV6_SADDR_RULE_SCOPE,
1390 IPV6_SADDR_RULE_PREFERRED,
1391#ifdef CONFIG_IPV6_MIP6
1392 IPV6_SADDR_RULE_HOA,
1393#endif
1394 IPV6_SADDR_RULE_OIF,
1395 IPV6_SADDR_RULE_LABEL,
YOSHIFUJI Hideakia9b05722008-03-02 10:48:21 +09001396 IPV6_SADDR_RULE_PRIVACY,
YOSHIFUJI Hideakia9b05722008-03-02 10:48:21 +09001397 IPV6_SADDR_RULE_ORCHID,
1398 IPV6_SADDR_RULE_PREFIX,
Erik Kline7fd25612014-10-28 18:11:14 +09001399#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
1400 IPV6_SADDR_RULE_NOT_OPTIMISTIC,
1401#endif
YOSHIFUJI Hideakia9b05722008-03-02 10:48:21 +09001402 IPV6_SADDR_RULE_MAX
YOSHIFUJI Hideaki072047e42005-11-08 09:38:30 -08001403};
1404
YOSHIFUJI Hideakia9b05722008-03-02 10:48:21 +09001405struct ipv6_saddr_score {
1406 int rule;
1407 int addr_type;
1408 struct inet6_ifaddr *ifa;
1409 DECLARE_BITMAP(scorebits, IPV6_SADDR_RULE_MAX);
1410 int scopedist;
1411 int matchlen;
1412};
1413
1414struct ipv6_saddr_dst {
YOSHIFUJI Hideaki9acd9f32008-04-10 15:42:10 +09001415 const struct in6_addr *addr;
YOSHIFUJI Hideakia9b05722008-03-02 10:48:21 +09001416 int ifindex;
1417 int scope;
1418 int label;
YOSHIFUJI Hideaki7cbca672008-03-25 09:37:42 +09001419 unsigned int prefs;
YOSHIFUJI Hideakia9b05722008-03-02 10:48:21 +09001420};
YOSHIFUJI Hideaki072047e42005-11-08 09:38:30 -08001421
Dave Jonesb6f99a22007-03-22 12:27:49 -07001422static inline int ipv6_saddr_preferred(int type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001423{
Ulrich Weber45bb0062010-02-25 23:28:58 +00001424 if (type & (IPV6_ADDR_MAPPED|IPV6_ADDR_COMPATv4|IPV6_ADDR_LOOPBACK))
YOSHIFUJI Hideaki072047e42005-11-08 09:38:30 -08001425 return 1;
1426 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001427}
1428
Matteo Croce35e015e2017-09-12 17:46:37 +02001429static bool ipv6_use_optimistic_addr(struct net *net,
1430 struct inet6_dev *idev)
Erik Kline7fd25612014-10-28 18:11:14 +09001431{
1432#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
Matteo Croce35e015e2017-09-12 17:46:37 +02001433 if (!idev)
1434 return false;
1435 if (!net->ipv6.devconf_all->optimistic_dad && !idev->cnf.optimistic_dad)
1436 return false;
1437 if (!net->ipv6.devconf_all->use_optimistic && !idev->cnf.use_optimistic)
1438 return false;
1439
1440 return true;
Erik Kline7fd25612014-10-28 18:11:14 +09001441#else
1442 return false;
1443#endif
1444}
1445
Sabrina Dubrocaf1c02cf2018-02-28 16:40:08 +01001446static bool ipv6_allow_optimistic_dad(struct net *net,
1447 struct inet6_dev *idev)
1448{
1449#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
1450 if (!idev)
1451 return false;
1452 if (!net->ipv6.devconf_all->optimistic_dad && !idev->cnf.optimistic_dad)
1453 return false;
1454
1455 return true;
1456#else
1457 return false;
1458#endif
1459}
1460
Benjamin Thery3de23252008-05-28 14:51:24 +02001461static int ipv6_get_saddr_eval(struct net *net,
1462 struct ipv6_saddr_score *score,
YOSHIFUJI Hideakia9b05722008-03-02 10:48:21 +09001463 struct ipv6_saddr_dst *dst,
1464 int i)
1465{
1466 int ret;
1467
1468 if (i <= score->rule) {
1469 switch (i) {
1470 case IPV6_SADDR_RULE_SCOPE:
1471 ret = score->scopedist;
1472 break;
1473 case IPV6_SADDR_RULE_PREFIX:
1474 ret = score->matchlen;
1475 break;
1476 default:
1477 ret = !!test_bit(i, score->scorebits);
1478 }
1479 goto out;
1480 }
1481
1482 switch (i) {
1483 case IPV6_SADDR_RULE_INIT:
1484 /* Rule 0: remember if hiscore is not ready yet */
1485 ret = !!score->ifa;
1486 break;
1487 case IPV6_SADDR_RULE_LOCAL:
1488 /* Rule 1: Prefer same address */
1489 ret = ipv6_addr_equal(&score->ifa->addr, dst->addr);
1490 break;
1491 case IPV6_SADDR_RULE_SCOPE:
1492 /* Rule 2: Prefer appropriate scope
1493 *
1494 * ret
1495 * ^
1496 * -1 | d 15
1497 * ---+--+-+---> scope
1498 * |
1499 * | d is scope of the destination.
1500 * B-d | \
1501 * | \ <- smaller scope is better if
stephen hemmingerdb9c7c32014-01-12 11:26:32 -08001502 * B-15 | \ if scope is enough for destination.
YOSHIFUJI Hideakia9b05722008-03-02 10:48:21 +09001503 * | ret = B - scope (-1 <= scope >= d <= 15).
1504 * d-C-1 | /
1505 * |/ <- greater is better
1506 * -C / if scope is not enough for destination.
1507 * /| ret = scope - C (-1 <= d < scope <= 15).
1508 *
1509 * d - C - 1 < B -15 (for all -1 <= d <= 15).
1510 * C > d + 14 - B >= 15 + 14 - B = 29 - B.
1511 * Assume B = 0 and we get C > 29.
1512 */
1513 ret = __ipv6_addr_src_scope(score->addr_type);
1514 if (ret >= dst->scope)
1515 ret = -ret;
1516 else
1517 ret -= 128; /* 30 is enough */
1518 score->scopedist = ret;
1519 break;
1520 case IPV6_SADDR_RULE_PREFERRED:
Erik Kline7fd25612014-10-28 18:11:14 +09001521 {
YOSHIFUJI Hideakia9b05722008-03-02 10:48:21 +09001522 /* Rule 3: Avoid deprecated and optimistic addresses */
Erik Kline7fd25612014-10-28 18:11:14 +09001523 u8 avoid = IFA_F_DEPRECATED;
1524
Matteo Croce35e015e2017-09-12 17:46:37 +02001525 if (!ipv6_use_optimistic_addr(net, score->ifa->idev))
Erik Kline7fd25612014-10-28 18:11:14 +09001526 avoid |= IFA_F_OPTIMISTIC;
YOSHIFUJI Hideakia9b05722008-03-02 10:48:21 +09001527 ret = ipv6_saddr_preferred(score->addr_type) ||
Erik Kline7fd25612014-10-28 18:11:14 +09001528 !(score->ifa->flags & avoid);
YOSHIFUJI Hideakia9b05722008-03-02 10:48:21 +09001529 break;
Erik Kline7fd25612014-10-28 18:11:14 +09001530 }
YOSHIFUJI Hideakia9b05722008-03-02 10:48:21 +09001531#ifdef CONFIG_IPV6_MIP6
1532 case IPV6_SADDR_RULE_HOA:
YOSHIFUJI Hideaki7cbca672008-03-25 09:37:42 +09001533 {
YOSHIFUJI Hideakia9b05722008-03-02 10:48:21 +09001534 /* Rule 4: Prefer home address */
YOSHIFUJI Hideaki7cbca672008-03-25 09:37:42 +09001535 int prefhome = !(dst->prefs & IPV6_PREFER_SRC_COA);
1536 ret = !(score->ifa->flags & IFA_F_HOMEADDRESS) ^ prefhome;
YOSHIFUJI Hideakia9b05722008-03-02 10:48:21 +09001537 break;
YOSHIFUJI Hideaki7cbca672008-03-25 09:37:42 +09001538 }
YOSHIFUJI Hideakia9b05722008-03-02 10:48:21 +09001539#endif
1540 case IPV6_SADDR_RULE_OIF:
1541 /* Rule 5: Prefer outgoing interface */
1542 ret = (!dst->ifindex ||
1543 dst->ifindex == score->ifa->idev->dev->ifindex);
1544 break;
1545 case IPV6_SADDR_RULE_LABEL:
1546 /* Rule 6: Prefer matching label */
Benjamin Thery3de23252008-05-28 14:51:24 +02001547 ret = ipv6_addr_label(net,
1548 &score->ifa->addr, score->addr_type,
YOSHIFUJI Hideakia9b05722008-03-02 10:48:21 +09001549 score->ifa->idev->dev->ifindex) == dst->label;
1550 break;
YOSHIFUJI Hideakia9b05722008-03-02 10:48:21 +09001551 case IPV6_SADDR_RULE_PRIVACY:
YOSHIFUJI Hideaki7cbca672008-03-25 09:37:42 +09001552 {
YOSHIFUJI Hideakia9b05722008-03-02 10:48:21 +09001553 /* Rule 7: Prefer public address
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001554 * Note: prefer temporary address if use_tempaddr >= 2
YOSHIFUJI Hideakia9b05722008-03-02 10:48:21 +09001555 */
YOSHIFUJI Hideaki7cbca672008-03-25 09:37:42 +09001556 int preftmp = dst->prefs & (IPV6_PREFER_SRC_PUBLIC|IPV6_PREFER_SRC_TMP) ?
1557 !!(dst->prefs & IPV6_PREFER_SRC_TMP) :
1558 score->ifa->idev->cnf.use_tempaddr >= 2;
1559 ret = (!(score->ifa->flags & IFA_F_TEMPORARY)) ^ preftmp;
YOSHIFUJI Hideakia9b05722008-03-02 10:48:21 +09001560 break;
YOSHIFUJI Hideaki7cbca672008-03-25 09:37:42 +09001561 }
YOSHIFUJI Hideakia9b05722008-03-02 10:48:21 +09001562 case IPV6_SADDR_RULE_ORCHID:
1563 /* Rule 8-: Prefer ORCHID vs ORCHID or
1564 * non-ORCHID vs non-ORCHID
1565 */
1566 ret = !(ipv6_addr_orchid(&score->ifa->addr) ^
1567 ipv6_addr_orchid(dst->addr));
1568 break;
1569 case IPV6_SADDR_RULE_PREFIX:
1570 /* Rule 8: Use longest matching prefix */
YOSHIFUJI Hideaki / 吉藤英明91b4b042012-09-10 18:41:07 +00001571 ret = ipv6_addr_diff(&score->ifa->addr, dst->addr);
1572 if (ret > score->ifa->prefix_len)
1573 ret = score->ifa->prefix_len;
1574 score->matchlen = ret;
YOSHIFUJI Hideakia9b05722008-03-02 10:48:21 +09001575 break;
Erik Kline7fd25612014-10-28 18:11:14 +09001576#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
1577 case IPV6_SADDR_RULE_NOT_OPTIMISTIC:
1578 /* Optimistic addresses still have lower precedence than other
1579 * preferred addresses.
1580 */
1581 ret = !(score->ifa->flags & IFA_F_OPTIMISTIC);
1582 break;
1583#endif
YOSHIFUJI Hideakia9b05722008-03-02 10:48:21 +09001584 default:
1585 ret = 0;
1586 }
1587
1588 if (ret)
1589 __set_bit(i, score->scorebits);
1590 score->rule = i;
1591out:
1592 return ret;
1593}
1594
YOSHIFUJI Hideaki/吉藤英明c0b8da12015-07-13 23:28:10 +09001595static int __ipv6_dev_get_saddr(struct net *net,
1596 struct ipv6_saddr_dst *dst,
YOSHIFUJI Hideaki/吉藤英明c0b8da12015-07-13 23:28:10 +09001597 struct inet6_dev *idev,
1598 struct ipv6_saddr_score *scores,
1599 int hiscore_idx)
YOSHIFUJI Hideaki/吉藤英明9131f3d2015-07-10 16:58:31 +09001600{
YOSHIFUJI Hideaki/吉藤英明c0b8da12015-07-13 23:28:10 +09001601 struct ipv6_saddr_score *score = &scores[1 - hiscore_idx], *hiscore = &scores[hiscore_idx];
YOSHIFUJI Hideaki/吉藤英明9131f3d2015-07-10 16:58:31 +09001602
Eric Dumazetf59c0312017-10-07 19:30:27 -07001603 list_for_each_entry_rcu(score->ifa, &idev->addr_list, if_list) {
YOSHIFUJI Hideaki/吉藤英明9131f3d2015-07-10 16:58:31 +09001604 int i;
1605
1606 /*
1607 * - Tentative Address (RFC2462 section 5.4)
1608 * - A tentative address is not considered
1609 * "assigned to an interface" in the traditional
1610 * sense, unless it is also flagged as optimistic.
1611 * - Candidate Source Address (section 4)
1612 * - In any case, anycast addresses, multicast
1613 * addresses, and the unspecified address MUST
1614 * NOT be included in a candidate set.
1615 */
1616 if ((score->ifa->flags & IFA_F_TENTATIVE) &&
1617 (!(score->ifa->flags & IFA_F_OPTIMISTIC)))
1618 continue;
1619
1620 score->addr_type = __ipv6_addr_type(&score->ifa->addr);
1621
1622 if (unlikely(score->addr_type == IPV6_ADDR_ANY ||
1623 score->addr_type & IPV6_ADDR_MULTICAST)) {
1624 net_dbg_ratelimited("ADDRCONF: unspecified / multicast address assigned as unicast address on %s",
1625 idev->dev->name);
1626 continue;
1627 }
1628
1629 score->rule = -1;
1630 bitmap_zero(score->scorebits, IPV6_SADDR_RULE_MAX);
1631
1632 for (i = 0; i < IPV6_SADDR_RULE_MAX; i++) {
1633 int minihiscore, miniscore;
1634
1635 minihiscore = ipv6_get_saddr_eval(net, hiscore, dst, i);
1636 miniscore = ipv6_get_saddr_eval(net, score, dst, i);
1637
1638 if (minihiscore > miniscore) {
1639 if (i == IPV6_SADDR_RULE_SCOPE &&
1640 score->scopedist > 0) {
1641 /*
1642 * special case:
1643 * each remaining entry
1644 * has too small (not enough)
1645 * scope, because ifa entries
1646 * are sorted by their scope
1647 * values.
1648 */
1649 goto out;
1650 }
1651 break;
1652 } else if (minihiscore < miniscore) {
YOSHIFUJI Hideaki/吉藤英明9131f3d2015-07-10 16:58:31 +09001653 swap(hiscore, score);
YOSHIFUJI Hideaki/吉藤英明c0b8da12015-07-13 23:28:10 +09001654 hiscore_idx = 1 - hiscore_idx;
YOSHIFUJI Hideaki/吉藤英明9131f3d2015-07-10 16:58:31 +09001655
1656 /* restore our iterator */
1657 score->ifa = hiscore->ifa;
1658
1659 break;
1660 }
1661 }
1662 }
1663out:
YOSHIFUJI Hideaki/吉藤英明c0b8da12015-07-13 23:28:10 +09001664 return hiscore_idx;
YOSHIFUJI Hideaki/吉藤英明9131f3d2015-07-10 16:58:31 +09001665}
1666
David Ahernafbac6012016-06-16 16:24:26 -07001667static int ipv6_get_saddr_master(struct net *net,
1668 const struct net_device *dst_dev,
1669 const struct net_device *master,
1670 struct ipv6_saddr_dst *dst,
1671 struct ipv6_saddr_score *scores,
1672 int hiscore_idx)
1673{
1674 struct inet6_dev *idev;
1675
1676 idev = __in6_dev_get(dst_dev);
1677 if (idev)
1678 hiscore_idx = __ipv6_dev_get_saddr(net, dst, idev,
1679 scores, hiscore_idx);
1680
1681 idev = __in6_dev_get(master);
1682 if (idev)
1683 hiscore_idx = __ipv6_dev_get_saddr(net, dst, idev,
1684 scores, hiscore_idx);
1685
1686 return hiscore_idx;
1687}
1688
Patrick McHardyb3f644f2012-08-26 19:14:14 +02001689int ipv6_dev_get_saddr(struct net *net, const struct net_device *dst_dev,
YOSHIFUJI Hideaki9acd9f32008-04-10 15:42:10 +09001690 const struct in6_addr *daddr, unsigned int prefs,
YOSHIFUJI Hideaki7cbca672008-03-25 09:37:42 +09001691 struct in6_addr *saddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001692{
YOSHIFUJI Hideaki/吉藤英明c0b8da12015-07-13 23:28:10 +09001693 struct ipv6_saddr_score scores[2], *hiscore;
YOSHIFUJI Hideakia9b05722008-03-02 10:48:21 +09001694 struct ipv6_saddr_dst dst;
YOSHIFUJI Hideaki/吉藤英明9131f3d2015-07-10 16:58:31 +09001695 struct inet6_dev *idev;
YOSHIFUJI Hideaki072047e42005-11-08 09:38:30 -08001696 struct net_device *dev;
YOSHIFUJI Hideakia9b05722008-03-02 10:48:21 +09001697 int dst_type;
YOSHIFUJI Hideaki/吉藤英明9131f3d2015-07-10 16:58:31 +09001698 bool use_oif_addr = false;
YOSHIFUJI Hideaki/吉藤英明c0b8da12015-07-13 23:28:10 +09001699 int hiscore_idx = 0;
Eric Dumazetcc429c82017-10-07 19:30:28 -07001700 int ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001701
YOSHIFUJI Hideakia9b05722008-03-02 10:48:21 +09001702 dst_type = __ipv6_addr_type(daddr);
1703 dst.addr = daddr;
1704 dst.ifindex = dst_dev ? dst_dev->ifindex : 0;
1705 dst.scope = __ipv6_addr_src_scope(dst_type);
Benjamin Thery3de23252008-05-28 14:51:24 +02001706 dst.label = ipv6_addr_label(net, daddr, dst_type, dst.ifindex);
YOSHIFUJI Hideaki7cbca672008-03-25 09:37:42 +09001707 dst.prefs = prefs;
YOSHIFUJI Hideakia9b05722008-03-02 10:48:21 +09001708
YOSHIFUJI Hideaki/吉藤英明c0b8da12015-07-13 23:28:10 +09001709 scores[hiscore_idx].rule = -1;
1710 scores[hiscore_idx].ifa = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001711
YOSHIFUJI Hideaki8814c4b2006-09-22 14:44:24 -07001712 rcu_read_lock();
YOSHIFUJI Hideaki072047e42005-11-08 09:38:30 -08001713
YOSHIFUJI Hideaki/吉藤英明9131f3d2015-07-10 16:58:31 +09001714 /* Candidate Source Address (section 4)
1715 * - multicast and link-local destination address,
1716 * the set of candidate source address MUST only
1717 * include addresses assigned to interfaces
1718 * belonging to the same link as the outgoing
1719 * interface.
1720 * (- For site-local destination addresses, the
1721 * set of candidate source addresses MUST only
1722 * include addresses assigned to interfaces
1723 * belonging to the same site as the outgoing
1724 * interface.)
Erik Kline3985e8a2015-07-22 16:38:25 +09001725 * - "It is RECOMMENDED that the candidate source addresses
1726 * be the set of unicast addresses assigned to the
1727 * interface that will be used to send to the destination
1728 * (the 'outgoing' interface)." (RFC 6724)
YOSHIFUJI Hideaki/吉藤英明9131f3d2015-07-10 16:58:31 +09001729 */
1730 if (dst_dev) {
Erik Kline3985e8a2015-07-22 16:38:25 +09001731 idev = __in6_dev_get(dst_dev);
YOSHIFUJI Hideaki/吉藤英明9131f3d2015-07-10 16:58:31 +09001732 if ((dst_type & IPV6_ADDR_MULTICAST) ||
Erik Kline3985e8a2015-07-22 16:38:25 +09001733 dst.scope <= IPV6_ADDR_SCOPE_LINKLOCAL ||
1734 (idev && idev->cnf.use_oif_addrs_only)) {
YOSHIFUJI Hideaki/吉藤英明9131f3d2015-07-10 16:58:31 +09001735 use_oif_addr = true;
YOSHIFUJI Hideaki072047e42005-11-08 09:38:30 -08001736 }
YOSHIFUJI Hideaki/吉藤英明9131f3d2015-07-10 16:58:31 +09001737 }
1738
1739 if (use_oif_addr) {
YOSHIFUJI Hideaki/吉藤英明c0b8da12015-07-13 23:28:10 +09001740 if (idev)
YOSHIFUJI Hideakic15df302015-07-16 16:51:30 +09001741 hiscore_idx = __ipv6_dev_get_saddr(net, &dst, idev, scores, hiscore_idx);
YOSHIFUJI Hideaki/吉藤英明9131f3d2015-07-10 16:58:31 +09001742 } else {
David Ahernafbac6012016-06-16 16:24:26 -07001743 const struct net_device *master;
1744 int master_idx = 0;
1745
1746 /* if dst_dev exists and is enslaved to an L3 device, then
1747 * prefer addresses from dst_dev and then the master over
1748 * any other enslaved devices in the L3 domain.
1749 */
1750 master = l3mdev_master_dev_rcu(dst_dev);
1751 if (master) {
1752 master_idx = master->ifindex;
1753
1754 hiscore_idx = ipv6_get_saddr_master(net, dst_dev,
1755 master, &dst,
1756 scores, hiscore_idx);
1757
1758 if (scores[hiscore_idx].ifa)
1759 goto out;
1760 }
1761
YOSHIFUJI Hideaki/吉藤英明9131f3d2015-07-10 16:58:31 +09001762 for_each_netdev_rcu(net, dev) {
David Ahernafbac6012016-06-16 16:24:26 -07001763 /* only consider addresses on devices in the
1764 * same L3 domain
1765 */
1766 if (l3mdev_master_ifindex_rcu(dev) != master_idx)
1767 continue;
YOSHIFUJI Hideaki/吉藤英明9131f3d2015-07-10 16:58:31 +09001768 idev = __in6_dev_get(dev);
1769 if (!idev)
1770 continue;
YOSHIFUJI Hideakic15df302015-07-16 16:51:30 +09001771 hiscore_idx = __ipv6_dev_get_saddr(net, &dst, idev, scores, hiscore_idx);
YOSHIFUJI Hideaki/吉藤英明9131f3d2015-07-10 16:58:31 +09001772 }
YOSHIFUJI Hideaki072047e42005-11-08 09:38:30 -08001773 }
David Ahernafbac6012016-06-16 16:24:26 -07001774
1775out:
YOSHIFUJI Hideaki/吉藤英明c0b8da12015-07-13 23:28:10 +09001776 hiscore = &scores[hiscore_idx];
YOSHIFUJI Hideakia9b05722008-03-02 10:48:21 +09001777 if (!hiscore->ifa)
Eric Dumazetcc429c82017-10-07 19:30:28 -07001778 ret = -EADDRNOTAVAIL;
1779 else
1780 *saddr = hiscore->ifa->addr;
YOSHIFUJI Hideaki1ab14572007-02-09 23:24:49 +09001781
Eric Dumazetcc429c82017-10-07 19:30:28 -07001782 rcu_read_unlock();
1783 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001784}
YOSHIFUJI Hideaki5e5f3f02008-03-03 21:44:34 +09001785EXPORT_SYMBOL(ipv6_dev_get_saddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001786
Amerigo Wang89657792013-06-29 21:30:49 +08001787int __ipv6_get_lladdr(struct inet6_dev *idev, struct in6_addr *addr,
Jiri Pirko479840f2013-12-06 09:45:21 +01001788 u32 banned_flags)
Hannes Frederic Sowab7b1bfc2013-06-23 18:39:01 +02001789{
1790 struct inet6_ifaddr *ifp;
1791 int err = -EADDRNOTAVAIL;
1792
Hannes Frederic Sowa602582c2014-01-19 21:58:19 +01001793 list_for_each_entry_reverse(ifp, &idev->addr_list, if_list) {
1794 if (ifp->scope > IFA_LINK)
1795 break;
Hannes Frederic Sowab7b1bfc2013-06-23 18:39:01 +02001796 if (ifp->scope == IFA_LINK &&
1797 !(ifp->flags & banned_flags)) {
1798 *addr = ifp->addr;
1799 err = 0;
1800 break;
1801 }
1802 }
1803 return err;
1804}
1805
Neil Horman95c385b2007-04-25 17:08:10 -07001806int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr,
Jiri Pirko479840f2013-12-06 09:45:21 +01001807 u32 banned_flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001808{
1809 struct inet6_dev *idev;
1810 int err = -EADDRNOTAVAIL;
1811
YOSHIFUJI Hideaki8814c4b2006-09-22 14:44:24 -07001812 rcu_read_lock();
Stephen Hemmingere21e8462010-03-20 16:09:01 -07001813 idev = __in6_dev_get(dev);
1814 if (idev) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001815 read_lock_bh(&idev->lock);
Hannes Frederic Sowab7b1bfc2013-06-23 18:39:01 +02001816 err = __ipv6_get_lladdr(idev, addr, banned_flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817 read_unlock_bh(&idev->lock);
1818 }
YOSHIFUJI Hideaki8814c4b2006-09-22 14:44:24 -07001819 rcu_read_unlock();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001820 return err;
1821}
1822
Eric Dumazetd9bf82c2017-10-07 19:30:24 -07001823static int ipv6_count_addresses(const struct inet6_dev *idev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001824{
Eric Dumazetd9bf82c2017-10-07 19:30:24 -07001825 const struct inet6_ifaddr *ifp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001826 int cnt = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001827
Eric Dumazetd9bf82c2017-10-07 19:30:24 -07001828 rcu_read_lock();
1829 list_for_each_entry_rcu(ifp, &idev->addr_list, if_list)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001830 cnt++;
Eric Dumazetd9bf82c2017-10-07 19:30:24 -07001831 rcu_read_unlock();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001832 return cnt;
1833}
1834
Eric Dumazetb71d1d42011-04-22 04:53:02 +00001835int ipv6_chk_addr(struct net *net, const struct in6_addr *addr,
Florian Westphal2a7851b2013-05-17 03:56:10 +00001836 const struct net_device *dev, int strict)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001837{
David Ahern232378e2018-03-13 08:29:37 -07001838 return ipv6_chk_addr_and_flags(net, addr, dev, !dev,
1839 strict, IFA_F_TENTATIVE);
Erik Klinec58da4c2015-02-04 20:01:23 +09001840}
1841EXPORT_SYMBOL(ipv6_chk_addr);
1842
David Ahern1893ff22018-03-13 08:29:38 -07001843/* device argument is used to find the L3 domain of interest. If
1844 * skip_dev_check is set, then the ifp device is not checked against
1845 * the passed in dev argument. So the 2 cases for addresses checks are:
1846 * 1. does the address exist in the L3 domain that dev is part of
1847 * (skip_dev_check = true), or
1848 *
1849 * 2. does the address exist on the specific device
1850 * (skip_dev_check = false)
1851 */
Erik Klinec58da4c2015-02-04 20:01:23 +09001852int ipv6_chk_addr_and_flags(struct net *net, const struct in6_addr *addr,
David Ahern232378e2018-03-13 08:29:37 -07001853 const struct net_device *dev, bool skip_dev_check,
1854 int strict, u32 banned_flags)
Erik Klinec58da4c2015-02-04 20:01:23 +09001855{
Eric Dumazet3f27fb22017-10-23 16:17:47 -07001856 unsigned int hash = inet6_addr_hash(net, addr);
David Ahern1893ff22018-03-13 08:29:38 -07001857 const struct net_device *l3mdev;
Stephen Hemmingereedf0422010-05-17 22:27:12 -07001858 struct inet6_ifaddr *ifp;
Erik Klinec58da4c2015-02-04 20:01:23 +09001859 u32 ifp_flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001860
Eric Dumazet480318a2017-10-23 16:17:48 -07001861 rcu_read_lock();
David Ahern232378e2018-03-13 08:29:37 -07001862
David Ahern1893ff22018-03-13 08:29:38 -07001863 l3mdev = l3mdev_master_dev_rcu(dev);
David Ahern232378e2018-03-13 08:29:37 -07001864 if (skip_dev_check)
1865 dev = NULL;
1866
Sasha Levinb67bfe02013-02-27 17:06:00 -08001867 hlist_for_each_entry_rcu(ifp, &inet6_addr_lst[hash], addr_lst) {
YOSHIFUJI Hideaki878628f2008-03-26 03:57:35 +09001868 if (!net_eq(dev_net(ifp->idev->dev), net))
Daniel Lezcanobfeade02008-01-10 22:43:18 -08001869 continue;
David Ahern1893ff22018-03-13 08:29:38 -07001870
1871 if (l3mdev_master_dev_rcu(ifp->idev->dev) != l3mdev)
1872 continue;
1873
Erik Klinec58da4c2015-02-04 20:01:23 +09001874 /* Decouple optimistic from tentative for evaluation here.
1875 * Ban optimistic addresses explicitly, when required.
1876 */
1877 ifp_flags = (ifp->flags&IFA_F_OPTIMISTIC)
1878 ? (ifp->flags&~IFA_F_TENTATIVE)
1879 : ifp->flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001880 if (ipv6_addr_equal(&ifp->addr, addr) &&
Erik Klinec58da4c2015-02-04 20:01:23 +09001881 !(ifp_flags&banned_flags) &&
Ian Morris63159f22015-03-29 14:00:04 +01001882 (!dev || ifp->idev->dev == dev ||
Stephen Hemmingereedf0422010-05-17 22:27:12 -07001883 !(ifp->scope&(IFA_LINK|IFA_HOST) || strict))) {
Eric Dumazet480318a2017-10-23 16:17:48 -07001884 rcu_read_unlock();
Stephen Hemmingereedf0422010-05-17 22:27:12 -07001885 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001886 }
1887 }
stephen hemminger5c578aed2010-03-17 20:31:11 +00001888
Eric Dumazet480318a2017-10-23 16:17:48 -07001889 rcu_read_unlock();
Stephen Hemmingereedf0422010-05-17 22:27:12 -07001890 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001891}
Erik Klinec58da4c2015-02-04 20:01:23 +09001892EXPORT_SYMBOL(ipv6_chk_addr_and_flags);
YOSHIFUJI Hideaki71590392007-02-22 22:05:40 +09001893
Linus Torvalds1da177e2005-04-16 15:20:36 -07001894
Catalin\(ux\) M. BOIE7df37ff2013-09-23 23:04:19 +03001895/* Compares an address/prefix_len with addresses on device @dev.
1896 * If one is found it returns true.
1897 */
1898bool ipv6_chk_custom_prefix(const struct in6_addr *addr,
1899 const unsigned int prefix_len, struct net_device *dev)
1900{
Eric Dumazet47e26942017-10-07 19:30:25 -07001901 const struct inet6_ifaddr *ifa;
1902 const struct inet6_dev *idev;
Catalin\(ux\) M. BOIE7df37ff2013-09-23 23:04:19 +03001903 bool ret = false;
1904
1905 rcu_read_lock();
1906 idev = __in6_dev_get(dev);
1907 if (idev) {
Eric Dumazet47e26942017-10-07 19:30:25 -07001908 list_for_each_entry_rcu(ifa, &idev->addr_list, if_list) {
Catalin\(ux\) M. BOIE7df37ff2013-09-23 23:04:19 +03001909 ret = ipv6_prefix_equal(addr, &ifa->addr, prefix_len);
1910 if (ret)
1911 break;
1912 }
Catalin\(ux\) M. BOIE7df37ff2013-09-23 23:04:19 +03001913 }
1914 rcu_read_unlock();
1915
1916 return ret;
1917}
1918EXPORT_SYMBOL(ipv6_chk_custom_prefix);
1919
Eric Dumazetb71d1d42011-04-22 04:53:02 +00001920int ipv6_chk_prefix(const struct in6_addr *addr, struct net_device *dev)
YOSHIFUJI Hideaki52eeeb82008-03-15 22:54:23 -04001921{
Eric Dumazet24ba3332017-10-07 19:30:26 -07001922 const struct inet6_ifaddr *ifa;
1923 const struct inet6_dev *idev;
YOSHIFUJI Hideaki52eeeb82008-03-15 22:54:23 -04001924 int onlink;
1925
1926 onlink = 0;
1927 rcu_read_lock();
1928 idev = __in6_dev_get(dev);
1929 if (idev) {
Eric Dumazet24ba3332017-10-07 19:30:26 -07001930 list_for_each_entry_rcu(ifa, &idev->addr_list, if_list) {
YOSHIFUJI Hideaki52eeeb82008-03-15 22:54:23 -04001931 onlink = ipv6_prefix_equal(addr, &ifa->addr,
1932 ifa->prefix_len);
1933 if (onlink)
1934 break;
1935 }
YOSHIFUJI Hideaki52eeeb82008-03-15 22:54:23 -04001936 }
1937 rcu_read_unlock();
1938 return onlink;
1939}
YOSHIFUJI Hideaki52eeeb82008-03-15 22:54:23 -04001940EXPORT_SYMBOL(ipv6_chk_prefix);
1941
YOSHIFUJI Hideaki9acd9f32008-04-10 15:42:10 +09001942struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net, const struct in6_addr *addr,
Daniel Lezcano1cab3da2008-01-10 22:44:09 -08001943 struct net_device *dev, int strict)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001944{
Eric Dumazet3f27fb22017-10-23 16:17:47 -07001945 unsigned int hash = inet6_addr_hash(net, addr);
David S. Millerb79d1d52010-03-25 21:39:21 -07001946 struct inet6_ifaddr *ifp, *result = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001947
Eric Dumazet24f226d2017-10-23 16:17:49 -07001948 rcu_read_lock();
1949 hlist_for_each_entry_rcu(ifp, &inet6_addr_lst[hash], addr_lst) {
YOSHIFUJI Hideaki878628f2008-03-26 03:57:35 +09001950 if (!net_eq(dev_net(ifp->idev->dev), net))
Daniel Lezcano1cab3da2008-01-10 22:44:09 -08001951 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001952 if (ipv6_addr_equal(&ifp->addr, addr)) {
Ian Morris63159f22015-03-29 14:00:04 +01001953 if (!dev || ifp->idev->dev == dev ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07001954 !(ifp->scope&(IFA_LINK|IFA_HOST) || strict)) {
David S. Millerb79d1d52010-03-25 21:39:21 -07001955 result = ifp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001956 in6_ifa_hold(ifp);
1957 break;
1958 }
1959 }
1960 }
Eric Dumazet24f226d2017-10-23 16:17:49 -07001961 rcu_read_unlock();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001962
David S. Millerb79d1d52010-03-25 21:39:21 -07001963 return result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001964}
1965
Linus Torvalds1da177e2005-04-16 15:20:36 -07001966/* Gets referenced address, destroys ifaddr */
1967
Brian Haleycc411d02009-09-09 14:41:32 +00001968static void addrconf_dad_stop(struct inet6_ifaddr *ifp, int dad_failed)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001969{
Lubomir Rintel3d171f32016-01-08 13:47:23 +01001970 if (dad_failed)
1971 ifp->flags |= IFA_F_DADFAILED;
1972
Sabrina Dubrocaec8add22017-06-29 16:56:54 +02001973 if (ifp->flags&IFA_F_TEMPORARY) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001974 struct inet6_ifaddr *ifpub;
1975 spin_lock_bh(&ifp->lock);
1976 ifpub = ifp->ifpub;
1977 if (ifpub) {
1978 in6_ifa_hold(ifpub);
1979 spin_unlock_bh(&ifp->lock);
Eric Dumazetfffcefe2017-11-06 14:13:29 -08001980 ipv6_create_tempaddr(ifpub, ifp, true);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001981 in6_ifa_put(ifpub);
1982 } else {
1983 spin_unlock_bh(&ifp->lock);
1984 }
1985 ipv6_del_addr(ifp);
Sabrina Dubrocaec8add22017-06-29 16:56:54 +02001986 } else if (ifp->flags&IFA_F_PERMANENT || !dad_failed) {
1987 spin_lock_bh(&ifp->lock);
1988 addrconf_del_dad_work(ifp);
1989 ifp->flags |= IFA_F_TENTATIVE;
Sabrina Dubrocaf1c02cf2018-02-28 16:40:08 +01001990 if (dad_failed)
1991 ifp->flags &= ~IFA_F_OPTIMISTIC;
Sabrina Dubrocaec8add22017-06-29 16:56:54 +02001992 spin_unlock_bh(&ifp->lock);
1993 if (dad_failed)
1994 ipv6_ifa_notify(0, ifp);
1995 in6_ifa_put(ifp);
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01001996 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001997 ipv6_del_addr(ifp);
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01001998 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001999}
2000
Herbert Xuf2344a12010-05-18 15:55:27 -07002001static int addrconf_dad_end(struct inet6_ifaddr *ifp)
2002{
2003 int err = -ENOENT;
2004
Hannes Frederic Sowa8e8e6762015-03-23 23:36:03 +01002005 spin_lock_bh(&ifp->lock);
Herbert Xuf2344a12010-05-18 15:55:27 -07002006 if (ifp->state == INET6_IFADDR_STATE_DAD) {
2007 ifp->state = INET6_IFADDR_STATE_POSTDAD;
2008 err = 0;
2009 }
Hannes Frederic Sowa8e8e6762015-03-23 23:36:03 +01002010 spin_unlock_bh(&ifp->lock);
Herbert Xuf2344a12010-05-18 15:55:27 -07002011
2012 return err;
2013}
2014
Vishwanath Paida13c592017-10-30 19:38:52 -04002015void addrconf_dad_failure(struct sk_buff *skb, struct inet6_ifaddr *ifp)
YOSHIFUJI Hideaki3c21edb2005-12-21 22:57:24 +09002016{
YOSHIFUJI Hideaki1b34be72008-06-28 14:18:38 +09002017 struct inet6_dev *idev = ifp->idev;
Hannes Frederic Sowa1855b7c2015-03-23 23:36:05 +01002018 struct net *net = dev_net(ifp->idev->dev);
Brian Haley9bdd8d42009-03-18 18:22:48 -07002019
Ursula Braun853dc2e2010-10-24 23:06:43 +00002020 if (addrconf_dad_end(ifp)) {
2021 in6_ifa_put(ifp);
Herbert Xuf2344a12010-05-18 15:55:27 -07002022 return;
Ursula Braun853dc2e2010-10-24 23:06:43 +00002023 }
Herbert Xuf2344a12010-05-18 15:55:27 -07002024
Vishwanath Paida13c592017-10-30 19:38:52 -04002025 net_info_ratelimited("%s: IPv6 duplicate address %pI6c used by %pM detected!\n",
2026 ifp->idev->dev->name, &ifp->addr, eth_hdr(skb)->h_source);
Brian Haley9bdd8d42009-03-18 18:22:48 -07002027
Hannes Frederic Sowa5f40ef72015-03-23 23:36:04 +01002028 spin_lock_bh(&ifp->lock);
YOSHIFUJI Hideaki1b34be72008-06-28 14:18:38 +09002029
Hannes Frederic Sowa5f40ef72015-03-23 23:36:04 +01002030 if (ifp->flags & IFA_F_STABLE_PRIVACY) {
Hannes Frederic Sowa5f40ef72015-03-23 23:36:04 +01002031 struct in6_addr new_addr;
2032 struct inet6_ifaddr *ifp2;
Hannes Frederic Sowa5f40ef72015-03-23 23:36:04 +01002033 int retries = ifp->stable_privacy_retry + 1;
David Aherne6464b82018-05-27 08:09:53 -07002034 struct ifa6_config cfg = {
2035 .pfx = &new_addr,
2036 .plen = ifp->prefix_len,
2037 .ifa_flags = ifp->flags,
2038 .valid_lft = ifp->valid_lft,
2039 .preferred_lft = ifp->prefered_lft,
2040 .scope = ifp->scope,
2041 };
Hannes Frederic Sowa5f40ef72015-03-23 23:36:04 +01002042
Hannes Frederic Sowa1855b7c2015-03-23 23:36:05 +01002043 if (retries > net->ipv6.sysctl.idgen_retries) {
Hannes Frederic Sowa5f40ef72015-03-23 23:36:04 +01002044 net_info_ratelimited("%s: privacy stable address generation failed because of DAD conflicts!\n",
2045 ifp->idev->dev->name);
2046 goto errdad;
2047 }
2048
2049 new_addr = ifp->addr;
2050 if (ipv6_generate_stable_address(&new_addr, retries,
2051 idev))
2052 goto errdad;
2053
Hannes Frederic Sowa5f40ef72015-03-23 23:36:04 +01002054 spin_unlock_bh(&ifp->lock);
2055
2056 if (idev->cnf.max_addresses &&
2057 ipv6_count_addresses(idev) >=
2058 idev->cnf.max_addresses)
2059 goto lock_errdad;
2060
2061 net_info_ratelimited("%s: generating new stable privacy address because of DAD conflict\n",
2062 ifp->idev->dev->name);
2063
David Aherne6464b82018-05-27 08:09:53 -07002064 ifp2 = ipv6_add_addr(idev, &cfg, false, NULL);
Hannes Frederic Sowa5f40ef72015-03-23 23:36:04 +01002065 if (IS_ERR(ifp2))
2066 goto lock_errdad;
2067
2068 spin_lock_bh(&ifp2->lock);
2069 ifp2->stable_privacy_retry = retries;
2070 ifp2->state = INET6_IFADDR_STATE_PREDAD;
2071 spin_unlock_bh(&ifp2->lock);
2072
Hannes Frederic Sowa1855b7c2015-03-23 23:36:05 +01002073 addrconf_mod_dad_work(ifp2, net->ipv6.sysctl.idgen_delay);
Hannes Frederic Sowa5f40ef72015-03-23 23:36:04 +01002074 in6_ifa_put(ifp2);
2075lock_errdad:
2076 spin_lock_bh(&ifp->lock);
YOSHIFUJI Hideaki1b34be72008-06-28 14:18:38 +09002077 }
2078
Hannes Frederic Sowa5f40ef72015-03-23 23:36:04 +01002079errdad:
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01002080 /* transition from _POSTDAD to _ERRDAD */
2081 ifp->state = INET6_IFADDR_STATE_ERRDAD;
Hannes Frederic Sowa8e8e6762015-03-23 23:36:03 +01002082 spin_unlock_bh(&ifp->lock);
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01002083
2084 addrconf_mod_dad_work(ifp, 0);
Wei Yongjun751eb6b2016-09-05 16:06:31 +08002085 in6_ifa_put(ifp);
YOSHIFUJI Hideaki3c21edb2005-12-21 22:57:24 +09002086}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002087
Sabrina Dubrocaa9ed4a22014-09-02 10:29:29 +02002088/* Join to solicited addr multicast group.
2089 * caller must hold RTNL */
Eric Dumazetb71d1d42011-04-22 04:53:02 +00002090void addrconf_join_solict(struct net_device *dev, const struct in6_addr *addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002091{
2092 struct in6_addr maddr;
2093
2094 if (dev->flags&(IFF_LOOPBACK|IFF_NOARP))
2095 return;
2096
2097 addrconf_addr_solict_mult(addr, &maddr);
2098 ipv6_dev_mc_inc(dev, &maddr);
2099}
2100
Sabrina Dubrocaa9ed4a22014-09-02 10:29:29 +02002101/* caller must hold RTNL */
Eric Dumazetb71d1d42011-04-22 04:53:02 +00002102void addrconf_leave_solict(struct inet6_dev *idev, const struct in6_addr *addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002103{
2104 struct in6_addr maddr;
2105
2106 if (idev->dev->flags&(IFF_LOOPBACK|IFF_NOARP))
2107 return;
2108
2109 addrconf_addr_solict_mult(addr, &maddr);
2110 __ipv6_dev_mc_dec(idev, &maddr);
2111}
2112
Sabrina Dubrocaa9ed4a22014-09-02 10:29:29 +02002113/* caller must hold RTNL */
Arnaldo Carvalho de Melo20380732005-08-16 02:18:02 -03002114static void addrconf_join_anycast(struct inet6_ifaddr *ifp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002115{
2116 struct in6_addr addr;
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01002117
Hannes Frederic Sowa88ad3142014-01-06 17:53:14 +01002118 if (ifp->prefix_len >= 127) /* RFC 6164 */
Bjørn Mork2bda8a02011-07-05 23:04:13 +00002119 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002120 ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len);
2121 if (ipv6_addr_any(&addr))
2122 return;
WANG Cong013b4d92014-09-11 15:35:11 -07002123 __ipv6_dev_ac_inc(ifp->idev, &addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002124}
2125
Sabrina Dubrocaa9ed4a22014-09-02 10:29:29 +02002126/* caller must hold RTNL */
Arnaldo Carvalho de Melo20380732005-08-16 02:18:02 -03002127static void addrconf_leave_anycast(struct inet6_ifaddr *ifp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002128{
2129 struct in6_addr addr;
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01002130
Hannes Frederic Sowa88ad3142014-01-06 17:53:14 +01002131 if (ifp->prefix_len >= 127) /* RFC 6164 */
YOSHIFUJI Hideaki32019e62011-07-24 11:44:34 +00002132 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002133 ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len);
2134 if (ipv6_addr_any(&addr))
2135 return;
2136 __ipv6_dev_ac_dec(ifp->idev, &addr);
2137}
2138
Alexander Aring8a7a4b42017-03-12 10:19:36 +02002139static int addrconf_ifid_6lowpan(u8 *eui, struct net_device *dev)
alex.bluesman.smirnov@gmail.com06a4c1c2012-05-10 03:25:52 +00002140{
Alexander Aring8a7a4b42017-03-12 10:19:36 +02002141 switch (dev->addr_len) {
2142 case ETH_ALEN:
Luiz Augusto von Dentz9dae2e02017-03-12 10:19:38 +02002143 memcpy(eui, dev->dev_addr, 3);
2144 eui[3] = 0xFF;
2145 eui[4] = 0xFE;
2146 memcpy(eui + 5, dev->dev_addr + 3, 3);
2147 break;
Alexander Aring8a7a4b42017-03-12 10:19:36 +02002148 case EUI64_ADDR_LEN:
2149 memcpy(eui, dev->dev_addr, EUI64_ADDR_LEN);
2150 eui[0] ^= 2;
2151 break;
2152 default:
alex.bluesman.smirnov@gmail.com06a4c1c2012-05-10 03:25:52 +00002153 return -1;
Alexander Aring8a7a4b42017-03-12 10:19:36 +02002154 }
2155
alex.bluesman.smirnov@gmail.com06a4c1c2012-05-10 03:25:52 +00002156 return 0;
2157}
2158
YOSHIFUJI Hideaki / 吉藤英明cb6bf352013-03-25 08:26:24 +00002159static int addrconf_ifid_ieee1394(u8 *eui, struct net_device *dev)
2160{
2161 union fwnet_hwaddr *ha;
2162
2163 if (dev->addr_len != FWNET_ALEN)
2164 return -1;
2165
2166 ha = (union fwnet_hwaddr *)dev->dev_addr;
2167
2168 memcpy(eui, &ha->uc.uniq_id, sizeof(ha->uc.uniq_id));
2169 eui[0] ^= 2;
2170 return 0;
2171}
2172
YOSHIFUJI Hideaki073a8e02006-03-20 16:54:49 -08002173static int addrconf_ifid_arcnet(u8 *eui, struct net_device *dev)
2174{
2175 /* XXX: inherit EUI-64 from other interface -- yoshfuji */
2176 if (dev->addr_len != ARCNET_ALEN)
2177 return -1;
2178 memset(eui, 0, 7);
Eldad Zack8e5e8f32012-04-01 07:49:08 +00002179 eui[7] = *(u8 *)dev->dev_addr;
YOSHIFUJI Hideaki073a8e02006-03-20 16:54:49 -08002180 return 0;
2181}
2182
2183static int addrconf_ifid_infiniband(u8 *eui, struct net_device *dev)
2184{
2185 if (dev->addr_len != INFINIBAND_ALEN)
2186 return -1;
2187 memcpy(eui, dev->dev_addr + 12, 8);
2188 eui[0] |= 2;
2189 return 0;
2190}
2191
stephen hemmingerc61393e2010-10-04 20:17:53 +00002192static int __ipv6_isatap_ifid(u8 *eui, __be32 addr)
YOSHIFUJI Hideakidfd982b2008-04-10 15:42:09 +09002193{
Sascha Hlusiak9af28512009-05-19 12:56:51 +00002194 if (addr == 0)
2195 return -1;
YOSHIFUJI Hideakidfd982b2008-04-10 15:42:09 +09002196 eui[0] = (ipv4_is_zeronet(addr) || ipv4_is_private_10(addr) ||
2197 ipv4_is_loopback(addr) || ipv4_is_linklocal_169(addr) ||
2198 ipv4_is_private_172(addr) || ipv4_is_test_192(addr) ||
2199 ipv4_is_anycast_6to4(addr) || ipv4_is_private_192(addr) ||
2200 ipv4_is_test_198(addr) || ipv4_is_multicast(addr) ||
2201 ipv4_is_lbcast(addr)) ? 0x00 : 0x02;
2202 eui[1] = 0;
2203 eui[2] = 0x5E;
2204 eui[3] = 0xFE;
2205 memcpy(eui + 4, &addr, 4);
2206 return 0;
2207}
YOSHIFUJI Hideakidfd982b2008-04-10 15:42:09 +09002208
2209static int addrconf_ifid_sit(u8 *eui, struct net_device *dev)
2210{
2211 if (dev->priv_flags & IFF_ISATAP)
2212 return __ipv6_isatap_ifid(eui, *(__be32 *)dev->dev_addr);
2213 return -1;
2214}
2215
stephen hemmingeraee80b52011-06-08 10:44:30 +00002216static int addrconf_ifid_gre(u8 *eui, struct net_device *dev)
2217{
2218 return __ipv6_isatap_ifid(eui, *(__be32 *)dev->dev_addr);
2219}
2220
Nicolas Dichtele8377352013-08-20 12:16:06 +02002221static int addrconf_ifid_ip6tnl(u8 *eui, struct net_device *dev)
2222{
2223 memcpy(eui, dev->perm_addr, 3);
2224 memcpy(eui + 5, dev->perm_addr + 3, 3);
2225 eui[3] = 0xFF;
2226 eui[4] = 0xFE;
2227 eui[0] ^= 2;
2228 return 0;
2229}
2230
Linus Torvalds1da177e2005-04-16 15:20:36 -07002231static int ipv6_generate_eui64(u8 *eui, struct net_device *dev)
2232{
2233 switch (dev->type) {
2234 case ARPHRD_ETHER:
2235 case ARPHRD_FDDI:
YOSHIFUJI Hideaki073a8e02006-03-20 16:54:49 -08002236 return addrconf_ifid_eui48(eui, dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002237 case ARPHRD_ARCNET:
YOSHIFUJI Hideaki073a8e02006-03-20 16:54:49 -08002238 return addrconf_ifid_arcnet(eui, dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002239 case ARPHRD_INFINIBAND:
YOSHIFUJI Hideaki073a8e02006-03-20 16:54:49 -08002240 return addrconf_ifid_infiniband(eui, dev);
Fred L. Templinc7dc89c2007-11-29 22:11:40 +11002241 case ARPHRD_SIT:
YOSHIFUJI Hideakidfd982b2008-04-10 15:42:09 +09002242 return addrconf_ifid_sit(eui, dev);
stephen hemmingeraee80b52011-06-08 10:44:30 +00002243 case ARPHRD_IPGRE:
Felix Jia45ce0fd2017-01-26 16:59:18 +13002244 case ARPHRD_TUNNEL:
stephen hemmingeraee80b52011-06-08 10:44:30 +00002245 return addrconf_ifid_gre(eui, dev);
Jukka Rissanene74bccb82013-12-11 17:05:36 +02002246 case ARPHRD_6LOWPAN:
Alexander Aring8a7a4b42017-03-12 10:19:36 +02002247 return addrconf_ifid_6lowpan(eui, dev);
YOSHIFUJI Hideaki / 吉藤英明cb6bf352013-03-25 08:26:24 +00002248 case ARPHRD_IEEE1394:
2249 return addrconf_ifid_ieee1394(eui, dev);
Nicolas Dichtele8377352013-08-20 12:16:06 +02002250 case ARPHRD_TUNNEL6:
Felix Jia45ce0fd2017-01-26 16:59:18 +13002251 case ARPHRD_IP6GRE:
Nicolas Dichtele8377352013-08-20 12:16:06 +02002252 return addrconf_ifid_ip6tnl(eui, dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002253 }
2254 return -1;
2255}
2256
2257static int ipv6_inherit_eui64(u8 *eui, struct inet6_dev *idev)
2258{
2259 int err = -1;
2260 struct inet6_ifaddr *ifp;
2261
2262 read_lock_bh(&idev->lock);
Hannes Frederic Sowa602582c2014-01-19 21:58:19 +01002263 list_for_each_entry_reverse(ifp, &idev->addr_list, if_list) {
2264 if (ifp->scope > IFA_LINK)
2265 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002266 if (ifp->scope == IFA_LINK && !(ifp->flags&IFA_F_TENTATIVE)) {
2267 memcpy(eui, ifp->addr.s6_addr+8, 8);
2268 err = 0;
2269 break;
2270 }
2271 }
2272 read_unlock_bh(&idev->lock);
2273 return err;
2274}
2275
Linus Torvalds1da177e2005-04-16 15:20:36 -07002276/* (re)generation of randomized interface identifier (RFC 3041 3.2, 3.5) */
Jiri Bohac9d6280d2016-10-13 18:50:02 +02002277static void ipv6_regen_rndid(struct inet6_dev *idev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002278{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002279regen:
YOSHIFUJI Hideaki955189e2006-03-20 16:54:09 -08002280 get_random_bytes(idev->rndid, sizeof(idev->rndid));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002281 idev->rndid[0] &= ~0x02;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002282
2283 /*
2284 * <draft-ietf-ipngwg-temp-addresses-v2-00.txt>:
2285 * check if generated address is not inappropriate
2286 *
2287 * - Reserved subnet anycast (RFC 2526)
2288 * 11111101 11....11 1xxxxxxx
Fred L. Templinc7dc89c2007-11-29 22:11:40 +11002289 * - ISATAP (RFC4214) 6.1
Linus Torvalds1da177e2005-04-16 15:20:36 -07002290 * 00-00-5E-FE-xx-xx-xx-xx
2291 * - value 0
2292 * - XXX: already assigned to an address on the device
2293 */
YOSHIFUJI Hideaki1ab14572007-02-09 23:24:49 +09002294 if (idev->rndid[0] == 0xfd &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07002295 (idev->rndid[1]&idev->rndid[2]&idev->rndid[3]&idev->rndid[4]&idev->rndid[5]&idev->rndid[6]) == 0xff &&
2296 (idev->rndid[7]&0x80))
2297 goto regen;
2298 if ((idev->rndid[0]|idev->rndid[1]) == 0) {
2299 if (idev->rndid[2] == 0x5e && idev->rndid[3] == 0xfe)
2300 goto regen;
2301 if ((idev->rndid[2]|idev->rndid[3]|idev->rndid[4]|idev->rndid[5]|idev->rndid[6]|idev->rndid[7]) == 0x00)
2302 goto regen;
2303 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002304}
2305
Jiri Bohac9d6280d2016-10-13 18:50:02 +02002306static void ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr)
Eldad Zack8e5e8f32012-04-01 07:49:08 +00002307{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002308 if (tmpaddr && memcmp(idev->rndid, &tmpaddr->s6_addr[8], 8) == 0)
Jiri Bohac9d6280d2016-10-13 18:50:02 +02002309 ipv6_regen_rndid(idev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002310}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002311
2312/*
2313 * Add prefix route.
2314 */
2315
2316static void
2317addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev,
David Ahernacb54e32018-04-17 17:33:22 -07002318 unsigned long expires, u32 flags, gfp_t gfp_flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002319{
Thomas Graf86872cb2006-08-22 00:01:08 -07002320 struct fib6_config cfg = {
David Ahernca254492015-10-12 11:47:10 -07002321 .fc_table = l3mdev_fib_table(dev) ? : RT6_TABLE_PREFIX,
Thomas Graf86872cb2006-08-22 00:01:08 -07002322 .fc_metric = IP6_RT_PRIO_ADDRCONF,
2323 .fc_ifindex = dev->ifindex,
2324 .fc_expires = expires,
2325 .fc_dst_len = plen,
2326 .fc_flags = RTF_UP | flags,
YOSHIFUJI Hideakic346dca2008-03-25 21:47:49 +09002327 .fc_nlinfo.nl_net = dev_net(dev),
Stephen Hemmingerf410a1f2008-08-23 05:16:46 -07002328 .fc_protocol = RTPROT_KERNEL,
David Aherne8478e82018-04-17 17:33:13 -07002329 .fc_type = RTN_UNICAST,
Thomas Graf86872cb2006-08-22 00:01:08 -07002330 };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002331
Alexey Dobriyan4e3fd7a2011-11-21 03:39:03 +00002332 cfg.fc_dst = *pfx;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002333
2334 /* Prevent useless cloning on PtP SIT.
2335 This thing is done here expecting that the whole
2336 class of non-broadcast devices need not cloning.
2337 */
Amerigo Wang07a93622012-10-29 16:23:10 +00002338#if IS_ENABLED(CONFIG_IPV6_SIT)
Thomas Graf86872cb2006-08-22 00:01:08 -07002339 if (dev->type == ARPHRD_SIT && (dev->flags & IFF_POINTOPOINT))
2340 cfg.fc_flags |= RTF_NONEXTHOP;
Joerg Roedel0be669b2006-10-10 14:49:53 -07002341#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002342
David Ahernacb54e32018-04-17 17:33:22 -07002343 ip6_route_add(&cfg, gfp_flags, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002344}
2345
Andreas Hofmeister14ef37b2011-10-26 03:24:29 +00002346
David Ahern8d1c8022018-04-17 17:33:26 -07002347static struct fib6_info *addrconf_get_prefix_route(const struct in6_addr *pfx,
Andreas Hofmeister14ef37b2011-10-26 03:24:29 +00002348 int plen,
2349 const struct net_device *dev,
2350 u32 flags, u32 noflags)
2351{
2352 struct fib6_node *fn;
David Ahern8d1c8022018-04-17 17:33:26 -07002353 struct fib6_info *rt = NULL;
Andreas Hofmeister14ef37b2011-10-26 03:24:29 +00002354 struct fib6_table *table;
David Ahernca254492015-10-12 11:47:10 -07002355 u32 tb_id = l3mdev_fib_table(dev) ? : RT6_TABLE_PREFIX;
Andreas Hofmeister14ef37b2011-10-26 03:24:29 +00002356
David Ahernca254492015-10-12 11:47:10 -07002357 table = fib6_get_table(dev_net(dev), tb_id);
Ian Morris63159f22015-03-29 14:00:04 +01002358 if (!table)
Andreas Hofmeister14ef37b2011-10-26 03:24:29 +00002359 return NULL;
2360
Wei Wang66f5d6c2017-10-06 12:06:10 -07002361 rcu_read_lock();
Wei Wang38fbeee2017-10-06 12:06:02 -07002362 fn = fib6_locate(&table->tb6_root, pfx, plen, NULL, 0, true);
Andreas Hofmeister14ef37b2011-10-26 03:24:29 +00002363 if (!fn)
2364 goto out;
Martin KaFai Lau1f56a01f2015-04-28 13:03:03 -07002365
Wei Wang66f5d6c2017-10-06 12:06:10 -07002366 for_each_fib6_node_rt_rcu(fn) {
David Ahern5e670d82018-04-17 17:33:14 -07002367 if (rt->fib6_nh.nh_dev->ifindex != dev->ifindex)
Andreas Hofmeister14ef37b2011-10-26 03:24:29 +00002368 continue;
David Ahern93c2fb22018-04-18 15:38:59 -07002369 if ((rt->fib6_flags & flags) != flags)
Andreas Hofmeister14ef37b2011-10-26 03:24:29 +00002370 continue;
David Ahern93c2fb22018-04-18 15:38:59 -07002371 if ((rt->fib6_flags & noflags) != 0)
Andreas Hofmeister14ef37b2011-10-26 03:24:29 +00002372 continue;
David Ahern93531c62018-04-17 17:33:25 -07002373 fib6_info_hold(rt);
Andreas Hofmeister14ef37b2011-10-26 03:24:29 +00002374 break;
2375 }
2376out:
Wei Wang66f5d6c2017-10-06 12:06:10 -07002377 rcu_read_unlock();
Andreas Hofmeister14ef37b2011-10-26 03:24:29 +00002378 return rt;
2379}
2380
2381
Linus Torvalds1da177e2005-04-16 15:20:36 -07002382/* Create "default" multicast route to the interface */
2383
2384static void addrconf_add_mroute(struct net_device *dev)
2385{
Thomas Graf86872cb2006-08-22 00:01:08 -07002386 struct fib6_config cfg = {
David Ahernca254492015-10-12 11:47:10 -07002387 .fc_table = l3mdev_fib_table(dev) ? : RT6_TABLE_LOCAL,
Thomas Graf86872cb2006-08-22 00:01:08 -07002388 .fc_metric = IP6_RT_PRIO_ADDRCONF,
2389 .fc_ifindex = dev->ifindex,
2390 .fc_dst_len = 8,
2391 .fc_flags = RTF_UP,
David Aherne8478e82018-04-17 17:33:13 -07002392 .fc_type = RTN_UNICAST,
YOSHIFUJI Hideakic346dca2008-03-25 21:47:49 +09002393 .fc_nlinfo.nl_net = dev_net(dev),
Thomas Graf86872cb2006-08-22 00:01:08 -07002394 };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002395
Thomas Graf86872cb2006-08-22 00:01:08 -07002396 ipv6_addr_set(&cfg.fc_dst, htonl(0xFF000000), 0, 0, 0);
2397
David Ahernacb54e32018-04-17 17:33:22 -07002398 ip6_route_add(&cfg, GFP_ATOMIC, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002399}
2400
Linus Torvalds1da177e2005-04-16 15:20:36 -07002401static struct inet6_dev *addrconf_add_dev(struct net_device *dev)
2402{
2403 struct inet6_dev *idev;
2404
2405 ASSERT_RTNL();
2406
Stephen Hemmingere21e8462010-03-20 16:09:01 -07002407 idev = ipv6_find_idev(dev);
2408 if (!idev)
Brian Haley64e724f2010-07-20 10:34:30 +00002409 return ERR_PTR(-ENOBUFS);
2410
2411 if (idev->cnf.disable_ipv6)
2412 return ERR_PTR(-EACCES);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002413
2414 /* Add default multicast route */
David Ahernba46ee42016-06-13 13:44:18 -07002415 if (!(dev->flags & IFF_LOOPBACK) && !netif_is_l3_master(dev))
Li Wei4af04ab2011-12-06 21:23:45 +00002416 addrconf_add_mroute(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002417
Linus Torvalds1da177e2005-04-16 15:20:36 -07002418 return idev;
2419}
2420
Jiri Pirko53bd6742013-12-06 09:45:22 +01002421static void manage_tempaddrs(struct inet6_dev *idev,
2422 struct inet6_ifaddr *ifp,
2423 __u32 valid_lft, __u32 prefered_lft,
2424 bool create, unsigned long now)
2425{
2426 u32 flags;
2427 struct inet6_ifaddr *ift;
2428
2429 read_lock_bh(&idev->lock);
2430 /* update all temporary addresses in the list */
2431 list_for_each_entry(ift, &idev->tempaddr_list, tmp_list) {
2432 int age, max_valid, max_prefered;
2433
2434 if (ifp != ift->ifpub)
2435 continue;
2436
2437 /* RFC 4941 section 3.3:
2438 * If a received option will extend the lifetime of a public
2439 * address, the lifetimes of temporary addresses should
2440 * be extended, subject to the overall constraint that no
2441 * temporary addresses should ever remain "valid" or "preferred"
2442 * for a time longer than (TEMP_VALID_LIFETIME) or
2443 * (TEMP_PREFERRED_LIFETIME - DESYNC_FACTOR), respectively.
2444 */
2445 age = (now - ift->cstamp) / HZ;
2446 max_valid = idev->cnf.temp_valid_lft - age;
2447 if (max_valid < 0)
2448 max_valid = 0;
2449
2450 max_prefered = idev->cnf.temp_prefered_lft -
Jiri Bohac76506a92016-10-13 18:52:15 +02002451 idev->desync_factor - age;
Jiri Pirko53bd6742013-12-06 09:45:22 +01002452 if (max_prefered < 0)
2453 max_prefered = 0;
2454
2455 if (valid_lft > max_valid)
2456 valid_lft = max_valid;
2457
2458 if (prefered_lft > max_prefered)
2459 prefered_lft = max_prefered;
2460
2461 spin_lock(&ift->lock);
2462 flags = ift->flags;
2463 ift->valid_lft = valid_lft;
2464 ift->prefered_lft = prefered_lft;
2465 ift->tstamp = now;
2466 if (prefered_lft > 0)
2467 ift->flags &= ~IFA_F_DEPRECATED;
2468
2469 spin_unlock(&ift->lock);
2470 if (!(flags&IFA_F_TENTATIVE))
2471 ipv6_ifa_notify(0, ift);
2472 }
2473
2474 if ((create || list_empty(&idev->tempaddr_list)) &&
2475 idev->cnf.use_tempaddr > 0) {
2476 /* When a new public address is created as described
2477 * in [ADDRCONF], also create a new temporary address.
2478 * Also create a temporary address if it's enabled but
2479 * no temporary address currently exists.
2480 */
2481 read_unlock_bh(&idev->lock);
Eric Dumazetfffcefe2017-11-06 14:13:29 -08002482 ipv6_create_tempaddr(ifp, NULL, false);
Jiri Pirko53bd6742013-12-06 09:45:22 +01002483 } else {
2484 read_unlock_bh(&idev->lock);
2485 }
2486}
2487
Bjørn Morkcc9da6c2015-12-16 16:44:38 +01002488static bool is_addr_mode_generate_stable(struct inet6_dev *idev)
2489{
Felix Jiad35a00b2017-01-26 16:59:17 +13002490 return idev->cnf.addr_gen_mode == IN6_ADDR_GEN_MODE_STABLE_PRIVACY ||
2491 idev->cnf.addr_gen_mode == IN6_ADDR_GEN_MODE_RANDOM;
Bjørn Morkcc9da6c2015-12-16 16:44:38 +01002492}
2493
Alexander Aringcc84b3c2016-06-15 21:20:24 +02002494int addrconf_prefix_rcv_add_addr(struct net *net, struct net_device *dev,
2495 const struct prefix_info *pinfo,
2496 struct inet6_dev *in6_dev,
2497 const struct in6_addr *addr, int addr_type,
2498 u32 addr_flags, bool sllao, bool tokenized,
2499 __u32 valid_lft, u32 prefered_lft)
Alexander Aring4f672232016-06-15 21:20:22 +02002500{
2501 struct inet6_ifaddr *ifp = ipv6_get_ifaddr(net, addr, dev, 1);
2502 int create = 0, update_lft = 0;
2503
2504 if (!ifp && valid_lft) {
2505 int max_addresses = in6_dev->cnf.max_addresses;
David Aherne6464b82018-05-27 08:09:53 -07002506 struct ifa6_config cfg = {
2507 .pfx = addr,
2508 .plen = pinfo->prefix_len,
2509 .ifa_flags = addr_flags,
2510 .valid_lft = valid_lft,
2511 .preferred_lft = prefered_lft,
2512 .scope = addr_type & IPV6_ADDR_SCOPE_MASK,
2513 };
Alexander Aring4f672232016-06-15 21:20:22 +02002514
2515#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
Matteo Croce35e015e2017-09-12 17:46:37 +02002516 if ((net->ipv6.devconf_all->optimistic_dad ||
2517 in6_dev->cnf.optimistic_dad) &&
Alexander Aring4f672232016-06-15 21:20:22 +02002518 !net->ipv6.devconf_all->forwarding && sllao)
David Aherne6464b82018-05-27 08:09:53 -07002519 cfg.ifa_flags |= IFA_F_OPTIMISTIC;
Alexander Aring4f672232016-06-15 21:20:22 +02002520#endif
2521
2522 /* Do not allow to create too much of autoconfigured
2523 * addresses; this would be too easy way to crash kernel.
2524 */
2525 if (!max_addresses ||
2526 ipv6_count_addresses(in6_dev) < max_addresses)
David Aherne6464b82018-05-27 08:09:53 -07002527 ifp = ipv6_add_addr(in6_dev, &cfg, false, NULL);
Alexander Aring4f672232016-06-15 21:20:22 +02002528
2529 if (IS_ERR_OR_NULL(ifp))
2530 return -1;
2531
Alexander Aring4f672232016-06-15 21:20:22 +02002532 create = 1;
2533 spin_lock_bh(&ifp->lock);
2534 ifp->flags |= IFA_F_MANAGETEMPADDR;
2535 ifp->cstamp = jiffies;
2536 ifp->tokenized = tokenized;
2537 spin_unlock_bh(&ifp->lock);
2538 addrconf_dad_start(ifp);
2539 }
2540
2541 if (ifp) {
2542 u32 flags;
2543 unsigned long now;
2544 u32 stored_lft;
2545
2546 /* update lifetime (RFC2462 5.5.3 e) */
2547 spin_lock_bh(&ifp->lock);
2548 now = jiffies;
2549 if (ifp->valid_lft > (now - ifp->tstamp) / HZ)
2550 stored_lft = ifp->valid_lft - (now - ifp->tstamp) / HZ;
2551 else
2552 stored_lft = 0;
Lorenzo Bianconif85f94b2018-04-16 17:52:59 +02002553 if (!create && stored_lft) {
Alexander Aring4f672232016-06-15 21:20:22 +02002554 const u32 minimum_lft = min_t(u32,
2555 stored_lft, MIN_VALID_LIFETIME);
2556 valid_lft = max(valid_lft, minimum_lft);
2557
2558 /* RFC4862 Section 5.5.3e:
2559 * "Note that the preferred lifetime of the
2560 * corresponding address is always reset to
2561 * the Preferred Lifetime in the received
2562 * Prefix Information option, regardless of
2563 * whether the valid lifetime is also reset or
2564 * ignored."
2565 *
2566 * So we should always update prefered_lft here.
2567 */
2568 update_lft = 1;
2569 }
2570
2571 if (update_lft) {
2572 ifp->valid_lft = valid_lft;
2573 ifp->prefered_lft = prefered_lft;
2574 ifp->tstamp = now;
2575 flags = ifp->flags;
2576 ifp->flags &= ~IFA_F_DEPRECATED;
2577 spin_unlock_bh(&ifp->lock);
2578
2579 if (!(flags&IFA_F_TENTATIVE))
2580 ipv6_ifa_notify(0, ifp);
2581 } else
2582 spin_unlock_bh(&ifp->lock);
2583
2584 manage_tempaddrs(in6_dev, ifp, valid_lft, prefered_lft,
2585 create, now);
2586
2587 in6_ifa_put(ifp);
2588 addrconf_verify();
2589 }
2590
2591 return 0;
2592}
Alexander Aringcc84b3c2016-06-15 21:20:24 +02002593EXPORT_SYMBOL_GPL(addrconf_prefix_rcv_add_addr);
Alexander Aring4f672232016-06-15 21:20:22 +02002594
Neil Hormane6bff992012-01-04 10:49:15 +00002595void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002596{
2597 struct prefix_info *pinfo;
2598 __u32 valid_lft;
2599 __u32 prefered_lft;
Alexander Aring4f672232016-06-15 21:20:22 +02002600 int addr_type, err;
Hannes Frederic Sowa64236f32015-03-23 23:36:02 +01002601 u32 addr_flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002602 struct inet6_dev *in6_dev;
Brian Haley56d417b2009-06-01 03:07:33 -07002603 struct net *net = dev_net(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002604
2605 pinfo = (struct prefix_info *) opt;
YOSHIFUJI Hideaki1ab14572007-02-09 23:24:49 +09002606
Linus Torvalds1da177e2005-04-16 15:20:36 -07002607 if (len < sizeof(struct prefix_info)) {
Joe Perchese32ac252018-03-26 08:35:01 -07002608 netdev_dbg(dev, "addrconf: prefix option too short\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002609 return;
2610 }
YOSHIFUJI Hideaki1ab14572007-02-09 23:24:49 +09002611
Linus Torvalds1da177e2005-04-16 15:20:36 -07002612 /*
2613 * Validation checks ([ADDRCONF], page 19)
2614 */
2615
2616 addr_type = ipv6_addr_type(&pinfo->prefix);
2617
2618 if (addr_type & (IPV6_ADDR_MULTICAST|IPV6_ADDR_LINKLOCAL))
2619 return;
2620
2621 valid_lft = ntohl(pinfo->valid);
2622 prefered_lft = ntohl(pinfo->prefered);
2623
2624 if (prefered_lft > valid_lft) {
Joe Perchese87cc472012-05-13 21:56:26 +00002625 net_warn_ratelimited("addrconf: prefix option has invalid lifetime\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002626 return;
2627 }
2628
2629 in6_dev = in6_dev_get(dev);
2630
Ian Morris63159f22015-03-29 14:00:04 +01002631 if (!in6_dev) {
Joe Perchese87cc472012-05-13 21:56:26 +00002632 net_dbg_ratelimited("addrconf: device %s not configured\n",
2633 dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002634 return;
2635 }
2636
2637 /*
2638 * Two things going on here:
2639 * 1) Add routes for on-link prefixes
2640 * 2) Configure prefixes with the auto flag set
2641 */
2642
YOSHIFUJI Hideaki4bed72e2008-05-27 17:37:49 +09002643 if (pinfo->onlink) {
David Ahern8d1c8022018-04-17 17:33:26 -07002644 struct fib6_info *rt;
YOSHIFUJI Hideaki4bed72e2008-05-27 17:37:49 +09002645 unsigned long rt_expires;
2646
YOSHIFUJI Hideaki6f704992008-05-19 16:56:11 -07002647 /* Avoid arithmetic overflow. Really, we could
2648 * save rt_expires in seconds, likely valid_lft,
2649 * but it would require division in fib gc, that it
2650 * not good.
2651 */
YOSHIFUJI Hideaki4bed72e2008-05-27 17:37:49 +09002652 if (HZ > USER_HZ)
2653 rt_expires = addrconf_timeout_fixup(valid_lft, HZ);
2654 else
2655 rt_expires = addrconf_timeout_fixup(valid_lft, USER_HZ);
YOSHIFUJI Hideaki3dd4bc62005-12-19 14:02:45 -08002656
YOSHIFUJI Hideaki4bed72e2008-05-27 17:37:49 +09002657 if (addrconf_finite_timeout(rt_expires))
2658 rt_expires *= HZ;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002659
Andreas Hofmeister14ef37b2011-10-26 03:24:29 +00002660 rt = addrconf_get_prefix_route(&pinfo->prefix,
2661 pinfo->prefix_len,
2662 dev,
2663 RTF_ADDRCONF | RTF_PREFIX_RT,
2664 RTF_GATEWAY | RTF_DEFAULT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002665
Andreas Hofmeister14ef37b2011-10-26 03:24:29 +00002666 if (rt) {
YOSHIFUJI Hideaki6f704992008-05-19 16:56:11 -07002667 /* Autoconf prefix route */
2668 if (valid_lft == 0) {
David Ahernafb1d4b52018-04-17 17:33:11 -07002669 ip6_del_rt(net, rt);
YOSHIFUJI Hideaki6f704992008-05-19 16:56:11 -07002670 rt = NULL;
YOSHIFUJI Hideaki4bed72e2008-05-27 17:37:49 +09002671 } else if (addrconf_finite_timeout(rt_expires)) {
YOSHIFUJI Hideaki6f704992008-05-19 16:56:11 -07002672 /* not infinity */
David Ahern14895682018-04-17 17:33:17 -07002673 fib6_set_expires(rt, jiffies + rt_expires);
YOSHIFUJI Hideaki6f704992008-05-19 16:56:11 -07002674 } else {
David Ahern14895682018-04-17 17:33:17 -07002675 fib6_clean_expires(rt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002676 }
2677 } else if (valid_lft) {
YOSHIFUJI Hideaki6f704992008-05-19 16:56:11 -07002678 clock_t expires = 0;
YOSHIFUJI Hideaki4bed72e2008-05-27 17:37:49 +09002679 int flags = RTF_ADDRCONF | RTF_PREFIX_RT;
2680 if (addrconf_finite_timeout(rt_expires)) {
YOSHIFUJI Hideaki6f704992008-05-19 16:56:11 -07002681 /* not infinity */
2682 flags |= RTF_EXPIRES;
2683 expires = jiffies_to_clock_t(rt_expires);
2684 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002685 addrconf_prefix_route(&pinfo->prefix, pinfo->prefix_len,
David Ahernacb54e32018-04-17 17:33:22 -07002686 dev, expires, flags, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002687 }
David Ahern93531c62018-04-17 17:33:25 -07002688 fib6_info_release(rt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002689 }
2690
2691 /* Try to figure out our local address for this prefix */
2692
2693 if (pinfo->autoconf && in6_dev->cnf.autoconf) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002694 struct in6_addr addr;
Alexander Aringf997c552016-06-15 21:20:23 +02002695 bool tokenized = false, dev_addr_generated = false;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002696
2697 if (pinfo->prefix_len == 64) {
2698 memcpy(&addr, &pinfo->prefix, 8);
Daniel Borkmannf53adae2013-04-08 04:01:30 +00002699
2700 if (!ipv6_addr_any(&in6_dev->token)) {
2701 read_lock_bh(&in6_dev->lock);
2702 memcpy(addr.s6_addr + 8,
2703 in6_dev->token.s6_addr + 8, 8);
2704 read_unlock_bh(&in6_dev->lock);
Daniel Borkmann617fe292013-04-09 03:47:16 +00002705 tokenized = true;
Bjørn Morkcc9da6c2015-12-16 16:44:38 +01002706 } else if (is_addr_mode_generate_stable(in6_dev) &&
Hannes Frederic Sowa622c81d52015-03-23 23:36:01 +01002707 !ipv6_generate_stable_address(&addr, 0,
2708 in6_dev)) {
Hannes Frederic Sowa64236f32015-03-23 23:36:02 +01002709 addr_flags |= IFA_F_STABLE_PRIVACY;
Hannes Frederic Sowa622c81d52015-03-23 23:36:01 +01002710 goto ok;
Daniel Borkmannf53adae2013-04-08 04:01:30 +00002711 } else if (ipv6_generate_eui64(addr.s6_addr + 8, dev) &&
2712 ipv6_inherit_eui64(addr.s6_addr + 8, in6_dev)) {
Alexander Aring4f672232016-06-15 21:20:22 +02002713 goto put;
Alexander Aringf997c552016-06-15 21:20:23 +02002714 } else {
2715 dev_addr_generated = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002716 }
2717 goto ok;
2718 }
Joe Perchese87cc472012-05-13 21:56:26 +00002719 net_dbg_ratelimited("IPv6 addrconf: prefix with wrong length %d\n",
2720 pinfo->prefix_len);
Alexander Aring4f672232016-06-15 21:20:22 +02002721 goto put;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002722
2723ok:
Alexander Aring4f672232016-06-15 21:20:22 +02002724 err = addrconf_prefix_rcv_add_addr(net, dev, pinfo, in6_dev,
2725 &addr, addr_type,
2726 addr_flags, sllao,
2727 tokenized, valid_lft,
2728 prefered_lft);
2729 if (err)
2730 goto put;
Alexander Aringf997c552016-06-15 21:20:23 +02002731
2732 /* Ignore error case here because previous prefix add addr was
2733 * successful which will be notified.
2734 */
2735 ndisc_ops_prefix_rcv_add_addr(net, dev, pinfo, in6_dev, &addr,
2736 addr_type, addr_flags, sllao,
2737 tokenized, valid_lft,
2738 prefered_lft,
2739 dev_addr_generated);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002740 }
2741 inet6_prefix_notify(RTM_NEWPREFIX, in6_dev, pinfo);
Alexander Aring4f672232016-06-15 21:20:22 +02002742put:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002743 in6_dev_put(in6_dev);
2744}
2745
2746/*
2747 * Set destination address.
2748 * Special case for SIT interfaces where we create a new "virtual"
2749 * device.
2750 */
Daniel Lezcanoaf284932008-03-05 10:46:57 -08002751int addrconf_set_dstaddr(struct net *net, void __user *arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002752{
2753 struct in6_ifreq ireq;
2754 struct net_device *dev;
2755 int err = -EINVAL;
2756
2757 rtnl_lock();
2758
2759 err = -EFAULT;
2760 if (copy_from_user(&ireq, arg, sizeof(struct in6_ifreq)))
2761 goto err_exit;
2762
Daniel Lezcanoaf284932008-03-05 10:46:57 -08002763 dev = __dev_get_by_index(net, ireq.ifr6_ifindex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002764
2765 err = -ENODEV;
Ian Morris63159f22015-03-29 14:00:04 +01002766 if (!dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002767 goto err_exit;
2768
Amerigo Wang07a93622012-10-29 16:23:10 +00002769#if IS_ENABLED(CONFIG_IPV6_SIT)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002770 if (dev->type == ARPHRD_SIT) {
Stephen Hemminger5bc3eb72008-11-19 21:52:05 -08002771 const struct net_device_ops *ops = dev->netdev_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002772 struct ifreq ifr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002773 struct ip_tunnel_parm p;
2774
2775 err = -EADDRNOTAVAIL;
2776 if (!(ipv6_addr_type(&ireq.ifr6_addr) & IPV6_ADDR_COMPATv4))
2777 goto err_exit;
2778
2779 memset(&p, 0, sizeof(p));
2780 p.iph.daddr = ireq.ifr6_addr.s6_addr32[3];
2781 p.iph.saddr = 0;
2782 p.iph.version = 4;
2783 p.iph.ihl = 5;
2784 p.iph.protocol = IPPROTO_IPV6;
2785 p.iph.ttl = 64;
Stephen Hemmingerd20b3102008-01-21 00:48:43 -08002786 ifr.ifr_ifru.ifru_data = (__force void __user *)&p;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002787
Stephen Hemminger5bc3eb72008-11-19 21:52:05 -08002788 if (ops->ndo_do_ioctl) {
2789 mm_segment_t oldfs = get_fs();
2790
2791 set_fs(KERNEL_DS);
2792 err = ops->ndo_do_ioctl(dev, &ifr, SIOCADDTUNNEL);
2793 set_fs(oldfs);
2794 } else
2795 err = -EOPNOTSUPP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002796
2797 if (err == 0) {
2798 err = -ENOBUFS;
Daniel Lezcanoaf284932008-03-05 10:46:57 -08002799 dev = __dev_get_by_name(net, p.name);
2800 if (!dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002801 goto err_exit;
2802 err = dev_open(dev);
2803 }
2804 }
Joerg Roedel0be669b2006-10-10 14:49:53 -07002805#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002806
2807err_exit:
2808 rtnl_unlock();
2809 return err;
2810}
2811
Madhu Challa93a714d2015-02-25 09:58:35 -08002812static int ipv6_mc_config(struct sock *sk, bool join,
2813 const struct in6_addr *addr, int ifindex)
2814{
2815 int ret;
2816
2817 ASSERT_RTNL();
2818
2819 lock_sock(sk);
2820 if (join)
Marcelo Ricardo Leitner54ff9ef2015-03-18 14:50:43 -03002821 ret = ipv6_sock_mc_join(sk, ifindex, addr);
Madhu Challa93a714d2015-02-25 09:58:35 -08002822 else
Marcelo Ricardo Leitner54ff9ef2015-03-18 14:50:43 -03002823 ret = ipv6_sock_mc_drop(sk, ifindex, addr);
Madhu Challa93a714d2015-02-25 09:58:35 -08002824 release_sock(sk);
2825
2826 return ret;
2827}
2828
Linus Torvalds1da177e2005-04-16 15:20:36 -07002829/*
2830 * Manual configuration of address on an interface
2831 */
Jiri Pirko479840f2013-12-06 09:45:21 +01002832static int inet6_addr_add(struct net *net, int ifindex,
David Ahern19b15182018-05-27 08:09:54 -07002833 struct ifa6_config *cfg,
David Ahernde95e042017-10-18 09:56:54 -07002834 struct netlink_ext_ack *extack)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002835{
2836 struct inet6_ifaddr *ifp;
2837 struct inet6_dev *idev;
2838 struct net_device *dev;
Madhu Challa93a714d2015-02-25 09:58:35 -08002839 unsigned long timeout;
2840 clock_t expires;
YOSHIFUJI Hideaki6f704992008-05-19 16:56:11 -07002841 u32 flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002842
2843 ASSERT_RTNL();
YOSHIFUJI Hideaki1ab14572007-02-09 23:24:49 +09002844
David Ahern19b15182018-05-27 08:09:54 -07002845 if (cfg->plen > 128)
Thomas Graf24ef0da2008-05-28 16:54:22 +02002846 return -EINVAL;
2847
Noriaki TAKAMIYA0778769d2006-07-28 18:12:10 +09002848 /* check the lifetime */
David Ahern19b15182018-05-27 08:09:54 -07002849 if (!cfg->valid_lft || cfg->preferred_lft > cfg->valid_lft)
Noriaki TAKAMIYA0778769d2006-07-28 18:12:10 +09002850 return -EINVAL;
2851
David Ahern19b15182018-05-27 08:09:54 -07002852 if (cfg->ifa_flags & IFA_F_MANAGETEMPADDR && cfg->plen != 64)
Jiri Pirko53bd6742013-12-06 09:45:22 +01002853 return -EINVAL;
2854
Daniel Lezcanoaf284932008-03-05 10:46:57 -08002855 dev = __dev_get_by_index(net, ifindex);
2856 if (!dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002857 return -ENODEV;
YOSHIFUJI Hideaki1ab14572007-02-09 23:24:49 +09002858
Brian Haley64e724f2010-07-20 10:34:30 +00002859 idev = addrconf_add_dev(dev);
2860 if (IS_ERR(idev))
2861 return PTR_ERR(idev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002862
David Ahern19b15182018-05-27 08:09:54 -07002863 if (cfg->ifa_flags & IFA_F_MCAUTOJOIN) {
Madhu Challa93a714d2015-02-25 09:58:35 -08002864 int ret = ipv6_mc_config(net->ipv6.mc_autojoin_sk,
David Ahern19b15182018-05-27 08:09:54 -07002865 true, cfg->pfx, ifindex);
Madhu Challa93a714d2015-02-25 09:58:35 -08002866
2867 if (ret < 0)
2868 return ret;
2869 }
2870
David Ahern19b15182018-05-27 08:09:54 -07002871 cfg->scope = ipv6_addr_scope(cfg->pfx);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002872
David Ahern19b15182018-05-27 08:09:54 -07002873 timeout = addrconf_timeout_fixup(cfg->valid_lft, HZ);
YOSHIFUJI Hideaki4bed72e2008-05-27 17:37:49 +09002874 if (addrconf_finite_timeout(timeout)) {
2875 expires = jiffies_to_clock_t(timeout * HZ);
David Ahern19b15182018-05-27 08:09:54 -07002876 cfg->valid_lft = timeout;
YOSHIFUJI Hideaki6f704992008-05-19 16:56:11 -07002877 flags = RTF_EXPIRES;
YOSHIFUJI Hideaki4bed72e2008-05-27 17:37:49 +09002878 } else {
2879 expires = 0;
2880 flags = 0;
David Ahern19b15182018-05-27 08:09:54 -07002881 cfg->ifa_flags |= IFA_F_PERMANENT;
YOSHIFUJI Hideaki6f704992008-05-19 16:56:11 -07002882 }
Noriaki TAKAMIYA0778769d2006-07-28 18:12:10 +09002883
David Ahern19b15182018-05-27 08:09:54 -07002884 timeout = addrconf_timeout_fixup(cfg->preferred_lft, HZ);
YOSHIFUJI Hideaki4bed72e2008-05-27 17:37:49 +09002885 if (addrconf_finite_timeout(timeout)) {
2886 if (timeout == 0)
David Ahern19b15182018-05-27 08:09:54 -07002887 cfg->ifa_flags |= IFA_F_DEPRECATED;
2888 cfg->preferred_lft = timeout;
YOSHIFUJI Hideaki4bed72e2008-05-27 17:37:49 +09002889 }
Noriaki TAKAMIYA0778769d2006-07-28 18:12:10 +09002890
David Ahern19b15182018-05-27 08:09:54 -07002891 ifp = ipv6_add_addr(idev, cfg, true, extack);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002892 if (!IS_ERR(ifp)) {
David Ahern19b15182018-05-27 08:09:54 -07002893 if (!(cfg->ifa_flags & IFA_F_NOPREFIXROUTE)) {
Thomas Haller761aac72014-01-15 15:36:58 +01002894 addrconf_prefix_route(&ifp->addr, ifp->prefix_len, dev,
David Ahernacb54e32018-04-17 17:33:22 -07002895 expires, flags, GFP_KERNEL);
Thomas Haller761aac72014-01-15 15:36:58 +01002896 }
2897
Lorenzo Bianconia2d481b2018-04-17 11:54:39 +02002898 /* Send a netlink notification if DAD is enabled and
2899 * optimistic flag is not set
2900 */
2901 if (!(ifp->flags & (IFA_F_OPTIMISTIC | IFA_F_NODAD)))
2902 ipv6_ifa_notify(0, ifp);
Neil Horman95c385b2007-04-25 17:08:10 -07002903 /*
2904 * Note that section 3.1 of RFC 4429 indicates
2905 * that the Optimistic flag should not be set for
2906 * manually configured addresses
2907 */
David S. Millercf22f9a2012-04-14 21:37:40 -04002908 addrconf_dad_start(ifp);
David Ahern19b15182018-05-27 08:09:54 -07002909 if (cfg->ifa_flags & IFA_F_MANAGETEMPADDR)
2910 manage_tempaddrs(idev, ifp, cfg->valid_lft,
2911 cfg->preferred_lft, true, jiffies);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002912 in6_ifa_put(ifp);
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01002913 addrconf_verify_rtnl();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002914 return 0;
David Ahern19b15182018-05-27 08:09:54 -07002915 } else if (cfg->ifa_flags & IFA_F_MCAUTOJOIN) {
2916 ipv6_mc_config(net->ipv6.mc_autojoin_sk, false,
2917 cfg->pfx, ifindex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002918 }
2919
2920 return PTR_ERR(ifp);
2921}
2922
Heiner Kallweit6046d5b2014-04-20 21:29:36 +02002923static int inet6_addr_del(struct net *net, int ifindex, u32 ifa_flags,
2924 const struct in6_addr *pfx, unsigned int plen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002925{
2926 struct inet6_ifaddr *ifp;
2927 struct inet6_dev *idev;
2928 struct net_device *dev;
YOSHIFUJI Hideaki1ab14572007-02-09 23:24:49 +09002929
Thomas Graf24ef0da2008-05-28 16:54:22 +02002930 if (plen > 128)
2931 return -EINVAL;
2932
Daniel Lezcanoaf284932008-03-05 10:46:57 -08002933 dev = __dev_get_by_index(net, ifindex);
2934 if (!dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002935 return -ENODEV;
2936
Ian Morrise5d08d72014-11-23 21:28:43 +00002937 idev = __in6_dev_get(dev);
Ian Morris63159f22015-03-29 14:00:04 +01002938 if (!idev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002939 return -ENXIO;
2940
2941 read_lock_bh(&idev->lock);
stephen hemminger502a2ff2010-03-17 20:31:13 +00002942 list_for_each_entry(ifp, &idev->addr_list, if_list) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002943 if (ifp->prefix_len == plen &&
2944 ipv6_addr_equal(pfx, &ifp->addr)) {
2945 in6_ifa_hold(ifp);
2946 read_unlock_bh(&idev->lock);
YOSHIFUJI Hideaki1ab14572007-02-09 23:24:49 +09002947
Heiner Kallweit6046d5b2014-04-20 21:29:36 +02002948 if (!(ifp->flags & IFA_F_TEMPORARY) &&
2949 (ifa_flags & IFA_F_MANAGETEMPADDR))
2950 manage_tempaddrs(idev, ifp, 0, 0, false,
2951 jiffies);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002952 ipv6_del_addr(ifp);
Heiner Kallweit6046d5b2014-04-20 21:29:36 +02002953 addrconf_verify_rtnl();
Madhu Challa93a714d2015-02-25 09:58:35 -08002954 if (ipv6_addr_is_multicast(pfx)) {
2955 ipv6_mc_config(net->ipv6.mc_autojoin_sk,
2956 false, pfx, dev->ifindex);
2957 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002958 return 0;
2959 }
2960 }
2961 read_unlock_bh(&idev->lock);
2962 return -EADDRNOTAVAIL;
2963}
2964
2965
Daniel Lezcanoaf284932008-03-05 10:46:57 -08002966int addrconf_add_ifaddr(struct net *net, void __user *arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002967{
David Ahern19b15182018-05-27 08:09:54 -07002968 struct ifa6_config cfg = {
2969 .ifa_flags = IFA_F_PERMANENT,
2970 .preferred_lft = INFINITY_LIFE_TIME,
2971 .valid_lft = INFINITY_LIFE_TIME,
2972 };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002973 struct in6_ifreq ireq;
2974 int err;
YOSHIFUJI Hideaki1ab14572007-02-09 23:24:49 +09002975
Eric W. Biedermanaf31f412012-11-16 03:03:06 +00002976 if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002977 return -EPERM;
YOSHIFUJI Hideaki1ab14572007-02-09 23:24:49 +09002978
Linus Torvalds1da177e2005-04-16 15:20:36 -07002979 if (copy_from_user(&ireq, arg, sizeof(struct in6_ifreq)))
2980 return -EFAULT;
2981
David Ahern19b15182018-05-27 08:09:54 -07002982 cfg.pfx = &ireq.ifr6_addr;
2983 cfg.plen = ireq.ifr6_prefixlen;
2984
Linus Torvalds1da177e2005-04-16 15:20:36 -07002985 rtnl_lock();
David Ahern19b15182018-05-27 08:09:54 -07002986 err = inet6_addr_add(net, ireq.ifr6_ifindex, &cfg, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002987 rtnl_unlock();
2988 return err;
2989}
2990
Daniel Lezcanoaf284932008-03-05 10:46:57 -08002991int addrconf_del_ifaddr(struct net *net, void __user *arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002992{
2993 struct in6_ifreq ireq;
2994 int err;
YOSHIFUJI Hideaki1ab14572007-02-09 23:24:49 +09002995
Eric W. Biedermanaf31f412012-11-16 03:03:06 +00002996 if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002997 return -EPERM;
2998
2999 if (copy_from_user(&ireq, arg, sizeof(struct in6_ifreq)))
3000 return -EFAULT;
3001
3002 rtnl_lock();
Heiner Kallweit6046d5b2014-04-20 21:29:36 +02003003 err = inet6_addr_del(net, ireq.ifr6_ifindex, 0, &ireq.ifr6_addr,
Daniel Lezcanoaf284932008-03-05 10:46:57 -08003004 ireq.ifr6_prefixlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003005 rtnl_unlock();
3006 return err;
3007}
3008
Ilpo Järvinenb5f348e2009-02-06 23:48:01 -08003009static void add_addr(struct inet6_dev *idev, const struct in6_addr *addr,
3010 int plen, int scope)
3011{
3012 struct inet6_ifaddr *ifp;
David Aherne6464b82018-05-27 08:09:53 -07003013 struct ifa6_config cfg = {
3014 .pfx = addr,
3015 .plen = plen,
3016 .ifa_flags = IFA_F_PERMANENT,
3017 .valid_lft = INFINITY_LIFE_TIME,
3018 .preferred_lft = INFINITY_LIFE_TIME,
3019 .scope = scope
3020 };
Ilpo Järvinenb5f348e2009-02-06 23:48:01 -08003021
David Aherne6464b82018-05-27 08:09:53 -07003022 ifp = ipv6_add_addr(idev, &cfg, true, NULL);
Ilpo Järvinenb5f348e2009-02-06 23:48:01 -08003023 if (!IS_ERR(ifp)) {
3024 spin_lock_bh(&ifp->lock);
3025 ifp->flags &= ~IFA_F_TENTATIVE;
3026 spin_unlock_bh(&ifp->lock);
Paolo Abeni764d3be2016-11-22 16:57:40 +01003027 rt_genid_bump_ipv6(dev_net(idev->dev));
Ilpo Järvinenb5f348e2009-02-06 23:48:01 -08003028 ipv6_ifa_notify(RTM_NEWADDR, ifp);
3029 in6_ifa_put(ifp);
3030 }
3031}
3032
Amerigo Wang07a93622012-10-29 16:23:10 +00003033#if IS_ENABLED(CONFIG_IPV6_SIT)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003034static void sit_add_v4_addrs(struct inet6_dev *idev)
3035{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003036 struct in6_addr addr;
3037 struct net_device *dev;
YOSHIFUJI Hideakic346dca2008-03-25 21:47:49 +09003038 struct net *net = dev_net(idev->dev);
Nicolas Dichtel929c9cf2013-11-14 13:51:05 +01003039 int scope, plen;
Nicolas Dichtelf0e2acf2013-11-14 13:51:06 +01003040 u32 pflags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003041
3042 ASSERT_RTNL();
3043
3044 memset(&addr, 0, sizeof(struct in6_addr));
3045 memcpy(&addr.s6_addr32[3], idev->dev->dev_addr, 4);
3046
3047 if (idev->dev->flags&IFF_POINTOPOINT) {
3048 addr.s6_addr32[0] = htonl(0xfe800000);
3049 scope = IFA_LINK;
Nicolas Dichtel929c9cf2013-11-14 13:51:05 +01003050 plen = 64;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003051 } else {
3052 scope = IPV6_ADDR_COMPATv4;
Nicolas Dichtel929c9cf2013-11-14 13:51:05 +01003053 plen = 96;
Nicolas Dichtelf0e2acf2013-11-14 13:51:06 +01003054 pflags |= RTF_NONEXTHOP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003055 }
3056
3057 if (addr.s6_addr32[3]) {
Nicolas Dichtel929c9cf2013-11-14 13:51:05 +01003058 add_addr(idev, &addr, plen, scope);
David Ahernacb54e32018-04-17 17:33:22 -07003059 addrconf_prefix_route(&addr, plen, idev->dev, 0, pflags,
3060 GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003061 return;
3062 }
3063
Benjamin Thery6fda7352008-03-05 10:47:47 -08003064 for_each_netdev(net, dev) {
Eldad Zack8e5e8f32012-04-01 07:49:08 +00003065 struct in_device *in_dev = __in_dev_get_rtnl(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003066 if (in_dev && (dev->flags & IFF_UP)) {
Eldad Zack8e5e8f32012-04-01 07:49:08 +00003067 struct in_ifaddr *ifa;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003068
3069 int flag = scope;
3070
3071 for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003072
3073 addr.s6_addr32[3] = ifa->ifa_local;
3074
3075 if (ifa->ifa_scope == RT_SCOPE_LINK)
3076 continue;
3077 if (ifa->ifa_scope >= RT_SCOPE_HOST) {
3078 if (idev->dev->flags&IFF_POINTOPOINT)
3079 continue;
3080 flag |= IFA_HOST;
3081 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003082
Ilpo Järvinenb5f348e2009-02-06 23:48:01 -08003083 add_addr(idev, &addr, plen, flag);
Nicolas Dichtelf0e2acf2013-11-14 13:51:06 +01003084 addrconf_prefix_route(&addr, plen, idev->dev, 0,
David Ahernacb54e32018-04-17 17:33:22 -07003085 pflags, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003086 }
3087 }
YOSHIFUJI Hideaki1ab14572007-02-09 23:24:49 +09003088 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003089}
Joerg Roedel0be669b2006-10-10 14:49:53 -07003090#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07003091
3092static void init_loopback(struct net_device *dev)
3093{
3094 struct inet6_dev *idev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003095
3096 /* ::1 */
3097
3098 ASSERT_RTNL();
3099
Ian Morrise5d08d72014-11-23 21:28:43 +00003100 idev = ipv6_find_idev(dev);
Ian Morris63159f22015-03-29 14:00:04 +01003101 if (!idev) {
Joe Perches91df42b2012-05-15 14:11:54 +00003102 pr_debug("%s: add_dev failed\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003103 return;
3104 }
3105
Ilpo Järvinenb5f348e2009-02-06 23:48:01 -08003106 add_addr(idev, &in6addr_loopback, 128, IFA_HOST);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003107}
3108
Alexander Aring2ad3ed52016-06-15 21:20:17 +02003109void addrconf_add_linklocal(struct inet6_dev *idev,
3110 const struct in6_addr *addr, u32 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003111{
David Aherne6464b82018-05-27 08:09:53 -07003112 struct ifa6_config cfg = {
3113 .pfx = addr,
3114 .plen = 64,
3115 .ifa_flags = flags | IFA_F_PERMANENT,
3116 .valid_lft = INFINITY_LIFE_TIME,
3117 .preferred_lft = INFINITY_LIFE_TIME,
3118 .scope = IFA_LINK
3119 };
Eldad Zack8e5e8f32012-04-01 07:49:08 +00003120 struct inet6_ifaddr *ifp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003121
Neil Horman95c385b2007-04-25 17:08:10 -07003122#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
Matteo Croce35e015e2017-09-12 17:46:37 +02003123 if ((dev_net(idev->dev)->ipv6.devconf_all->optimistic_dad ||
3124 idev->cnf.optimistic_dad) &&
David Miller702beb82008-07-20 18:17:02 -07003125 !dev_net(idev->dev)->ipv6.devconf_all->forwarding)
David Aherne6464b82018-05-27 08:09:53 -07003126 cfg.ifa_flags |= IFA_F_OPTIMISTIC;
Neil Horman95c385b2007-04-25 17:08:10 -07003127#endif
3128
David Aherne6464b82018-05-27 08:09:53 -07003129 ifp = ipv6_add_addr(idev, &cfg, true, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003130 if (!IS_ERR(ifp)) {
David Ahernacb54e32018-04-17 17:33:22 -07003131 addrconf_prefix_route(&ifp->addr, ifp->prefix_len, idev->dev,
3132 0, 0, GFP_ATOMIC);
David S. Millercf22f9a2012-04-14 21:37:40 -04003133 addrconf_dad_start(ifp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003134 in6_ifa_put(ifp);
3135 }
3136}
Alexander Aring2ad3ed52016-06-15 21:20:17 +02003137EXPORT_SYMBOL_GPL(addrconf_add_linklocal);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003138
Hannes Frederic Sowa622c81d52015-03-23 23:36:01 +01003139static bool ipv6_reserved_interfaceid(struct in6_addr address)
3140{
3141 if ((address.s6_addr32[2] | address.s6_addr32[3]) == 0)
3142 return true;
3143
3144 if (address.s6_addr32[2] == htonl(0x02005eff) &&
3145 ((address.s6_addr32[3] & htonl(0xfe000000)) == htonl(0xfe000000)))
3146 return true;
3147
3148 if (address.s6_addr32[2] == htonl(0xfdffffff) &&
3149 ((address.s6_addr32[3] & htonl(0xffffff80)) == htonl(0xffffff80)))
3150 return true;
3151
3152 return false;
3153}
3154
3155static int ipv6_generate_stable_address(struct in6_addr *address,
3156 u8 dad_count,
3157 const struct inet6_dev *idev)
3158{
Hannes Frederic Sowa622c81d52015-03-23 23:36:01 +01003159 static DEFINE_SPINLOCK(lock);
3160 static __u32 digest[SHA_DIGEST_WORDS];
3161 static __u32 workspace[SHA_WORKSPACE_WORDS];
3162
3163 static union {
3164 char __data[SHA_MESSAGE_BYTES];
3165 struct {
3166 struct in6_addr secret;
Hannes Frederic Sowaff402172015-03-24 11:05:28 +01003167 __be32 prefix[2];
Hannes Frederic Sowa622c81d52015-03-23 23:36:01 +01003168 unsigned char hwaddr[MAX_ADDR_LEN];
3169 u8 dad_count;
3170 } __packed;
3171 } data;
3172
3173 struct in6_addr secret;
3174 struct in6_addr temp;
3175 struct net *net = dev_net(idev->dev);
3176
3177 BUILD_BUG_ON(sizeof(data.__data) != sizeof(data));
3178
3179 if (idev->cnf.stable_secret.initialized)
3180 secret = idev->cnf.stable_secret.secret;
3181 else if (net->ipv6.devconf_dflt->stable_secret.initialized)
3182 secret = net->ipv6.devconf_dflt->stable_secret.secret;
3183 else
3184 return -1;
3185
3186retry:
3187 spin_lock_bh(&lock);
3188
3189 sha_init(digest);
3190 memset(&data, 0, sizeof(data));
3191 memset(workspace, 0, sizeof(workspace));
3192 memcpy(data.hwaddr, idev->dev->perm_addr, idev->dev->addr_len);
Hannes Frederic Sowaff402172015-03-24 11:05:28 +01003193 data.prefix[0] = address->s6_addr32[0];
3194 data.prefix[1] = address->s6_addr32[1];
Hannes Frederic Sowa622c81d52015-03-23 23:36:01 +01003195 data.secret = secret;
3196 data.dad_count = dad_count;
3197
3198 sha_transform(digest, data.__data, workspace);
3199
3200 temp = *address;
Hannes Frederic Sowaff402172015-03-24 11:05:28 +01003201 temp.s6_addr32[2] = (__force __be32)digest[0];
3202 temp.s6_addr32[3] = (__force __be32)digest[1];
Hannes Frederic Sowa622c81d52015-03-23 23:36:01 +01003203
3204 spin_unlock_bh(&lock);
3205
3206 if (ipv6_reserved_interfaceid(temp)) {
3207 dad_count++;
Hannes Frederic Sowa1855b7c2015-03-23 23:36:05 +01003208 if (dad_count > dev_net(idev->dev)->ipv6.sysctl.idgen_retries)
Hannes Frederic Sowa622c81d52015-03-23 23:36:01 +01003209 return -1;
3210 goto retry;
3211 }
3212
3213 *address = temp;
3214 return 0;
3215}
3216
Bjørn Morkcc9da6c2015-12-16 16:44:38 +01003217static void ipv6_gen_mode_random_init(struct inet6_dev *idev)
3218{
3219 struct ipv6_stable_secret *s = &idev->cnf.stable_secret;
3220
3221 if (s->initialized)
3222 return;
3223 s = &idev->cnf.stable_secret;
3224 get_random_bytes(&s->secret, sizeof(s->secret));
3225 s->initialized = true;
3226}
3227
Jiri Pirkobc91b0f2014-07-11 21:10:18 +02003228static void addrconf_addr_gen(struct inet6_dev *idev, bool prefix_route)
3229{
Hannes Frederic Sowa622c81d52015-03-23 23:36:01 +01003230 struct in6_addr addr;
Jiri Pirkobc91b0f2014-07-11 21:10:18 +02003231
David Ahernca254492015-10-12 11:47:10 -07003232 /* no link local addresses on L3 master devices */
3233 if (netif_is_l3_master(idev->dev))
3234 return;
3235
Hannes Frederic Sowa622c81d52015-03-23 23:36:01 +01003236 ipv6_addr_set(&addr, htonl(0xFE800000), 0, 0, 0);
3237
Felix Jiad35a00b2017-01-26 16:59:17 +13003238 switch (idev->cnf.addr_gen_mode) {
Bjørn Morkcc9da6c2015-12-16 16:44:38 +01003239 case IN6_ADDR_GEN_MODE_RANDOM:
3240 ipv6_gen_mode_random_init(idev);
3241 /* fallthrough */
3242 case IN6_ADDR_GEN_MODE_STABLE_PRIVACY:
Hannes Frederic Sowa622c81d52015-03-23 23:36:01 +01003243 if (!ipv6_generate_stable_address(&addr, 0, idev))
Hannes Frederic Sowa64236f32015-03-23 23:36:02 +01003244 addrconf_add_linklocal(idev, &addr,
3245 IFA_F_STABLE_PRIVACY);
Hannes Frederic Sowa622c81d52015-03-23 23:36:01 +01003246 else if (prefix_route)
David Ahernacb54e32018-04-17 17:33:22 -07003247 addrconf_prefix_route(&addr, 64, idev->dev,
3248 0, 0, GFP_KERNEL);
Bjørn Morkcc9da6c2015-12-16 16:44:38 +01003249 break;
3250 case IN6_ADDR_GEN_MODE_EUI64:
Jiri Pirkobc91b0f2014-07-11 21:10:18 +02003251 /* addrconf_add_linklocal also adds a prefix_route and we
3252 * only need to care about prefix routes if ipv6_generate_eui64
3253 * couldn't generate one.
3254 */
3255 if (ipv6_generate_eui64(addr.s6_addr + 8, idev->dev) == 0)
Hannes Frederic Sowa64236f32015-03-23 23:36:02 +01003256 addrconf_add_linklocal(idev, &addr, 0);
Jiri Pirkobc91b0f2014-07-11 21:10:18 +02003257 else if (prefix_route)
David Ahernacb54e32018-04-17 17:33:22 -07003258 addrconf_prefix_route(&addr, 64, idev->dev,
David Ahern27b10602018-04-18 15:39:06 -07003259 0, 0, GFP_KERNEL);
Bjørn Morkcc9da6c2015-12-16 16:44:38 +01003260 break;
3261 case IN6_ADDR_GEN_MODE_NONE:
3262 default:
3263 /* will not add any link local address */
3264 break;
Jiri Pirkobc91b0f2014-07-11 21:10:18 +02003265 }
3266}
3267
Linus Torvalds1da177e2005-04-16 15:20:36 -07003268static void addrconf_dev_config(struct net_device *dev)
3269{
Eldad Zack8e5e8f32012-04-01 07:49:08 +00003270 struct inet6_dev *idev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003271
3272 ASSERT_RTNL();
3273
Herbert Xu74235a22007-06-14 13:02:55 -07003274 if ((dev->type != ARPHRD_ETHER) &&
3275 (dev->type != ARPHRD_FDDI) &&
Herbert Xu74235a22007-06-14 13:02:55 -07003276 (dev->type != ARPHRD_ARCNET) &&
alex.bluesman.smirnov@gmail.com06a4c1c2012-05-10 03:25:52 +00003277 (dev->type != ARPHRD_INFINIBAND) &&
Nicolas Dichtele8377352013-08-20 12:16:06 +02003278 (dev->type != ARPHRD_IEEE1394) &&
Jukka Rissanene74bccb82013-12-11 17:05:36 +02003279 (dev->type != ARPHRD_TUNNEL6) &&
Bjørn Morkcc9da6c2015-12-16 16:44:38 +01003280 (dev->type != ARPHRD_6LOWPAN) &&
Felix Jia45ce0fd2017-01-26 16:59:18 +13003281 (dev->type != ARPHRD_IP6GRE) &&
3282 (dev->type != ARPHRD_IPGRE) &&
3283 (dev->type != ARPHRD_TUNNEL) &&
Bjørn Morkcc9da6c2015-12-16 16:44:38 +01003284 (dev->type != ARPHRD_NONE)) {
Herbert Xu74235a22007-06-14 13:02:55 -07003285 /* Alas, we support only Ethernet autoconfiguration. */
3286 return;
3287 }
3288
Linus Torvalds1da177e2005-04-16 15:20:36 -07003289 idev = addrconf_add_dev(dev);
Brian Haley64e724f2010-07-20 10:34:30 +00003290 if (IS_ERR(idev))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003291 return;
3292
Bjørn Morkcc9da6c2015-12-16 16:44:38 +01003293 /* this device type has no EUI support */
3294 if (dev->type == ARPHRD_NONE &&
Felix Jiad35a00b2017-01-26 16:59:17 +13003295 idev->cnf.addr_gen_mode == IN6_ADDR_GEN_MODE_EUI64)
3296 idev->cnf.addr_gen_mode = IN6_ADDR_GEN_MODE_RANDOM;
Bjørn Morkcc9da6c2015-12-16 16:44:38 +01003297
Jiri Pirkobc91b0f2014-07-11 21:10:18 +02003298 addrconf_addr_gen(idev, false);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003299}
3300
Amerigo Wang07a93622012-10-29 16:23:10 +00003301#if IS_ENABLED(CONFIG_IPV6_SIT)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003302static void addrconf_sit_config(struct net_device *dev)
3303{
3304 struct inet6_dev *idev;
3305
3306 ASSERT_RTNL();
3307
YOSHIFUJI Hideaki1ab14572007-02-09 23:24:49 +09003308 /*
3309 * Configure the tunnel with one of our IPv4
3310 * addresses... we should configure all of
Linus Torvalds1da177e2005-04-16 15:20:36 -07003311 * our v4 addrs in the tunnel
3312 */
3313
Ian Morrise5d08d72014-11-23 21:28:43 +00003314 idev = ipv6_find_idev(dev);
Ian Morris63159f22015-03-29 14:00:04 +01003315 if (!idev) {
Joe Perches91df42b2012-05-15 14:11:54 +00003316 pr_debug("%s: add_dev failed\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003317 return;
3318 }
3319
Fred L. Templinc7dc89c2007-11-29 22:11:40 +11003320 if (dev->priv_flags & IFF_ISATAP) {
Jiri Pirkobc91b0f2014-07-11 21:10:18 +02003321 addrconf_addr_gen(idev, false);
Fred L. Templinc7dc89c2007-11-29 22:11:40 +11003322 return;
3323 }
3324
Linus Torvalds1da177e2005-04-16 15:20:36 -07003325 sit_add_v4_addrs(idev);
3326
Nicolas Dichtel62b54dd2012-10-01 23:19:14 +00003327 if (dev->flags&IFF_POINTOPOINT)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003328 addrconf_add_mroute(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003329}
Joerg Roedel0be669b2006-10-10 14:49:53 -07003330#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07003331
Amerigo Wang07a93622012-10-29 16:23:10 +00003332#if IS_ENABLED(CONFIG_NET_IPGRE)
stephen hemmingeraee80b52011-06-08 10:44:30 +00003333static void addrconf_gre_config(struct net_device *dev)
3334{
3335 struct inet6_dev *idev;
stephen hemmingeraee80b52011-06-08 10:44:30 +00003336
stephen hemmingeraee80b52011-06-08 10:44:30 +00003337 ASSERT_RTNL();
3338
Ian Morrise5d08d72014-11-23 21:28:43 +00003339 idev = ipv6_find_idev(dev);
Ian Morris63159f22015-03-29 14:00:04 +01003340 if (!idev) {
Joe Perches91df42b2012-05-15 14:11:54 +00003341 pr_debug("%s: add_dev failed\n", __func__);
stephen hemmingeraee80b52011-06-08 10:44:30 +00003342 return;
3343 }
3344
Jiri Pirkobc91b0f2014-07-11 21:10:18 +02003345 addrconf_addr_gen(idev, true);
Hannes Frederic Sowad9e4ce62015-10-08 18:19:39 +02003346 if (dev->flags & IFF_POINTOPOINT)
3347 addrconf_add_mroute(dev);
stephen hemmingeraee80b52011-06-08 10:44:30 +00003348}
3349#endif
3350
David Ahernafb1d4b52018-04-17 17:33:11 -07003351static int fixup_permanent_addr(struct net *net,
3352 struct inet6_dev *idev,
David Ahernf1705ec2016-02-24 09:25:37 -08003353 struct inet6_ifaddr *ifp)
3354{
David Ahern93c2fb22018-04-18 15:38:59 -07003355 /* !fib6_node means the host route was removed from the
David Ahern8048ced2017-04-25 09:17:29 -07003356 * FIB, for example, if 'lo' device is taken down. In that
3357 * case regenerate the host route.
3358 */
David Ahern93c2fb22018-04-18 15:38:59 -07003359 if (!ifp->rt || !ifp->rt->fib6_node) {
David Ahern360a9882018-04-18 15:39:00 -07003360 struct fib6_info *f6i, *prev;
David Ahernf1705ec2016-02-24 09:25:37 -08003361
David Ahern360a9882018-04-18 15:39:00 -07003362 f6i = addrconf_f6i_alloc(net, idev, &ifp->addr, false,
3363 GFP_ATOMIC);
3364 if (IS_ERR(f6i))
3365 return PTR_ERR(f6i);
David Ahernf1705ec2016-02-24 09:25:37 -08003366
David Ahern8048ced2017-04-25 09:17:29 -07003367 /* ifp->rt can be accessed outside of rtnl */
3368 spin_lock(&ifp->lock);
3369 prev = ifp->rt;
David Ahern360a9882018-04-18 15:39:00 -07003370 ifp->rt = f6i;
David Ahern8048ced2017-04-25 09:17:29 -07003371 spin_unlock(&ifp->lock);
3372
David Ahern93531c62018-04-17 17:33:25 -07003373 fib6_info_release(prev);
David Ahernf1705ec2016-02-24 09:25:37 -08003374 }
3375
3376 if (!(ifp->flags & IFA_F_NOPREFIXROUTE)) {
3377 addrconf_prefix_route(&ifp->addr, ifp->prefix_len,
David Ahernacb54e32018-04-17 17:33:22 -07003378 idev->dev, 0, 0, GFP_ATOMIC);
David Ahernf1705ec2016-02-24 09:25:37 -08003379 }
3380
David Ahern6d717132017-05-02 14:43:44 -07003381 if (ifp->state == INET6_IFADDR_STATE_PREDAD)
3382 addrconf_dad_start(ifp);
David Ahernf1705ec2016-02-24 09:25:37 -08003383
3384 return 0;
3385}
3386
David Ahernafb1d4b52018-04-17 17:33:11 -07003387static void addrconf_permanent_addr(struct net *net, struct net_device *dev)
David Ahernf1705ec2016-02-24 09:25:37 -08003388{
3389 struct inet6_ifaddr *ifp, *tmp;
3390 struct inet6_dev *idev;
3391
3392 idev = __in6_dev_get(dev);
3393 if (!idev)
3394 return;
3395
3396 write_lock_bh(&idev->lock);
3397
3398 list_for_each_entry_safe(ifp, tmp, &idev->addr_list, if_list) {
3399 if ((ifp->flags & IFA_F_PERMANENT) &&
David Ahernafb1d4b52018-04-17 17:33:11 -07003400 fixup_permanent_addr(net, idev, ifp) < 0) {
David Ahernf1705ec2016-02-24 09:25:37 -08003401 write_unlock_bh(&idev->lock);
Eric Dumazete669b862017-10-30 22:47:09 -07003402 in6_ifa_hold(ifp);
David Ahernf1705ec2016-02-24 09:25:37 -08003403 ipv6_del_addr(ifp);
3404 write_lock_bh(&idev->lock);
3405
3406 net_info_ratelimited("%s: Failed to add prefix route for address %pI6c; dropping\n",
3407 idev->dev->name, &ifp->addr);
3408 }
3409 }
3410
3411 write_unlock_bh(&idev->lock);
3412}
3413
YOSHIFUJI Hideaki1ab14572007-02-09 23:24:49 +09003414static int addrconf_notify(struct notifier_block *this, unsigned long event,
Jiri Pirko351638e2013-05-28 01:30:21 +00003415 void *ptr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003416{
Jiri Pirko351638e2013-05-28 01:30:21 +00003417 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
David Ahern4f7f34e2016-04-07 11:10:41 -07003418 struct netdev_notifier_changeupper_info *info;
Eric Dumazet748e2d92012-08-22 21:50:59 +00003419 struct inet6_dev *idev = __in6_dev_get(dev);
WANG Cong60abc0b2017-06-21 14:34:58 -07003420 struct net *net = dev_net(dev);
YOSHIFUJI Hideakic5e33bd2005-12-21 22:57:44 +09003421 int run_pending = 0;
Herbert Xub217d612007-07-30 17:04:52 -07003422 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003423
Stephen Hemmingere21e8462010-03-20 16:09:01 -07003424 switch (event) {
YOSHIFUJI Hideaki45ba9dd2007-02-15 02:07:27 +09003425 case NETDEV_REGISTER:
Herbert Xu74235a22007-06-14 13:02:55 -07003426 if (!idev && dev->mtu >= IPV6_MIN_MTU) {
YOSHIFUJI Hideaki45ba9dd2007-02-15 02:07:27 +09003427 idev = ipv6_add_dev(dev);
WANG Conga317a2f2014-07-25 15:25:09 -07003428 if (IS_ERR(idev))
3429 return notifier_from_errno(PTR_ERR(idev));
YOSHIFUJI Hideaki45ba9dd2007-02-15 02:07:27 +09003430 }
3431 break;
Stephen Hemmingerbcdd5532010-03-20 16:08:18 -07003432
Alexander Duyckb7b0b1d2015-10-26 11:06:33 -07003433 case NETDEV_CHANGEMTU:
3434 /* if MTU under IPV6_MIN_MTU stop IPv6 on this interface. */
3435 if (dev->mtu < IPV6_MIN_MTU) {
WANG Cong60abc0b2017-06-21 14:34:58 -07003436 addrconf_ifdown(dev, dev != net->loopback_dev);
Alexander Duyckb7b0b1d2015-10-26 11:06:33 -07003437 break;
3438 }
3439
3440 if (idev) {
3441 rt6_mtu_change(dev, dev->mtu);
3442 idev->cnf.mtu6 = dev->mtu;
3443 break;
3444 }
3445
3446 /* allocate new idev */
3447 idev = ipv6_add_dev(dev);
3448 if (IS_ERR(idev))
3449 break;
3450
3451 /* device is still not ready */
3452 if (!(idev->if_flags & IF_READY))
3453 break;
3454
3455 run_pending = 1;
3456
3457 /* fall through */
3458
Linus Torvalds1da177e2005-04-16 15:20:36 -07003459 case NETDEV_UP:
YOSHIFUJI Hideaki3c21edb2005-12-21 22:57:24 +09003460 case NETDEV_CHANGE:
Jay Vosburghc2edacf2007-07-09 10:42:47 -07003461 if (dev->flags & IFF_SLAVE)
3462 break;
3463
WANG Cong3ce62a82014-09-11 15:07:16 -07003464 if (idev && idev->cnf.disable_ipv6)
3465 break;
3466
YOSHIFUJI Hideaki3c21edb2005-12-21 22:57:24 +09003467 if (event == NETDEV_UP) {
David Ahern38bd10c2016-04-21 20:56:12 -07003468 /* restore routes for permanent addresses */
David Ahernafb1d4b52018-04-17 17:33:11 -07003469 addrconf_permanent_addr(net, dev);
David Ahern38bd10c2016-04-21 20:56:12 -07003470
Mike Manning1f372c72017-09-25 22:01:36 +01003471 if (!addrconf_link_ready(dev)) {
YOSHIFUJI Hideaki3c21edb2005-12-21 22:57:24 +09003472 /* device is not ready yet. */
Joe Perchesf3213832012-05-15 14:11:53 +00003473 pr_info("ADDRCONF(NETDEV_UP): %s: link is not ready\n",
YOSHIFUJI Hideaki3c21edb2005-12-21 22:57:24 +09003474 dev->name);
3475 break;
3476 }
Kristian Slavov99081042006-02-08 16:10:53 -08003477
Evgeniy Polyakovd31c7b82007-11-30 23:36:08 +11003478 if (!idev && dev->mtu >= IPV6_MIN_MTU)
3479 idev = ipv6_add_dev(dev);
3480
WANG Conga317a2f2014-07-25 15:25:09 -07003481 if (!IS_ERR_OR_NULL(idev)) {
Kristian Slavov99081042006-02-08 16:10:53 -08003482 idev->if_flags |= IF_READY;
Benjamin Therye3ec6cf2008-11-05 01:43:57 -08003483 run_pending = 1;
3484 }
Alexander Duyckb7b0b1d2015-10-26 11:06:33 -07003485 } else if (event == NETDEV_CHANGE) {
Mike Manning1f372c72017-09-25 22:01:36 +01003486 if (!addrconf_link_ready(dev)) {
YOSHIFUJI Hideaki3c21edb2005-12-21 22:57:24 +09003487 /* device is still not ready. */
Ido Schimmel27c6fa72018-01-07 12:45:05 +02003488 rt6_sync_down_dev(dev, event);
YOSHIFUJI Hideaki3c21edb2005-12-21 22:57:24 +09003489 break;
3490 }
3491
3492 if (idev) {
Linus Lüssinga088d1d2017-02-03 08:11:03 +01003493 if (idev->if_flags & IF_READY) {
3494 /* device is already configured -
3495 * but resend MLD reports, we might
3496 * have roamed and need to update
3497 * multicast snooping switches
3498 */
3499 ipv6_mc_up(idev);
Ido Schimmel27c6fa72018-01-07 12:45:05 +02003500 rt6_sync_up(dev, RTNH_F_LINKDOWN);
YOSHIFUJI Hideaki3c21edb2005-12-21 22:57:24 +09003501 break;
Linus Lüssinga088d1d2017-02-03 08:11:03 +01003502 }
YOSHIFUJI Hideaki3c21edb2005-12-21 22:57:24 +09003503 idev->if_flags |= IF_READY;
3504 }
3505
Joe Perchesf3213832012-05-15 14:11:53 +00003506 pr_info("ADDRCONF(NETDEV_CHANGE): %s: link becomes ready\n",
3507 dev->name);
YOSHIFUJI Hideaki3c21edb2005-12-21 22:57:24 +09003508
YOSHIFUJI Hideakic5e33bd2005-12-21 22:57:44 +09003509 run_pending = 1;
YOSHIFUJI Hideaki3c21edb2005-12-21 22:57:24 +09003510 }
3511
Stephen Hemmingere21e8462010-03-20 16:09:01 -07003512 switch (dev->type) {
Amerigo Wang07a93622012-10-29 16:23:10 +00003513#if IS_ENABLED(CONFIG_IPV6_SIT)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003514 case ARPHRD_SIT:
3515 addrconf_sit_config(dev);
3516 break;
Joerg Roedel0be669b2006-10-10 14:49:53 -07003517#endif
Amerigo Wang07a93622012-10-29 16:23:10 +00003518#if IS_ENABLED(CONFIG_NET_IPGRE)
stephen hemmingeraee80b52011-06-08 10:44:30 +00003519 case ARPHRD_IPGRE:
3520 addrconf_gre_config(dev);
3521 break;
3522#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07003523 case ARPHRD_LOOPBACK:
3524 init_loopback(dev);
3525 break;
3526
3527 default:
3528 addrconf_dev_config(dev);
3529 break;
Stephen Hemminger3ff50b72007-04-20 17:09:22 -07003530 }
Stephen Hemmingerbcdd5532010-03-20 16:08:18 -07003531
WANG Conga317a2f2014-07-25 15:25:09 -07003532 if (!IS_ERR_OR_NULL(idev)) {
YOSHIFUJI Hideakic5e33bd2005-12-21 22:57:44 +09003533 if (run_pending)
3534 addrconf_dad_run(idev);
3535
Ido Schimmel2127d952018-01-07 12:45:03 +02003536 /* Device has an address by now */
3537 rt6_sync_up(dev, RTNH_F_DEAD);
3538
Stephen Hemmingerbcdd5532010-03-20 16:08:18 -07003539 /*
3540 * If the MTU changed during the interface down,
3541 * when the interface up, the changed MTU must be
3542 * reflected in the idev as well as routers.
Linus Torvalds1da177e2005-04-16 15:20:36 -07003543 */
Stephen Hemmingerbcdd5532010-03-20 16:08:18 -07003544 if (idev->cnf.mtu6 != dev->mtu &&
3545 dev->mtu >= IPV6_MIN_MTU) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003546 rt6_mtu_change(dev, dev->mtu);
3547 idev->cnf.mtu6 = dev->mtu;
3548 }
3549 idev->tstamp = jiffies;
3550 inet6_ifinfo_notify(RTM_NEWLINK, idev);
Stephen Hemmingerbcdd5532010-03-20 16:08:18 -07003551
3552 /*
3553 * If the changed mtu during down is lower than
3554 * IPV6_MIN_MTU stop IPv6 on this interface.
Linus Torvalds1da177e2005-04-16 15:20:36 -07003555 */
3556 if (dev->mtu < IPV6_MIN_MTU)
WANG Cong60abc0b2017-06-21 14:34:58 -07003557 addrconf_ifdown(dev, dev != net->loopback_dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003558 }
3559 break;
3560
Linus Torvalds1da177e2005-04-16 15:20:36 -07003561 case NETDEV_DOWN:
3562 case NETDEV_UNREGISTER:
3563 /*
3564 * Remove all addresses from this interface.
3565 */
3566 addrconf_ifdown(dev, event != NETDEV_DOWN);
3567 break;
YOSHIFUJI Hideaki3c21edb2005-12-21 22:57:24 +09003568
Linus Torvalds1da177e2005-04-16 15:20:36 -07003569 case NETDEV_CHANGENAME:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003570 if (idev) {
Stephen Hemminger5632c512007-04-28 21:16:39 -07003571 snmp6_unregister_dev(idev);
Pavel Emelyanov408c4762008-01-10 17:41:21 -08003572 addrconf_sysctl_unregister(idev);
WANG Conga317a2f2014-07-25 15:25:09 -07003573 err = addrconf_sysctl_register(idev);
Herbert Xub217d612007-07-30 17:04:52 -07003574 if (err)
3575 return notifier_from_errno(err);
WANG Conga317a2f2014-07-25 15:25:09 -07003576 err = snmp6_register_dev(idev);
3577 if (err) {
3578 addrconf_sysctl_unregister(idev);
3579 return notifier_from_errno(err);
3580 }
Stephen Hemminger5632c512007-04-28 21:16:39 -07003581 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003582 break;
Stephen Hemmingerbcdd5532010-03-20 16:08:18 -07003583
Jiri Pirko93d9b7d2010-03-10 10:28:56 +00003584 case NETDEV_PRE_TYPE_CHANGE:
3585 case NETDEV_POST_TYPE_CHANGE:
Andrew Lunn3ef09522015-12-03 21:12:32 +01003586 if (idev)
3587 addrconf_type_change(dev, event);
Moni Shoua75c78502009-09-15 02:37:40 -07003588 break;
David Ahern4f7f34e2016-04-07 11:10:41 -07003589
3590 case NETDEV_CHANGEUPPER:
3591 info = ptr;
3592
3593 /* flush all routes if dev is linked to or unlinked from
3594 * an L3 master device (e.g., VRF)
3595 */
3596 if (info->upper_dev && netif_is_l3_master(info->upper_dev))
3597 addrconf_ifdown(dev, 0);
Stephen Hemminger3ff50b72007-04-20 17:09:22 -07003598 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003599
3600 return NOTIFY_OK;
3601}
3602
3603/*
3604 * addrconf module should be notified of a device going up
3605 */
3606static struct notifier_block ipv6_dev_notf = {
3607 .notifier_call = addrconf_notify,
WANG Cong242d3a42017-05-08 10:12:13 -07003608 .priority = ADDRCONF_NOTIFY_PRIORITY,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003609};
3610
Jiri Pirko93d9b7d2010-03-10 10:28:56 +00003611static void addrconf_type_change(struct net_device *dev, unsigned long event)
Moni Shoua75c78502009-09-15 02:37:40 -07003612{
3613 struct inet6_dev *idev;
3614 ASSERT_RTNL();
3615
3616 idev = __in6_dev_get(dev);
3617
Jiri Pirko93d9b7d2010-03-10 10:28:56 +00003618 if (event == NETDEV_POST_TYPE_CHANGE)
Moni Shoua75c78502009-09-15 02:37:40 -07003619 ipv6_mc_remap(idev);
Jiri Pirko93d9b7d2010-03-10 10:28:56 +00003620 else if (event == NETDEV_PRE_TYPE_CHANGE)
Moni Shoua75c78502009-09-15 02:37:40 -07003621 ipv6_mc_unmap(idev);
3622}
3623
David Ahern70af9212016-04-08 12:01:21 -07003624static bool addr_is_local(const struct in6_addr *addr)
3625{
3626 return ipv6_addr_type(addr) &
3627 (IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK);
3628}
3629
Linus Torvalds1da177e2005-04-16 15:20:36 -07003630static int addrconf_ifdown(struct net_device *dev, int how)
3631{
Ido Schimmel4c981e22018-01-07 12:45:04 +02003632 unsigned long event = how ? NETDEV_UNREGISTER : NETDEV_DOWN;
YOSHIFUJI Hideakic346dca2008-03-25 21:47:49 +09003633 struct net *net = dev_net(dev);
stephen hemminger502a2ff2010-03-17 20:31:13 +00003634 struct inet6_dev *idev;
David Ahernf1705ec2016-02-24 09:25:37 -08003635 struct inet6_ifaddr *ifa, *tmp;
Ivan Vecera0aef78a2018-04-24 19:51:29 +02003636 bool keep_addr = false;
David S. Miller73a8bd72011-01-23 23:27:15 -08003637 int state, i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003638
3639 ASSERT_RTNL();
3640
Ido Schimmel4c981e22018-01-07 12:45:04 +02003641 rt6_disable_ip(dev, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003642
3643 idev = __in6_dev_get(dev);
Ian Morris63159f22015-03-29 14:00:04 +01003644 if (!idev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003645 return -ENODEV;
3646
Stephen Hemmingerbcdd5532010-03-20 16:08:18 -07003647 /*
3648 * Step 1: remove reference to ipv6 device from parent device.
3649 * Do not dev_put!
Linus Torvalds1da177e2005-04-16 15:20:36 -07003650 */
Denis V. Lunev439e2382008-04-03 13:30:17 -07003651 if (how) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003652 idev->dead = 1;
YOSHIFUJI Hideaki8814c4b2006-09-22 14:44:24 -07003653
3654 /* protected by rtnl_lock */
Stephen Hemmingera9b3cd72011-08-01 16:19:00 +00003655 RCU_INIT_POINTER(dev->ip6_ptr, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003656
3657 /* Step 1.5: remove snmp6 entry */
3658 snmp6_unregister_dev(idev);
3659
3660 }
3661
David Ahernf1705ec2016-02-24 09:25:37 -08003662 /* combine the user config with event to determine if permanent
3663 * addresses are to be removed from address hash table
3664 */
Ivan Vecera0aef78a2018-04-24 19:51:29 +02003665 if (!how && !idev->cnf.disable_ipv6) {
3666 /* aggregate the system setting and interface setting */
3667 int _keep_addr = net->ipv6.devconf_all->keep_addr_on_down;
3668
3669 if (!_keep_addr)
3670 _keep_addr = idev->cnf.keep_addr_on_down;
3671
3672 keep_addr = (_keep_addr > 0);
3673 }
David Ahernf1705ec2016-02-24 09:25:37 -08003674
David S. Miller73a8bd72011-01-23 23:27:15 -08003675 /* Step 2: clear hash table */
3676 for (i = 0; i < IN6_ADDR_HSIZE; i++) {
3677 struct hlist_head *h = &inet6_addr_lst[i];
David S. Miller73a8bd72011-01-23 23:27:15 -08003678
3679 spin_lock_bh(&addrconf_hash_lock);
Ian Morris67ba4152014-08-24 21:53:10 +01003680restart:
Sasha Levinb67bfe02013-02-27 17:06:00 -08003681 hlist_for_each_entry_rcu(ifa, h, addr_lst) {
David S. Miller73a8bd72011-01-23 23:27:15 -08003682 if (ifa->idev == idev) {
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01003683 addrconf_del_dad_work(ifa);
David Ahernf1705ec2016-02-24 09:25:37 -08003684 /* combined flag + permanent flag decide if
3685 * address is retained on a down event
3686 */
3687 if (!keep_addr ||
David Ahern70af9212016-04-08 12:01:21 -07003688 !(ifa->flags & IFA_F_PERMANENT) ||
3689 addr_is_local(&ifa->addr)) {
David Ahernf1705ec2016-02-24 09:25:37 -08003690 hlist_del_init_rcu(&ifa->addr_lst);
3691 goto restart;
3692 }
David S. Miller73a8bd72011-01-23 23:27:15 -08003693 }
3694 }
3695 spin_unlock_bh(&addrconf_hash_lock);
3696 }
3697
Linus Torvalds1da177e2005-04-16 15:20:36 -07003698 write_lock_bh(&idev->lock);
3699
Hannes Frederic Sowab7b1bfc2013-06-23 18:39:01 +02003700 addrconf_del_rs_timer(idev);
3701
Stephen Hemmingerbcdd5532010-03-20 16:08:18 -07003702 /* Step 2: clear flags for stateless addrconf */
Denis V. Lunev439e2382008-04-03 13:30:17 -07003703 if (!how)
YOSHIFUJI Hideaki3c21edb2005-12-21 22:57:24 +09003704 idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD|IF_READY);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003705
Stephen Hemmingerbcdd5532010-03-20 16:08:18 -07003706 /* Step 3: clear tempaddr list */
stephen hemminger372e6c82010-03-17 20:31:09 +00003707 while (!list_empty(&idev->tempaddr_list)) {
3708 ifa = list_first_entry(&idev->tempaddr_list,
3709 struct inet6_ifaddr, tmp_list);
3710 list_del(&ifa->tmp_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003711 write_unlock_bh(&idev->lock);
3712 spin_lock_bh(&ifa->lock);
3713
3714 if (ifa->ifpub) {
3715 in6_ifa_put(ifa->ifpub);
3716 ifa->ifpub = NULL;
3717 }
3718 spin_unlock_bh(&ifa->lock);
3719 in6_ifa_put(ifa);
3720 write_lock_bh(&idev->lock);
3721 }
stephen hemminger8f37ada2010-03-03 08:19:59 +00003722
David Ahernf1705ec2016-02-24 09:25:37 -08003723 list_for_each_entry_safe(ifa, tmp, &idev->addr_list, if_list) {
David Ahern8d1c8022018-04-17 17:33:26 -07003724 struct fib6_info *rt = NULL;
Rabin Vincenta2d6cbb2017-04-10 08:36:39 +02003725 bool keep;
David Ahern38bd10c2016-04-21 20:56:12 -07003726
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01003727 addrconf_del_dad_work(ifa);
stephen hemminger84e8b802010-03-02 13:32:46 +00003728
Rabin Vincenta2d6cbb2017-04-10 08:36:39 +02003729 keep = keep_addr && (ifa->flags & IFA_F_PERMANENT) &&
3730 !addr_is_local(&ifa->addr);
Rabin Vincenta2d6cbb2017-04-10 08:36:39 +02003731
David S. Miller73a8bd72011-01-23 23:27:15 -08003732 write_unlock_bh(&idev->lock);
Hannes Frederic Sowa8e8e6762015-03-23 23:36:03 +01003733 spin_lock_bh(&ifa->lock);
David Ahernf1705ec2016-02-24 09:25:37 -08003734
Rabin Vincenta2d6cbb2017-04-10 08:36:39 +02003735 if (keep) {
David Ahernf1705ec2016-02-24 09:25:37 -08003736 /* set state to skip the notifier below */
3737 state = INET6_IFADDR_STATE_DEAD;
David Ahern6d717132017-05-02 14:43:44 -07003738 ifa->state = INET6_IFADDR_STATE_PREDAD;
David Ahernf1705ec2016-02-24 09:25:37 -08003739 if (!(ifa->flags & IFA_F_NODAD))
3740 ifa->flags |= IFA_F_TENTATIVE;
David Ahern38bd10c2016-04-21 20:56:12 -07003741
3742 rt = ifa->rt;
3743 ifa->rt = NULL;
David Ahernf1705ec2016-02-24 09:25:37 -08003744 } else {
3745 state = ifa->state;
3746 ifa->state = INET6_IFADDR_STATE_DEAD;
David Ahernf1705ec2016-02-24 09:25:37 -08003747 }
3748
Hannes Frederic Sowa8e8e6762015-03-23 23:36:03 +01003749 spin_unlock_bh(&ifa->lock);
stephen hemminger84e8b802010-03-02 13:32:46 +00003750
David Ahern38bd10c2016-04-21 20:56:12 -07003751 if (rt)
David Ahernafb1d4b52018-04-17 17:33:11 -07003752 ip6_del_rt(net, rt);
David Ahern38bd10c2016-04-21 20:56:12 -07003753
David S. Miller73a8bd72011-01-23 23:27:15 -08003754 if (state != INET6_IFADDR_STATE_DEAD) {
3755 __ipv6_ifa_notify(RTM_DELADDR, ifa);
Cong Wangf88c91d2013-04-14 23:18:43 +08003756 inet6addr_notifier_call_chain(NETDEV_DOWN, ifa);
Mike Manningea06f712016-07-22 18:32:11 +01003757 } else {
3758 if (idev->cnf.forwarding)
3759 addrconf_leave_anycast(ifa);
3760 addrconf_leave_solict(ifa->idev, &ifa->addr);
stephen hemminger27bdb2a2010-04-12 05:41:32 +00003761 }
stephen hemminger8f37ada2010-03-03 08:19:59 +00003762
David S. Miller73a8bd72011-01-23 23:27:15 -08003763 write_lock_bh(&idev->lock);
Eric Dumazet8ef802a2017-10-07 19:30:23 -07003764 if (!keep) {
3765 list_del_rcu(&ifa->if_list);
3766 in6_ifa_put(ifa);
3767 }
David S. Miller73a8bd72011-01-23 23:27:15 -08003768 }
stephen hemminger8f37ada2010-03-03 08:19:59 +00003769
Linus Torvalds1da177e2005-04-16 15:20:36 -07003770 write_unlock_bh(&idev->lock);
3771
Sabrina Dubroca381f4dc2014-09-10 23:23:02 +02003772 /* Step 5: Discard anycast and multicast list */
3773 if (how) {
3774 ipv6_ac_destroy_dev(idev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003775 ipv6_mc_destroy_dev(idev);
Sabrina Dubroca381f4dc2014-09-10 23:23:02 +02003776 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003777 ipv6_mc_down(idev);
Sabrina Dubroca381f4dc2014-09-10 23:23:02 +02003778 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003779
Linus Torvalds1da177e2005-04-16 15:20:36 -07003780 idev->tstamp = jiffies;
YOSHIFUJI Hideaki1ab14572007-02-09 23:24:49 +09003781
Stephen Hemmingerbcdd5532010-03-20 16:08:18 -07003782 /* Last: Shot the device (if unregistered) */
Denis V. Lunev439e2382008-04-03 13:30:17 -07003783 if (how) {
Pavel Emelyanov408c4762008-01-10 17:41:21 -08003784 addrconf_sysctl_unregister(idev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003785 neigh_parms_release(&nd_tbl, idev->nd_parms);
3786 neigh_ifdown(&nd_tbl, dev);
3787 in6_dev_put(idev);
3788 }
3789 return 0;
3790}
3791
Kees Cooke99e88a2017-10-16 14:43:17 -07003792static void addrconf_rs_timer(struct timer_list *t)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003793{
Kees Cooke99e88a2017-10-16 14:43:17 -07003794 struct inet6_dev *idev = from_timer(idev, t, rs_timer);
Cong Wangcaf92bc2013-08-31 13:44:32 +08003795 struct net_device *dev = idev->dev;
Hannes Frederic Sowab7b1bfc2013-06-23 18:39:01 +02003796 struct in6_addr lladdr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003797
Hannes Frederic Sowab7b1bfc2013-06-23 18:39:01 +02003798 write_lock(&idev->lock);
stephen hemminger5b2a1952010-03-02 13:32:45 +00003799 if (idev->dead || !(idev->if_flags & IF_READY))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003800 goto out;
3801
Shmulik Ladkani9ba2add2012-12-02 01:44:53 +00003802 if (!ipv6_accept_ra(idev))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003803 goto out;
stephen hemminger5b2a1952010-03-02 13:32:45 +00003804
3805 /* Announcement received after solicitation was sent */
3806 if (idev->if_flags & IF_RA_RCVD)
3807 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003808
Maciej Żenczykowskibd11f072016-09-27 23:57:58 -07003809 if (idev->rs_probes++ < idev->cnf.rtr_solicits || idev->cnf.rtr_solicits < 0) {
Cong Wangcaf92bc2013-08-31 13:44:32 +08003810 write_unlock(&idev->lock);
3811 if (!ipv6_get_lladdr(dev, &lladdr, IFA_F_TENTATIVE))
3812 ndisc_send_rs(dev, &lladdr,
Hannes Frederic Sowab7b1bfc2013-06-23 18:39:01 +02003813 &in6addr_linklocal_allrouters);
3814 else
Cong Wangcaf92bc2013-08-31 13:44:32 +08003815 goto put;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003816
Cong Wangcaf92bc2013-08-31 13:44:32 +08003817 write_lock(&idev->lock);
Maciej Żenczykowskibd11f072016-09-27 23:57:58 -07003818 idev->rs_interval = rfc3315_s14_backoff_update(
3819 idev->rs_interval, idev->cnf.rtr_solicit_max_interval);
Hannes Frederic Sowab7b1bfc2013-06-23 18:39:01 +02003820 /* The wait after the last probe can be shorter */
3821 addrconf_mod_rs_timer(idev, (idev->rs_probes ==
3822 idev->cnf.rtr_solicits) ?
3823 idev->cnf.rtr_solicit_delay :
Maciej Żenczykowskibd11f072016-09-27 23:57:58 -07003824 idev->rs_interval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003825 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003826 /*
3827 * Note: we do not support deprecated "all on-link"
3828 * assumption any longer.
3829 */
Joe Perches91df42b2012-05-15 14:11:54 +00003830 pr_debug("%s: no IPv6 routers present\n", idev->dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003831 }
3832
3833out:
Hannes Frederic Sowab7b1bfc2013-06-23 18:39:01 +02003834 write_unlock(&idev->lock);
Cong Wangcaf92bc2013-08-31 13:44:32 +08003835put:
Hannes Frederic Sowab7b1bfc2013-06-23 18:39:01 +02003836 in6_dev_put(idev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003837}
3838
3839/*
3840 * Duplicate Address Detection
3841 */
YOSHIFUJI Hideaki3c21edb2005-12-21 22:57:24 +09003842static void addrconf_dad_kick(struct inet6_ifaddr *ifp)
3843{
3844 unsigned long rand_num;
3845 struct inet6_dev *idev = ifp->idev;
Erik Nordmarkadc176c2016-12-02 14:00:08 -08003846 u64 nonce;
YOSHIFUJI Hideaki3c21edb2005-12-21 22:57:24 +09003847
Neil Horman95c385b2007-04-25 17:08:10 -07003848 if (ifp->flags & IFA_F_OPTIMISTIC)
3849 rand_num = 0;
3850 else
Aruna-Hewapathirane63862b52014-01-11 07:15:59 -05003851 rand_num = prandom_u32() % (idev->cnf.rtr_solicit_delay ? : 1);
Neil Horman95c385b2007-04-25 17:08:10 -07003852
Erik Nordmarkadc176c2016-12-02 14:00:08 -08003853 nonce = 0;
3854 if (idev->cnf.enhanced_dad ||
3855 dev_net(idev->dev)->ipv6.devconf_all->enhanced_dad) {
3856 do
3857 get_random_bytes(&nonce, 6);
3858 while (nonce == 0);
3859 }
3860 ifp->dad_nonce = nonce;
Hannes Frederic Sowab7b1bfc2013-06-23 18:39:01 +02003861 ifp->dad_probes = idev->cnf.dad_transmits;
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01003862 addrconf_mod_dad_work(ifp, rand_num);
YOSHIFUJI Hideaki3c21edb2005-12-21 22:57:24 +09003863}
3864
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01003865static void addrconf_dad_begin(struct inet6_ifaddr *ifp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003866{
3867 struct inet6_dev *idev = ifp->idev;
3868 struct net_device *dev = idev->dev;
Paolo Abeni764d3be2016-11-22 16:57:40 +01003869 bool bump_id, notify = false;
David Ahernafb1d4b52018-04-17 17:33:11 -07003870 struct net *net;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003871
3872 addrconf_join_solict(dev, &ifp->addr);
3873
Aruna-Hewapathirane63862b52014-01-11 07:15:59 -05003874 prandom_seed((__force u32) ifp->addr.s6_addr32[3]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003875
3876 read_lock_bh(&idev->lock);
Herbert Xu622ccdf2010-05-18 15:56:06 -07003877 spin_lock(&ifp->lock);
Herbert Xue9d3e082010-05-18 15:36:06 -07003878 if (ifp->state == INET6_IFADDR_STATE_DEAD)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003879 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003880
David Ahernafb1d4b52018-04-17 17:33:11 -07003881 net = dev_net(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003882 if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) ||
David Ahernafb1d4b52018-04-17 17:33:11 -07003883 (net->ipv6.devconf_all->accept_dad < 1 &&
Matteo Crocea2d3f3e2017-10-05 19:03:05 +02003884 idev->cnf.accept_dad < 1) ||
Noriaki TAKAMIYA55ebaef2006-09-22 14:45:27 -07003885 !(ifp->flags&IFA_F_TENTATIVE) ||
3886 ifp->flags & IFA_F_NODAD) {
David Ahernc76fe2d2018-01-25 20:16:29 -08003887 bool send_na = false;
3888
3889 if (ifp->flags & IFA_F_TENTATIVE &&
3890 !(ifp->flags & IFA_F_OPTIMISTIC))
3891 send_na = true;
Paolo Abeni764d3be2016-11-22 16:57:40 +01003892 bump_id = ifp->flags & IFA_F_TENTATIVE;
Brian Haleycc411d02009-09-09 14:41:32 +00003893 ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED);
stephen hemminger21809fa2010-02-08 19:48:52 +00003894 spin_unlock(&ifp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003895 read_unlock_bh(&idev->lock);
3896
David Ahernc76fe2d2018-01-25 20:16:29 -08003897 addrconf_dad_completed(ifp, bump_id, send_na);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003898 return;
3899 }
3900
YOSHIFUJI Hideaki6732bad2005-12-27 13:35:15 -08003901 if (!(idev->if_flags & IF_READY)) {
stephen hemminger21809fa2010-02-08 19:48:52 +00003902 spin_unlock(&ifp->lock);
YOSHIFUJI Hideaki6732bad2005-12-27 13:35:15 -08003903 read_unlock_bh(&idev->lock);
YOSHIFUJI Hideaki3c21edb2005-12-21 22:57:24 +09003904 /*
Masatake YAMATO590a9882009-06-09 10:41:12 +09003905 * If the device is not ready:
YOSHIFUJI Hideaki3c21edb2005-12-21 22:57:24 +09003906 * - keep it tentative if it is a permanent address.
3907 * - otherwise, kill it.
3908 */
3909 in6_ifa_hold(ifp);
Brian Haleycc411d02009-09-09 14:41:32 +00003910 addrconf_dad_stop(ifp, 0);
YOSHIFUJI Hideaki6732bad2005-12-27 13:35:15 -08003911 return;
YOSHIFUJI Hideaki3c21edb2005-12-21 22:57:24 +09003912 }
Neil Horman95c385b2007-04-25 17:08:10 -07003913
3914 /*
3915 * Optimistic nodes can start receiving
3916 * Frames right away
3917 */
Erik Kline7fd25612014-10-28 18:11:14 +09003918 if (ifp->flags & IFA_F_OPTIMISTIC) {
David Ahernafb1d4b52018-04-17 17:33:11 -07003919 ip6_ins_rt(net, ifp->rt);
3920 if (ipv6_use_optimistic_addr(net, idev)) {
Erik Kline7fd25612014-10-28 18:11:14 +09003921 /* Because optimistic nodes can use this address,
3922 * notify listeners. If DAD fails, RTM_DELADDR is sent.
3923 */
subashab@codeaurora.org16186a82016-02-02 02:11:10 +00003924 notify = true;
Erik Kline7fd25612014-10-28 18:11:14 +09003925 }
3926 }
Neil Horman95c385b2007-04-25 17:08:10 -07003927
YOSHIFUJI Hideaki6732bad2005-12-27 13:35:15 -08003928 addrconf_dad_kick(ifp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003929out:
Herbert Xu622ccdf2010-05-18 15:56:06 -07003930 spin_unlock(&ifp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003931 read_unlock_bh(&idev->lock);
subashab@codeaurora.org16186a82016-02-02 02:11:10 +00003932 if (notify)
3933 ipv6_ifa_notify(RTM_NEWADDR, ifp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003934}
3935
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01003936static void addrconf_dad_start(struct inet6_ifaddr *ifp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003937{
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01003938 bool begin_dad = false;
3939
Hannes Frederic Sowa8e8e6762015-03-23 23:36:03 +01003940 spin_lock_bh(&ifp->lock);
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01003941 if (ifp->state != INET6_IFADDR_STATE_DEAD) {
3942 ifp->state = INET6_IFADDR_STATE_PREDAD;
3943 begin_dad = true;
3944 }
Hannes Frederic Sowa8e8e6762015-03-23 23:36:03 +01003945 spin_unlock_bh(&ifp->lock);
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01003946
3947 if (begin_dad)
3948 addrconf_mod_dad_work(ifp, 0);
3949}
3950
3951static void addrconf_dad_work(struct work_struct *w)
3952{
3953 struct inet6_ifaddr *ifp = container_of(to_delayed_work(w),
3954 struct inet6_ifaddr,
3955 dad_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003956 struct inet6_dev *idev = ifp->idev;
Paolo Abeni764d3be2016-11-22 16:57:40 +01003957 bool bump_id, disable_ipv6 = false;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003958 struct in6_addr mcaddr;
3959
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01003960 enum {
3961 DAD_PROCESS,
3962 DAD_BEGIN,
3963 DAD_ABORT,
3964 } action = DAD_PROCESS;
3965
3966 rtnl_lock();
3967
Hannes Frederic Sowa8e8e6762015-03-23 23:36:03 +01003968 spin_lock_bh(&ifp->lock);
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01003969 if (ifp->state == INET6_IFADDR_STATE_PREDAD) {
3970 action = DAD_BEGIN;
3971 ifp->state = INET6_IFADDR_STATE_DAD;
3972 } else if (ifp->state == INET6_IFADDR_STATE_ERRDAD) {
3973 action = DAD_ABORT;
3974 ifp->state = INET6_IFADDR_STATE_POSTDAD;
Mike Manning85b51b12016-08-18 14:39:40 +01003975
Matteo Croce35e015e2017-09-12 17:46:37 +02003976 if ((dev_net(idev->dev)->ipv6.devconf_all->accept_dad > 1 ||
3977 idev->cnf.accept_dad > 1) &&
3978 !idev->cnf.disable_ipv6 &&
Mike Manning85b51b12016-08-18 14:39:40 +01003979 !(ifp->flags & IFA_F_STABLE_PRIVACY)) {
3980 struct in6_addr addr;
3981
3982 addr.s6_addr32[0] = htonl(0xfe800000);
3983 addr.s6_addr32[1] = 0;
3984
3985 if (!ipv6_generate_eui64(addr.s6_addr + 8, idev->dev) &&
3986 ipv6_addr_equal(&ifp->addr, &addr)) {
3987 /* DAD failed for link-local based on MAC */
3988 idev->cnf.disable_ipv6 = 1;
3989
3990 pr_info("%s: IPv6 being disabled!\n",
3991 ifp->idev->dev->name);
3992 disable_ipv6 = true;
3993 }
3994 }
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01003995 }
Hannes Frederic Sowa8e8e6762015-03-23 23:36:03 +01003996 spin_unlock_bh(&ifp->lock);
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01003997
3998 if (action == DAD_BEGIN) {
3999 addrconf_dad_begin(ifp);
4000 goto out;
4001 } else if (action == DAD_ABORT) {
Wei Yongjun751eb6b2016-09-05 16:06:31 +08004002 in6_ifa_hold(ifp);
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01004003 addrconf_dad_stop(ifp, 1);
Mike Manning85b51b12016-08-18 14:39:40 +01004004 if (disable_ipv6)
4005 addrconf_ifdown(idev->dev, 0);
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01004006 goto out;
4007 }
4008
Hannes Frederic Sowab7b1bfc2013-06-23 18:39:01 +02004009 if (!ifp->dad_probes && addrconf_dad_end(ifp))
Herbert Xuf2344a12010-05-18 15:55:27 -07004010 goto out;
4011
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01004012 write_lock_bh(&idev->lock);
stephen hemminger122e4512010-03-02 13:32:44 +00004013 if (idev->dead || !(idev->if_flags & IF_READY)) {
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01004014 write_unlock_bh(&idev->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004015 goto out;
4016 }
stephen hemminger21809fa2010-02-08 19:48:52 +00004017
4018 spin_lock(&ifp->lock);
Herbert Xu622ccdf2010-05-18 15:56:06 -07004019 if (ifp->state == INET6_IFADDR_STATE_DEAD) {
4020 spin_unlock(&ifp->lock);
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01004021 write_unlock_bh(&idev->lock);
Herbert Xu622ccdf2010-05-18 15:56:06 -07004022 goto out;
4023 }
4024
Hannes Frederic Sowab7b1bfc2013-06-23 18:39:01 +02004025 if (ifp->dad_probes == 0) {
David Ahernc76fe2d2018-01-25 20:16:29 -08004026 bool send_na = false;
4027
Linus Torvalds1da177e2005-04-16 15:20:36 -07004028 /*
4029 * DAD was successful
4030 */
4031
David Ahernc76fe2d2018-01-25 20:16:29 -08004032 if (ifp->flags & IFA_F_TENTATIVE &&
4033 !(ifp->flags & IFA_F_OPTIMISTIC))
4034 send_na = true;
Paolo Abeni764d3be2016-11-22 16:57:40 +01004035 bump_id = ifp->flags & IFA_F_TENTATIVE;
Brian Haleycc411d02009-09-09 14:41:32 +00004036 ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED);
stephen hemminger21809fa2010-02-08 19:48:52 +00004037 spin_unlock(&ifp->lock);
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01004038 write_unlock_bh(&idev->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004039
David Ahernc76fe2d2018-01-25 20:16:29 -08004040 addrconf_dad_completed(ifp, bump_id, send_na);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004041
4042 goto out;
4043 }
4044
Hannes Frederic Sowab7b1bfc2013-06-23 18:39:01 +02004045 ifp->dad_probes--;
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01004046 addrconf_mod_dad_work(ifp,
4047 NEIGH_VAR(ifp->idev->nd_parms, RETRANS_TIME));
stephen hemminger21809fa2010-02-08 19:48:52 +00004048 spin_unlock(&ifp->lock);
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01004049 write_unlock_bh(&idev->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004050
4051 /* send a neighbour solicitation for our addr */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004052 addrconf_addr_solict_mult(&ifp->addr, &mcaddr);
Erik Nordmarkadc176c2016-12-02 14:00:08 -08004053 ndisc_send_ns(ifp->idev->dev, &ifp->addr, &mcaddr, &in6addr_any,
4054 ifp->dad_nonce);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004055out:
4056 in6_ifa_put(ifp);
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01004057 rtnl_unlock();
Linus Torvalds1da177e2005-04-16 15:20:36 -07004058}
4059
Hannes Frederic Sowa11ffff72014-01-16 20:13:04 +01004060/* ifp->idev must be at least read locked */
4061static bool ipv6_lonely_lladdr(struct inet6_ifaddr *ifp)
4062{
4063 struct inet6_ifaddr *ifpiter;
4064 struct inet6_dev *idev = ifp->idev;
4065
Hannes Frederic Sowa602582c2014-01-19 21:58:19 +01004066 list_for_each_entry_reverse(ifpiter, &idev->addr_list, if_list) {
4067 if (ifpiter->scope > IFA_LINK)
4068 break;
Hannes Frederic Sowa11ffff72014-01-16 20:13:04 +01004069 if (ifp != ifpiter && ifpiter->scope == IFA_LINK &&
4070 (ifpiter->flags & (IFA_F_PERMANENT|IFA_F_TENTATIVE|
4071 IFA_F_OPTIMISTIC|IFA_F_DADFAILED)) ==
4072 IFA_F_PERMANENT)
4073 return false;
4074 }
4075 return true;
4076}
4077
David Ahernc76fe2d2018-01-25 20:16:29 -08004078static void addrconf_dad_completed(struct inet6_ifaddr *ifp, bool bump_id,
4079 bool send_na)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004080{
Stephen Hemmingere21e8462010-03-20 16:09:01 -07004081 struct net_device *dev = ifp->idev->dev;
Hannes Frederic Sowab7b1bfc2013-06-23 18:39:01 +02004082 struct in6_addr lladdr;
Hannes Frederic Sowab173ee42013-06-27 00:07:01 +02004083 bool send_rs, send_mld;
Hannes Frederic Sowab7b1bfc2013-06-23 18:39:01 +02004084
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01004085 addrconf_del_dad_work(ifp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004086
4087 /*
4088 * Configure the address for reception. Now it is valid.
4089 */
4090
4091 ipv6_ifa_notify(RTM_NEWADDR, ifp);
4092
Tore Anderson026359b2011-08-28 23:47:33 +00004093 /* If added prefix is link local and we are prepared to process
4094 router advertisements, start sending router solicitations.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004095 */
4096
Hannes Frederic Sowa1ec047e2013-06-27 00:06:56 +02004097 read_lock_bh(&ifp->idev->lock);
Hannes Frederic Sowa11ffff72014-01-16 20:13:04 +01004098 send_mld = ifp->scope == IFA_LINK && ipv6_lonely_lladdr(ifp);
Hannes Frederic Sowab173ee42013-06-27 00:07:01 +02004099 send_rs = send_mld &&
4100 ipv6_accept_ra(ifp->idev) &&
Maciej Żenczykowskibd11f072016-09-27 23:57:58 -07004101 ifp->idev->cnf.rtr_solicits != 0 &&
Hannes Frederic Sowab173ee42013-06-27 00:07:01 +02004102 (dev->flags&IFF_LOOPBACK) == 0;
Hannes Frederic Sowa1ec047e2013-06-27 00:06:56 +02004103 read_unlock_bh(&ifp->idev->lock);
4104
Hannes Frederic Sowab173ee42013-06-27 00:07:01 +02004105 /* While dad is in progress mld report's source address is in6_addrany.
4106 * Resend with proper ll now.
4107 */
4108 if (send_mld)
4109 ipv6_mc_dad_complete(ifp->idev);
4110
David Ahernc76fe2d2018-01-25 20:16:29 -08004111 /* send unsolicited NA if enabled */
4112 if (send_na &&
4113 (ifp->idev->cnf.ndisc_notify ||
4114 dev_net(dev)->ipv6.devconf_all->ndisc_notify)) {
4115 ndisc_send_na(dev, &in6addr_linklocal_allnodes, &ifp->addr,
4116 /*router=*/ !!ifp->idev->cnf.forwarding,
4117 /*solicited=*/ false, /*override=*/ true,
4118 /*inc_opt=*/ true);
4119 }
4120
Hannes Frederic Sowa1ec047e2013-06-27 00:06:56 +02004121 if (send_rs) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004122 /*
4123 * If a host as already performed a random delay
4124 * [...] as part of DAD [...] there is no need
4125 * to delay again before sending the first RS
4126 */
Hannes Frederic Sowa1ec047e2013-06-27 00:06:56 +02004127 if (ipv6_get_lladdr(dev, &lladdr, IFA_F_TENTATIVE))
Hannes Frederic Sowab7b1bfc2013-06-23 18:39:01 +02004128 return;
Hannes Frederic Sowa1ec047e2013-06-27 00:06:56 +02004129 ndisc_send_rs(dev, &lladdr, &in6addr_linklocal_allrouters);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004130
Hannes Frederic Sowab7b1bfc2013-06-23 18:39:01 +02004131 write_lock_bh(&ifp->idev->lock);
4132 spin_lock(&ifp->lock);
Maciej Żenczykowskibd11f072016-09-27 23:57:58 -07004133 ifp->idev->rs_interval = rfc3315_s14_backoff_init(
4134 ifp->idev->cnf.rtr_solicit_interval);
Hannes Frederic Sowab7b1bfc2013-06-23 18:39:01 +02004135 ifp->idev->rs_probes = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004136 ifp->idev->if_flags |= IF_RS_SENT;
Maciej Żenczykowskibd11f072016-09-27 23:57:58 -07004137 addrconf_mod_rs_timer(ifp->idev, ifp->idev->rs_interval);
Hannes Frederic Sowab7b1bfc2013-06-23 18:39:01 +02004138 spin_unlock(&ifp->lock);
4139 write_unlock_bh(&ifp->idev->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004140 }
Paolo Abeni764d3be2016-11-22 16:57:40 +01004141
4142 if (bump_id)
4143 rt_genid_bump_ipv6(dev_net(dev));
Marcus Huewea11a7f72017-02-06 18:34:56 +01004144
4145 /* Make sure that a new temporary address will be created
4146 * before this temporary address becomes deprecated.
4147 */
4148 if (ifp->flags & IFA_F_TEMPORARY)
4149 addrconf_verify_rtnl();
Linus Torvalds1da177e2005-04-16 15:20:36 -07004150}
4151
Stephen Hemmingere21e8462010-03-20 16:09:01 -07004152static void addrconf_dad_run(struct inet6_dev *idev)
4153{
YOSHIFUJI Hideakic5e33bd2005-12-21 22:57:44 +09004154 struct inet6_ifaddr *ifp;
4155
4156 read_lock_bh(&idev->lock);
stephen hemminger502a2ff2010-03-17 20:31:13 +00004157 list_for_each_entry(ifp, &idev->addr_list, if_list) {
stephen hemminger21809fa2010-02-08 19:48:52 +00004158 spin_lock(&ifp->lock);
Herbert Xuf2344a12010-05-18 15:55:27 -07004159 if (ifp->flags & IFA_F_TENTATIVE &&
4160 ifp->state == INET6_IFADDR_STATE_DAD)
4161 addrconf_dad_kick(ifp);
stephen hemminger21809fa2010-02-08 19:48:52 +00004162 spin_unlock(&ifp->lock);
YOSHIFUJI Hideakic5e33bd2005-12-21 22:57:44 +09004163 }
4164 read_unlock_bh(&idev->lock);
4165}
4166
Linus Torvalds1da177e2005-04-16 15:20:36 -07004167#ifdef CONFIG_PROC_FS
4168struct if6_iter_state {
Daniel Lezcano3c400902008-01-10 22:42:49 -08004169 struct seq_net_private p;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004170 int bucket;
Mihai Maruseac1d578302012-01-03 23:31:35 +00004171 int offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004172};
4173
Mihai Maruseac1d578302012-01-03 23:31:35 +00004174static struct inet6_ifaddr *if6_get_first(struct seq_file *seq, loff_t pos)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004175{
Linus Torvalds1da177e2005-04-16 15:20:36 -07004176 struct if6_iter_state *state = seq->private;
YOSHIFUJI Hideaki12188542008-03-26 02:36:06 +09004177 struct net *net = seq_file_net(seq);
Eric Dumazeta5c1d982017-10-23 16:17:50 -07004178 struct inet6_ifaddr *ifa = NULL;
Mihai Maruseac1d578302012-01-03 23:31:35 +00004179 int p = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004180
Mihai Maruseac1d578302012-01-03 23:31:35 +00004181 /* initial bucket if pos is 0 */
4182 if (pos == 0) {
4183 state->bucket = 0;
4184 state->offset = 0;
4185 }
4186
4187 for (; state->bucket < IN6_ADDR_HSIZE; ++state->bucket) {
Eric Dumazeta5c1d982017-10-23 16:17:50 -07004188 hlist_for_each_entry_rcu(ifa, &inet6_addr_lst[state->bucket],
Mihai Maruseac1d578302012-01-03 23:31:35 +00004189 addr_lst) {
Eric Dumazet9f0d3c22012-10-16 07:37:27 +00004190 if (!net_eq(dev_net(ifa->idev->dev), net))
4191 continue;
Mihai Maruseac1d578302012-01-03 23:31:35 +00004192 /* sync with offset */
4193 if (p < state->offset) {
4194 p++;
4195 continue;
4196 }
4197 state->offset++;
Eric Dumazet9f0d3c22012-10-16 07:37:27 +00004198 return ifa;
Mihai Maruseac1d578302012-01-03 23:31:35 +00004199 }
4200
4201 /* prepare for next bucket */
4202 state->offset = 0;
4203 p = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004204 }
stephen hemmingerc2e21292010-03-17 20:31:10 +00004205 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004206}
4207
stephen hemmingerc2e21292010-03-17 20:31:10 +00004208static struct inet6_ifaddr *if6_get_next(struct seq_file *seq,
4209 struct inet6_ifaddr *ifa)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004210{
4211 struct if6_iter_state *state = seq->private;
YOSHIFUJI Hideaki12188542008-03-26 02:36:06 +09004212 struct net *net = seq_file_net(seq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004213
Eric Dumazeta5c1d982017-10-23 16:17:50 -07004214 hlist_for_each_entry_continue_rcu(ifa, addr_lst) {
Eric Dumazet9f0d3c22012-10-16 07:37:27 +00004215 if (!net_eq(dev_net(ifa->idev->dev), net))
4216 continue;
Mihai Maruseac1d578302012-01-03 23:31:35 +00004217 state->offset++;
Eric Dumazet9f0d3c22012-10-16 07:37:27 +00004218 return ifa;
Mihai Maruseac1d578302012-01-03 23:31:35 +00004219 }
stephen hemmingerc2e21292010-03-17 20:31:10 +00004220
4221 while (++state->bucket < IN6_ADDR_HSIZE) {
Mihai Maruseac1d578302012-01-03 23:31:35 +00004222 state->offset = 0;
Eric Dumazeta5c1d982017-10-23 16:17:50 -07004223 hlist_for_each_entry_rcu(ifa,
stephen hemmingerc2e21292010-03-17 20:31:10 +00004224 &inet6_addr_lst[state->bucket], addr_lst) {
Eric Dumazet9f0d3c22012-10-16 07:37:27 +00004225 if (!net_eq(dev_net(ifa->idev->dev), net))
4226 continue;
Mihai Maruseac1d578302012-01-03 23:31:35 +00004227 state->offset++;
Eric Dumazet9f0d3c22012-10-16 07:37:27 +00004228 return ifa;
Daniel Lezcano3c400902008-01-10 22:42:49 -08004229 }
4230 }
4231
stephen hemmingerc2e21292010-03-17 20:31:10 +00004232 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004233}
4234
Linus Torvalds1da177e2005-04-16 15:20:36 -07004235static void *if6_seq_start(struct seq_file *seq, loff_t *pos)
Eric Dumazeta5c1d982017-10-23 16:17:50 -07004236 __acquires(rcu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004237{
Eric Dumazeta5c1d982017-10-23 16:17:50 -07004238 rcu_read_lock();
Mihai Maruseac1d578302012-01-03 23:31:35 +00004239 return if6_get_first(seq, *pos);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004240}
4241
4242static void *if6_seq_next(struct seq_file *seq, void *v, loff_t *pos)
4243{
4244 struct inet6_ifaddr *ifa;
4245
4246 ifa = if6_get_next(seq, v);
4247 ++*pos;
4248 return ifa;
4249}
4250
4251static void if6_seq_stop(struct seq_file *seq, void *v)
Eric Dumazeta5c1d982017-10-23 16:17:50 -07004252 __releases(rcu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004253{
Eric Dumazeta5c1d982017-10-23 16:17:50 -07004254 rcu_read_unlock();
Linus Torvalds1da177e2005-04-16 15:20:36 -07004255}
4256
4257static int if6_seq_show(struct seq_file *seq, void *v)
4258{
4259 struct inet6_ifaddr *ifp = (struct inet6_ifaddr *)v;
Jiri Pirko971a3512013-12-10 13:56:29 +01004260 seq_printf(seq, "%pi6 %02x %02x %02x %02x %8s\n",
Harvey Harrisonb0711952008-10-28 16:05:40 -07004261 &ifp->addr,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004262 ifp->idev->dev->ifindex,
4263 ifp->prefix_len,
4264 ifp->scope,
Jiri Pirko971a3512013-12-10 13:56:29 +01004265 (u8) ifp->flags,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004266 ifp->idev->dev->name);
4267 return 0;
4268}
4269
Philippe De Muyter56b3d972007-07-10 23:07:31 -07004270static const struct seq_operations if6_seq_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004271 .start = if6_seq_start,
4272 .next = if6_seq_next,
4273 .show = if6_seq_show,
4274 .stop = if6_seq_stop,
4275};
4276
4277static int if6_seq_open(struct inode *inode, struct file *file)
4278{
Daniel Lezcano3c400902008-01-10 22:42:49 -08004279 return seq_open_net(inode, file, &if6_seq_ops,
4280 sizeof(struct if6_iter_state));
Linus Torvalds1da177e2005-04-16 15:20:36 -07004281}
4282
Arjan van de Ven9a321442007-02-12 00:55:35 -08004283static const struct file_operations if6_fops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004284 .open = if6_seq_open,
4285 .read = seq_read,
4286 .llseek = seq_lseek,
Daniel Lezcano3c400902008-01-10 22:42:49 -08004287 .release = seq_release_net,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004288};
4289
Alexey Dobriyan2c8c1e72010-01-17 03:35:32 +00004290static int __net_init if6_proc_net_init(struct net *net)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004291{
Joe Perchesd6444062018-03-23 15:54:38 -07004292 if (!proc_create("if_inet6", 0444, net->proc_net, &if6_fops))
Linus Torvalds1da177e2005-04-16 15:20:36 -07004293 return -ENOMEM;
4294 return 0;
4295}
4296
Alexey Dobriyan2c8c1e72010-01-17 03:35:32 +00004297static void __net_exit if6_proc_net_exit(struct net *net)
Daniel Lezcano3c400902008-01-10 22:42:49 -08004298{
Gao fengece31ff2013-02-18 01:34:56 +00004299 remove_proc_entry("if_inet6", net->proc_net);
Daniel Lezcano3c400902008-01-10 22:42:49 -08004300}
4301
4302static struct pernet_operations if6_proc_net_ops = {
Ian Morris67ba4152014-08-24 21:53:10 +01004303 .init = if6_proc_net_init,
4304 .exit = if6_proc_net_exit,
Daniel Lezcano3c400902008-01-10 22:42:49 -08004305};
4306
4307int __init if6_proc_init(void)
4308{
4309 return register_pernet_subsys(&if6_proc_net_ops);
4310}
4311
Linus Torvalds1da177e2005-04-16 15:20:36 -07004312void if6_proc_exit(void)
4313{
Daniel Lezcano3c400902008-01-10 22:42:49 -08004314 unregister_pernet_subsys(&if6_proc_net_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004315}
4316#endif /* CONFIG_PROC_FS */
4317
Amerigo Wang07a93622012-10-29 16:23:10 +00004318#if IS_ENABLED(CONFIG_IPV6_MIP6)
Noriaki TAKAMIYA3b9f9a12006-09-22 14:45:56 -07004319/* Check if address is a home address configured on any interface. */
Eric Dumazetb71d1d42011-04-22 04:53:02 +00004320int ipv6_chk_home_addr(struct net *net, const struct in6_addr *addr)
Noriaki TAKAMIYA3b9f9a12006-09-22 14:45:56 -07004321{
Eric Dumazet3f27fb22017-10-23 16:17:47 -07004322 unsigned int hash = inet6_addr_hash(net, addr);
stephen hemmingerc2e21292010-03-17 20:31:10 +00004323 struct inet6_ifaddr *ifp = NULL;
Eric Dumazet3f27fb22017-10-23 16:17:47 -07004324 int ret = 0;
stephen hemmingerc2e21292010-03-17 20:31:10 +00004325
Eric Dumazet4e5f47a2017-10-23 16:17:51 -07004326 rcu_read_lock();
4327 hlist_for_each_entry_rcu(ifp, &inet6_addr_lst[hash], addr_lst) {
YOSHIFUJI Hideaki878628f2008-03-26 03:57:35 +09004328 if (!net_eq(dev_net(ifp->idev->dev), net))
Daniel Lezcano389f6612008-01-10 22:44:40 -08004329 continue;
YOSHIFUJI Hideakicaad2952008-04-10 15:42:07 +09004330 if (ipv6_addr_equal(&ifp->addr, addr) &&
Noriaki TAKAMIYA3b9f9a12006-09-22 14:45:56 -07004331 (ifp->flags & IFA_F_HOMEADDRESS)) {
4332 ret = 1;
4333 break;
4334 }
4335 }
Eric Dumazet4e5f47a2017-10-23 16:17:51 -07004336 rcu_read_unlock();
Noriaki TAKAMIYA3b9f9a12006-09-22 14:45:56 -07004337 return ret;
4338}
4339#endif
4340
Linus Torvalds1da177e2005-04-16 15:20:36 -07004341/*
4342 * Periodic address status verification
4343 */
4344
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01004345static void addrconf_verify_rtnl(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004346{
YOSHIFUJI Hideakib2db7562010-03-20 16:11:12 -07004347 unsigned long now, next, next_sec, next_sched;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004348 struct inet6_ifaddr *ifp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004349 int i;
4350
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01004351 ASSERT_RTNL();
4352
stephen hemminger5c578aed2010-03-17 20:31:11 +00004353 rcu_read_lock_bh();
Linus Torvalds1da177e2005-04-16 15:20:36 -07004354 now = jiffies;
YOSHIFUJI Hideakib2db7562010-03-20 16:11:12 -07004355 next = round_jiffies_up(now + ADDR_CHECK_FREQUENCY);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004356
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01004357 cancel_delayed_work(&addr_chk_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004358
Stephen Hemmingerbcdd5532010-03-20 16:08:18 -07004359 for (i = 0; i < IN6_ADDR_HSIZE; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004360restart:
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01004361 hlist_for_each_entry_rcu_bh(ifp, &inet6_addr_lst[i], addr_lst) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004362 unsigned long age;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004363
Yasushi Asanofad8da32013-12-31 12:04:19 +09004364 /* When setting preferred_lft to a value not zero or
4365 * infinity, while valid_lft is infinity
4366 * IFA_F_PERMANENT has a non-infinity life time.
4367 */
4368 if ((ifp->flags & IFA_F_PERMANENT) &&
4369 (ifp->prefered_lft == INFINITY_LIFE_TIME))
Linus Torvalds1da177e2005-04-16 15:20:36 -07004370 continue;
4371
4372 spin_lock(&ifp->lock);
YOSHIFUJI Hideakib2db7562010-03-20 16:11:12 -07004373 /* We try to batch several events at once. */
4374 age = (now - ifp->tstamp + ADDRCONF_TIMER_FUZZ_MINUS) / HZ;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004375
YOSHIFUJI Hideaki8f27ebb2006-07-28 18:12:11 +09004376 if (ifp->valid_lft != INFINITY_LIFE_TIME &&
4377 age >= ifp->valid_lft) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004378 spin_unlock(&ifp->lock);
4379 in6_ifa_hold(ifp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004380 ipv6_del_addr(ifp);
4381 goto restart;
YOSHIFUJI Hideaki8f27ebb2006-07-28 18:12:11 +09004382 } else if (ifp->prefered_lft == INFINITY_LIFE_TIME) {
4383 spin_unlock(&ifp->lock);
4384 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004385 } else if (age >= ifp->prefered_lft) {
Brian Haleya1ed0522009-07-02 07:10:52 +00004386 /* jiffies - ifp->tstamp > age >= ifp->prefered_lft */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004387 int deprecate = 0;
4388
4389 if (!(ifp->flags&IFA_F_DEPRECATED)) {
4390 deprecate = 1;
4391 ifp->flags |= IFA_F_DEPRECATED;
4392 }
4393
Yasushi Asanofad8da32013-12-31 12:04:19 +09004394 if ((ifp->valid_lft != INFINITY_LIFE_TIME) &&
4395 (time_before(ifp->tstamp + ifp->valid_lft * HZ, next)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07004396 next = ifp->tstamp + ifp->valid_lft * HZ;
4397
4398 spin_unlock(&ifp->lock);
4399
4400 if (deprecate) {
4401 in6_ifa_hold(ifp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004402
4403 ipv6_ifa_notify(0, ifp);
4404 in6_ifa_put(ifp);
4405 goto restart;
4406 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004407 } else if ((ifp->flags&IFA_F_TEMPORARY) &&
4408 !(ifp->flags&IFA_F_TENTATIVE)) {
stephen hemminger88949cf2010-03-17 20:31:17 +00004409 unsigned long regen_advance = ifp->idev->cnf.regen_max_retry *
4410 ifp->idev->cnf.dad_transmits *
Jiri Pirko1f9248e2013-12-07 19:26:53 +01004411 NEIGH_VAR(ifp->idev->nd_parms, RETRANS_TIME) / HZ;
stephen hemminger88949cf2010-03-17 20:31:17 +00004412
Linus Torvalds1da177e2005-04-16 15:20:36 -07004413 if (age >= ifp->prefered_lft - regen_advance) {
4414 struct inet6_ifaddr *ifpub = ifp->ifpub;
4415 if (time_before(ifp->tstamp + ifp->prefered_lft * HZ, next))
4416 next = ifp->tstamp + ifp->prefered_lft * HZ;
4417 if (!ifp->regen_count && ifpub) {
4418 ifp->regen_count++;
4419 in6_ifa_hold(ifp);
4420 in6_ifa_hold(ifpub);
4421 spin_unlock(&ifp->lock);
stephen hemminger5c578aed2010-03-17 20:31:11 +00004422
Hiroyuki YAMAMORI291d8092005-12-23 11:24:05 -08004423 spin_lock(&ifpub->lock);
4424 ifpub->regen_count = 0;
4425 spin_unlock(&ifpub->lock);
Eric Dumazete64e4692018-01-26 16:10:43 -08004426 rcu_read_unlock_bh();
Eric Dumazetfffcefe2017-11-06 14:13:29 -08004427 ipv6_create_tempaddr(ifpub, ifp, true);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004428 in6_ifa_put(ifpub);
4429 in6_ifa_put(ifp);
Eric Dumazete64e4692018-01-26 16:10:43 -08004430 rcu_read_lock_bh();
Linus Torvalds1da177e2005-04-16 15:20:36 -07004431 goto restart;
4432 }
4433 } else if (time_before(ifp->tstamp + ifp->prefered_lft * HZ - regen_advance * HZ, next))
4434 next = ifp->tstamp + ifp->prefered_lft * HZ - regen_advance * HZ;
4435 spin_unlock(&ifp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004436 } else {
4437 /* ifp->prefered_lft <= ifp->valid_lft */
4438 if (time_before(ifp->tstamp + ifp->prefered_lft * HZ, next))
4439 next = ifp->tstamp + ifp->prefered_lft * HZ;
4440 spin_unlock(&ifp->lock);
4441 }
4442 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004443 }
4444
YOSHIFUJI Hideakib2db7562010-03-20 16:11:12 -07004445 next_sec = round_jiffies_up(next);
4446 next_sched = next;
4447
4448 /* If rounded timeout is accurate enough, accept it. */
4449 if (time_before(next_sec, next + ADDRCONF_TIMER_FUZZ))
4450 next_sched = next_sec;
4451
4452 /* And minimum interval is ADDRCONF_TIMER_FUZZ_MAX. */
4453 if (time_before(next_sched, jiffies + ADDRCONF_TIMER_FUZZ_MAX))
4454 next_sched = jiffies + ADDRCONF_TIMER_FUZZ_MAX;
4455
Joe Perchese32ac252018-03-26 08:35:01 -07004456 pr_debug("now = %lu, schedule = %lu, rounded schedule = %lu => %lu\n",
4457 now, next, next_sec, next_sched);
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01004458 mod_delayed_work(addrconf_wq, &addr_chk_work, next_sched - now);
stephen hemminger5c578aed2010-03-17 20:31:11 +00004459 rcu_read_unlock_bh();
Linus Torvalds1da177e2005-04-16 15:20:36 -07004460}
4461
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01004462static void addrconf_verify_work(struct work_struct *w)
4463{
4464 rtnl_lock();
4465 addrconf_verify_rtnl();
4466 rtnl_unlock();
4467}
4468
4469static void addrconf_verify(void)
4470{
4471 mod_delayed_work(addrconf_wq, &addr_chk_work, 0);
4472}
4473
Nicolas Dichtelcaeaba72013-05-16 22:32:00 +00004474static struct in6_addr *extract_addr(struct nlattr *addr, struct nlattr *local,
4475 struct in6_addr **peer_pfx)
Thomas Graf461d8832006-09-18 00:09:49 -07004476{
4477 struct in6_addr *pfx = NULL;
4478
Nicolas Dichtelcaeaba72013-05-16 22:32:00 +00004479 *peer_pfx = NULL;
4480
Thomas Graf461d8832006-09-18 00:09:49 -07004481 if (addr)
4482 pfx = nla_data(addr);
4483
4484 if (local) {
4485 if (pfx && nla_memcmp(local, pfx, sizeof(*pfx)))
Nicolas Dichtelcaeaba72013-05-16 22:32:00 +00004486 *peer_pfx = pfx;
4487 pfx = nla_data(local);
Thomas Graf461d8832006-09-18 00:09:49 -07004488 }
4489
4490 return pfx;
4491}
4492
Patrick McHardyef7c79e2007-06-05 12:38:30 -07004493static const struct nla_policy ifa_ipv6_policy[IFA_MAX+1] = {
Thomas Graf461d8832006-09-18 00:09:49 -07004494 [IFA_ADDRESS] = { .len = sizeof(struct in6_addr) },
4495 [IFA_LOCAL] = { .len = sizeof(struct in6_addr) },
4496 [IFA_CACHEINFO] = { .len = sizeof(struct ifa_cacheinfo) },
Jiri Pirko479840f2013-12-06 09:45:21 +01004497 [IFA_FLAGS] = { .len = sizeof(u32) },
Thomas Graf461d8832006-09-18 00:09:49 -07004498};
4499
Linus Torvalds1da177e2005-04-16 15:20:36 -07004500static int
David Ahernc21ef3e2017-04-16 09:48:24 -07004501inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh,
4502 struct netlink_ext_ack *extack)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004503{
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09004504 struct net *net = sock_net(skb->sk);
Thomas Grafb933f712006-09-18 00:10:19 -07004505 struct ifaddrmsg *ifm;
4506 struct nlattr *tb[IFA_MAX+1];
Nicolas Dichtelcaeaba72013-05-16 22:32:00 +00004507 struct in6_addr *pfx, *peer_pfx;
Heiner Kallweit6046d5b2014-04-20 21:29:36 +02004508 u32 ifa_flags;
Thomas Grafb933f712006-09-18 00:10:19 -07004509 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004510
Johannes Bergfceb6432017-04-12 14:34:07 +02004511 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy,
David Ahernc21ef3e2017-04-16 09:48:24 -07004512 extack);
Thomas Grafb933f712006-09-18 00:10:19 -07004513 if (err < 0)
4514 return err;
4515
4516 ifm = nlmsg_data(nlh);
Nicolas Dichtelcaeaba72013-05-16 22:32:00 +00004517 pfx = extract_addr(tb[IFA_ADDRESS], tb[IFA_LOCAL], &peer_pfx);
Ian Morris63159f22015-03-29 14:00:04 +01004518 if (!pfx)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004519 return -EINVAL;
4520
Heiner Kallweit6046d5b2014-04-20 21:29:36 +02004521 ifa_flags = tb[IFA_FLAGS] ? nla_get_u32(tb[IFA_FLAGS]) : ifm->ifa_flags;
4522
4523 /* We ignore other flags so far. */
4524 ifa_flags &= IFA_F_MANAGETEMPADDR;
4525
4526 return inet6_addr_del(net, ifm->ifa_index, ifa_flags, pfx,
4527 ifm->ifa_prefixlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004528}
4529
Jiri Pirko479840f2013-12-06 09:45:21 +01004530static int inet6_addr_modify(struct inet6_ifaddr *ifp, u32 ifa_flags,
Noriaki TAKAMIYA55ebaef2006-09-22 14:45:27 -07004531 u32 prefered_lft, u32 valid_lft)
Noriaki TAKAMIYA081bba52006-07-28 18:12:13 +09004532{
YOSHIFUJI Hideaki6f704992008-05-19 16:56:11 -07004533 u32 flags;
4534 clock_t expires;
YOSHIFUJI Hideaki4bed72e2008-05-27 17:37:49 +09004535 unsigned long timeout;
Jiri Pirko53bd6742013-12-06 09:45:22 +01004536 bool was_managetempaddr;
Thomas Haller5b84efe2014-01-15 15:36:59 +01004537 bool had_prefixroute;
YOSHIFUJI Hideaki46d48042007-02-07 20:36:26 +09004538
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01004539 ASSERT_RTNL();
4540
Noriaki TAKAMIYA081bba52006-07-28 18:12:13 +09004541 if (!valid_lft || (prefered_lft > valid_lft))
4542 return -EINVAL;
4543
Jiri Pirko53bd6742013-12-06 09:45:22 +01004544 if (ifa_flags & IFA_F_MANAGETEMPADDR &&
4545 (ifp->flags & IFA_F_TEMPORARY || ifp->prefix_len != 64))
4546 return -EINVAL;
4547
Sabrina Dubrocaf1c02cf2018-02-28 16:40:08 +01004548 if (!(ifp->flags & IFA_F_TENTATIVE) || ifp->flags & IFA_F_DADFAILED)
4549 ifa_flags &= ~IFA_F_OPTIMISTIC;
4550
YOSHIFUJI Hideaki4bed72e2008-05-27 17:37:49 +09004551 timeout = addrconf_timeout_fixup(valid_lft, HZ);
4552 if (addrconf_finite_timeout(timeout)) {
4553 expires = jiffies_to_clock_t(timeout * HZ);
4554 valid_lft = timeout;
YOSHIFUJI Hideaki6f704992008-05-19 16:56:11 -07004555 flags = RTF_EXPIRES;
YOSHIFUJI Hideaki4bed72e2008-05-27 17:37:49 +09004556 } else {
4557 expires = 0;
4558 flags = 0;
4559 ifa_flags |= IFA_F_PERMANENT;
YOSHIFUJI Hideaki6f704992008-05-19 16:56:11 -07004560 }
Noriaki TAKAMIYA081bba52006-07-28 18:12:13 +09004561
YOSHIFUJI Hideaki4bed72e2008-05-27 17:37:49 +09004562 timeout = addrconf_timeout_fixup(prefered_lft, HZ);
4563 if (addrconf_finite_timeout(timeout)) {
4564 if (timeout == 0)
4565 ifa_flags |= IFA_F_DEPRECATED;
4566 prefered_lft = timeout;
4567 }
Noriaki TAKAMIYA081bba52006-07-28 18:12:13 +09004568
4569 spin_lock_bh(&ifp->lock);
Jiri Pirko53bd6742013-12-06 09:45:22 +01004570 was_managetempaddr = ifp->flags & IFA_F_MANAGETEMPADDR;
Thomas Haller5b84efe2014-01-15 15:36:59 +01004571 had_prefixroute = ifp->flags & IFA_F_PERMANENT &&
4572 !(ifp->flags & IFA_F_NOPREFIXROUTE);
Jiri Pirko53bd6742013-12-06 09:45:22 +01004573 ifp->flags &= ~(IFA_F_DEPRECATED | IFA_F_PERMANENT | IFA_F_NODAD |
Thomas Haller761aac72014-01-15 15:36:58 +01004574 IFA_F_HOMEADDRESS | IFA_F_MANAGETEMPADDR |
4575 IFA_F_NOPREFIXROUTE);
Jiri Pirko53bd6742013-12-06 09:45:22 +01004576 ifp->flags |= ifa_flags;
Noriaki TAKAMIYA081bba52006-07-28 18:12:13 +09004577 ifp->tstamp = jiffies;
4578 ifp->valid_lft = valid_lft;
4579 ifp->prefered_lft = prefered_lft;
4580
4581 spin_unlock_bh(&ifp->lock);
4582 if (!(ifp->flags&IFA_F_TENTATIVE))
4583 ipv6_ifa_notify(0, ifp);
Noriaki TAKAMIYA081bba52006-07-28 18:12:13 +09004584
Thomas Haller761aac72014-01-15 15:36:58 +01004585 if (!(ifa_flags & IFA_F_NOPREFIXROUTE)) {
David Ahernacb54e32018-04-17 17:33:22 -07004586 addrconf_prefix_route(&ifp->addr, ifp->prefix_len,
4587 ifp->idev->dev, expires, flags,
4588 GFP_KERNEL);
Thomas Haller5b84efe2014-01-15 15:36:59 +01004589 } else if (had_prefixroute) {
4590 enum cleanup_prefix_rt_t action;
4591 unsigned long rt_expires;
4592
4593 write_lock_bh(&ifp->idev->lock);
4594 action = check_cleanup_prefix_route(ifp, &rt_expires);
4595 write_unlock_bh(&ifp->idev->lock);
4596
4597 if (action != CLEANUP_PREFIX_RT_NOP) {
4598 cleanup_prefix_route(ifp, rt_expires,
4599 action == CLEANUP_PREFIX_RT_DEL);
4600 }
Thomas Haller761aac72014-01-15 15:36:58 +01004601 }
Jiri Pirko53bd6742013-12-06 09:45:22 +01004602
4603 if (was_managetempaddr || ifp->flags & IFA_F_MANAGETEMPADDR) {
4604 if (was_managetempaddr && !(ifp->flags & IFA_F_MANAGETEMPADDR))
4605 valid_lft = prefered_lft = 0;
4606 manage_tempaddrs(ifp->idev, ifp, valid_lft, prefered_lft,
4607 !was_managetempaddr, jiffies);
4608 }
4609
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01004610 addrconf_verify_rtnl();
Noriaki TAKAMIYA081bba52006-07-28 18:12:13 +09004611
4612 return 0;
4613}
4614
4615static int
David Ahernc21ef3e2017-04-16 09:48:24 -07004616inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh,
4617 struct netlink_ext_ack *extack)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004618{
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09004619 struct net *net = sock_net(skb->sk);
Thomas Graf461d8832006-09-18 00:09:49 -07004620 struct ifaddrmsg *ifm;
4621 struct nlattr *tb[IFA_MAX+1];
David Ahern19b15182018-05-27 08:09:54 -07004622 struct in6_addr *peer_pfx;
Thomas Graf7198f8c2006-09-18 00:13:46 -07004623 struct inet6_ifaddr *ifa;
4624 struct net_device *dev;
Sabrina Dubrocaf1c02cf2018-02-28 16:40:08 +01004625 struct inet6_dev *idev;
David Ahern19b15182018-05-27 08:09:54 -07004626 struct ifa6_config cfg;
Thomas Graf461d8832006-09-18 00:09:49 -07004627 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004628
Johannes Bergfceb6432017-04-12 14:34:07 +02004629 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy,
David Ahernc21ef3e2017-04-16 09:48:24 -07004630 extack);
Thomas Graf461d8832006-09-18 00:09:49 -07004631 if (err < 0)
4632 return err;
4633
David Ahern19b15182018-05-27 08:09:54 -07004634 memset(&cfg, 0, sizeof(cfg));
4635
Thomas Graf461d8832006-09-18 00:09:49 -07004636 ifm = nlmsg_data(nlh);
David Ahern19b15182018-05-27 08:09:54 -07004637 cfg.pfx = extract_addr(tb[IFA_ADDRESS], tb[IFA_LOCAL], &peer_pfx);
4638 if (!cfg.pfx)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004639 return -EINVAL;
4640
David Ahern19b15182018-05-27 08:09:54 -07004641 cfg.peer_pfx = peer_pfx;
4642 cfg.plen = ifm->ifa_prefixlen;
4643 cfg.valid_lft = INFINITY_LIFE_TIME;
4644 cfg.preferred_lft = INFINITY_LIFE_TIME;
4645
Thomas Graf461d8832006-09-18 00:09:49 -07004646 if (tb[IFA_CACHEINFO]) {
Noriaki TAKAMIYA0778769d2006-07-28 18:12:10 +09004647 struct ifa_cacheinfo *ci;
Thomas Graf461d8832006-09-18 00:09:49 -07004648
4649 ci = nla_data(tb[IFA_CACHEINFO]);
David Ahern19b15182018-05-27 08:09:54 -07004650 cfg.valid_lft = ci->ifa_valid;
4651 cfg.preferred_lft = ci->ifa_prefered;
Noriaki TAKAMIYA0778769d2006-07-28 18:12:10 +09004652 }
4653
Daniel Lezcanoaf284932008-03-05 10:46:57 -08004654 dev = __dev_get_by_index(net, ifm->ifa_index);
Ian Morris63159f22015-03-29 14:00:04 +01004655 if (!dev)
Thomas Graf7198f8c2006-09-18 00:13:46 -07004656 return -ENODEV;
4657
David Ahern19b15182018-05-27 08:09:54 -07004658 if (tb[IFA_FLAGS])
4659 cfg.ifa_flags = nla_get_u32(tb[IFA_FLAGS]);
4660 else
4661 cfg.ifa_flags = ifm->ifa_flags;
Jiri Pirko479840f2013-12-06 09:45:21 +01004662
Noriaki TAKAMIYA55ebaef2006-09-22 14:45:27 -07004663 /* We ignore other flags so far. */
David Ahern19b15182018-05-27 08:09:54 -07004664 cfg.ifa_flags &= IFA_F_NODAD | IFA_F_HOMEADDRESS |
4665 IFA_F_MANAGETEMPADDR | IFA_F_NOPREFIXROUTE |
4666 IFA_F_MCAUTOJOIN | IFA_F_OPTIMISTIC;
Sabrina Dubrocaf1c02cf2018-02-28 16:40:08 +01004667
4668 idev = ipv6_find_idev(dev);
4669 if (IS_ERR(idev))
4670 return PTR_ERR(idev);
4671
4672 if (!ipv6_allow_optimistic_dad(net, idev))
David Ahern19b15182018-05-27 08:09:54 -07004673 cfg.ifa_flags &= ~IFA_F_OPTIMISTIC;
Sabrina Dubrocaf1c02cf2018-02-28 16:40:08 +01004674
David Ahern19b15182018-05-27 08:09:54 -07004675 if (cfg.ifa_flags & IFA_F_NODAD &&
4676 cfg.ifa_flags & IFA_F_OPTIMISTIC) {
Sabrina Dubrocaf1c02cf2018-02-28 16:40:08 +01004677 NL_SET_ERR_MSG(extack, "IFA_F_NODAD and IFA_F_OPTIMISTIC are mutually exclusive");
4678 return -EINVAL;
4679 }
Noriaki TAKAMIYA55ebaef2006-09-22 14:45:27 -07004680
David Ahern19b15182018-05-27 08:09:54 -07004681 ifa = ipv6_get_ifaddr(net, cfg.pfx, dev, 1);
Ian Morris63159f22015-03-29 14:00:04 +01004682 if (!ifa) {
Thomas Graf7198f8c2006-09-18 00:13:46 -07004683 /*
4684 * It would be best to check for !NLM_F_CREATE here but
stephen hemmingerdb9c7c32014-01-12 11:26:32 -08004685 * userspace already relies on not having to provide this.
Thomas Graf7198f8c2006-09-18 00:13:46 -07004686 */
David Ahern19b15182018-05-27 08:09:54 -07004687 return inet6_addr_add(net, ifm->ifa_index, &cfg, extack);
Noriaki TAKAMIYA081bba52006-07-28 18:12:13 +09004688 }
4689
Thomas Graf7198f8c2006-09-18 00:13:46 -07004690 if (nlh->nlmsg_flags & NLM_F_EXCL ||
4691 !(nlh->nlmsg_flags & NLM_F_REPLACE))
4692 err = -EEXIST;
4693 else
David Ahern19b15182018-05-27 08:09:54 -07004694 err = inet6_addr_modify(ifa, cfg.ifa_flags, cfg.preferred_lft,
4695 cfg.valid_lft);
Thomas Graf7198f8c2006-09-18 00:13:46 -07004696
4697 in6_ifa_put(ifa);
4698
4699 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004700}
4701
Jiri Pirko479840f2013-12-06 09:45:21 +01004702static void put_ifaddrmsg(struct nlmsghdr *nlh, u8 prefixlen, u32 flags,
Thomas Graf101bb222006-09-18 00:11:52 -07004703 u8 scope, int ifindex)
4704{
4705 struct ifaddrmsg *ifm;
4706
4707 ifm = nlmsg_data(nlh);
4708 ifm->ifa_family = AF_INET6;
4709 ifm->ifa_prefixlen = prefixlen;
4710 ifm->ifa_flags = flags;
4711 ifm->ifa_scope = scope;
4712 ifm->ifa_index = ifindex;
4713}
4714
Thomas Graf85486af2006-09-18 00:11:24 -07004715static int put_cacheinfo(struct sk_buff *skb, unsigned long cstamp,
4716 unsigned long tstamp, u32 preferred, u32 valid)
4717{
4718 struct ifa_cacheinfo ci;
4719
Thomas Graf18a31e12010-11-17 04:12:02 +00004720 ci.cstamp = cstamp_delta(cstamp);
4721 ci.tstamp = cstamp_delta(tstamp);
Thomas Graf85486af2006-09-18 00:11:24 -07004722 ci.ifa_prefered = preferred;
4723 ci.ifa_valid = valid;
4724
4725 return nla_put(skb, IFA_CACHEINFO, sizeof(ci), &ci);
4726}
4727
Thomas Graf101bb222006-09-18 00:11:52 -07004728static inline int rt_scope(int ifa_scope)
4729{
4730 if (ifa_scope & IFA_HOST)
4731 return RT_SCOPE_HOST;
4732 else if (ifa_scope & IFA_LINK)
4733 return RT_SCOPE_LINK;
4734 else if (ifa_scope & IFA_SITE)
4735 return RT_SCOPE_SITE;
4736 else
4737 return RT_SCOPE_UNIVERSE;
4738}
4739
Thomas Graf0ab68032006-09-18 00:12:35 -07004740static inline int inet6_ifaddr_msgsize(void)
4741{
Thomas Graf339bf982006-11-10 14:10:15 -08004742 return NLMSG_ALIGN(sizeof(struct ifaddrmsg))
Nicolas Dichtelcaeaba72013-05-16 22:32:00 +00004743 + nla_total_size(16) /* IFA_LOCAL */
Thomas Graf339bf982006-11-10 14:10:15 -08004744 + nla_total_size(16) /* IFA_ADDRESS */
Jiri Pirko479840f2013-12-06 09:45:21 +01004745 + nla_total_size(sizeof(struct ifa_cacheinfo))
4746 + nla_total_size(4) /* IFA_FLAGS */;
Thomas Graf0ab68032006-09-18 00:12:35 -07004747}
YOSHIFUJI Hideakic5396a32006-06-17 22:48:48 -07004748
Linus Torvalds1da177e2005-04-16 15:20:36 -07004749static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
Eric W. Biederman15e47302012-09-07 20:12:54 +00004750 u32 portid, u32 seq, int event, unsigned int flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004751{
Linus Torvalds1da177e2005-04-16 15:20:36 -07004752 struct nlmsghdr *nlh;
Thomas Graf85486af2006-09-18 00:11:24 -07004753 u32 preferred, valid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004754
Eric W. Biederman15e47302012-09-07 20:12:54 +00004755 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct ifaddrmsg), flags);
Ian Morris63159f22015-03-29 14:00:04 +01004756 if (!nlh)
Patrick McHardy26932562007-01-31 23:16:40 -08004757 return -EMSGSIZE;
Thomas Graf0ab68032006-09-18 00:12:35 -07004758
Thomas Graf101bb222006-09-18 00:11:52 -07004759 put_ifaddrmsg(nlh, ifa->prefix_len, ifa->flags, rt_scope(ifa->scope),
4760 ifa->idev->dev->ifindex);
4761
Yasushi Asanofad8da32013-12-31 12:04:19 +09004762 if (!((ifa->flags&IFA_F_PERMANENT) &&
4763 (ifa->prefered_lft == INFINITY_LIFE_TIME))) {
Thomas Graf85486af2006-09-18 00:11:24 -07004764 preferred = ifa->prefered_lft;
4765 valid = ifa->valid_lft;
4766 if (preferred != INFINITY_LIFE_TIME) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004767 long tval = (jiffies - ifa->tstamp)/HZ;
Jens Rosenbooma1faa692009-06-25 04:55:50 +00004768 if (preferred > tval)
4769 preferred -= tval;
4770 else
4771 preferred = 0;
Ben Hutchingsf56619f2010-06-26 11:37:47 +00004772 if (valid != INFINITY_LIFE_TIME) {
4773 if (valid > tval)
4774 valid -= tval;
4775 else
4776 valid = 0;
4777 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004778 }
4779 } else {
Thomas Graf85486af2006-09-18 00:11:24 -07004780 preferred = INFINITY_LIFE_TIME;
4781 valid = INFINITY_LIFE_TIME;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004782 }
Thomas Graf85486af2006-09-18 00:11:24 -07004783
Cong Wang7996c792013-05-22 05:41:06 +00004784 if (!ipv6_addr_any(&ifa->peer_addr)) {
Jiri Benc930345e2015-03-29 16:59:25 +02004785 if (nla_put_in6_addr(skb, IFA_LOCAL, &ifa->addr) < 0 ||
4786 nla_put_in6_addr(skb, IFA_ADDRESS, &ifa->peer_addr) < 0)
Nicolas Dichtelcaeaba72013-05-16 22:32:00 +00004787 goto error;
4788 } else
Jiri Benc930345e2015-03-29 16:59:25 +02004789 if (nla_put_in6_addr(skb, IFA_ADDRESS, &ifa->addr) < 0)
Nicolas Dichtelcaeaba72013-05-16 22:32:00 +00004790 goto error;
4791
4792 if (put_cacheinfo(skb, ifa->cstamp, ifa->tstamp, preferred, valid) < 0)
4793 goto error;
Thomas Graf85486af2006-09-18 00:11:24 -07004794
Jiri Pirko479840f2013-12-06 09:45:21 +01004795 if (nla_put_u32(skb, IFA_FLAGS, ifa->flags) < 0)
4796 goto error;
4797
Johannes Berg053c0952015-01-16 22:09:00 +01004798 nlmsg_end(skb, nlh);
4799 return 0;
Nicolas Dichtelcaeaba72013-05-16 22:32:00 +00004800
4801error:
4802 nlmsg_cancel(skb, nlh);
4803 return -EMSGSIZE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004804}
4805
4806static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca,
Eric W. Biederman15e47302012-09-07 20:12:54 +00004807 u32 portid, u32 seq, int event, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004808{
Linus Torvalds1da177e2005-04-16 15:20:36 -07004809 struct nlmsghdr *nlh;
Thomas Graf101bb222006-09-18 00:11:52 -07004810 u8 scope = RT_SCOPE_UNIVERSE;
4811 int ifindex = ifmca->idev->dev->ifindex;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004812
Thomas Graf101bb222006-09-18 00:11:52 -07004813 if (ipv6_addr_scope(&ifmca->mca_addr) & IFA_SITE)
4814 scope = RT_SCOPE_SITE;
4815
Eric W. Biederman15e47302012-09-07 20:12:54 +00004816 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct ifaddrmsg), flags);
Ian Morris63159f22015-03-29 14:00:04 +01004817 if (!nlh)
Patrick McHardy26932562007-01-31 23:16:40 -08004818 return -EMSGSIZE;
Thomas Graf0ab68032006-09-18 00:12:35 -07004819
Thomas Graf101bb222006-09-18 00:11:52 -07004820 put_ifaddrmsg(nlh, 128, IFA_F_PERMANENT, scope, ifindex);
Jiri Benc930345e2015-03-29 16:59:25 +02004821 if (nla_put_in6_addr(skb, IFA_MULTICAST, &ifmca->mca_addr) < 0 ||
Thomas Graf0ab68032006-09-18 00:12:35 -07004822 put_cacheinfo(skb, ifmca->mca_cstamp, ifmca->mca_tstamp,
Patrick McHardy26932562007-01-31 23:16:40 -08004823 INFINITY_LIFE_TIME, INFINITY_LIFE_TIME) < 0) {
4824 nlmsg_cancel(skb, nlh);
4825 return -EMSGSIZE;
4826 }
Thomas Graf85486af2006-09-18 00:11:24 -07004827
Johannes Berg053c0952015-01-16 22:09:00 +01004828 nlmsg_end(skb, nlh);
4829 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004830}
4831
4832static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca,
Eric W. Biederman15e47302012-09-07 20:12:54 +00004833 u32 portid, u32 seq, int event, unsigned int flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004834{
David Ahern9ee8cbb2018-04-18 15:39:01 -07004835 struct net_device *dev = fib6_info_nh_dev(ifaca->aca_rt);
4836 int ifindex = dev ? dev->ifindex : 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004837 struct nlmsghdr *nlh;
Thomas Graf101bb222006-09-18 00:11:52 -07004838 u8 scope = RT_SCOPE_UNIVERSE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004839
Thomas Graf101bb222006-09-18 00:11:52 -07004840 if (ipv6_addr_scope(&ifaca->aca_addr) & IFA_SITE)
4841 scope = RT_SCOPE_SITE;
4842
Eric W. Biederman15e47302012-09-07 20:12:54 +00004843 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct ifaddrmsg), flags);
Ian Morris63159f22015-03-29 14:00:04 +01004844 if (!nlh)
Patrick McHardy26932562007-01-31 23:16:40 -08004845 return -EMSGSIZE;
Thomas Graf0ab68032006-09-18 00:12:35 -07004846
Thomas Graf101bb222006-09-18 00:11:52 -07004847 put_ifaddrmsg(nlh, 128, IFA_F_PERMANENT, scope, ifindex);
Jiri Benc930345e2015-03-29 16:59:25 +02004848 if (nla_put_in6_addr(skb, IFA_ANYCAST, &ifaca->aca_addr) < 0 ||
Thomas Graf0ab68032006-09-18 00:12:35 -07004849 put_cacheinfo(skb, ifaca->aca_cstamp, ifaca->aca_tstamp,
Patrick McHardy26932562007-01-31 23:16:40 -08004850 INFINITY_LIFE_TIME, INFINITY_LIFE_TIME) < 0) {
4851 nlmsg_cancel(skb, nlh);
4852 return -EMSGSIZE;
4853 }
Thomas Graf85486af2006-09-18 00:11:24 -07004854
Johannes Berg053c0952015-01-16 22:09:00 +01004855 nlmsg_end(skb, nlh);
4856 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004857}
4858
Stephen Hemmingere21e8462010-03-20 16:09:01 -07004859enum addr_type_t {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004860 UNICAST_ADDR,
4861 MULTICAST_ADDR,
4862 ANYCAST_ADDR,
4863};
4864
Eric Dumazet234b27c2009-11-12 04:11:50 +00004865/* called with rcu_read_lock() */
4866static int in6_dump_addrs(struct inet6_dev *idev, struct sk_buff *skb,
4867 struct netlink_callback *cb, enum addr_type_t type,
4868 int s_ip_idx, int *p_ip_idx)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004869{
Linus Torvalds1da177e2005-04-16 15:20:36 -07004870 struct ifmcaddr6 *ifmca;
4871 struct ifacaddr6 *ifaca;
Eric Dumazet234b27c2009-11-12 04:11:50 +00004872 int err = 1;
4873 int ip_idx = *p_ip_idx;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004874
Eric Dumazet234b27c2009-11-12 04:11:50 +00004875 read_lock_bh(&idev->lock);
4876 switch (type) {
stephen hemminger502a2ff2010-03-17 20:31:13 +00004877 case UNICAST_ADDR: {
4878 struct inet6_ifaddr *ifa;
4879
Eric Dumazet234b27c2009-11-12 04:11:50 +00004880 /* unicast address incl. temp addr */
stephen hemminger502a2ff2010-03-17 20:31:13 +00004881 list_for_each_entry(ifa, &idev->addr_list, if_list) {
4882 if (++ip_idx < s_ip_idx)
Eric Dumazet234b27c2009-11-12 04:11:50 +00004883 continue;
4884 err = inet6_fill_ifaddr(skb, ifa,
Eric W. Biederman15e47302012-09-07 20:12:54 +00004885 NETLINK_CB(cb->skb).portid,
Eric Dumazet234b27c2009-11-12 04:11:50 +00004886 cb->nlh->nlmsg_seq,
4887 RTM_NEWADDR,
4888 NLM_F_MULTI);
Johannes Berg053c0952015-01-16 22:09:00 +01004889 if (err < 0)
Eric Dumazet234b27c2009-11-12 04:11:50 +00004890 break;
Nicolas Dichtel63998ac2013-03-22 06:28:43 +00004891 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
Linus Torvalds1da177e2005-04-16 15:20:36 -07004892 }
Eric Dumazet234b27c2009-11-12 04:11:50 +00004893 break;
stephen hemminger502a2ff2010-03-17 20:31:13 +00004894 }
Eric Dumazet234b27c2009-11-12 04:11:50 +00004895 case MULTICAST_ADDR:
4896 /* multicast address */
4897 for (ifmca = idev->mc_list; ifmca;
4898 ifmca = ifmca->next, ip_idx++) {
4899 if (ip_idx < s_ip_idx)
4900 continue;
4901 err = inet6_fill_ifmcaddr(skb, ifmca,
Eric W. Biederman15e47302012-09-07 20:12:54 +00004902 NETLINK_CB(cb->skb).portid,
Eric Dumazet234b27c2009-11-12 04:11:50 +00004903 cb->nlh->nlmsg_seq,
4904 RTM_GETMULTICAST,
4905 NLM_F_MULTI);
Johannes Berg053c0952015-01-16 22:09:00 +01004906 if (err < 0)
Eric Dumazet234b27c2009-11-12 04:11:50 +00004907 break;
4908 }
4909 break;
4910 case ANYCAST_ADDR:
4911 /* anycast address */
4912 for (ifaca = idev->ac_list; ifaca;
4913 ifaca = ifaca->aca_next, ip_idx++) {
4914 if (ip_idx < s_ip_idx)
4915 continue;
4916 err = inet6_fill_ifacaddr(skb, ifaca,
Eric W. Biederman15e47302012-09-07 20:12:54 +00004917 NETLINK_CB(cb->skb).portid,
Eric Dumazet234b27c2009-11-12 04:11:50 +00004918 cb->nlh->nlmsg_seq,
4919 RTM_GETANYCAST,
4920 NLM_F_MULTI);
Johannes Berg053c0952015-01-16 22:09:00 +01004921 if (err < 0)
Eric Dumazet234b27c2009-11-12 04:11:50 +00004922 break;
4923 }
4924 break;
4925 default:
4926 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004927 }
Eric Dumazet234b27c2009-11-12 04:11:50 +00004928 read_unlock_bh(&idev->lock);
4929 *p_ip_idx = ip_idx;
4930 return err;
4931}
4932
4933static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
4934 enum addr_type_t type)
4935{
4936 struct net *net = sock_net(skb->sk);
4937 int h, s_h;
4938 int idx, ip_idx;
4939 int s_idx, s_ip_idx;
4940 struct net_device *dev;
4941 struct inet6_dev *idev;
4942 struct hlist_head *head;
Eric Dumazet234b27c2009-11-12 04:11:50 +00004943
4944 s_h = cb->args[0];
4945 s_idx = idx = cb->args[1];
4946 s_ip_idx = ip_idx = cb->args[2];
4947
4948 rcu_read_lock();
Nicolas Dichtel63998ac2013-03-22 06:28:43 +00004949 cb->seq = atomic_read(&net->ipv6.dev_addr_genid) ^ net->dev_base_seq;
Eric Dumazet234b27c2009-11-12 04:11:50 +00004950 for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
4951 idx = 0;
4952 head = &net->dev_index_head[h];
Sasha Levinb67bfe02013-02-27 17:06:00 -08004953 hlist_for_each_entry_rcu(dev, head, index_hlist) {
Eric Dumazet234b27c2009-11-12 04:11:50 +00004954 if (idx < s_idx)
4955 goto cont;
Patrick McHardy4b97efd2010-03-26 20:27:49 -07004956 if (h > s_h || idx > s_idx)
Eric Dumazet234b27c2009-11-12 04:11:50 +00004957 s_ip_idx = 0;
4958 ip_idx = 0;
Stephen Hemmingere21e8462010-03-20 16:09:01 -07004959 idev = __in6_dev_get(dev);
4960 if (!idev)
Eric Dumazet234b27c2009-11-12 04:11:50 +00004961 goto cont;
4962
4963 if (in6_dump_addrs(idev, skb, cb, type,
David S. Miller7b46a642015-01-18 23:36:08 -05004964 s_ip_idx, &ip_idx) < 0)
Eric Dumazet234b27c2009-11-12 04:11:50 +00004965 goto done;
4966cont:
4967 idx++;
4968 }
4969 }
4970done:
4971 rcu_read_unlock();
4972 cb->args[0] = h;
4973 cb->args[1] = idx;
4974 cb->args[2] = ip_idx;
4975
Linus Torvalds1da177e2005-04-16 15:20:36 -07004976 return skb->len;
4977}
4978
4979static int inet6_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
4980{
4981 enum addr_type_t type = UNICAST_ADDR;
Denis V. Lunevb8542722007-12-01 00:21:31 +11004982
Linus Torvalds1da177e2005-04-16 15:20:36 -07004983 return inet6_dump_addr(skb, cb, type);
4984}
4985
4986static int inet6_dump_ifmcaddr(struct sk_buff *skb, struct netlink_callback *cb)
4987{
4988 enum addr_type_t type = MULTICAST_ADDR;
Denis V. Lunevb8542722007-12-01 00:21:31 +11004989
Linus Torvalds1da177e2005-04-16 15:20:36 -07004990 return inet6_dump_addr(skb, cb, type);
4991}
4992
4993
4994static int inet6_dump_ifacaddr(struct sk_buff *skb, struct netlink_callback *cb)
4995{
4996 enum addr_type_t type = ANYCAST_ADDR;
Denis V. Lunevb8542722007-12-01 00:21:31 +11004997
Linus Torvalds1da177e2005-04-16 15:20:36 -07004998 return inet6_dump_addr(skb, cb, type);
4999}
5000
David Ahernc21ef3e2017-04-16 09:48:24 -07005001static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr *nlh,
5002 struct netlink_ext_ack *extack)
Noriaki TAKAMIYA6c223822006-07-28 18:12:12 +09005003{
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09005004 struct net *net = sock_net(in_skb->sk);
Thomas Graf1b29fc22006-09-18 00:10:50 -07005005 struct ifaddrmsg *ifm;
5006 struct nlattr *tb[IFA_MAX+1];
Nicolas Dichtelcaeaba72013-05-16 22:32:00 +00005007 struct in6_addr *addr = NULL, *peer;
Noriaki TAKAMIYA6c223822006-07-28 18:12:12 +09005008 struct net_device *dev = NULL;
5009 struct inet6_ifaddr *ifa;
5010 struct sk_buff *skb;
Noriaki TAKAMIYA6c223822006-07-28 18:12:12 +09005011 int err;
5012
Johannes Bergfceb6432017-04-12 14:34:07 +02005013 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy,
David Ahernc21ef3e2017-04-16 09:48:24 -07005014 extack);
Thomas Graf1b29fc22006-09-18 00:10:50 -07005015 if (err < 0)
Florian Westphalc24675f2017-10-11 10:28:01 +02005016 return err;
Noriaki TAKAMIYA6c223822006-07-28 18:12:12 +09005017
Nicolas Dichtelcaeaba72013-05-16 22:32:00 +00005018 addr = extract_addr(tb[IFA_ADDRESS], tb[IFA_LOCAL], &peer);
Florian Westphalc24675f2017-10-11 10:28:01 +02005019 if (!addr)
5020 return -EINVAL;
Thomas Graf1b29fc22006-09-18 00:10:50 -07005021
5022 ifm = nlmsg_data(nlh);
Noriaki TAKAMIYA6c223822006-07-28 18:12:12 +09005023 if (ifm->ifa_index)
Florian Westphalc24675f2017-10-11 10:28:01 +02005024 dev = dev_get_by_index(net, ifm->ifa_index);
Noriaki TAKAMIYA6c223822006-07-28 18:12:12 +09005025
Stephen Hemmingere21e8462010-03-20 16:09:01 -07005026 ifa = ipv6_get_ifaddr(net, addr, dev, 1);
5027 if (!ifa) {
Thomas Graf1b29fc22006-09-18 00:10:50 -07005028 err = -EADDRNOTAVAIL;
5029 goto errout;
Noriaki TAKAMIYA6c223822006-07-28 18:12:12 +09005030 }
5031
Stephen Hemmingere21e8462010-03-20 16:09:01 -07005032 skb = nlmsg_new(inet6_ifaddr_msgsize(), GFP_KERNEL);
5033 if (!skb) {
Thomas Graf1b29fc22006-09-18 00:10:50 -07005034 err = -ENOBUFS;
5035 goto errout_ifa;
5036 }
5037
Eric W. Biederman15e47302012-09-07 20:12:54 +00005038 err = inet6_fill_ifaddr(skb, ifa, NETLINK_CB(in_skb).portid,
Noriaki TAKAMIYA6c223822006-07-28 18:12:12 +09005039 nlh->nlmsg_seq, RTM_NEWADDR, 0);
Patrick McHardy26932562007-01-31 23:16:40 -08005040 if (err < 0) {
5041 /* -EMSGSIZE implies BUG in inet6_ifaddr_msgsize() */
5042 WARN_ON(err == -EMSGSIZE);
5043 kfree_skb(skb);
5044 goto errout_ifa;
5045 }
Eric W. Biederman15e47302012-09-07 20:12:54 +00005046 err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).portid);
Thomas Graf1b29fc22006-09-18 00:10:50 -07005047errout_ifa:
Noriaki TAKAMIYA6c223822006-07-28 18:12:12 +09005048 in6_ifa_put(ifa);
Thomas Graf1b29fc22006-09-18 00:10:50 -07005049errout:
Florian Westphalc24675f2017-10-11 10:28:01 +02005050 if (dev)
5051 dev_put(dev);
Noriaki TAKAMIYA6c223822006-07-28 18:12:12 +09005052 return err;
Noriaki TAKAMIYA6c223822006-07-28 18:12:12 +09005053}
5054
Linus Torvalds1da177e2005-04-16 15:20:36 -07005055static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa)
5056{
5057 struct sk_buff *skb;
YOSHIFUJI Hideakic346dca2008-03-25 21:47:49 +09005058 struct net *net = dev_net(ifa->idev->dev);
Thomas Graf5d620262006-08-15 00:35:02 -07005059 int err = -ENOBUFS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005060
Thomas Graf0ab68032006-09-18 00:12:35 -07005061 skb = nlmsg_new(inet6_ifaddr_msgsize(), GFP_ATOMIC);
Ian Morris63159f22015-03-29 14:00:04 +01005062 if (!skb)
Thomas Graf5d620262006-08-15 00:35:02 -07005063 goto errout;
5064
5065 err = inet6_fill_ifaddr(skb, ifa, 0, 0, event, 0);
Patrick McHardy26932562007-01-31 23:16:40 -08005066 if (err < 0) {
5067 /* -EMSGSIZE implies BUG in inet6_ifaddr_msgsize() */
5068 WARN_ON(err == -EMSGSIZE);
5069 kfree_skb(skb);
5070 goto errout;
5071 }
Pablo Neira Ayuso1ce85fe2009-02-24 23:18:28 -08005072 rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
5073 return;
Thomas Graf5d620262006-08-15 00:35:02 -07005074errout:
5075 if (err < 0)
Benjamin Thery6fda7352008-03-05 10:47:47 -08005076 rtnl_set_sk_err(net, RTNLGRP_IPV6_IFADDR, err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005077}
5078
Dave Jonesb6f99a22007-03-22 12:27:49 -07005079static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005080 __s32 *array, int bytes)
5081{
Thomas Graf04561c12006-11-14 19:53:58 -08005082 BUG_ON(bytes < (DEVCONF_MAX * 4));
5083
Linus Torvalds1da177e2005-04-16 15:20:36 -07005084 memset(array, 0, bytes);
5085 array[DEVCONF_FORWARDING] = cnf->forwarding;
5086 array[DEVCONF_HOPLIMIT] = cnf->hop_limit;
5087 array[DEVCONF_MTU6] = cnf->mtu6;
5088 array[DEVCONF_ACCEPT_RA] = cnf->accept_ra;
5089 array[DEVCONF_ACCEPT_REDIRECTS] = cnf->accept_redirects;
5090 array[DEVCONF_AUTOCONF] = cnf->autoconf;
5091 array[DEVCONF_DAD_TRANSMITS] = cnf->dad_transmits;
5092 array[DEVCONF_RTR_SOLICITS] = cnf->rtr_solicits;
Thomas Graf93908d12010-11-17 01:44:24 +00005093 array[DEVCONF_RTR_SOLICIT_INTERVAL] =
5094 jiffies_to_msecs(cnf->rtr_solicit_interval);
Maciej Żenczykowskibd11f072016-09-27 23:57:58 -07005095 array[DEVCONF_RTR_SOLICIT_MAX_INTERVAL] =
5096 jiffies_to_msecs(cnf->rtr_solicit_max_interval);
Thomas Graf93908d12010-11-17 01:44:24 +00005097 array[DEVCONF_RTR_SOLICIT_DELAY] =
5098 jiffies_to_msecs(cnf->rtr_solicit_delay);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005099 array[DEVCONF_FORCE_MLD_VERSION] = cnf->force_mld_version;
Hannes Frederic Sowafc4eba52013-08-14 01:03:46 +02005100 array[DEVCONF_MLDV1_UNSOLICITED_REPORT_INTERVAL] =
5101 jiffies_to_msecs(cnf->mldv1_unsolicited_report_interval);
5102 array[DEVCONF_MLDV2_UNSOLICITED_REPORT_INTERVAL] =
5103 jiffies_to_msecs(cnf->mldv2_unsolicited_report_interval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005104 array[DEVCONF_USE_TEMPADDR] = cnf->use_tempaddr;
5105 array[DEVCONF_TEMP_VALID_LFT] = cnf->temp_valid_lft;
5106 array[DEVCONF_TEMP_PREFERED_LFT] = cnf->temp_prefered_lft;
5107 array[DEVCONF_REGEN_MAX_RETRY] = cnf->regen_max_retry;
5108 array[DEVCONF_MAX_DESYNC_FACTOR] = cnf->max_desync_factor;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005109 array[DEVCONF_MAX_ADDRESSES] = cnf->max_addresses;
YOSHIFUJI Hideaki65f5c7c2006-03-20 16:55:08 -08005110 array[DEVCONF_ACCEPT_RA_DEFRTR] = cnf->accept_ra_defrtr;
Hangbin Liu8013d1d72015-07-30 14:28:42 +08005111 array[DEVCONF_ACCEPT_RA_MIN_HOP_LIMIT] = cnf->accept_ra_min_hop_limit;
YOSHIFUJI Hideakic4fd30e2006-03-20 16:55:26 -08005112 array[DEVCONF_ACCEPT_RA_PINFO] = cnf->accept_ra_pinfo;
YOSHIFUJI Hideaki930d6ff2006-03-20 17:05:30 -08005113#ifdef CONFIG_IPV6_ROUTER_PREF
5114 array[DEVCONF_ACCEPT_RA_RTR_PREF] = cnf->accept_ra_rtr_pref;
Thomas Graf93908d12010-11-17 01:44:24 +00005115 array[DEVCONF_RTR_PROBE_INTERVAL] =
5116 jiffies_to_msecs(cnf->rtr_probe_interval);
Neil Hormanfa03ef32007-01-30 14:30:10 -08005117#ifdef CONFIG_IPV6_ROUTE_INFO
Joel Scherpelzbbea1242017-03-22 18:19:04 +09005118 array[DEVCONF_ACCEPT_RA_RT_INFO_MIN_PLEN] = cnf->accept_ra_rt_info_min_plen;
YOSHIFUJI Hideaki09c884d2006-03-20 17:07:03 -08005119 array[DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN] = cnf->accept_ra_rt_info_max_plen;
5120#endif
YOSHIFUJI Hideaki930d6ff2006-03-20 17:05:30 -08005121#endif
YOSHIFUJI Hideakifbea49e2006-09-22 14:43:49 -07005122 array[DEVCONF_PROXY_NDP] = cnf->proxy_ndp;
YOSHIFUJI Hideaki0bcbc922007-04-24 14:58:30 -07005123 array[DEVCONF_ACCEPT_SOURCE_ROUTE] = cnf->accept_source_route;
Neil Horman95c385b2007-04-25 17:08:10 -07005124#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
5125 array[DEVCONF_OPTIMISTIC_DAD] = cnf->optimistic_dad;
Erik Kline7fd25612014-10-28 18:11:14 +09005126 array[DEVCONF_USE_OPTIMISTIC] = cnf->use_optimistic;
Neil Horman95c385b2007-04-25 17:08:10 -07005127#endif
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09005128#ifdef CONFIG_IPV6_MROUTE
5129 array[DEVCONF_MC_FORWARDING] = cnf->mc_forwarding;
5130#endif
YOSHIFUJI Hideaki778d80b2008-06-28 14:17:11 +09005131 array[DEVCONF_DISABLE_IPV6] = cnf->disable_ipv6;
YOSHIFUJI Hideaki1b34be72008-06-28 14:18:38 +09005132 array[DEVCONF_ACCEPT_DAD] = cnf->accept_dad;
Cosmin Ratiuc3faca02009-10-09 03:11:14 +00005133 array[DEVCONF_FORCE_TLLAO] = cnf->force_tllao;
Hannes Frederic Sowa5cb04432012-11-06 16:46:20 +00005134 array[DEVCONF_NDISC_NOTIFY] = cnf->ndisc_notify;
Hannes Frederic Sowab800c3b2013-08-27 01:36:51 +02005135 array[DEVCONF_SUPPRESS_FRAG_NDISC] = cnf->suppress_frag_ndisc;
Ben Greeard9333192014-06-25 14:44:53 -07005136 array[DEVCONF_ACCEPT_RA_FROM_LOCAL] = cnf->accept_ra_from_local;
Harout Hedeshianc2943f12015-01-20 10:06:05 -07005137 array[DEVCONF_ACCEPT_RA_MTU] = cnf->accept_ra_mtu;
Andy Gospodarek35103d12015-08-13 10:39:01 -04005138 array[DEVCONF_IGNORE_ROUTES_WITH_LINKDOWN] = cnf->ignore_routes_with_linkdown;
Hannes Frederic Sowa3d1bec92015-03-23 23:36:00 +01005139 /* we omit DEVCONF_STABLE_SECRET for now */
Erik Kline3985e8a2015-07-22 16:38:25 +09005140 array[DEVCONF_USE_OIF_ADDRS_ONLY] = cnf->use_oif_addrs_only;
Johannes Bergabbc3042016-02-04 13:31:19 +01005141 array[DEVCONF_DROP_UNICAST_IN_L2_MULTICAST] = cnf->drop_unicast_in_l2_multicast;
Johannes Berg7a02bf82016-02-04 13:31:20 +01005142 array[DEVCONF_DROP_UNSOLICITED_NA] = cnf->drop_unsolicited_na;
David Ahernf1705ec2016-02-24 09:25:37 -08005143 array[DEVCONF_KEEP_ADDR_ON_DOWN] = cnf->keep_addr_on_down;
David Lebrun1ababeb2016-11-08 14:57:39 +01005144 array[DEVCONF_SEG6_ENABLED] = cnf->seg6_enabled;
David Lebrunbf355b82016-11-08 14:57:42 +01005145#ifdef CONFIG_IPV6_SEG6_HMAC
5146 array[DEVCONF_SEG6_REQUIRE_HMAC] = cnf->seg6_require_hmac;
5147#endif
Erik Nordmarkadc176c2016-12-02 14:00:08 -08005148 array[DEVCONF_ENHANCED_DAD] = cnf->enhanced_dad;
Felix Jiad35a00b2017-01-26 16:59:17 +13005149 array[DEVCONF_ADDR_GEN_MODE] = cnf->addr_gen_mode;
David Forsterdf789fe2017-02-23 16:27:18 +00005150 array[DEVCONF_DISABLE_POLICY] = cnf->disable_policy;
Maciej Żenczykowski2210d6b2017-11-07 21:52:09 -08005151 array[DEVCONF_NDISC_TCLASS] = cnf->ndisc_tclass;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005152}
5153
Thomas Grafb382b192010-11-16 04:33:57 +00005154static inline size_t inet6_ifla6_size(void)
5155{
5156 return nla_total_size(4) /* IFLA_INET6_FLAGS */
5157 + nla_total_size(sizeof(struct ifla_cacheinfo))
5158 + nla_total_size(DEVCONF_MAX * 4) /* IFLA_INET6_CONF */
5159 + nla_total_size(IPSTATS_MIB_MAX * 8) /* IFLA_INET6_STATS */
Daniel Borkmannf53adae2013-04-08 04:01:30 +00005160 + nla_total_size(ICMP6_MIB_MAX * 8) /* IFLA_INET6_ICMP6STATS */
5161 + nla_total_size(sizeof(struct in6_addr)); /* IFLA_INET6_TOKEN */
Thomas Grafb382b192010-11-16 04:33:57 +00005162}
5163
Thomas Graf339bf982006-11-10 14:10:15 -08005164static inline size_t inet6_if_nlmsg_size(void)
5165{
5166 return NLMSG_ALIGN(sizeof(struct ifinfomsg))
5167 + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */
5168 + nla_total_size(MAX_ADDR_LEN) /* IFLA_ADDRESS */
5169 + nla_total_size(4) /* IFLA_MTU */
5170 + nla_total_size(4) /* IFLA_LINK */
Andy Gospodarek03443382015-08-13 15:26:35 -04005171 + nla_total_size(1) /* IFLA_OPERSTATE */
Thomas Grafb382b192010-11-16 04:33:57 +00005172 + nla_total_size(inet6_ifla6_size()); /* IFLA_PROTINFO */
Thomas Graf339bf982006-11-10 14:10:15 -08005173}
YOSHIFUJI Hideakic5396a32006-06-17 22:48:48 -07005174
Eric Dumazetbe281e52011-05-19 01:14:23 +00005175static inline void __snmp6_fill_statsdev(u64 *stats, atomic_long_t *mib,
Jia Heaca05672016-09-30 11:29:03 +08005176 int bytes)
Herbert Xu7f7d9a62007-04-24 21:54:09 -07005177{
5178 int i;
Jia Heaca05672016-09-30 11:29:03 +08005179 int pad = bytes - sizeof(u64) * ICMP6_MIB_MAX;
Herbert Xu7f7d9a62007-04-24 21:54:09 -07005180 BUG_ON(pad < 0);
5181
5182 /* Use put_unaligned() because stats may not be aligned for u64. */
Jia Heaca05672016-09-30 11:29:03 +08005183 put_unaligned(ICMP6_MIB_MAX, &stats[0]);
5184 for (i = 1; i < ICMP6_MIB_MAX; i++)
Eric Dumazetbe281e52011-05-19 01:14:23 +00005185 put_unaligned(atomic_long_read(&mib[i]), &stats[i]);
Herbert Xu7f7d9a62007-04-24 21:54:09 -07005186
Jia Heaca05672016-09-30 11:29:03 +08005187 memset(&stats[ICMP6_MIB_MAX], 0, pad);
Herbert Xu7f7d9a62007-04-24 21:54:09 -07005188}
5189
WANG Cong698365f2014-05-05 15:55:55 -07005190static inline void __snmp6_fill_stats64(u64 *stats, void __percpu *mib,
Raghavendra K Ta3a77372015-08-30 11:29:42 +05305191 int bytes, size_t syncpoff)
Eric Dumazet4ce3c182010-06-30 13:31:19 -07005192{
Raghavendra K Ta3a77372015-08-30 11:29:42 +05305193 int i, c;
5194 u64 buff[IPSTATS_MIB_MAX];
5195 int pad = bytes - sizeof(u64) * IPSTATS_MIB_MAX;
5196
Eric Dumazet4ce3c182010-06-30 13:31:19 -07005197 BUG_ON(pad < 0);
5198
Raghavendra K Ta3a77372015-08-30 11:29:42 +05305199 memset(buff, 0, sizeof(buff));
5200 buff[0] = IPSTATS_MIB_MAX;
Eric Dumazet4ce3c182010-06-30 13:31:19 -07005201
Raghavendra K Ta3a77372015-08-30 11:29:42 +05305202 for_each_possible_cpu(c) {
5203 for (i = 1; i < IPSTATS_MIB_MAX; i++)
5204 buff[i] += snmp_get_cpu_field64(mib, c, i, syncpoff);
5205 }
5206
5207 memcpy(stats, buff, IPSTATS_MIB_MAX * sizeof(u64));
5208 memset(&stats[IPSTATS_MIB_MAX], 0, pad);
Eric Dumazet4ce3c182010-06-30 13:31:19 -07005209}
5210
Herbert Xu7f7d9a62007-04-24 21:54:09 -07005211static void snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype,
5212 int bytes)
5213{
Stephen Hemmingere21e8462010-03-20 16:09:01 -07005214 switch (attrtype) {
Herbert Xu7f7d9a62007-04-24 21:54:09 -07005215 case IFLA_INET6_STATS:
Raghavendra K Ta3a77372015-08-30 11:29:42 +05305216 __snmp6_fill_stats64(stats, idev->stats.ipv6, bytes,
5217 offsetof(struct ipstats_mib, syncp));
Herbert Xu7f7d9a62007-04-24 21:54:09 -07005218 break;
5219 case IFLA_INET6_ICMP6STATS:
Jia Heaca05672016-09-30 11:29:03 +08005220 __snmp6_fill_statsdev(stats, idev->stats.icmpv6dev->mibs, bytes);
Herbert Xu7f7d9a62007-04-24 21:54:09 -07005221 break;
5222 }
5223}
5224
Sowmini Varadhand5566fd2015-09-11 16:48:48 -04005225static int inet6_fill_ifla6_attrs(struct sk_buff *skb, struct inet6_dev *idev,
5226 u32 ext_filter_mask)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005227{
YOSHIFUJI Hideakibf99f1b2007-04-20 15:56:20 -07005228 struct nlattr *nla;
Thomas Graf04561c12006-11-14 19:53:58 -08005229 struct ifla_cacheinfo ci;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005230
David S. Millerc78679e2012-04-01 20:27:33 -04005231 if (nla_put_u32(skb, IFLA_INET6_FLAGS, idev->if_flags))
5232 goto nla_put_failure;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005233 ci.max_reasm_len = IPV6_MAXPLEN;
David S. Miller24912422010-11-19 13:13:47 -08005234 ci.tstamp = cstamp_delta(idev->tstamp);
5235 ci.reachable_time = jiffies_to_msecs(idev->nd_parms->reachable_time);
Jiri Pirko1f9248e2013-12-07 19:26:53 +01005236 ci.retrans_time = jiffies_to_msecs(NEIGH_VAR(idev->nd_parms, RETRANS_TIME));
David S. Millerc78679e2012-04-01 20:27:33 -04005237 if (nla_put(skb, IFLA_INET6_CACHEINFO, sizeof(ci), &ci))
5238 goto nla_put_failure;
YOSHIFUJI Hideakibf99f1b2007-04-20 15:56:20 -07005239 nla = nla_reserve(skb, IFLA_INET6_CONF, DEVCONF_MAX * sizeof(s32));
Ian Morris63159f22015-03-29 14:00:04 +01005240 if (!nla)
Thomas Graf04561c12006-11-14 19:53:58 -08005241 goto nla_put_failure;
YOSHIFUJI Hideakibf99f1b2007-04-20 15:56:20 -07005242 ipv6_store_devconf(&idev->cnf, nla_data(nla), nla_len(nla));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005243
YOSHIFUJI Hideakibf99f1b2007-04-20 15:56:20 -07005244 /* XXX - MC not implemented */
5245
Sowmini Varadhand5566fd2015-09-11 16:48:48 -04005246 if (ext_filter_mask & RTEXT_FILTER_SKIP_STATS)
5247 return 0;
5248
YOSHIFUJI Hideakibf99f1b2007-04-20 15:56:20 -07005249 nla = nla_reserve(skb, IFLA_INET6_STATS, IPSTATS_MIB_MAX * sizeof(u64));
Ian Morris63159f22015-03-29 14:00:04 +01005250 if (!nla)
YOSHIFUJI Hideakibf99f1b2007-04-20 15:56:20 -07005251 goto nla_put_failure;
5252 snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_STATS, nla_len(nla));
5253
5254 nla = nla_reserve(skb, IFLA_INET6_ICMP6STATS, ICMP6_MIB_MAX * sizeof(u64));
Ian Morris63159f22015-03-29 14:00:04 +01005255 if (!nla)
YOSHIFUJI Hideakibf99f1b2007-04-20 15:56:20 -07005256 goto nla_put_failure;
5257 snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_ICMP6STATS, nla_len(nla));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005258
Daniel Borkmannf53adae2013-04-08 04:01:30 +00005259 nla = nla_reserve(skb, IFLA_INET6_TOKEN, sizeof(struct in6_addr));
Ian Morris63159f22015-03-29 14:00:04 +01005260 if (!nla)
Daniel Borkmannf53adae2013-04-08 04:01:30 +00005261 goto nla_put_failure;
Jiri Pirkobc91b0f2014-07-11 21:10:18 +02005262
Felix Jiad35a00b2017-01-26 16:59:17 +13005263 if (nla_put_u8(skb, IFLA_INET6_ADDR_GEN_MODE, idev->cnf.addr_gen_mode))
Jiri Pirkobc91b0f2014-07-11 21:10:18 +02005264 goto nla_put_failure;
5265
Daniel Borkmannf53adae2013-04-08 04:01:30 +00005266 read_lock_bh(&idev->lock);
5267 memcpy(nla_data(nla), idev->token.s6_addr, nla_len(nla));
5268 read_unlock_bh(&idev->lock);
5269
Thomas Grafb382b192010-11-16 04:33:57 +00005270 return 0;
5271
5272nla_put_failure:
5273 return -EMSGSIZE;
5274}
5275
Arad, Ronenb1974ed2015-10-19 09:23:28 -07005276static size_t inet6_get_link_af_size(const struct net_device *dev,
5277 u32 ext_filter_mask)
Thomas Grafb382b192010-11-16 04:33:57 +00005278{
5279 if (!__in6_dev_get(dev))
5280 return 0;
5281
5282 return inet6_ifla6_size();
5283}
5284
Sowmini Varadhand5566fd2015-09-11 16:48:48 -04005285static int inet6_fill_link_af(struct sk_buff *skb, const struct net_device *dev,
5286 u32 ext_filter_mask)
Thomas Grafb382b192010-11-16 04:33:57 +00005287{
5288 struct inet6_dev *idev = __in6_dev_get(dev);
5289
5290 if (!idev)
5291 return -ENODATA;
5292
Sowmini Varadhand5566fd2015-09-11 16:48:48 -04005293 if (inet6_fill_ifla6_attrs(skb, idev, ext_filter_mask) < 0)
Thomas Grafb382b192010-11-16 04:33:57 +00005294 return -EMSGSIZE;
5295
5296 return 0;
5297}
5298
Daniel Borkmannf53adae2013-04-08 04:01:30 +00005299static int inet6_set_iftoken(struct inet6_dev *idev, struct in6_addr *token)
5300{
Daniel Borkmannf53adae2013-04-08 04:01:30 +00005301 struct inet6_ifaddr *ifp;
5302 struct net_device *dev = idev->dev;
Daniel Borkmann47e27d52016-04-08 15:55:00 +02005303 bool clear_token, update_rs = false;
Hannes Frederic Sowadc848292013-06-24 21:42:40 +02005304 struct in6_addr ll_addr;
Daniel Borkmannf53adae2013-04-08 04:01:30 +00005305
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01005306 ASSERT_RTNL();
5307
Ian Morris63159f22015-03-29 14:00:04 +01005308 if (!token)
Daniel Borkmannf53adae2013-04-08 04:01:30 +00005309 return -EINVAL;
Daniel Borkmannf53adae2013-04-08 04:01:30 +00005310 if (dev->flags & (IFF_LOOPBACK | IFF_NOARP))
5311 return -EINVAL;
Daniel Borkmannf53adae2013-04-08 04:01:30 +00005312 if (!ipv6_accept_ra(idev))
5313 return -EINVAL;
Maciej Żenczykowskibd11f072016-09-27 23:57:58 -07005314 if (idev->cnf.rtr_solicits == 0)
Daniel Borkmannf53adae2013-04-08 04:01:30 +00005315 return -EINVAL;
5316
5317 write_lock_bh(&idev->lock);
5318
5319 BUILD_BUG_ON(sizeof(token->s6_addr) != 16);
5320 memcpy(idev->token.s6_addr + 8, token->s6_addr + 8, 8);
5321
5322 write_unlock_bh(&idev->lock);
5323
Daniel Borkmann47e27d52016-04-08 15:55:00 +02005324 clear_token = ipv6_addr_any(token);
5325 if (clear_token)
5326 goto update_lft;
5327
Hannes Frederic Sowadc848292013-06-24 21:42:40 +02005328 if (!idev->dead && (idev->if_flags & IF_READY) &&
5329 !ipv6_get_lladdr(dev, &ll_addr, IFA_F_TENTATIVE |
5330 IFA_F_OPTIMISTIC)) {
Daniel Borkmannfc403832013-04-09 03:47:15 +00005331 /* If we're not ready, then normal ifup will take care
5332 * of this. Otherwise, we need to request our rs here.
5333 */
5334 ndisc_send_rs(dev, &ll_addr, &in6addr_linklocal_allrouters);
5335 update_rs = true;
5336 }
Daniel Borkmannf53adae2013-04-08 04:01:30 +00005337
Daniel Borkmann47e27d52016-04-08 15:55:00 +02005338update_lft:
Daniel Borkmannf53adae2013-04-08 04:01:30 +00005339 write_lock_bh(&idev->lock);
Daniel Borkmannfc403832013-04-09 03:47:15 +00005340
Hannes Frederic Sowa77ecaac2013-06-26 03:41:49 +02005341 if (update_rs) {
Daniel Borkmannfc403832013-04-09 03:47:15 +00005342 idev->if_flags |= IF_RS_SENT;
Maciej Żenczykowskibd11f072016-09-27 23:57:58 -07005343 idev->rs_interval = rfc3315_s14_backoff_init(
5344 idev->cnf.rtr_solicit_interval);
Hannes Frederic Sowa77ecaac2013-06-26 03:41:49 +02005345 idev->rs_probes = 1;
Maciej Żenczykowskibd11f072016-09-27 23:57:58 -07005346 addrconf_mod_rs_timer(idev, idev->rs_interval);
Hannes Frederic Sowa77ecaac2013-06-26 03:41:49 +02005347 }
Daniel Borkmannf53adae2013-04-08 04:01:30 +00005348
5349 /* Well, that's kinda nasty ... */
5350 list_for_each_entry(ifp, &idev->addr_list, if_list) {
5351 spin_lock(&ifp->lock);
Daniel Borkmann617fe292013-04-09 03:47:16 +00005352 if (ifp->tokenized) {
Daniel Borkmannf53adae2013-04-08 04:01:30 +00005353 ifp->valid_lft = 0;
5354 ifp->prefered_lft = 0;
5355 }
5356 spin_unlock(&ifp->lock);
5357 }
5358
5359 write_unlock_bh(&idev->lock);
Lubomir Rintelb2ed64a2014-10-27 17:39:16 +01005360 inet6_ifinfo_notify(RTM_NEWLINK, idev);
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01005361 addrconf_verify_rtnl();
Daniel Borkmannf53adae2013-04-08 04:01:30 +00005362 return 0;
5363}
5364
Daniel Borkmann11b1f822015-02-05 14:39:11 +01005365static const struct nla_policy inet6_af_policy[IFLA_INET6_MAX + 1] = {
5366 [IFLA_INET6_ADDR_GEN_MODE] = { .type = NLA_U8 },
5367 [IFLA_INET6_TOKEN] = { .len = sizeof(struct in6_addr) },
5368};
5369
5370static int inet6_validate_link_af(const struct net_device *dev,
5371 const struct nlattr *nla)
5372{
5373 struct nlattr *tb[IFLA_INET6_MAX + 1];
5374
5375 if (dev && !__in6_dev_get(dev))
5376 return -EAFNOSUPPORT;
5377
Johannes Bergfceb6432017-04-12 14:34:07 +02005378 return nla_parse_nested(tb, IFLA_INET6_MAX, nla, inet6_af_policy,
5379 NULL);
Daniel Borkmann11b1f822015-02-05 14:39:11 +01005380}
5381
Felix Jiad35a00b2017-01-26 16:59:17 +13005382static int check_addr_gen_mode(int mode)
5383{
5384 if (mode != IN6_ADDR_GEN_MODE_EUI64 &&
5385 mode != IN6_ADDR_GEN_MODE_NONE &&
5386 mode != IN6_ADDR_GEN_MODE_STABLE_PRIVACY &&
5387 mode != IN6_ADDR_GEN_MODE_RANDOM)
5388 return -EINVAL;
5389 return 1;
5390}
5391
5392static int check_stable_privacy(struct inet6_dev *idev, struct net *net,
5393 int mode)
5394{
5395 if (mode == IN6_ADDR_GEN_MODE_STABLE_PRIVACY &&
5396 !idev->cnf.stable_secret.initialized &&
5397 !net->ipv6.devconf_dflt->stable_secret.initialized)
5398 return -EINVAL;
5399 return 1;
5400}
5401
Daniel Borkmannf53adae2013-04-08 04:01:30 +00005402static int inet6_set_link_af(struct net_device *dev, const struct nlattr *nla)
5403{
5404 int err = -EINVAL;
5405 struct inet6_dev *idev = __in6_dev_get(dev);
5406 struct nlattr *tb[IFLA_INET6_MAX + 1];
5407
5408 if (!idev)
5409 return -EAFNOSUPPORT;
5410
Johannes Bergfceb6432017-04-12 14:34:07 +02005411 if (nla_parse_nested(tb, IFLA_INET6_MAX, nla, NULL, NULL) < 0)
Daniel Borkmannf53adae2013-04-08 04:01:30 +00005412 BUG();
5413
Jiri Pirkobc91b0f2014-07-11 21:10:18 +02005414 if (tb[IFLA_INET6_TOKEN]) {
Daniel Borkmannf53adae2013-04-08 04:01:30 +00005415 err = inet6_set_iftoken(idev, nla_data(tb[IFLA_INET6_TOKEN]));
Jiri Pirkobc91b0f2014-07-11 21:10:18 +02005416 if (err)
5417 return err;
5418 }
5419
5420 if (tb[IFLA_INET6_ADDR_GEN_MODE]) {
5421 u8 mode = nla_get_u8(tb[IFLA_INET6_ADDR_GEN_MODE]);
5422
Felix Jiad35a00b2017-01-26 16:59:17 +13005423 if (check_addr_gen_mode(mode) < 0 ||
5424 check_stable_privacy(idev, dev_net(dev), mode) < 0)
Jiri Pirkobc91b0f2014-07-11 21:10:18 +02005425 return -EINVAL;
Hannes Frederic Sowa622c81d52015-03-23 23:36:01 +01005426
Felix Jiad35a00b2017-01-26 16:59:17 +13005427 idev->cnf.addr_gen_mode = mode;
Jiri Pirkobc91b0f2014-07-11 21:10:18 +02005428 err = 0;
5429 }
Daniel Borkmannf53adae2013-04-08 04:01:30 +00005430
5431 return err;
5432}
5433
Thomas Grafb382b192010-11-16 04:33:57 +00005434static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
Eric W. Biederman15e47302012-09-07 20:12:54 +00005435 u32 portid, u32 seq, int event, unsigned int flags)
Thomas Grafb382b192010-11-16 04:33:57 +00005436{
5437 struct net_device *dev = idev->dev;
5438 struct ifinfomsg *hdr;
5439 struct nlmsghdr *nlh;
5440 void *protoinfo;
5441
Eric W. Biederman15e47302012-09-07 20:12:54 +00005442 nlh = nlmsg_put(skb, portid, seq, event, sizeof(*hdr), flags);
Ian Morris63159f22015-03-29 14:00:04 +01005443 if (!nlh)
Thomas Grafb382b192010-11-16 04:33:57 +00005444 return -EMSGSIZE;
5445
5446 hdr = nlmsg_data(nlh);
5447 hdr->ifi_family = AF_INET6;
5448 hdr->__ifi_pad = 0;
5449 hdr->ifi_type = dev->type;
5450 hdr->ifi_index = dev->ifindex;
5451 hdr->ifi_flags = dev_get_flags(dev);
5452 hdr->ifi_change = 0;
5453
David S. Millerc78679e2012-04-01 20:27:33 -04005454 if (nla_put_string(skb, IFLA_IFNAME, dev->name) ||
5455 (dev->addr_len &&
5456 nla_put(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr)) ||
5457 nla_put_u32(skb, IFLA_MTU, dev->mtu) ||
Nicolas Dichtela54acb32015-04-02 17:07:00 +02005458 (dev->ifindex != dev_get_iflink(dev) &&
Andy Gospodarek03443382015-08-13 15:26:35 -04005459 nla_put_u32(skb, IFLA_LINK, dev_get_iflink(dev))) ||
5460 nla_put_u8(skb, IFLA_OPERSTATE,
5461 netif_running(dev) ? dev->operstate : IF_OPER_DOWN))
David S. Millerc78679e2012-04-01 20:27:33 -04005462 goto nla_put_failure;
Thomas Grafb382b192010-11-16 04:33:57 +00005463 protoinfo = nla_nest_start(skb, IFLA_PROTINFO);
Ian Morris63159f22015-03-29 14:00:04 +01005464 if (!protoinfo)
Thomas Grafb382b192010-11-16 04:33:57 +00005465 goto nla_put_failure;
5466
Sowmini Varadhand5566fd2015-09-11 16:48:48 -04005467 if (inet6_fill_ifla6_attrs(skb, idev, 0) < 0)
Thomas Grafb382b192010-11-16 04:33:57 +00005468 goto nla_put_failure;
5469
Thomas Graf04561c12006-11-14 19:53:58 -08005470 nla_nest_end(skb, protoinfo);
Johannes Berg053c0952015-01-16 22:09:00 +01005471 nlmsg_end(skb, nlh);
5472 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005473
Thomas Graf04561c12006-11-14 19:53:58 -08005474nla_put_failure:
Patrick McHardy26932562007-01-31 23:16:40 -08005475 nlmsg_cancel(skb, nlh);
5476 return -EMSGSIZE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005477}
5478
5479static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
5480{
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09005481 struct net *net = sock_net(skb->sk);
Eric Dumazet84d26972009-11-09 12:11:28 +00005482 int h, s_h;
David S. Miller434a8a52009-11-11 18:53:00 -08005483 int idx = 0, s_idx;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005484 struct net_device *dev;
5485 struct inet6_dev *idev;
Eric Dumazet84d26972009-11-09 12:11:28 +00005486 struct hlist_head *head;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005487
Eric Dumazet84d26972009-11-09 12:11:28 +00005488 s_h = cb->args[0];
5489 s_idx = cb->args[1];
5490
5491 rcu_read_lock();
5492 for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
5493 idx = 0;
5494 head = &net->dev_index_head[h];
Sasha Levinb67bfe02013-02-27 17:06:00 -08005495 hlist_for_each_entry_rcu(dev, head, index_hlist) {
Eric Dumazet84d26972009-11-09 12:11:28 +00005496 if (idx < s_idx)
5497 goto cont;
5498 idev = __in6_dev_get(dev);
5499 if (!idev)
5500 goto cont;
5501 if (inet6_fill_ifinfo(skb, idev,
Eric W. Biederman15e47302012-09-07 20:12:54 +00005502 NETLINK_CB(cb->skb).portid,
Eric Dumazet84d26972009-11-09 12:11:28 +00005503 cb->nlh->nlmsg_seq,
Johannes Berg053c0952015-01-16 22:09:00 +01005504 RTM_NEWLINK, NLM_F_MULTI) < 0)
Eric Dumazet84d26972009-11-09 12:11:28 +00005505 goto out;
Pavel Emelianov7562f872007-05-03 15:13:45 -07005506cont:
Eric Dumazet84d26972009-11-09 12:11:28 +00005507 idx++;
5508 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005509 }
Eric Dumazet84d26972009-11-09 12:11:28 +00005510out:
5511 rcu_read_unlock();
5512 cb->args[1] = idx;
5513 cb->args[0] = h;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005514
5515 return skb->len;
5516}
5517
5518void inet6_ifinfo_notify(int event, struct inet6_dev *idev)
5519{
5520 struct sk_buff *skb;
YOSHIFUJI Hideakic346dca2008-03-25 21:47:49 +09005521 struct net *net = dev_net(idev->dev);
Thomas Graf8d7a76c2006-08-15 00:35:47 -07005522 int err = -ENOBUFS;
YOSHIFUJI Hideaki1ab14572007-02-09 23:24:49 +09005523
Thomas Graf339bf982006-11-10 14:10:15 -08005524 skb = nlmsg_new(inet6_if_nlmsg_size(), GFP_ATOMIC);
Ian Morris63159f22015-03-29 14:00:04 +01005525 if (!skb)
Thomas Graf8d7a76c2006-08-15 00:35:47 -07005526 goto errout;
5527
5528 err = inet6_fill_ifinfo(skb, idev, 0, 0, event, 0);
Patrick McHardy26932562007-01-31 23:16:40 -08005529 if (err < 0) {
5530 /* -EMSGSIZE implies BUG in inet6_if_nlmsg_size() */
5531 WARN_ON(err == -EMSGSIZE);
5532 kfree_skb(skb);
5533 goto errout;
5534 }
Nicolas Dichtel5f75a102010-12-07 23:38:31 +00005535 rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFINFO, NULL, GFP_ATOMIC);
Pablo Neira Ayuso1ce85fe2009-02-24 23:18:28 -08005536 return;
Thomas Graf8d7a76c2006-08-15 00:35:47 -07005537errout:
5538 if (err < 0)
Nicolas Dichtel5f75a102010-12-07 23:38:31 +00005539 rtnl_set_sk_err(net, RTNLGRP_IPV6_IFINFO, err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005540}
5541
Thomas Graf339bf982006-11-10 14:10:15 -08005542static inline size_t inet6_prefix_nlmsg_size(void)
5543{
5544 return NLMSG_ALIGN(sizeof(struct prefixmsg))
5545 + nla_total_size(sizeof(struct in6_addr))
5546 + nla_total_size(sizeof(struct prefix_cacheinfo));
5547}
YOSHIFUJI Hideakic5396a32006-06-17 22:48:48 -07005548
Linus Torvalds1da177e2005-04-16 15:20:36 -07005549static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev,
Eric W. Biederman15e47302012-09-07 20:12:54 +00005550 struct prefix_info *pinfo, u32 portid, u32 seq,
Thomas Graf6051e2f2006-11-14 19:54:19 -08005551 int event, unsigned int flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005552{
Thomas Graf6051e2f2006-11-14 19:54:19 -08005553 struct prefixmsg *pmsg;
5554 struct nlmsghdr *nlh;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005555 struct prefix_cacheinfo ci;
5556
Eric W. Biederman15e47302012-09-07 20:12:54 +00005557 nlh = nlmsg_put(skb, portid, seq, event, sizeof(*pmsg), flags);
Ian Morris63159f22015-03-29 14:00:04 +01005558 if (!nlh)
Patrick McHardy26932562007-01-31 23:16:40 -08005559 return -EMSGSIZE;
Thomas Graf6051e2f2006-11-14 19:54:19 -08005560
5561 pmsg = nlmsg_data(nlh);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005562 pmsg->prefix_family = AF_INET6;
Patrick McHardy8a470772005-06-28 12:56:45 -07005563 pmsg->prefix_pad1 = 0;
5564 pmsg->prefix_pad2 = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005565 pmsg->prefix_ifindex = idev->dev->ifindex;
5566 pmsg->prefix_len = pinfo->prefix_len;
5567 pmsg->prefix_type = pinfo->type;
Patrick McHardy8a470772005-06-28 12:56:45 -07005568 pmsg->prefix_pad3 = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005569 pmsg->prefix_flags = 0;
5570 if (pinfo->onlink)
5571 pmsg->prefix_flags |= IF_PREFIX_ONLINK;
5572 if (pinfo->autoconf)
5573 pmsg->prefix_flags |= IF_PREFIX_AUTOCONF;
5574
David S. Millerc78679e2012-04-01 20:27:33 -04005575 if (nla_put(skb, PREFIX_ADDRESS, sizeof(pinfo->prefix), &pinfo->prefix))
5576 goto nla_put_failure;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005577 ci.preferred_time = ntohl(pinfo->prefered);
5578 ci.valid_time = ntohl(pinfo->valid);
David S. Millerc78679e2012-04-01 20:27:33 -04005579 if (nla_put(skb, PREFIX_CACHEINFO, sizeof(ci), &ci))
5580 goto nla_put_failure;
Johannes Berg053c0952015-01-16 22:09:00 +01005581 nlmsg_end(skb, nlh);
5582 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005583
Thomas Graf6051e2f2006-11-14 19:54:19 -08005584nla_put_failure:
Patrick McHardy26932562007-01-31 23:16:40 -08005585 nlmsg_cancel(skb, nlh);
5586 return -EMSGSIZE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005587}
5588
YOSHIFUJI Hideaki1ab14572007-02-09 23:24:49 +09005589static void inet6_prefix_notify(int event, struct inet6_dev *idev,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005590 struct prefix_info *pinfo)
5591{
5592 struct sk_buff *skb;
YOSHIFUJI Hideakic346dca2008-03-25 21:47:49 +09005593 struct net *net = dev_net(idev->dev);
Thomas Graf8c384bfa2006-08-15 00:36:07 -07005594 int err = -ENOBUFS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005595
Thomas Graf339bf982006-11-10 14:10:15 -08005596 skb = nlmsg_new(inet6_prefix_nlmsg_size(), GFP_ATOMIC);
Ian Morris63159f22015-03-29 14:00:04 +01005597 if (!skb)
Thomas Graf8c384bfa2006-08-15 00:36:07 -07005598 goto errout;
5599
5600 err = inet6_fill_prefix(skb, idev, pinfo, 0, 0, event, 0);
Patrick McHardy26932562007-01-31 23:16:40 -08005601 if (err < 0) {
5602 /* -EMSGSIZE implies BUG in inet6_prefix_nlmsg_size() */
5603 WARN_ON(err == -EMSGSIZE);
5604 kfree_skb(skb);
5605 goto errout;
5606 }
Pablo Neira Ayuso1ce85fe2009-02-24 23:18:28 -08005607 rtnl_notify(skb, net, 0, RTNLGRP_IPV6_PREFIX, NULL, GFP_ATOMIC);
5608 return;
Thomas Graf8c384bfa2006-08-15 00:36:07 -07005609errout:
5610 if (err < 0)
Benjamin Thery6fda7352008-03-05 10:47:47 -08005611 rtnl_set_sk_err(net, RTNLGRP_IPV6_PREFIX, err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005612}
5613
Linus Torvalds1da177e2005-04-16 15:20:36 -07005614static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
5615{
Nicolas Dichtel63998ac2013-03-22 06:28:43 +00005616 struct net *net = dev_net(ifp->idev->dev);
5617
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01005618 if (event)
5619 ASSERT_RTNL();
5620
Linus Torvalds1da177e2005-04-16 15:20:36 -07005621 inet6_ifa_notify(event ? : RTM_NEWADDR, ifp);
5622
5623 switch (event) {
5624 case RTM_NEWADDR:
Neil Horman95c385b2007-04-25 17:08:10 -07005625 /*
5626 * If the address was optimistic
5627 * we inserted the route at the start of
5628 * our DAD process, so we don't need
5629 * to do it again
5630 */
David Ahern93c2fb22018-04-18 15:38:59 -07005631 if (!rcu_access_pointer(ifp->rt->fib6_node))
David Ahernafb1d4b52018-04-17 17:33:11 -07005632 ip6_ins_rt(net, ifp->rt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005633 if (ifp->idev->cnf.forwarding)
5634 addrconf_join_anycast(ifp);
Cong Wang7996c792013-05-22 05:41:06 +00005635 if (!ipv6_addr_any(&ifp->peer_addr))
Nicolas Dichtelcaeaba72013-05-16 22:32:00 +00005636 addrconf_prefix_route(&ifp->peer_addr, 128,
David Ahernacb54e32018-04-17 17:33:22 -07005637 ifp->idev->dev, 0, 0,
David Ahern27b10602018-04-18 15:39:06 -07005638 GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005639 break;
5640 case RTM_DELADDR:
5641 if (ifp->idev->cnf.forwarding)
5642 addrconf_leave_anycast(ifp);
5643 addrconf_leave_solict(ifp->idev, &ifp->addr);
Cong Wang7996c792013-05-22 05:41:06 +00005644 if (!ipv6_addr_any(&ifp->peer_addr)) {
David Ahern8d1c8022018-04-17 17:33:26 -07005645 struct fib6_info *rt;
Nicolas Dichtelcaeaba72013-05-16 22:32:00 +00005646
Nicolas Dichtele7478df2014-09-03 23:59:22 +02005647 rt = addrconf_get_prefix_route(&ifp->peer_addr, 128,
5648 ifp->idev->dev, 0, 0);
Martin KaFai Lau8e3d5be2015-09-15 14:30:08 -07005649 if (rt)
David Ahernafb1d4b52018-04-17 17:33:11 -07005650 ip6_del_rt(net, rt);
Nicolas Dichtelcaeaba72013-05-16 22:32:00 +00005651 }
David Ahern38bd10c2016-04-21 20:56:12 -07005652 if (ifp->rt) {
David Ahern93531c62018-04-17 17:33:25 -07005653 ip6_del_rt(net, ifp->rt);
5654 ifp->rt = NULL;
David Ahern38bd10c2016-04-21 20:56:12 -07005655 }
Hannes Frederic Sowa705f1c82014-09-28 00:46:06 +02005656 rt_genid_bump_ipv6(net);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005657 break;
5658 }
Nicolas Dichtel63998ac2013-03-22 06:28:43 +00005659 atomic_inc(&net->ipv6.dev_addr_genid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005660}
5661
5662static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
5663{
YOSHIFUJI Hideaki8814c4b2006-09-22 14:44:24 -07005664 rcu_read_lock_bh();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005665 if (likely(ifp->idev->dead == 0))
5666 __ipv6_ifa_notify(event, ifp);
YOSHIFUJI Hideaki8814c4b2006-09-22 14:44:24 -07005667 rcu_read_unlock_bh();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005668}
5669
5670#ifdef CONFIG_SYSCTL
5671
5672static
Joe Perchesfe2c6332013-06-11 23:04:25 -07005673int addrconf_sysctl_forward(struct ctl_table *ctl, int write,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005674 void __user *buffer, size_t *lenp, loff_t *ppos)
5675{
5676 int *valp = ctl->data;
5677 int val = *valp;
Eric W. Biederman88af1822010-02-19 13:22:59 +00005678 loff_t pos = *ppos;
Joe Perchesfe2c6332013-06-11 23:04:25 -07005679 struct ctl_table lctl;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005680 int ret;
5681
Francesco Ruggeri013d97e2012-01-16 10:40:10 +00005682 /*
5683 * ctl->data points to idev->cnf.forwarding, we should
5684 * not modify it until we get the rtnl lock.
5685 */
5686 lctl = *ctl;
5687 lctl.data = &val;
5688
5689 ret = proc_dointvec(&lctl, write, buffer, lenp, ppos);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005690
Pavel Emelyanovc8fecf22007-12-05 01:50:24 -08005691 if (write)
Stephen Hemmingerb325fdd2009-02-26 06:55:31 +00005692 ret = addrconf_fixup_forwarding(ctl, valp, val);
Eric W. Biederman88af1822010-02-19 13:22:59 +00005693 if (ret)
5694 *ppos = pos;
YOSHIFUJI Hideaki1ab14572007-02-09 23:24:49 +09005695 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005696}
5697
Marcelo Leitner77751422015-02-23 11:17:13 -03005698static
5699int addrconf_sysctl_mtu(struct ctl_table *ctl, int write,
5700 void __user *buffer, size_t *lenp, loff_t *ppos)
5701{
5702 struct inet6_dev *idev = ctl->extra1;
5703 int min_mtu = IPV6_MIN_MTU;
5704 struct ctl_table lctl;
5705
5706 lctl = *ctl;
5707 lctl.extra1 = &min_mtu;
5708 lctl.extra2 = idev ? &idev->dev->mtu : NULL;
5709
5710 return proc_dointvec_minmax(&lctl, write, buffer, lenp, ppos);
5711}
5712
Brian Haley56d417b2009-06-01 03:07:33 -07005713static void dev_disable_change(struct inet6_dev *idev)
5714{
Cong Wang75538c22013-05-29 11:30:50 +08005715 struct netdev_notifier_info info;
5716
Brian Haley56d417b2009-06-01 03:07:33 -07005717 if (!idev || !idev->dev)
5718 return;
5719
Cong Wang75538c22013-05-29 11:30:50 +08005720 netdev_notifier_info_init(&info, idev->dev);
Brian Haley56d417b2009-06-01 03:07:33 -07005721 if (idev->cnf.disable_ipv6)
Cong Wang75538c22013-05-29 11:30:50 +08005722 addrconf_notify(NULL, NETDEV_DOWN, &info);
Brian Haley56d417b2009-06-01 03:07:33 -07005723 else
Cong Wang75538c22013-05-29 11:30:50 +08005724 addrconf_notify(NULL, NETDEV_UP, &info);
Brian Haley56d417b2009-06-01 03:07:33 -07005725}
5726
5727static void addrconf_disable_change(struct net *net, __s32 newf)
5728{
5729 struct net_device *dev;
5730 struct inet6_dev *idev;
5731
Kefeng Wang03e4def2017-01-19 16:26:21 +08005732 for_each_netdev(net, dev) {
Brian Haley56d417b2009-06-01 03:07:33 -07005733 idev = __in6_dev_get(dev);
5734 if (idev) {
5735 int changed = (!idev->cnf.disable_ipv6) ^ (!newf);
5736 idev->cnf.disable_ipv6 = newf;
5737 if (changed)
5738 dev_disable_change(idev);
5739 }
Brian Haley56d417b2009-06-01 03:07:33 -07005740 }
Brian Haley56d417b2009-06-01 03:07:33 -07005741}
5742
Francesco Ruggeri013d97e2012-01-16 10:40:10 +00005743static int addrconf_disable_ipv6(struct ctl_table *table, int *p, int newf)
Brian Haley56d417b2009-06-01 03:07:33 -07005744{
5745 struct net *net;
Francesco Ruggeri013d97e2012-01-16 10:40:10 +00005746 int old;
5747
5748 if (!rtnl_trylock())
5749 return restart_syscall();
Brian Haley56d417b2009-06-01 03:07:33 -07005750
5751 net = (struct net *)table->extra2;
Francesco Ruggeri013d97e2012-01-16 10:40:10 +00005752 old = *p;
5753 *p = newf;
Brian Haley56d417b2009-06-01 03:07:33 -07005754
Francesco Ruggeri013d97e2012-01-16 10:40:10 +00005755 if (p == &net->ipv6.devconf_dflt->disable_ipv6) {
5756 rtnl_unlock();
Brian Haley56d417b2009-06-01 03:07:33 -07005757 return 0;
Eric W. Biederman88af1822010-02-19 13:22:59 +00005758 }
Brian Haley56d417b2009-06-01 03:07:33 -07005759
5760 if (p == &net->ipv6.devconf_all->disable_ipv6) {
Brian Haley56d417b2009-06-01 03:07:33 -07005761 net->ipv6.devconf_dflt->disable_ipv6 = newf;
5762 addrconf_disable_change(net, newf);
Francesco Ruggeri013d97e2012-01-16 10:40:10 +00005763 } else if ((!newf) ^ (!old))
Brian Haley56d417b2009-06-01 03:07:33 -07005764 dev_disable_change((struct inet6_dev *)table->extra1);
5765
5766 rtnl_unlock();
5767 return 0;
5768}
5769
5770static
Joe Perchesfe2c6332013-06-11 23:04:25 -07005771int addrconf_sysctl_disable(struct ctl_table *ctl, int write,
Brian Haley56d417b2009-06-01 03:07:33 -07005772 void __user *buffer, size_t *lenp, loff_t *ppos)
5773{
5774 int *valp = ctl->data;
5775 int val = *valp;
Eric W. Biederman88af1822010-02-19 13:22:59 +00005776 loff_t pos = *ppos;
Joe Perchesfe2c6332013-06-11 23:04:25 -07005777 struct ctl_table lctl;
Brian Haley56d417b2009-06-01 03:07:33 -07005778 int ret;
5779
Francesco Ruggeri013d97e2012-01-16 10:40:10 +00005780 /*
5781 * ctl->data points to idev->cnf.disable_ipv6, we should
5782 * not modify it until we get the rtnl lock.
5783 */
5784 lctl = *ctl;
5785 lctl.data = &val;
5786
5787 ret = proc_dointvec(&lctl, write, buffer, lenp, ppos);
Brian Haley56d417b2009-06-01 03:07:33 -07005788
5789 if (write)
5790 ret = addrconf_disable_ipv6(ctl, valp, val);
Eric W. Biederman88af1822010-02-19 13:22:59 +00005791 if (ret)
5792 *ppos = pos;
Brian Haley56d417b2009-06-01 03:07:33 -07005793 return ret;
5794}
5795
stephen hemmingerc92d5492013-12-17 22:37:14 -08005796static
5797int addrconf_sysctl_proxy_ndp(struct ctl_table *ctl, int write,
5798 void __user *buffer, size_t *lenp, loff_t *ppos)
5799{
5800 int *valp = ctl->data;
5801 int ret;
5802 int old, new;
5803
5804 old = *valp;
5805 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
5806 new = *valp;
5807
5808 if (write && old != new) {
5809 struct net *net = ctl->extra2;
5810
5811 if (!rtnl_trylock())
5812 return restart_syscall();
5813
5814 if (valp == &net->ipv6.devconf_dflt->proxy_ndp)
David Ahern85b3daa2017-03-28 14:28:04 -07005815 inet6_netconf_notify_devconf(net, RTM_NEWNETCONF,
5816 NETCONFA_PROXY_NEIGH,
stephen hemmingerc92d5492013-12-17 22:37:14 -08005817 NETCONFA_IFINDEX_DEFAULT,
5818 net->ipv6.devconf_dflt);
5819 else if (valp == &net->ipv6.devconf_all->proxy_ndp)
David Ahern85b3daa2017-03-28 14:28:04 -07005820 inet6_netconf_notify_devconf(net, RTM_NEWNETCONF,
5821 NETCONFA_PROXY_NEIGH,
stephen hemmingerc92d5492013-12-17 22:37:14 -08005822 NETCONFA_IFINDEX_ALL,
5823 net->ipv6.devconf_all);
5824 else {
5825 struct inet6_dev *idev = ctl->extra1;
5826
David Ahern85b3daa2017-03-28 14:28:04 -07005827 inet6_netconf_notify_devconf(net, RTM_NEWNETCONF,
5828 NETCONFA_PROXY_NEIGH,
stephen hemmingerc92d5492013-12-17 22:37:14 -08005829 idev->dev->ifindex,
5830 &idev->cnf);
5831 }
5832 rtnl_unlock();
5833 }
5834
5835 return ret;
5836}
5837
Felix Jiad35a00b2017-01-26 16:59:17 +13005838static int addrconf_sysctl_addr_gen_mode(struct ctl_table *ctl, int write,
5839 void __user *buffer, size_t *lenp,
5840 loff_t *ppos)
5841{
5842 int ret = 0;
5843 int new_val;
5844 struct inet6_dev *idev = (struct inet6_dev *)ctl->extra1;
5845 struct net *net = (struct net *)ctl->extra2;
5846
Felix Jia8c171d62017-02-27 12:41:23 +13005847 if (!rtnl_trylock())
5848 return restart_syscall();
5849
Felix Jiad35a00b2017-01-26 16:59:17 +13005850 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
5851
5852 if (write) {
5853 new_val = *((int *)ctl->data);
5854
Felix Jia8c171d62017-02-27 12:41:23 +13005855 if (check_addr_gen_mode(new_val) < 0) {
5856 ret = -EINVAL;
5857 goto out;
5858 }
Felix Jiad35a00b2017-01-26 16:59:17 +13005859
5860 /* request for default */
5861 if (&net->ipv6.devconf_dflt->addr_gen_mode == ctl->data) {
5862 ipv6_devconf_dflt.addr_gen_mode = new_val;
5863
5864 /* request for individual net device */
5865 } else {
5866 if (!idev)
Felix Jia8c171d62017-02-27 12:41:23 +13005867 goto out;
Felix Jiad35a00b2017-01-26 16:59:17 +13005868
Felix Jia8c171d62017-02-27 12:41:23 +13005869 if (check_stable_privacy(idev, net, new_val) < 0) {
5870 ret = -EINVAL;
5871 goto out;
5872 }
Felix Jiad35a00b2017-01-26 16:59:17 +13005873
5874 if (idev->cnf.addr_gen_mode != new_val) {
5875 idev->cnf.addr_gen_mode = new_val;
Felix Jiad35a00b2017-01-26 16:59:17 +13005876 addrconf_dev_config(idev->dev);
Felix Jiad35a00b2017-01-26 16:59:17 +13005877 }
5878 }
5879 }
5880
Felix Jia8c171d62017-02-27 12:41:23 +13005881out:
5882 rtnl_unlock();
5883
Felix Jiad35a00b2017-01-26 16:59:17 +13005884 return ret;
5885}
5886
Hannes Frederic Sowa3d1bec92015-03-23 23:36:00 +01005887static int addrconf_sysctl_stable_secret(struct ctl_table *ctl, int write,
5888 void __user *buffer, size_t *lenp,
5889 loff_t *ppos)
5890{
5891 int err;
5892 struct in6_addr addr;
5893 char str[IPV6_MAX_STRLEN];
5894 struct ctl_table lctl = *ctl;
Hannes Frederic Sowa622c81d52015-03-23 23:36:01 +01005895 struct net *net = ctl->extra2;
Hannes Frederic Sowa3d1bec92015-03-23 23:36:00 +01005896 struct ipv6_stable_secret *secret = ctl->data;
5897
Hannes Frederic Sowa622c81d52015-03-23 23:36:01 +01005898 if (&net->ipv6.devconf_all->stable_secret == ctl->data)
5899 return -EIO;
5900
Hannes Frederic Sowa3d1bec92015-03-23 23:36:00 +01005901 lctl.maxlen = IPV6_MAX_STRLEN;
5902 lctl.data = str;
5903
5904 if (!rtnl_trylock())
5905 return restart_syscall();
5906
5907 if (!write && !secret->initialized) {
5908 err = -EIO;
5909 goto out;
5910 }
5911
WANG Cong5449a5c2015-12-21 10:55:45 -08005912 err = snprintf(str, sizeof(str), "%pI6", &secret->secret);
5913 if (err >= sizeof(str)) {
5914 err = -EIO;
5915 goto out;
Hannes Frederic Sowa3d1bec92015-03-23 23:36:00 +01005916 }
5917
5918 err = proc_dostring(&lctl, write, buffer, lenp, ppos);
5919 if (err || !write)
5920 goto out;
5921
5922 if (in6_pton(str, -1, addr.in6_u.u6_addr8, -1, NULL) != 1) {
5923 err = -EIO;
5924 goto out;
5925 }
5926
5927 secret->initialized = true;
5928 secret->secret = addr;
5929
Hannes Frederic Sowa622c81d52015-03-23 23:36:01 +01005930 if (&net->ipv6.devconf_dflt->stable_secret == ctl->data) {
5931 struct net_device *dev;
5932
5933 for_each_netdev(net, dev) {
5934 struct inet6_dev *idev = __in6_dev_get(dev);
5935
5936 if (idev) {
Felix Jiad35a00b2017-01-26 16:59:17 +13005937 idev->cnf.addr_gen_mode =
Hannes Frederic Sowa622c81d52015-03-23 23:36:01 +01005938 IN6_ADDR_GEN_MODE_STABLE_PRIVACY;
5939 }
5940 }
5941 } else {
5942 struct inet6_dev *idev = ctl->extra1;
5943
Felix Jiad35a00b2017-01-26 16:59:17 +13005944 idev->cnf.addr_gen_mode = IN6_ADDR_GEN_MODE_STABLE_PRIVACY;
Hannes Frederic Sowa622c81d52015-03-23 23:36:01 +01005945 }
5946
Hannes Frederic Sowa3d1bec92015-03-23 23:36:00 +01005947out:
5948 rtnl_unlock();
5949
5950 return err;
5951}
stephen hemmingerc92d5492013-12-17 22:37:14 -08005952
Andy Gospodarek35103d12015-08-13 10:39:01 -04005953static
5954int addrconf_sysctl_ignore_routes_with_linkdown(struct ctl_table *ctl,
5955 int write,
5956 void __user *buffer,
5957 size_t *lenp,
5958 loff_t *ppos)
5959{
5960 int *valp = ctl->data;
5961 int val = *valp;
5962 loff_t pos = *ppos;
5963 struct ctl_table lctl;
5964 int ret;
5965
5966 /* ctl->data points to idev->cnf.ignore_routes_when_linkdown
5967 * we should not modify it until we get the rtnl lock.
5968 */
5969 lctl = *ctl;
5970 lctl.data = &val;
5971
5972 ret = proc_dointvec(&lctl, write, buffer, lenp, ppos);
5973
5974 if (write)
5975 ret = addrconf_fixup_linkdown(ctl, valp, val);
5976 if (ret)
5977 *ppos = pos;
5978 return ret;
5979}
5980
David Forsterdf789fe2017-02-23 16:27:18 +00005981static
5982void addrconf_set_nopolicy(struct rt6_info *rt, int action)
5983{
5984 if (rt) {
5985 if (action)
5986 rt->dst.flags |= DST_NOPOLICY;
5987 else
5988 rt->dst.flags &= ~DST_NOPOLICY;
5989 }
5990}
5991
5992static
5993void addrconf_disable_policy_idev(struct inet6_dev *idev, int val)
5994{
5995 struct inet6_ifaddr *ifa;
5996
5997 read_lock_bh(&idev->lock);
5998 list_for_each_entry(ifa, &idev->addr_list, if_list) {
5999 spin_lock(&ifa->lock);
6000 if (ifa->rt) {
David Ahern8d1c8022018-04-17 17:33:26 -07006001 struct fib6_info *rt = ifa->rt;
David Forsterdf789fe2017-02-23 16:27:18 +00006002 int cpu;
6003
Wei Wang66f5d6c2017-10-06 12:06:10 -07006004 rcu_read_lock();
David Ahern3b6761d2018-04-17 17:33:20 -07006005 ifa->rt->dst_nopolicy = val ? true : false;
David Forsterdf789fe2017-02-23 16:27:18 +00006006 if (rt->rt6i_pcpu) {
6007 for_each_possible_cpu(cpu) {
6008 struct rt6_info **rtp;
6009
6010 rtp = per_cpu_ptr(rt->rt6i_pcpu, cpu);
6011 addrconf_set_nopolicy(*rtp, val);
6012 }
6013 }
Wei Wang66f5d6c2017-10-06 12:06:10 -07006014 rcu_read_unlock();
David Forsterdf789fe2017-02-23 16:27:18 +00006015 }
6016 spin_unlock(&ifa->lock);
6017 }
6018 read_unlock_bh(&idev->lock);
6019}
6020
6021static
6022int addrconf_disable_policy(struct ctl_table *ctl, int *valp, int val)
6023{
6024 struct inet6_dev *idev;
6025 struct net *net;
6026
6027 if (!rtnl_trylock())
6028 return restart_syscall();
6029
6030 *valp = val;
6031
6032 net = (struct net *)ctl->extra2;
6033 if (valp == &net->ipv6.devconf_dflt->disable_policy) {
6034 rtnl_unlock();
6035 return 0;
6036 }
6037
6038 if (valp == &net->ipv6.devconf_all->disable_policy) {
6039 struct net_device *dev;
6040
6041 for_each_netdev(net, dev) {
6042 idev = __in6_dev_get(dev);
6043 if (idev)
6044 addrconf_disable_policy_idev(idev, val);
6045 }
6046 } else {
6047 idev = (struct inet6_dev *)ctl->extra1;
6048 addrconf_disable_policy_idev(idev, val);
6049 }
6050
6051 rtnl_unlock();
6052 return 0;
6053}
6054
6055static
6056int addrconf_sysctl_disable_policy(struct ctl_table *ctl, int write,
6057 void __user *buffer, size_t *lenp,
6058 loff_t *ppos)
6059{
6060 int *valp = ctl->data;
6061 int val = *valp;
6062 loff_t pos = *ppos;
6063 struct ctl_table lctl;
6064 int ret;
6065
6066 lctl = *ctl;
6067 lctl.data = &val;
6068 ret = proc_dointvec(&lctl, write, buffer, lenp, ppos);
6069
6070 if (write && (*valp != val))
6071 ret = addrconf_disable_policy(ctl, valp, val);
6072
6073 if (ret)
6074 *ppos = pos;
6075
6076 return ret;
6077}
6078
Maciej Żenczykowskicb4a4c62016-10-07 01:00:49 -07006079static int minus_one = -1;
Maciej Żenczykowski2210d6b2017-11-07 21:52:09 -08006080static const int zero = 0;
Maciej Żenczykowskicb9e6842016-09-29 00:33:43 -07006081static const int one = 1;
6082static const int two_five_five = 255;
6083
Konstantin Khlebnikov607ea7c2016-04-18 14:41:10 +03006084static const struct ctl_table addrconf_sysctl[] = {
Konstantin Khlebnikov5df1f772016-04-18 14:41:17 +03006085 {
6086 .procname = "forwarding",
6087 .data = &ipv6_devconf.forwarding,
6088 .maxlen = sizeof(int),
6089 .mode = 0644,
6090 .proc_handler = addrconf_sysctl_forward,
6091 },
6092 {
6093 .procname = "hop_limit",
6094 .data = &ipv6_devconf.hop_limit,
6095 .maxlen = sizeof(int),
6096 .mode = 0644,
Maciej Żenczykowskicb9e6842016-09-29 00:33:43 -07006097 .proc_handler = proc_dointvec_minmax,
6098 .extra1 = (void *)&one,
6099 .extra2 = (void *)&two_five_five,
Konstantin Khlebnikov5df1f772016-04-18 14:41:17 +03006100 },
6101 {
6102 .procname = "mtu",
6103 .data = &ipv6_devconf.mtu6,
6104 .maxlen = sizeof(int),
6105 .mode = 0644,
6106 .proc_handler = addrconf_sysctl_mtu,
6107 },
6108 {
6109 .procname = "accept_ra",
6110 .data = &ipv6_devconf.accept_ra,
6111 .maxlen = sizeof(int),
6112 .mode = 0644,
6113 .proc_handler = proc_dointvec,
6114 },
6115 {
6116 .procname = "accept_redirects",
6117 .data = &ipv6_devconf.accept_redirects,
6118 .maxlen = sizeof(int),
6119 .mode = 0644,
6120 .proc_handler = proc_dointvec,
6121 },
6122 {
6123 .procname = "autoconf",
6124 .data = &ipv6_devconf.autoconf,
6125 .maxlen = sizeof(int),
6126 .mode = 0644,
6127 .proc_handler = proc_dointvec,
6128 },
6129 {
6130 .procname = "dad_transmits",
6131 .data = &ipv6_devconf.dad_transmits,
6132 .maxlen = sizeof(int),
6133 .mode = 0644,
6134 .proc_handler = proc_dointvec,
6135 },
6136 {
6137 .procname = "router_solicitations",
6138 .data = &ipv6_devconf.rtr_solicits,
6139 .maxlen = sizeof(int),
6140 .mode = 0644,
Maciej Żenczykowskicb4a4c62016-10-07 01:00:49 -07006141 .proc_handler = proc_dointvec_minmax,
6142 .extra1 = &minus_one,
Konstantin Khlebnikov5df1f772016-04-18 14:41:17 +03006143 },
6144 {
6145 .procname = "router_solicitation_interval",
6146 .data = &ipv6_devconf.rtr_solicit_interval,
6147 .maxlen = sizeof(int),
6148 .mode = 0644,
6149 .proc_handler = proc_dointvec_jiffies,
6150 },
6151 {
Maciej Żenczykowskibd11f072016-09-27 23:57:58 -07006152 .procname = "router_solicitation_max_interval",
6153 .data = &ipv6_devconf.rtr_solicit_max_interval,
6154 .maxlen = sizeof(int),
6155 .mode = 0644,
6156 .proc_handler = proc_dointvec_jiffies,
6157 },
6158 {
Konstantin Khlebnikov5df1f772016-04-18 14:41:17 +03006159 .procname = "router_solicitation_delay",
6160 .data = &ipv6_devconf.rtr_solicit_delay,
6161 .maxlen = sizeof(int),
6162 .mode = 0644,
6163 .proc_handler = proc_dointvec_jiffies,
6164 },
6165 {
6166 .procname = "force_mld_version",
6167 .data = &ipv6_devconf.force_mld_version,
6168 .maxlen = sizeof(int),
6169 .mode = 0644,
6170 .proc_handler = proc_dointvec,
6171 },
6172 {
6173 .procname = "mldv1_unsolicited_report_interval",
6174 .data =
6175 &ipv6_devconf.mldv1_unsolicited_report_interval,
6176 .maxlen = sizeof(int),
6177 .mode = 0644,
6178 .proc_handler = proc_dointvec_ms_jiffies,
6179 },
6180 {
6181 .procname = "mldv2_unsolicited_report_interval",
6182 .data =
6183 &ipv6_devconf.mldv2_unsolicited_report_interval,
6184 .maxlen = sizeof(int),
6185 .mode = 0644,
6186 .proc_handler = proc_dointvec_ms_jiffies,
6187 },
6188 {
6189 .procname = "use_tempaddr",
6190 .data = &ipv6_devconf.use_tempaddr,
6191 .maxlen = sizeof(int),
6192 .mode = 0644,
6193 .proc_handler = proc_dointvec,
6194 },
6195 {
6196 .procname = "temp_valid_lft",
6197 .data = &ipv6_devconf.temp_valid_lft,
6198 .maxlen = sizeof(int),
6199 .mode = 0644,
6200 .proc_handler = proc_dointvec,
6201 },
6202 {
6203 .procname = "temp_prefered_lft",
6204 .data = &ipv6_devconf.temp_prefered_lft,
6205 .maxlen = sizeof(int),
6206 .mode = 0644,
6207 .proc_handler = proc_dointvec,
6208 },
6209 {
6210 .procname = "regen_max_retry",
6211 .data = &ipv6_devconf.regen_max_retry,
6212 .maxlen = sizeof(int),
6213 .mode = 0644,
6214 .proc_handler = proc_dointvec,
6215 },
6216 {
6217 .procname = "max_desync_factor",
6218 .data = &ipv6_devconf.max_desync_factor,
6219 .maxlen = sizeof(int),
6220 .mode = 0644,
6221 .proc_handler = proc_dointvec,
6222 },
6223 {
6224 .procname = "max_addresses",
6225 .data = &ipv6_devconf.max_addresses,
6226 .maxlen = sizeof(int),
6227 .mode = 0644,
6228 .proc_handler = proc_dointvec,
6229 },
6230 {
6231 .procname = "accept_ra_defrtr",
6232 .data = &ipv6_devconf.accept_ra_defrtr,
6233 .maxlen = sizeof(int),
6234 .mode = 0644,
6235 .proc_handler = proc_dointvec,
6236 },
6237 {
6238 .procname = "accept_ra_min_hop_limit",
6239 .data = &ipv6_devconf.accept_ra_min_hop_limit,
6240 .maxlen = sizeof(int),
6241 .mode = 0644,
6242 .proc_handler = proc_dointvec,
6243 },
6244 {
6245 .procname = "accept_ra_pinfo",
6246 .data = &ipv6_devconf.accept_ra_pinfo,
6247 .maxlen = sizeof(int),
6248 .mode = 0644,
6249 .proc_handler = proc_dointvec,
6250 },
YOSHIFUJI Hideaki930d6ff2006-03-20 17:05:30 -08006251#ifdef CONFIG_IPV6_ROUTER_PREF
Konstantin Khlebnikov5df1f772016-04-18 14:41:17 +03006252 {
6253 .procname = "accept_ra_rtr_pref",
6254 .data = &ipv6_devconf.accept_ra_rtr_pref,
6255 .maxlen = sizeof(int),
6256 .mode = 0644,
6257 .proc_handler = proc_dointvec,
6258 },
6259 {
6260 .procname = "router_probe_interval",
6261 .data = &ipv6_devconf.rtr_probe_interval,
6262 .maxlen = sizeof(int),
6263 .mode = 0644,
6264 .proc_handler = proc_dointvec_jiffies,
6265 },
Neil Hormanfa03ef32007-01-30 14:30:10 -08006266#ifdef CONFIG_IPV6_ROUTE_INFO
Konstantin Khlebnikov5df1f772016-04-18 14:41:17 +03006267 {
Joel Scherpelzbbea1242017-03-22 18:19:04 +09006268 .procname = "accept_ra_rt_info_min_plen",
6269 .data = &ipv6_devconf.accept_ra_rt_info_min_plen,
6270 .maxlen = sizeof(int),
6271 .mode = 0644,
6272 .proc_handler = proc_dointvec,
6273 },
6274 {
Konstantin Khlebnikov5df1f772016-04-18 14:41:17 +03006275 .procname = "accept_ra_rt_info_max_plen",
6276 .data = &ipv6_devconf.accept_ra_rt_info_max_plen,
6277 .maxlen = sizeof(int),
6278 .mode = 0644,
6279 .proc_handler = proc_dointvec,
6280 },
YOSHIFUJI Hideaki09c884d2006-03-20 17:07:03 -08006281#endif
YOSHIFUJI Hideaki930d6ff2006-03-20 17:05:30 -08006282#endif
Konstantin Khlebnikov5df1f772016-04-18 14:41:17 +03006283 {
6284 .procname = "proxy_ndp",
6285 .data = &ipv6_devconf.proxy_ndp,
6286 .maxlen = sizeof(int),
6287 .mode = 0644,
6288 .proc_handler = addrconf_sysctl_proxy_ndp,
6289 },
6290 {
6291 .procname = "accept_source_route",
6292 .data = &ipv6_devconf.accept_source_route,
6293 .maxlen = sizeof(int),
6294 .mode = 0644,
6295 .proc_handler = proc_dointvec,
6296 },
Neil Horman95c385b2007-04-25 17:08:10 -07006297#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
Konstantin Khlebnikov5df1f772016-04-18 14:41:17 +03006298 {
6299 .procname = "optimistic_dad",
6300 .data = &ipv6_devconf.optimistic_dad,
6301 .maxlen = sizeof(int),
6302 .mode = 0644,
6303 .proc_handler = proc_dointvec,
6304 },
6305 {
6306 .procname = "use_optimistic",
6307 .data = &ipv6_devconf.use_optimistic,
6308 .maxlen = sizeof(int),
6309 .mode = 0644,
6310 .proc_handler = proc_dointvec,
6311 },
Neil Horman95c385b2007-04-25 17:08:10 -07006312#endif
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09006313#ifdef CONFIG_IPV6_MROUTE
Konstantin Khlebnikov5df1f772016-04-18 14:41:17 +03006314 {
6315 .procname = "mc_forwarding",
6316 .data = &ipv6_devconf.mc_forwarding,
6317 .maxlen = sizeof(int),
6318 .mode = 0444,
6319 .proc_handler = proc_dointvec,
6320 },
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09006321#endif
Konstantin Khlebnikov5df1f772016-04-18 14:41:17 +03006322 {
6323 .procname = "disable_ipv6",
6324 .data = &ipv6_devconf.disable_ipv6,
6325 .maxlen = sizeof(int),
6326 .mode = 0644,
6327 .proc_handler = addrconf_sysctl_disable,
6328 },
6329 {
6330 .procname = "accept_dad",
6331 .data = &ipv6_devconf.accept_dad,
6332 .maxlen = sizeof(int),
6333 .mode = 0644,
6334 .proc_handler = proc_dointvec,
6335 },
6336 {
6337 .procname = "force_tllao",
6338 .data = &ipv6_devconf.force_tllao,
6339 .maxlen = sizeof(int),
6340 .mode = 0644,
6341 .proc_handler = proc_dointvec
6342 },
6343 {
6344 .procname = "ndisc_notify",
6345 .data = &ipv6_devconf.ndisc_notify,
6346 .maxlen = sizeof(int),
6347 .mode = 0644,
6348 .proc_handler = proc_dointvec
6349 },
6350 {
6351 .procname = "suppress_frag_ndisc",
6352 .data = &ipv6_devconf.suppress_frag_ndisc,
6353 .maxlen = sizeof(int),
6354 .mode = 0644,
6355 .proc_handler = proc_dointvec
6356 },
6357 {
6358 .procname = "accept_ra_from_local",
6359 .data = &ipv6_devconf.accept_ra_from_local,
6360 .maxlen = sizeof(int),
6361 .mode = 0644,
6362 .proc_handler = proc_dointvec,
6363 },
6364 {
6365 .procname = "accept_ra_mtu",
6366 .data = &ipv6_devconf.accept_ra_mtu,
6367 .maxlen = sizeof(int),
6368 .mode = 0644,
6369 .proc_handler = proc_dointvec,
6370 },
6371 {
6372 .procname = "stable_secret",
6373 .data = &ipv6_devconf.stable_secret,
6374 .maxlen = IPV6_MAX_STRLEN,
6375 .mode = 0600,
6376 .proc_handler = addrconf_sysctl_stable_secret,
6377 },
6378 {
6379 .procname = "use_oif_addrs_only",
6380 .data = &ipv6_devconf.use_oif_addrs_only,
6381 .maxlen = sizeof(int),
6382 .mode = 0644,
6383 .proc_handler = proc_dointvec,
6384 },
6385 {
6386 .procname = "ignore_routes_with_linkdown",
6387 .data = &ipv6_devconf.ignore_routes_with_linkdown,
6388 .maxlen = sizeof(int),
6389 .mode = 0644,
6390 .proc_handler = addrconf_sysctl_ignore_routes_with_linkdown,
6391 },
6392 {
6393 .procname = "drop_unicast_in_l2_multicast",
6394 .data = &ipv6_devconf.drop_unicast_in_l2_multicast,
6395 .maxlen = sizeof(int),
6396 .mode = 0644,
6397 .proc_handler = proc_dointvec,
6398 },
6399 {
6400 .procname = "drop_unsolicited_na",
6401 .data = &ipv6_devconf.drop_unsolicited_na,
6402 .maxlen = sizeof(int),
6403 .mode = 0644,
6404 .proc_handler = proc_dointvec,
6405 },
6406 {
6407 .procname = "keep_addr_on_down",
6408 .data = &ipv6_devconf.keep_addr_on_down,
6409 .maxlen = sizeof(int),
6410 .mode = 0644,
6411 .proc_handler = proc_dointvec,
David Ahernf1705ec2016-02-24 09:25:37 -08006412
Konstantin Khlebnikov5df1f772016-04-18 14:41:17 +03006413 },
6414 {
David Lebrun1ababeb2016-11-08 14:57:39 +01006415 .procname = "seg6_enabled",
6416 .data = &ipv6_devconf.seg6_enabled,
6417 .maxlen = sizeof(int),
6418 .mode = 0644,
6419 .proc_handler = proc_dointvec,
6420 },
David Lebrunbf355b82016-11-08 14:57:42 +01006421#ifdef CONFIG_IPV6_SEG6_HMAC
6422 {
6423 .procname = "seg6_require_hmac",
6424 .data = &ipv6_devconf.seg6_require_hmac,
6425 .maxlen = sizeof(int),
6426 .mode = 0644,
6427 .proc_handler = proc_dointvec,
6428 },
6429#endif
David Lebrun1ababeb2016-11-08 14:57:39 +01006430 {
Erik Nordmarkadc176c2016-12-02 14:00:08 -08006431 .procname = "enhanced_dad",
6432 .data = &ipv6_devconf.enhanced_dad,
6433 .maxlen = sizeof(int),
6434 .mode = 0644,
6435 .proc_handler = proc_dointvec,
6436 },
6437 {
Felix Jiad35a00b2017-01-26 16:59:17 +13006438 .procname = "addr_gen_mode",
6439 .data = &ipv6_devconf.addr_gen_mode,
6440 .maxlen = sizeof(int),
6441 .mode = 0644,
6442 .proc_handler = addrconf_sysctl_addr_gen_mode,
6443 },
6444 {
David Forsterdf789fe2017-02-23 16:27:18 +00006445 .procname = "disable_policy",
6446 .data = &ipv6_devconf.disable_policy,
6447 .maxlen = sizeof(int),
6448 .mode = 0644,
6449 .proc_handler = addrconf_sysctl_disable_policy,
6450 },
6451 {
Maciej Żenczykowski2210d6b2017-11-07 21:52:09 -08006452 .procname = "ndisc_tclass",
6453 .data = &ipv6_devconf.ndisc_tclass,
6454 .maxlen = sizeof(int),
6455 .mode = 0644,
6456 .proc_handler = proc_dointvec_minmax,
6457 .extra1 = (void *)&zero,
6458 .extra2 = (void *)&two_five_five,
6459 },
6460 {
Konstantin Khlebnikov5df1f772016-04-18 14:41:17 +03006461 /* sentinel */
6462 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006463};
6464
Pavel Emelyanovbff16c22008-01-10 17:42:13 -08006465static int __addrconf_sysctl_register(struct net *net, char *dev_name,
Eric W. Biedermanf8572d82009-11-05 13:32:03 -08006466 struct inet6_dev *idev, struct ipv6_devconf *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006467{
Nicolas Dichtel29c994e2016-08-30 10:09:22 +02006468 int i, ifindex;
Konstantin Khlebnikov607ea7c2016-04-18 14:41:10 +03006469 struct ctl_table *table;
Eric W. Biederman6105e292012-04-19 13:41:24 +00006470 char path[sizeof("net/ipv6/conf/") + IFNAMSIZ];
Pavel Emelyanov1dab6222007-12-02 00:59:38 +11006471
Konstantin Khlebnikov607ea7c2016-04-18 14:41:10 +03006472 table = kmemdup(addrconf_sysctl, sizeof(addrconf_sysctl), GFP_KERNEL);
6473 if (!table)
Pavel Emelyanovf68635e2007-12-02 00:21:52 +11006474 goto out;
6475
Konstantin Khlebnikov607ea7c2016-04-18 14:41:10 +03006476 for (i = 0; table[i].data; i++) {
6477 table[i].data += (char *)p - (char *)&ipv6_devconf;
Maciej Żenczykowskicb9e6842016-09-29 00:33:43 -07006478 /* If one of these is already set, then it is not safe to
6479 * overwrite either of them: this makes proc_dointvec_minmax
6480 * usable.
6481 */
6482 if (!table[i].extra1 && !table[i].extra2) {
6483 table[i].extra1 = idev; /* embedded; no ref */
6484 table[i].extra2 = net;
6485 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006486 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006487
Eric W. Biederman6105e292012-04-19 13:41:24 +00006488 snprintf(path, sizeof(path), "net/ipv6/conf/%s", dev_name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006489
Konstantin Khlebnikov607ea7c2016-04-18 14:41:10 +03006490 p->sysctl_header = register_net_sysctl(net, path, table);
6491 if (!p->sysctl_header)
Eric W. Biederman6105e292012-04-19 13:41:24 +00006492 goto free;
Pavel Emelyanovf68635e2007-12-02 00:21:52 +11006493
Nicolas Dichtel29c994e2016-08-30 10:09:22 +02006494 if (!strcmp(dev_name, "all"))
6495 ifindex = NETCONFA_IFINDEX_ALL;
6496 else if (!strcmp(dev_name, "default"))
6497 ifindex = NETCONFA_IFINDEX_DEFAULT;
6498 else
6499 ifindex = idev->dev->ifindex;
David Ahern85b3daa2017-03-28 14:28:04 -07006500 inet6_netconf_notify_devconf(net, RTM_NEWNETCONF, NETCONFA_ALL,
6501 ifindex, p);
Pavel Emelyanov95897312008-01-10 17:41:45 -08006502 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006503
Pavel Emelyanovf68635e2007-12-02 00:21:52 +11006504free:
Konstantin Khlebnikov607ea7c2016-04-18 14:41:10 +03006505 kfree(table);
Pavel Emelyanovf68635e2007-12-02 00:21:52 +11006506out:
Pavel Emelyanov95897312008-01-10 17:41:45 -08006507 return -ENOBUFS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006508}
6509
David Ahern23452172017-03-28 14:28:05 -07006510static void __addrconf_sysctl_unregister(struct net *net,
6511 struct ipv6_devconf *p, int ifindex)
Pavel Emelyanov408c4762008-01-10 17:41:21 -08006512{
Konstantin Khlebnikov607ea7c2016-04-18 14:41:10 +03006513 struct ctl_table *table;
Pavel Emelyanov408c4762008-01-10 17:41:21 -08006514
Konstantin Khlebnikov607ea7c2016-04-18 14:41:10 +03006515 if (!p->sysctl_header)
Pavel Emelyanov408c4762008-01-10 17:41:21 -08006516 return;
6517
Konstantin Khlebnikov607ea7c2016-04-18 14:41:10 +03006518 table = p->sysctl_header->ctl_table_arg;
6519 unregister_net_sysctl_table(p->sysctl_header);
6520 p->sysctl_header = NULL;
6521 kfree(table);
David Ahern23452172017-03-28 14:28:05 -07006522
6523 inet6_netconf_notify_devconf(net, RTM_DELNETCONF, 0, ifindex, NULL);
Pavel Emelyanov408c4762008-01-10 17:41:21 -08006524}
6525
WANG Conga317a2f2014-07-25 15:25:09 -07006526static int addrconf_sysctl_register(struct inet6_dev *idev)
Pavel Emelyanovf52295a2007-12-02 00:58:37 +11006527{
WANG Conga317a2f2014-07-25 15:25:09 -07006528 int err;
6529
6530 if (!sysctl_dev_name_is_allowed(idev->dev->name))
6531 return -EINVAL;
6532
6533 err = neigh_sysctl_register(idev->dev, idev->nd_parms,
6534 &ndisc_ifinfo_sysctl_change);
6535 if (err)
6536 return err;
6537 err = __addrconf_sysctl_register(dev_net(idev->dev), idev->dev->name,
6538 idev, &idev->cnf);
6539 if (err)
6540 neigh_sysctl_unregister(idev->nd_parms);
6541
6542 return err;
Pavel Emelyanovf52295a2007-12-02 00:58:37 +11006543}
6544
Pavel Emelyanov408c4762008-01-10 17:41:21 -08006545static void addrconf_sysctl_unregister(struct inet6_dev *idev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006546{
David Ahern23452172017-03-28 14:28:05 -07006547 __addrconf_sysctl_unregister(dev_net(idev->dev), &idev->cnf,
6548 idev->dev->ifindex);
Pavel Emelyanov408c4762008-01-10 17:41:21 -08006549 neigh_sysctl_unregister(idev->nd_parms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006550}
6551
6552
6553#endif
6554
Alexey Dobriyan2c8c1e72010-01-17 03:35:32 +00006555static int __net_init addrconf_init_net(struct net *net)
Pavel Emelyanove0da5a42008-01-10 17:42:55 -08006556{
Hong Zhiguoa79ca222013-03-26 01:52:45 +08006557 int err = -ENOMEM;
Pavel Emelyanove0da5a42008-01-10 17:42:55 -08006558 struct ipv6_devconf *all, *dflt;
6559
Hong Zhiguoa79ca222013-03-26 01:52:45 +08006560 all = kmemdup(&ipv6_devconf, sizeof(ipv6_devconf), GFP_KERNEL);
Ian Morris63159f22015-03-29 14:00:04 +01006561 if (!all)
Hong Zhiguoa79ca222013-03-26 01:52:45 +08006562 goto err_alloc_all;
Pavel Emelyanove0da5a42008-01-10 17:42:55 -08006563
Hong Zhiguoa79ca222013-03-26 01:52:45 +08006564 dflt = kmemdup(&ipv6_devconf_dflt, sizeof(ipv6_devconf_dflt), GFP_KERNEL);
Ian Morris63159f22015-03-29 14:00:04 +01006565 if (!dflt)
Hong Zhiguoa79ca222013-03-26 01:52:45 +08006566 goto err_alloc_dflt;
Pavel Emelyanove0da5a42008-01-10 17:42:55 -08006567
Hong Zhiguoa79ca222013-03-26 01:52:45 +08006568 /* these will be inherited by all namespaces */
6569 dflt->autoconf = ipv6_defaults.autoconf;
6570 dflt->disable_ipv6 = ipv6_defaults.disable_ipv6;
Pavel Emelyanove0da5a42008-01-10 17:42:55 -08006571
Hannes Frederic Sowa3d1bec92015-03-23 23:36:00 +01006572 dflt->stable_secret.initialized = false;
6573 all->stable_secret.initialized = false;
6574
Pavel Emelyanove0da5a42008-01-10 17:42:55 -08006575 net->ipv6.devconf_all = all;
6576 net->ipv6.devconf_dflt = dflt;
6577
6578#ifdef CONFIG_SYSCTL
Eric W. Biedermanf8572d82009-11-05 13:32:03 -08006579 err = __addrconf_sysctl_register(net, "all", NULL, all);
Pavel Emelyanove0da5a42008-01-10 17:42:55 -08006580 if (err < 0)
6581 goto err_reg_all;
6582
Eric W. Biedermanf8572d82009-11-05 13:32:03 -08006583 err = __addrconf_sysctl_register(net, "default", NULL, dflt);
Pavel Emelyanove0da5a42008-01-10 17:42:55 -08006584 if (err < 0)
6585 goto err_reg_dflt;
6586#endif
6587 return 0;
6588
6589#ifdef CONFIG_SYSCTL
6590err_reg_dflt:
David Ahern23452172017-03-28 14:28:05 -07006591 __addrconf_sysctl_unregister(net, all, NETCONFA_IFINDEX_ALL);
Pavel Emelyanove0da5a42008-01-10 17:42:55 -08006592err_reg_all:
6593 kfree(dflt);
6594#endif
6595err_alloc_dflt:
6596 kfree(all);
6597err_alloc_all:
6598 return err;
6599}
6600
Alexey Dobriyan2c8c1e72010-01-17 03:35:32 +00006601static void __net_exit addrconf_exit_net(struct net *net)
Pavel Emelyanove0da5a42008-01-10 17:42:55 -08006602{
6603#ifdef CONFIG_SYSCTL
David Ahern23452172017-03-28 14:28:05 -07006604 __addrconf_sysctl_unregister(net, net->ipv6.devconf_dflt,
6605 NETCONFA_IFINDEX_DEFAULT);
6606 __addrconf_sysctl_unregister(net, net->ipv6.devconf_all,
6607 NETCONFA_IFINDEX_ALL);
Pavel Emelyanove0da5a42008-01-10 17:42:55 -08006608#endif
zhuyj73cf0e922014-11-26 10:25:58 +08006609 kfree(net->ipv6.devconf_dflt);
6610 kfree(net->ipv6.devconf_all);
Pavel Emelyanove0da5a42008-01-10 17:42:55 -08006611}
6612
6613static struct pernet_operations addrconf_ops = {
6614 .init = addrconf_init_net,
6615 .exit = addrconf_exit_net,
6616};
6617
Daniel Borkmann207895fd32015-01-29 12:15:03 +01006618static struct rtnl_af_ops inet6_ops __read_mostly = {
Thomas Grafb382b192010-11-16 04:33:57 +00006619 .family = AF_INET6,
6620 .fill_link_af = inet6_fill_link_af,
6621 .get_link_af_size = inet6_get_link_af_size,
Daniel Borkmann11b1f822015-02-05 14:39:11 +01006622 .validate_link_af = inet6_validate_link_af,
Daniel Borkmannf53adae2013-04-08 04:01:30 +00006623 .set_link_af = inet6_set_link_af,
Thomas Grafb382b192010-11-16 04:33:57 +00006624};
6625
Linus Torvalds1da177e2005-04-16 15:20:36 -07006626/*
6627 * Init / cleanup code
6628 */
6629
6630int __init addrconf_init(void)
6631{
WANG Conga317a2f2014-07-25 15:25:09 -07006632 struct inet6_dev *idev;
stephen hemmingerc2e21292010-03-17 20:31:10 +00006633 int i, err;
YOSHIFUJI Hideaki2a8cc6c2007-11-14 15:56:23 +09006634
Stephen Hemmingere21e8462010-03-20 16:09:01 -07006635 err = ipv6_addr_label_init();
6636 if (err < 0) {
Joe Perchesf3213832012-05-15 14:11:53 +00006637 pr_crit("%s: cannot initialize default policy table: %d\n",
6638 __func__, err);
Neil Horman2cc6d2b2010-09-24 09:55:52 +00006639 goto out;
YOSHIFUJI Hideaki2a8cc6c2007-11-14 15:56:23 +09006640 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006641
Neil Horman2cc6d2b2010-09-24 09:55:52 +00006642 err = register_pernet_subsys(&addrconf_ops);
6643 if (err < 0)
6644 goto out_addrlabel;
Pavel Emelyanove0da5a42008-01-10 17:42:55 -08006645
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01006646 addrconf_wq = create_workqueue("ipv6_addrconf");
6647 if (!addrconf_wq) {
6648 err = -ENOMEM;
6649 goto out_nowq;
6650 }
6651
Linus Torvalds1da177e2005-04-16 15:20:36 -07006652 /* The addrconf netdev notifier requires that loopback_dev
6653 * has it's ipv6 private information allocated and setup
6654 * before it can bring up and give link-local addresses
6655 * to other devices which are up.
6656 *
6657 * Unfortunately, loopback_dev is not necessarily the first
6658 * entry in the global dev_base list of net devices. In fact,
6659 * it is likely to be the very last entry on that list.
6660 * So this causes the notifier registry below to try and
6661 * give link-local addresses to all devices besides loopback_dev
6662 * first, then loopback_dev, which cases all the non-loopback_dev
6663 * devices to fail to get a link-local address.
6664 *
6665 * So, as a temporary fix, allocate the ipv6 structure for
6666 * loopback_dev first by hand.
6667 * Longer term, all of the dependencies ipv6 has upon the loopback
6668 * device and it being up should be removed.
6669 */
6670 rtnl_lock();
WANG Conga317a2f2014-07-25 15:25:09 -07006671 idev = ipv6_add_dev(init_net.loopback_dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006672 rtnl_unlock();
WANG Conga317a2f2014-07-25 15:25:09 -07006673 if (IS_ERR(idev)) {
6674 err = PTR_ERR(idev);
Pavel Emelyanove0da5a42008-01-10 17:42:55 -08006675 goto errlo;
WANG Conga317a2f2014-07-25 15:25:09 -07006676 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006677
WANG Cong2f460932017-05-03 22:07:31 -07006678 ip6_route_init_special_entries();
6679
stephen hemmingerc2e21292010-03-17 20:31:10 +00006680 for (i = 0; i < IN6_ADDR_HSIZE; i++)
6681 INIT_HLIST_HEAD(&inet6_addr_lst[i]);
6682
Linus Torvalds1da177e2005-04-16 15:20:36 -07006683 register_netdevice_notifier(&ipv6_dev_notf);
6684
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01006685 addrconf_verify();
Thomas Grafc127ea22007-03-22 11:58:32 -07006686
stephen hemminger3678a9d2013-12-30 10:41:32 -08006687 rtnl_af_register(&inet6_ops);
Thomas Grafb382b192010-11-16 04:33:57 +00006688
Florian Westphal16feebc2017-12-02 21:44:08 +01006689 err = rtnl_register_module(THIS_MODULE, PF_INET6, RTM_GETLINK,
6690 NULL, inet6_dump_ifinfo, 0);
Thomas Grafc127ea22007-03-22 11:58:32 -07006691 if (err < 0)
6692 goto errout;
6693
Florian Westphal16feebc2017-12-02 21:44:08 +01006694 err = rtnl_register_module(THIS_MODULE, PF_INET6, RTM_NEWADDR,
6695 inet6_rtm_newaddr, NULL, 0);
6696 if (err < 0)
6697 goto errout;
6698 err = rtnl_register_module(THIS_MODULE, PF_INET6, RTM_DELADDR,
6699 inet6_rtm_deladdr, NULL, 0);
6700 if (err < 0)
6701 goto errout;
6702 err = rtnl_register_module(THIS_MODULE, PF_INET6, RTM_GETADDR,
6703 inet6_rtm_getaddr, inet6_dump_ifaddr,
6704 RTNL_FLAG_DOIT_UNLOCKED);
6705 if (err < 0)
6706 goto errout;
6707 err = rtnl_register_module(THIS_MODULE, PF_INET6, RTM_GETMULTICAST,
6708 NULL, inet6_dump_ifmcaddr, 0);
6709 if (err < 0)
6710 goto errout;
6711 err = rtnl_register_module(THIS_MODULE, PF_INET6, RTM_GETANYCAST,
6712 NULL, inet6_dump_ifacaddr, 0);
6713 if (err < 0)
6714 goto errout;
6715 err = rtnl_register_module(THIS_MODULE, PF_INET6, RTM_GETNETCONF,
6716 inet6_netconf_get_devconf,
6717 inet6_netconf_dump_devconf,
6718 RTNL_FLAG_DOIT_UNLOCKED);
6719 if (err < 0)
6720 goto errout;
Florian Westphala3fde2a2017-12-04 19:19:18 +01006721 err = ipv6_addr_label_rtnl_register();
6722 if (err < 0)
6723 goto errout;
YOSHIFUJI Hideaki2a8cc6c2007-11-14 15:56:23 +09006724
Linus Torvalds1da177e2005-04-16 15:20:36 -07006725 return 0;
Thomas Grafc127ea22007-03-22 11:58:32 -07006726errout:
Florian Westphal16feebc2017-12-02 21:44:08 +01006727 rtnl_unregister_all(PF_INET6);
Thomas Grafb382b192010-11-16 04:33:57 +00006728 rtnl_af_unregister(&inet6_ops);
Thomas Grafc127ea22007-03-22 11:58:32 -07006729 unregister_netdevice_notifier(&ipv6_dev_notf);
Pavel Emelyanove0da5a42008-01-10 17:42:55 -08006730errlo:
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01006731 destroy_workqueue(addrconf_wq);
6732out_nowq:
Pavel Emelyanove0da5a42008-01-10 17:42:55 -08006733 unregister_pernet_subsys(&addrconf_ops);
Neil Horman2cc6d2b2010-09-24 09:55:52 +00006734out_addrlabel:
6735 ipv6_addr_label_cleanup();
6736out:
Thomas Grafc127ea22007-03-22 11:58:32 -07006737 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006738}
6739
Daniel Lezcano09f77092007-12-13 05:34:58 -08006740void addrconf_cleanup(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006741{
Daniel Lezcano176c39a2009-03-03 01:06:45 -08006742 struct net_device *dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006743 int i;
6744
6745 unregister_netdevice_notifier(&ipv6_dev_notf);
Pavel Emelyanove0da5a42008-01-10 17:42:55 -08006746 unregister_pernet_subsys(&addrconf_ops);
Neil Horman2cc6d2b2010-09-24 09:55:52 +00006747 ipv6_addr_label_cleanup();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006748
Florian Westphal5c451212017-10-04 15:58:49 +02006749 rtnl_af_unregister(&inet6_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006750
Florian Westphal5c451212017-10-04 15:58:49 +02006751 rtnl_lock();
Thomas Grafb382b192010-11-16 04:33:57 +00006752
Daniel Lezcano176c39a2009-03-03 01:06:45 -08006753 /* clean dev list */
6754 for_each_netdev(&init_net, dev) {
6755 if (__in6_dev_get(dev) == NULL)
6756 continue;
6757 addrconf_ifdown(dev, 1);
6758 }
6759 addrconf_ifdown(init_net.loopback_dev, 2);
6760
Linus Torvalds1da177e2005-04-16 15:20:36 -07006761 /*
Linus Torvalds1da177e2005-04-16 15:20:36 -07006762 * Check hash table.
6763 */
stephen hemminger5c578aed2010-03-17 20:31:11 +00006764 spin_lock_bh(&addrconf_hash_lock);
stephen hemmingerc2e21292010-03-17 20:31:10 +00006765 for (i = 0; i < IN6_ADDR_HSIZE; i++)
6766 WARN_ON(!hlist_empty(&inet6_addr_lst[i]));
stephen hemminger5c578aed2010-03-17 20:31:11 +00006767 spin_unlock_bh(&addrconf_hash_lock);
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01006768 cancel_delayed_work(&addr_chk_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006769 rtnl_unlock();
Hannes Frederic Sowac15b1cc2014-03-27 18:28:07 +01006770
6771 destroy_workqueue(addrconf_wq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006772}