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 : : u32 banned_flags);
85 : : int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr,
86 : : u32 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 : : bool ipv6_chk_acast_addr_src(struct net *net, struct net_device *dev,
210 : : const struct in6_addr *addr);
211 : :
212 : : /* Device notifier */
213 : : int register_inet6addr_notifier(struct notifier_block *nb);
214 : : int unregister_inet6addr_notifier(struct notifier_block *nb);
215 : : int inet6addr_notifier_call_chain(unsigned long val, void *v);
216 : :
217 : : void inet6_netconf_notify_devconf(struct net *net, int type, int ifindex,
218 : : struct ipv6_devconf *devconf);
219 : :
220 : : /**
221 : : * __in6_dev_get - get inet6_dev pointer from netdevice
222 : : * @dev: network device
223 : : *
224 : : * Caller must hold rcu_read_lock or RTNL, because this function
225 : : * does not take a reference on the inet6_dev.
226 : : */
227 : : static inline struct inet6_dev *__in6_dev_get(const struct net_device *dev)
228 : : {
229 : : return rcu_dereference_rtnl(dev->ip6_ptr);
230 : : }
231 : :
232 : : /**
233 : : * in6_dev_get - get inet6_dev pointer from netdevice
234 : : * @dev: network device
235 : : *
236 : : * This version can be used in any context, and takes a reference
237 : : * on the inet6_dev. Callers must use in6_dev_put() later to
238 : : * release this reference.
239 : : */
240 : : static inline struct inet6_dev *in6_dev_get(const struct net_device *dev)
241 : : {
242 : : struct inet6_dev *idev;
243 : :
244 : : rcu_read_lock();
245 : 0 : idev = rcu_dereference(dev->ip6_ptr);
246 [ # # # # : 0 : if (idev)
# # # # #
# # # ]
247 : 0 : atomic_inc(&idev->refcnt);
248 : : rcu_read_unlock();
249 : : return idev;
250 : : }
251 : :
252 : 0 : static inline struct neigh_parms *__in6_dev_nd_parms_get_rcu(const struct net_device *dev)
253 : : {
254 : : struct inet6_dev *idev = __in6_dev_get(dev);
255 : :
256 [ # # ]: 0 : return idev ? idev->nd_parms : NULL;
257 : : }
258 : :
259 : : void in6_dev_finish_destroy(struct inet6_dev *idev);
260 : :
261 : : static inline void in6_dev_put(struct inet6_dev *idev)
262 : : {
263 [ # # # # : 5 : if (atomic_dec_and_test(&idev->refcnt))
# # # # -
+ # # # #
# # # # #
# # # # #
# # # # ]
264 : 0 : in6_dev_finish_destroy(idev);
265 : : }
266 : :
267 : : static inline void __in6_dev_put(struct inet6_dev *idev)
268 : : {
269 : 0 : atomic_dec(&idev->refcnt);
270 : : }
271 : :
272 : : static inline void in6_dev_hold(struct inet6_dev *idev)
273 : : {
274 : 5 : atomic_inc(&idev->refcnt);
275 : : }
276 : :
277 : : void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp);
278 : :
279 : : static inline void in6_ifa_put(struct inet6_ifaddr *ifp)
280 : : {
281 [ # # # # : 0 : if (atomic_dec_and_test(&ifp->refcnt))
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
282 : 0 : inet6_ifa_finish_destroy(ifp);
283 : : }
284 : :
285 : : static inline void __in6_ifa_put(struct inet6_ifaddr *ifp)
286 : : {
287 : 0 : atomic_dec(&ifp->refcnt);
288 : : }
289 : :
290 : : static inline void in6_ifa_hold(struct inet6_ifaddr *ifp)
291 : : {
292 : 0 : atomic_inc(&ifp->refcnt);
293 : : }
294 : :
295 : :
296 : : /*
297 : : * compute link-local solicited-node multicast address
298 : : */
299 : :
300 : : static inline void addrconf_addr_solict_mult(const struct in6_addr *addr,
301 : : struct in6_addr *solicited)
302 : : {
303 : 0 : ipv6_addr_set(solicited,
304 : : htonl(0xFF020000), 0,
305 : : htonl(0x1),
306 : : htonl(0xFF000000) | addr->s6_addr32[3]);
307 : : }
308 : :
309 : : static inline bool ipv6_addr_is_multicast(const struct in6_addr *addr)
310 : : {
311 : 30 : return (addr->s6_addr32[0] & htonl(0xFF000000)) == htonl(0xFF000000);
312 : : }
313 : :
314 : : static inline bool ipv6_addr_is_ll_all_nodes(const struct in6_addr *addr)
315 : : {
316 : : #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
317 : : __u64 *p = (__u64 *)addr;
318 : : return ((p[0] ^ cpu_to_be64(0xff02000000000000UL)) | (p[1] ^ cpu_to_be64(1))) == 0UL;
319 : : #else
320 : 0 : return ((addr->s6_addr32[0] ^ htonl(0xff020000)) |
321 : 0 : addr->s6_addr32[1] | addr->s6_addr32[2] |
322 : 0 : (addr->s6_addr32[3] ^ htonl(0x00000001))) == 0;
323 : : #endif
324 : : }
325 : :
326 : : static inline bool ipv6_addr_is_ll_all_routers(const struct in6_addr *addr)
327 : : {
328 : : #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
329 : : __u64 *p = (__u64 *)addr;
330 : : return ((p[0] ^ cpu_to_be64(0xff02000000000000UL)) | (p[1] ^ cpu_to_be64(2))) == 0UL;
331 : : #else
332 : : return ((addr->s6_addr32[0] ^ htonl(0xff020000)) |
333 : : addr->s6_addr32[1] | addr->s6_addr32[2] |
334 : : (addr->s6_addr32[3] ^ htonl(0x00000002))) == 0;
335 : : #endif
336 : : }
337 : :
338 : : static inline bool ipv6_addr_is_isatap(const struct in6_addr *addr)
339 : : {
340 : 0 : return (addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE);
341 : : }
342 : :
343 : : static inline bool ipv6_addr_is_solict_mult(const struct in6_addr *addr)
344 : : {
345 : : #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
346 : : __u64 *p = (__u64 *)addr;
347 : : return ((p[0] ^ cpu_to_be64(0xff02000000000000UL)) |
348 : : ((p[1] ^ cpu_to_be64(0x00000001ff000000UL)) &
349 : : cpu_to_be64(0xffffffffff000000UL))) == 0UL;
350 : : #else
351 : 0 : return ((addr->s6_addr32[0] ^ htonl(0xff020000)) |
352 : 0 : addr->s6_addr32[1] |
353 : 0 : (addr->s6_addr32[2] ^ htonl(0x00000001)) |
354 : 0 : (addr->s6_addr[12] ^ 0xff)) == 0;
355 : : #endif
356 : : }
357 : :
358 : : #ifdef CONFIG_PROC_FS
359 : : int if6_proc_init(void);
360 : : void if6_proc_exit(void);
361 : : #endif
362 : :
363 : : #endif
|