Branch data Line data Source code
1 : : #ifndef _ADDRCONF_H
2 : : #define _ADDRCONF_H
3 : :
4 : : #define MAX_RTR_SOLICITATIONS 3
5 : : #define RTR_SOLICITATION_INTERVAL (4*HZ)
6 : :
7 : : #define MIN_VALID_LIFETIME (2*3600) /* 2 hours */
8 : :
9 : : #define TEMP_VALID_LIFETIME (7*86400)
10 : : #define TEMP_PREFERRED_LIFETIME (86400)
11 : : #define REGEN_MAX_RETRY (3)
12 : : #define MAX_DESYNC_FACTOR (600)
13 : :
14 : : #define ADDR_CHECK_FREQUENCY (120*HZ)
15 : :
16 : : #define IPV6_MAX_ADDRESSES 16
17 : :
18 : : #define ADDRCONF_TIMER_FUZZ_MINUS (HZ > 50 ? HZ / 50 : 1)
19 : : #define ADDRCONF_TIMER_FUZZ (HZ / 4)
20 : : #define ADDRCONF_TIMER_FUZZ_MAX (HZ)
21 : :
22 : : #include <linux/in.h>
23 : : #include <linux/in6.h>
24 : :
25 : : struct prefix_info {
26 : : __u8 type;
27 : : __u8 length;
28 : : __u8 prefix_len;
29 : :
30 : : #if defined(__BIG_ENDIAN_BITFIELD)
31 : : __u8 onlink : 1,
32 : : autoconf : 1,
33 : : reserved : 6;
34 : : #elif defined(__LITTLE_ENDIAN_BITFIELD)
35 : : __u8 reserved : 6,
36 : : autoconf : 1,
37 : : onlink : 1;
38 : : #else
39 : : #error "Please fix <asm/byteorder.h>"
40 : : #endif
41 : : __be32 valid;
42 : : __be32 prefered;
43 : : __be32 reserved2;
44 : :
45 : : struct in6_addr prefix;
46 : : };
47 : :
48 : :
49 : : #include <linux/netdevice.h>
50 : : #include <net/if_inet6.h>
51 : : #include <net/ipv6.h>
52 : :
53 : : #define IN6_ADDR_HSIZE_SHIFT 4
54 : : #define IN6_ADDR_HSIZE (1 << IN6_ADDR_HSIZE_SHIFT)
55 : :
56 : : int addrconf_init(void);
57 : : void addrconf_cleanup(void);
58 : :
59 : : int addrconf_add_ifaddr(struct net *net, void __user *arg);
60 : : int addrconf_del_ifaddr(struct net *net, void __user *arg);
61 : : int addrconf_set_dstaddr(struct net *net, void __user *arg);
62 : :
63 : : int ipv6_chk_addr(struct net *net, const struct in6_addr *addr,
64 : : const struct net_device *dev, int strict);
65 : :
66 : : #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
67 : : int ipv6_chk_home_addr(struct net *net, const struct in6_addr *addr);
68 : : #endif
69 : :
70 : : bool ipv6_chk_custom_prefix(const struct in6_addr *addr,
71 : : const unsigned int prefix_len,
72 : : struct net_device *dev);
73 : :
74 : : int ipv6_chk_prefix(const struct in6_addr *addr, struct net_device *dev);
75 : :
76 : : struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net,
77 : : const struct in6_addr *addr,
78 : : struct net_device *dev, int strict);
79 : :
80 : : int ipv6_dev_get_saddr(struct net *net, const struct net_device *dev,
81 : : const struct in6_addr *daddr, unsigned int srcprefs,
82 : : struct in6_addr *saddr);
83 : : int __ipv6_get_lladdr(struct inet6_dev *idev, struct in6_addr *addr,
84 : : unsigned char banned_flags);
85 : : int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr,
86 : : unsigned char banned_flags);
87 : : int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2);
88 : : void addrconf_join_solict(struct net_device *dev, const struct in6_addr *addr);
89 : : void addrconf_leave_solict(struct inet6_dev *idev, const struct in6_addr *addr);
90 : :
91 : : static inline unsigned long addrconf_timeout_fixup(u32 timeout,
92 : : unsigned int unit)
93 : : {
94 [ # # ]: 0 : if (timeout == 0xffffffff)
[ # # # # ]
[ # # ]
[ # # # # ]
95 : : return ~0UL;
96 : :
97 : : /*
98 : : * Avoid arithmetic overflow.
99 : : * Assuming unit is constant and non-zero, this "if" statement
100 : : * will go away on 64bit archs.
101 : : */
102 [ # # ][ # # ]: 0 : if (0xfffffffe > LONG_MAX / unit && timeout > LONG_MAX / unit)
[ # # ][ # # ]
[ # # ][ # # ]
103 : : return LONG_MAX / unit;
104 : :
105 : : return timeout;
106 : : }
107 : :
108 : : static inline int addrconf_finite_timeout(unsigned long timeout)
109 : : {
110 : : return ~timeout;
111 : : }
112 : :
113 : : /*
114 : : * IPv6 Address Label subsystem (addrlabel.c)
115 : : */
116 : : int ipv6_addr_label_init(void);
117 : : void ipv6_addr_label_cleanup(void);
118 : : void ipv6_addr_label_rtnl_register(void);
119 : : u32 ipv6_addr_label(struct net *net, const struct in6_addr *addr,
120 : : int type, int ifindex);
121 : :
122 : : /*
123 : : * multicast prototypes (mcast.c)
124 : : */
125 : : int ipv6_sock_mc_join(struct sock *sk, int ifindex,
126 : : const struct in6_addr *addr);
127 : : int ipv6_sock_mc_drop(struct sock *sk, int ifindex,
128 : : const struct in6_addr *addr);
129 : : void ipv6_sock_mc_close(struct sock *sk);
130 : : bool inet6_mc_check(struct sock *sk, const struct in6_addr *mc_addr,
131 : : const struct in6_addr *src_addr);
132 : :
133 : : int ipv6_dev_mc_inc(struct net_device *dev, const struct in6_addr *addr);
134 : : int __ipv6_dev_mc_dec(struct inet6_dev *idev, const struct in6_addr *addr);
135 : : int ipv6_dev_mc_dec(struct net_device *dev, const struct in6_addr *addr);
136 : : void ipv6_mc_up(struct inet6_dev *idev);
137 : : void ipv6_mc_down(struct inet6_dev *idev);
138 : : void ipv6_mc_unmap(struct inet6_dev *idev);
139 : : void ipv6_mc_remap(struct inet6_dev *idev);
140 : : void ipv6_mc_init_dev(struct inet6_dev *idev);
141 : : void ipv6_mc_destroy_dev(struct inet6_dev *idev);
142 : : void addrconf_dad_failure(struct inet6_ifaddr *ifp);
143 : :
144 : : bool ipv6_chk_mcast_addr(struct net_device *dev, const struct in6_addr *group,
145 : : const struct in6_addr *src_addr);
146 : :
147 : : void ipv6_mc_dad_complete(struct inet6_dev *idev);
148 : :
149 : : /* A stub used by vxlan module. This is ugly, ideally these
150 : : * symbols should be built into the core kernel.
151 : : */
152 : : struct ipv6_stub {
153 : : int (*ipv6_sock_mc_join)(struct sock *sk, int ifindex,
154 : : const struct in6_addr *addr);
155 : : int (*ipv6_sock_mc_drop)(struct sock *sk, int ifindex,
156 : : const struct in6_addr *addr);
157 : : int (*ipv6_dst_lookup)(struct sock *sk, struct dst_entry **dst,
158 : : struct flowi6 *fl6);
159 : : void (*udpv6_encap_enable)(void);
160 : : void (*ndisc_send_na)(struct net_device *dev, struct neighbour *neigh,
161 : : const struct in6_addr *daddr,
162 : : const struct in6_addr *solicited_addr,
163 : : bool router, bool solicited, bool override, bool inc_opt);
164 : : struct neigh_table *nd_tbl;
165 : : };
166 : : extern const struct ipv6_stub *ipv6_stub __read_mostly;
167 : :
168 : : /*
169 : : * identify MLD packets for MLD filter exceptions
170 : : */
171 : 0 : static inline bool ipv6_is_mld(struct sk_buff *skb, int nexthdr, int offset)
172 : : {
173 : : struct icmp6hdr *hdr;
174 : :
175 [ # # ][ # # ]: 0 : if (nexthdr != IPPROTO_ICMPV6 ||
176 : 0 : !pskb_network_may_pull(skb, offset + sizeof(struct icmp6hdr)))
177 : : return false;
178 : :
179 : 0 : hdr = (struct icmp6hdr *)(skb_network_header(skb) + offset);
180 : :
181 [ # # ][ # # ]: 0 : switch (hdr->icmp6_type) {
182 : : case ICMPV6_MGM_QUERY:
183 : : case ICMPV6_MGM_REPORT:
184 : : case ICMPV6_MGM_REDUCTION:
185 : : case ICMPV6_MLD2_REPORT:
186 : : return true;
187 : : default:
188 : : break;
189 : : }
190 : : return false;
191 : : }
192 : :
193 : : void addrconf_prefix_rcv(struct net_device *dev,
194 : : u8 *opt, int len, bool sllao);
195 : :
196 : : /*
197 : : * anycast prototypes (anycast.c)
198 : : */
199 : : int ipv6_sock_ac_join(struct sock *sk, int ifindex,
200 : : const struct in6_addr *addr);
201 : : int ipv6_sock_ac_drop(struct sock *sk, int ifindex,
202 : : const struct in6_addr *addr);
203 : : void ipv6_sock_ac_close(struct sock *sk);
204 : :
205 : : int ipv6_dev_ac_inc(struct net_device *dev, const struct in6_addr *addr);
206 : : int __ipv6_dev_ac_dec(struct inet6_dev *idev, const struct in6_addr *addr);
207 : : bool ipv6_chk_acast_addr(struct net *net, struct net_device *dev,
208 : : const struct in6_addr *addr);
209 : :
210 : :
211 : : /* Device notifier */
212 : : int register_inet6addr_notifier(struct notifier_block *nb);
213 : : int unregister_inet6addr_notifier(struct notifier_block *nb);
214 : : int inet6addr_notifier_call_chain(unsigned long val, void *v);
215 : :
216 : : void inet6_netconf_notify_devconf(struct net *net, int type, int ifindex,
217 : : struct ipv6_devconf *devconf);
218 : :
219 : : /**
220 : : * __in6_dev_get - get inet6_dev pointer from netdevice
221 : : * @dev: network device
222 : : *
223 : : * Caller must hold rcu_read_lock or RTNL, because this function
224 : : * does not take a reference on the inet6_dev.
225 : : */
226 : : static inline struct inet6_dev *__in6_dev_get(const struct net_device *dev)
227 : : {
228 : : return rcu_dereference_rtnl(dev->ip6_ptr);
229 : : }
230 : :
231 : : /**
232 : : * in6_dev_get - get inet6_dev pointer from netdevice
233 : : * @dev: network device
234 : : *
235 : : * This version can be used in any context, and takes a reference
236 : : * on the inet6_dev. Callers must use in6_dev_put() later to
237 : : * release this reference.
238 : : */
239 : : static inline struct inet6_dev *in6_dev_get(const struct net_device *dev)
240 : : {
241 : : struct inet6_dev *idev;
242 : :
243 : : rcu_read_lock();
244 : 0 : idev = rcu_dereference(dev->ip6_ptr);
245 [ # # # # : 0 : if (idev)
# # # # #
# # # ]
246 : 0 : atomic_inc(&idev->refcnt);
247 : : rcu_read_unlock();
248 : : return idev;
249 : : }
250 : :
251 : : void in6_dev_finish_destroy(struct inet6_dev *idev);
252 : :
253 : : static inline void in6_dev_put(struct inet6_dev *idev)
254 : : {
255 [ # # # # : 106 : if (atomic_dec_and_test(&idev->refcnt))
# # # # -
+ # # # #
- + # # #
# # # # #
# # # # ]
256 : 0 : in6_dev_finish_destroy(idev);
257 : : }
258 : :
259 : : static inline void __in6_dev_put(struct inet6_dev *idev)
260 : : {
261 : 0 : atomic_dec(&idev->refcnt);
262 : : }
263 : :
264 : : static inline void in6_dev_hold(struct inet6_dev *idev)
265 : : {
266 : 106 : atomic_inc(&idev->refcnt);
267 : : }
268 : :
269 : : void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp);
270 : :
271 : : static inline void in6_ifa_put(struct inet6_ifaddr *ifp)
272 : : {
273 [ # # # # : 3 : if (atomic_dec_and_test(&ifp->refcnt))
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
- + # # #
# # # # #
# # ]
274 : 0 : inet6_ifa_finish_destroy(ifp);
275 : : }
276 : :
277 : : static inline void __in6_ifa_put(struct inet6_ifaddr *ifp)
278 : : {
279 : 0 : atomic_dec(&ifp->refcnt);
280 : : }
281 : :
282 : : static inline void in6_ifa_hold(struct inet6_ifaddr *ifp)
283 : : {
284 : 0 : atomic_inc(&ifp->refcnt);
285 : : }
286 : :
287 : :
288 : : /*
289 : : * compute link-local solicited-node multicast address
290 : : */
291 : :
292 : : static inline void addrconf_addr_solict_mult(const struct in6_addr *addr,
293 : : struct in6_addr *solicited)
294 : : {
295 : 0 : ipv6_addr_set(solicited,
296 : : htonl(0xFF020000), 0,
297 : : htonl(0x1),
298 : : htonl(0xFF000000) | addr->s6_addr32[3]);
299 : : }
300 : :
301 : : static inline bool ipv6_addr_is_multicast(const struct in6_addr *addr)
302 : : {
303 : 612 : return (addr->s6_addr32[0] & htonl(0xFF000000)) == htonl(0xFF000000);
304 : : }
305 : :
306 : : static inline bool ipv6_addr_is_ll_all_nodes(const struct in6_addr *addr)
307 : : {
308 : : #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
309 : : __u64 *p = (__u64 *)addr;
310 : : return ((p[0] ^ cpu_to_be64(0xff02000000000000UL)) | (p[1] ^ cpu_to_be64(1))) == 0UL;
311 : : #else
312 : 0 : return ((addr->s6_addr32[0] ^ htonl(0xff020000)) |
313 : 0 : addr->s6_addr32[1] | addr->s6_addr32[2] |
314 : 0 : (addr->s6_addr32[3] ^ htonl(0x00000001))) == 0;
315 : : #endif
316 : : }
317 : :
318 : : static inline bool ipv6_addr_is_ll_all_routers(const struct in6_addr *addr)
319 : : {
320 : : #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
321 : : __u64 *p = (__u64 *)addr;
322 : : return ((p[0] ^ cpu_to_be64(0xff02000000000000UL)) | (p[1] ^ cpu_to_be64(2))) == 0UL;
323 : : #else
324 : : return ((addr->s6_addr32[0] ^ htonl(0xff020000)) |
325 : : addr->s6_addr32[1] | addr->s6_addr32[2] |
326 : : (addr->s6_addr32[3] ^ htonl(0x00000002))) == 0;
327 : : #endif
328 : : }
329 : :
330 : : static inline bool ipv6_addr_is_isatap(const struct in6_addr *addr)
331 : : {
332 : 0 : return (addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE);
333 : : }
334 : :
335 : : static inline bool ipv6_addr_is_solict_mult(const struct in6_addr *addr)
336 : : {
337 : : #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
338 : : __u64 *p = (__u64 *)addr;
339 : : return ((p[0] ^ cpu_to_be64(0xff02000000000000UL)) |
340 : : ((p[1] ^ cpu_to_be64(0x00000001ff000000UL)) &
341 : : cpu_to_be64(0xffffffffff000000UL))) == 0UL;
342 : : #else
343 : 0 : return ((addr->s6_addr32[0] ^ htonl(0xff020000)) |
344 : 0 : addr->s6_addr32[1] |
345 : 0 : (addr->s6_addr32[2] ^ htonl(0x00000001)) |
346 : 0 : (addr->s6_addr[12] ^ 0xff)) == 0;
347 : : #endif
348 : : }
349 : :
350 : : #ifdef CONFIG_PROC_FS
351 : : int if6_proc_init(void);
352 : : void if6_proc_exit(void);
353 : : #endif
354 : :
355 : : #endif
|