.. | .. |
---|
28 | 28 | #include <linux/err.h> |
---|
29 | 29 | #include <linux/sysctl.h> |
---|
30 | 30 | #include <linux/workqueue.h> |
---|
| 31 | +#include <linux/android_kabi.h> |
---|
31 | 32 | #include <net/rtnetlink.h> |
---|
32 | 33 | |
---|
33 | 34 | /* |
---|
.. | .. |
---|
72 | 73 | struct net_device *dev; |
---|
73 | 74 | struct list_head list; |
---|
74 | 75 | int (*neigh_setup)(struct neighbour *); |
---|
75 | | - void (*neigh_cleanup)(struct neighbour *); |
---|
76 | 76 | struct neigh_table *tbl; |
---|
77 | 77 | |
---|
78 | 78 | void *sysctl_table; |
---|
.. | .. |
---|
84 | 84 | int reachable_time; |
---|
85 | 85 | int data[NEIGH_VAR_DATA_MAX]; |
---|
86 | 86 | DECLARE_BITMAP(data_state, NEIGH_VAR_DATA_MAX); |
---|
| 87 | + |
---|
| 88 | + ANDROID_KABI_RESERVE(1); |
---|
87 | 89 | }; |
---|
88 | 90 | |
---|
89 | 91 | static inline void neigh_var_set(struct neigh_parms *p, int index, int val) |
---|
.. | .. |
---|
140 | 142 | unsigned long updated; |
---|
141 | 143 | rwlock_t lock; |
---|
142 | 144 | refcount_t refcnt; |
---|
143 | | - struct sk_buff_head arp_queue; |
---|
144 | 145 | unsigned int arp_queue_len_bytes; |
---|
| 146 | + struct sk_buff_head arp_queue; |
---|
145 | 147 | struct timer_list timer; |
---|
146 | 148 | unsigned long used; |
---|
147 | 149 | atomic_t probes; |
---|
.. | .. |
---|
149 | 151 | __u8 nud_state; |
---|
150 | 152 | __u8 type; |
---|
151 | 153 | __u8 dead; |
---|
| 154 | + u8 protocol; |
---|
152 | 155 | seqlock_t ha_lock; |
---|
153 | | - unsigned char ha[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))]; |
---|
| 156 | + unsigned char ha[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))] __aligned(8); |
---|
154 | 157 | struct hh_cache hh; |
---|
155 | 158 | int (*output)(struct neighbour *, struct sk_buff *); |
---|
156 | 159 | const struct neigh_ops *ops; |
---|
| 160 | + struct list_head gc_list; |
---|
157 | 161 | struct rcu_head rcu; |
---|
158 | 162 | struct net_device *dev; |
---|
| 163 | + |
---|
| 164 | + ANDROID_KABI_RESERVE(1); |
---|
| 165 | + |
---|
159 | 166 | u8 primary_key[0]; |
---|
160 | 167 | } __randomize_layout; |
---|
161 | 168 | |
---|
.. | .. |
---|
172 | 179 | possible_net_t net; |
---|
173 | 180 | struct net_device *dev; |
---|
174 | 181 | u8 flags; |
---|
175 | | - u8 key[0]; |
---|
| 182 | + u8 protocol; |
---|
| 183 | + u8 key[]; |
---|
176 | 184 | }; |
---|
177 | 185 | |
---|
178 | 186 | /* |
---|
.. | .. |
---|
202 | 210 | int (*pconstructor)(struct pneigh_entry *); |
---|
203 | 211 | void (*pdestructor)(struct pneigh_entry *); |
---|
204 | 212 | void (*proxy_redo)(struct sk_buff *skb); |
---|
| 213 | + int (*is_multicast)(const void *pkey); |
---|
| 214 | + bool (*allow_add)(const struct net_device *dev, |
---|
| 215 | + struct netlink_ext_ack *extack); |
---|
205 | 216 | char *id; |
---|
206 | 217 | struct neigh_parms parms; |
---|
207 | 218 | struct list_head parms_list; |
---|
.. | .. |
---|
214 | 225 | struct timer_list proxy_timer; |
---|
215 | 226 | struct sk_buff_head proxy_queue; |
---|
216 | 227 | atomic_t entries; |
---|
| 228 | + atomic_t gc_entries; |
---|
| 229 | + struct list_head gc_list; |
---|
217 | 230 | rwlock_t lock; |
---|
218 | 231 | unsigned long last_rand; |
---|
219 | 232 | struct neigh_statistics __percpu *stats; |
---|
220 | 233 | struct neigh_hash_table __rcu *nht; |
---|
221 | 234 | struct pneigh_entry **phash_buckets; |
---|
| 235 | + |
---|
| 236 | + ANDROID_KABI_RESERVE(1); |
---|
222 | 237 | }; |
---|
223 | 238 | |
---|
224 | 239 | enum { |
---|
.. | .. |
---|
246 | 261 | #define NEIGH_UPDATE_F_OVERRIDE 0x00000001 |
---|
247 | 262 | #define NEIGH_UPDATE_F_WEAK_OVERRIDE 0x00000002 |
---|
248 | 263 | #define NEIGH_UPDATE_F_OVERRIDE_ISROUTER 0x00000004 |
---|
| 264 | +#define NEIGH_UPDATE_F_USE 0x10000000 |
---|
249 | 265 | #define NEIGH_UPDATE_F_EXT_LEARNED 0x20000000 |
---|
250 | 266 | #define NEIGH_UPDATE_F_ISROUTER 0x40000000 |
---|
251 | 267 | #define NEIGH_UPDATE_F_ADMIN 0x80000000 |
---|
252 | 268 | |
---|
| 269 | +extern const struct nla_policy nda_policy[]; |
---|
253 | 270 | |
---|
254 | 271 | static inline bool neigh_key_eq16(const struct neighbour *n, const void *pkey) |
---|
255 | 272 | { |
---|
.. | .. |
---|
323 | 340 | bool neigh_remove_one(struct neighbour *ndel, struct neigh_table *tbl); |
---|
324 | 341 | void neigh_changeaddr(struct neigh_table *tbl, struct net_device *dev); |
---|
325 | 342 | int neigh_ifdown(struct neigh_table *tbl, struct net_device *dev); |
---|
| 343 | +int neigh_carrier_down(struct neigh_table *tbl, struct net_device *dev); |
---|
326 | 344 | int neigh_resolve_output(struct neighbour *neigh, struct sk_buff *skb); |
---|
327 | 345 | int neigh_connected_output(struct neighbour *neigh, struct sk_buff *skb); |
---|
328 | 346 | int neigh_direct_output(struct neighbour *neigh, struct sk_buff *skb); |
---|
.. | .. |
---|
384 | 402 | void neigh_seq_stop(struct seq_file *, void *); |
---|
385 | 403 | |
---|
386 | 404 | int neigh_proc_dointvec(struct ctl_table *ctl, int write, |
---|
387 | | - void __user *buffer, size_t *lenp, loff_t *ppos); |
---|
| 405 | + void *buffer, size_t *lenp, loff_t *ppos); |
---|
388 | 406 | int neigh_proc_dointvec_jiffies(struct ctl_table *ctl, int write, |
---|
389 | | - void __user *buffer, |
---|
| 407 | + void *buffer, |
---|
390 | 408 | size_t *lenp, loff_t *ppos); |
---|
391 | 409 | int neigh_proc_dointvec_ms_jiffies(struct ctl_table *ctl, int write, |
---|
392 | | - void __user *buffer, |
---|
393 | | - size_t *lenp, loff_t *ppos); |
---|
| 410 | + void *buffer, size_t *lenp, loff_t *ppos); |
---|
394 | 411 | |
---|
395 | 412 | int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p, |
---|
396 | 413 | proc_handler *proc_handler); |
---|
.. | .. |
---|
491 | 508 | return dev_queue_xmit(skb); |
---|
492 | 509 | } |
---|
493 | 510 | |
---|
494 | | -static inline int neigh_output(struct neighbour *n, struct sk_buff *skb) |
---|
| 511 | +static inline int neigh_output(struct neighbour *n, struct sk_buff *skb, |
---|
| 512 | + bool skip_cache) |
---|
495 | 513 | { |
---|
496 | 514 | const struct hh_cache *hh = &n->hh; |
---|
497 | 515 | |
---|
498 | | - if ((n->nud_state & NUD_CONNECTED) && hh->hh_len) |
---|
| 516 | + /* n->nud_state and hh->hh_len could be changed under us. |
---|
| 517 | + * neigh_hh_output() is taking care of the race later. |
---|
| 518 | + */ |
---|
| 519 | + if (!skip_cache && |
---|
| 520 | + (READ_ONCE(n->nud_state) & NUD_CONNECTED) && |
---|
| 521 | + READ_ONCE(hh->hh_len)) |
---|
499 | 522 | return neigh_hh_output(hh, skb); |
---|
500 | | - else |
---|
501 | | - return n->output(n, skb); |
---|
| 523 | + |
---|
| 524 | + return n->output(n, skb); |
---|
502 | 525 | } |
---|
503 | 526 | |
---|
504 | 527 | static inline struct neighbour * |
---|
.. | .. |
---|
545 | 568 | } while (read_seqretry(&n->ha_lock, seq)); |
---|
546 | 569 | } |
---|
547 | 570 | |
---|
548 | | -static inline void neigh_update_ext_learned(struct neighbour *neigh, u32 flags, |
---|
549 | | - int *notify) |
---|
| 571 | +static inline void neigh_update_is_router(struct neighbour *neigh, u32 flags, |
---|
| 572 | + int *notify) |
---|
550 | 573 | { |
---|
551 | 574 | u8 ndm_flags = 0; |
---|
552 | 575 | |
---|
553 | | - if (!(flags & NEIGH_UPDATE_F_ADMIN)) |
---|
554 | | - return; |
---|
555 | | - |
---|
556 | | - ndm_flags |= (flags & NEIGH_UPDATE_F_EXT_LEARNED) ? NTF_EXT_LEARNED : 0; |
---|
557 | | - if ((neigh->flags ^ ndm_flags) & NTF_EXT_LEARNED) { |
---|
558 | | - if (ndm_flags & NTF_EXT_LEARNED) |
---|
559 | | - neigh->flags |= NTF_EXT_LEARNED; |
---|
| 576 | + ndm_flags |= (flags & NEIGH_UPDATE_F_ISROUTER) ? NTF_ROUTER : 0; |
---|
| 577 | + if ((neigh->flags ^ ndm_flags) & NTF_ROUTER) { |
---|
| 578 | + if (ndm_flags & NTF_ROUTER) |
---|
| 579 | + neigh->flags |= NTF_ROUTER; |
---|
560 | 580 | else |
---|
561 | | - neigh->flags &= ~NTF_EXT_LEARNED; |
---|
| 581 | + neigh->flags &= ~NTF_ROUTER; |
---|
562 | 582 | *notify = 1; |
---|
563 | 583 | } |
---|
564 | 584 | } |
---|