.. | .. |
---|
2 | 2 | #ifndef _NDISC_H |
---|
3 | 3 | #define _NDISC_H |
---|
4 | 4 | |
---|
| 5 | +#include <net/ipv6_stubs.h> |
---|
| 6 | + |
---|
5 | 7 | /* |
---|
6 | 8 | * ICMP codes for neighbour discovery messages |
---|
7 | 9 | */ |
---|
.. | .. |
---|
79 | 81 | struct nd_msg { |
---|
80 | 82 | struct icmp6hdr icmph; |
---|
81 | 83 | struct in6_addr target; |
---|
82 | | - __u8 opt[0]; |
---|
| 84 | + __u8 opt[]; |
---|
83 | 85 | }; |
---|
84 | 86 | |
---|
85 | 87 | struct rs_msg { |
---|
86 | 88 | struct icmp6hdr icmph; |
---|
87 | | - __u8 opt[0]; |
---|
| 89 | + __u8 opt[]; |
---|
88 | 90 | }; |
---|
89 | 91 | |
---|
90 | 92 | struct ra_msg { |
---|
.. | .. |
---|
97 | 99 | struct icmp6hdr icmph; |
---|
98 | 100 | struct in6_addr target; |
---|
99 | 101 | struct in6_addr dest; |
---|
100 | | - __u8 opt[0]; |
---|
| 102 | + __u8 opt[]; |
---|
101 | 103 | }; |
---|
102 | 104 | |
---|
103 | 105 | struct nd_opt_hdr { |
---|
.. | .. |
---|
381 | 383 | return ___neigh_lookup_noref(&nd_tbl, neigh_key_eq128, ndisc_hashfn, pkey, dev); |
---|
382 | 384 | } |
---|
383 | 385 | |
---|
| 386 | +static inline |
---|
| 387 | +struct neighbour *__ipv6_neigh_lookup_noref_stub(struct net_device *dev, |
---|
| 388 | + const void *pkey) |
---|
| 389 | +{ |
---|
| 390 | + return ___neigh_lookup_noref(ipv6_stub->nd_tbl, neigh_key_eq128, |
---|
| 391 | + ndisc_hashfn, pkey, dev); |
---|
| 392 | +} |
---|
| 393 | + |
---|
384 | 394 | static inline struct neighbour *__ipv6_neigh_lookup(struct net_device *dev, const void *pkey) |
---|
385 | 395 | { |
---|
386 | 396 | struct neighbour *n; |
---|
.. | .. |
---|
405 | 415 | unsigned long now = jiffies; |
---|
406 | 416 | |
---|
407 | 417 | /* avoid dirtying neighbour */ |
---|
408 | | - if (n->confirmed != now) |
---|
409 | | - n->confirmed = now; |
---|
| 418 | + if (READ_ONCE(n->confirmed) != now) |
---|
| 419 | + WRITE_ONCE(n->confirmed, now); |
---|
410 | 420 | } |
---|
411 | 421 | rcu_read_unlock_bh(); |
---|
| 422 | +} |
---|
| 423 | + |
---|
| 424 | +static inline void __ipv6_confirm_neigh_stub(struct net_device *dev, |
---|
| 425 | + const void *pkey) |
---|
| 426 | +{ |
---|
| 427 | + struct neighbour *n; |
---|
| 428 | + |
---|
| 429 | + rcu_read_lock_bh(); |
---|
| 430 | + n = __ipv6_neigh_lookup_noref_stub(dev, pkey); |
---|
| 431 | + if (n) { |
---|
| 432 | + unsigned long now = jiffies; |
---|
| 433 | + |
---|
| 434 | + /* avoid dirtying neighbour */ |
---|
| 435 | + if (READ_ONCE(n->confirmed) != now) |
---|
| 436 | + WRITE_ONCE(n->confirmed, now); |
---|
| 437 | + } |
---|
| 438 | + rcu_read_unlock_bh(); |
---|
| 439 | +} |
---|
| 440 | + |
---|
| 441 | +/* uses ipv6_stub and is meant for use outside of IPv6 core */ |
---|
| 442 | +static inline struct neighbour *ip_neigh_gw6(struct net_device *dev, |
---|
| 443 | + const void *addr) |
---|
| 444 | +{ |
---|
| 445 | + struct neighbour *neigh; |
---|
| 446 | + |
---|
| 447 | + neigh = __ipv6_neigh_lookup_noref_stub(dev, addr); |
---|
| 448 | + if (unlikely(!neigh)) |
---|
| 449 | + neigh = __neigh_create(ipv6_stub->nd_tbl, addr, dev, false); |
---|
| 450 | + |
---|
| 451 | + return neigh; |
---|
412 | 452 | } |
---|
413 | 453 | |
---|
414 | 454 | int ndisc_init(void); |
---|
.. | .. |
---|
454 | 494 | |
---|
455 | 495 | #ifdef CONFIG_SYSCTL |
---|
456 | 496 | int ndisc_ifinfo_sysctl_change(struct ctl_table *ctl, int write, |
---|
457 | | - void __user *buffer, size_t *lenp, loff_t *ppos); |
---|
| 497 | + void *buffer, size_t *lenp, loff_t *ppos); |
---|
458 | 498 | int ndisc_ifinfo_sysctl_strategy(struct ctl_table *ctl, |
---|
459 | 499 | void __user *oldval, size_t __user *oldlenp, |
---|
460 | 500 | void __user *newval, size_t newlen); |
---|