| 1 |
|
| 2 | #ifndef _NET_NEIGHBOUR_H
|
| 3 | #define _NET_NEIGHBOUR_H
|
| 4 |
|
| 5 | #include <linux/neighbour.h>
|
| 6 |
|
| 7 | |
| 8 | * Generic neighbour manipulation
|
| 9 | *
|
| 10 | * Authors:
|
| 11 | * Pedro Roque <[email protected]>
|
| 12 | * Alexey Kuznetsov <[email protected]>
|
| 13 | *
|
| 14 | * Changes:
|
| 15 | *
|
| 16 | * Harald Welte: <[email protected]>
|
| 17 | * - Add neighbour cache statistics like rtstat
|
| 18 |
|
| 19 |
|
| 20 | #include <linux/atomic.h>
|
| 21 | #include <linux/refcount.h>
|
| 22 | #include <linux/netdevice.h>
|
| 23 | #include <linux/skbuff.h>
|
| 24 | #include <linux/rcupdate.h>
|
| 25 | #include <linux/seq_file.h>
|
| 26 | #include <linux/bitmap.h>
|
| 27 |
|
| 28 | #include <linux/err.h>
|
| 29 | #include <linux/sysctl.h>
|
| 30 | #include <linux/workqueue.h>
|
| 31 | #include <net/rtnetlink.h>
|
| 32 | #include <net/neighbour_tables.h>
|
| 33 |
|
| 34 | |
| 35 | * NUD stands for "neighbor unreachability detection"
|
| 36 |
|
| 37 |
|
| 38 | #define NUD_IN_TIMER (NUD_INCOMPLETE|NUD_REACHABLE|NUD_DELAY|NUD_PROBE)
|
| 39 | #define NUD_VALID (NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE|NUD_PROBE|NUD_STALE|NUD_DELAY)
|
| 40 | #define NUD_CONNECTED (NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE)
|
| 41 |
|
| 42 | struct neighbour;
|
| 43 |
|
| 44 | enum {
|
| 45 | NEIGH_VAR_MCAST_PROBES,
|
| 46 | NEIGH_VAR_UCAST_PROBES,
|
| 47 | NEIGH_VAR_APP_PROBES,
|
| 48 | NEIGH_VAR_MCAST_REPROBES,
|
| 49 | NEIGH_VAR_RETRANS_TIME,
|
| 50 | NEIGH_VAR_BASE_REACHABLE_TIME,
|
| 51 | NEIGH_VAR_DELAY_PROBE_TIME,
|
| 52 | NEIGH_VAR_INTERVAL_PROBE_TIME_MS,
|
| 53 | NEIGH_VAR_GC_STALETIME,
|
| 54 | NEIGH_VAR_QUEUE_LEN_BYTES,
|
| 55 | NEIGH_VAR_PROXY_QLEN,
|
| 56 | NEIGH_VAR_ANYCAST_DELAY,
|
| 57 | NEIGH_VAR_PROXY_DELAY,
|
| 58 | NEIGH_VAR_LOCKTIME,
|
| 59 | #define NEIGH_VAR_DATA_MAX (NEIGH_VAR_LOCKTIME + 1)
|
| 60 |
|
| 61 | NEIGH_VAR_QUEUE_LEN,
|
| 62 | NEIGH_VAR_RETRANS_TIME_MS,
|
| 63 | NEIGH_VAR_BASE_REACHABLE_TIME_MS,
|
| 64 |
|
| 65 | NEIGH_VAR_GC_INTERVAL,
|
| 66 | NEIGH_VAR_GC_THRESH1,
|
| 67 | NEIGH_VAR_GC_THRESH2,
|
| 68 | NEIGH_VAR_GC_THRESH3,
|
| 69 | NEIGH_VAR_MAX
|
| 70 | };
|
| 71 |
|
| 72 | struct neigh_parms {
|
| 73 | possible_net_t net;
|
| 74 | struct net_device *dev;
|
| 75 | netdevice_tracker dev_tracker;
|
| 76 | struct list_head list;
|
| 77 | int (*neigh_setup)(struct neighbour *);
|
| 78 | struct neigh_table *tbl;
|
| 79 |
|
| 80 | void *sysctl_table;
|
| 81 |
|
| 82 | int dead;
|
| 83 | refcount_t refcnt;
|
| 84 | struct rcu_head rcu_head;
|
| 85 |
|
| 86 | int reachable_time;
|
| 87 | u32 qlen;
|
| 88 | int data[NEIGH_VAR_DATA_MAX];
|
| 89 | DECLARE_BITMAP(data_state, NEIGH_VAR_DATA_MAX);
|
| 90 | };
|
| 91 |
|
| 92 | static inline void neigh_var_set(struct neigh_parms *p, int index, int val)
|
| 93 | {
|
| 94 | set_bit(index, p->data_state);
|
| 95 | WRITE_ONCE(p->data[index], val);
|
| 96 | }
|
| 97 |
|
| 98 | #define __NEIGH_VAR(p, attr) ((p)->data[NEIGH_VAR_ ## attr])
|
| 99 | #define NEIGH_VAR(p, attr) READ_ONCE(__NEIGH_VAR(p, attr))
|
| 100 | #define NEIGH_VAR_PTR(p, attr) (&(__NEIGH_VAR(p, attr)))
|
| 101 |
|
| 102 | |
| 103 | * In other cases, NEIGH_VAR_SET should be used.
|
| 104 |
|
| 105 | #define NEIGH_VAR_INIT(p, attr, val) (__NEIGH_VAR(p, attr) = val)
|
| 106 | #define NEIGH_VAR_SET(p, attr, val) neigh_var_set(p, NEIGH_VAR_ ## attr, val)
|
| 107 |
|
| 108 | static inline void neigh_parms_data_state_setall(struct neigh_parms *p)
|
| 109 | {
|
| 110 | bitmap_fill(p->data_state, NEIGH_VAR_DATA_MAX);
|
| 111 | }
|
| 112 |
|
| 113 | static inline void neigh_parms_data_state_cleanall(struct neigh_parms *p)
|
| 114 | {
|
| 115 | bitmap_zero(p->data_state, NEIGH_VAR_DATA_MAX);
|
| 116 | }
|
| 117 |
|
| 118 | struct neigh_statistics {
|
| 119 | unsigned long allocs;
|
| 120 | unsigned long destroys;
|
| 121 | unsigned long hash_grows;
|
| 122 |
|
| 123 | unsigned long res_failed;
|
| 124 |
|
| 125 | unsigned long lookups;
|
| 126 | unsigned long hits;
|
| 127 |
|
| 128 | unsigned long rcv_probes_mcast;
|
| 129 | unsigned long rcv_probes_ucast;
|
| 130 |
|
| 131 | unsigned long periodic_gc_runs;
|
| 132 | unsigned long forced_gc_runs;
|
| 133 |
|
| 134 | unsigned long unres_discards;
|
| 135 | unsigned long table_fulls;
|
| 136 | };
|
| 137 |
|
| 138 | #define NEIGH_CACHE_STAT_INC(tbl, field) this_cpu_inc((tbl)->stats->field)
|
| 139 |
|
| 140 | struct neighbour {
|
| 141 | struct hlist_node hash;
|
| 142 | struct hlist_node dev_list;
|
| 143 | struct neigh_table *tbl;
|
| 144 | struct neigh_parms *parms;
|
| 145 | unsigned long confirmed;
|
| 146 | unsigned long updated;
|
| 147 | rwlock_t lock;
|
| 148 | refcount_t refcnt;
|
| 149 | unsigned int arp_queue_len_bytes;
|
| 150 | struct sk_buff_head arp_queue;
|
| 151 | struct timer_list timer;
|
| 152 | unsigned long used;
|
| 153 | atomic_t probes;
|
| 154 | u8 nud_state;
|
| 155 | u8 type;
|
| 156 | u8 dead;
|
| 157 | u8 protocol;
|
| 158 | u32 flags;
|
| 159 | seqlock_t ha_lock;
|
| 160 | unsigned char ha[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))] __aligned(8);
|
| 161 | struct hh_cache hh;
|
| 162 | int (*output)(struct neighbour *, struct sk_buff *);
|
| 163 | const struct neigh_ops *ops;
|
| 164 | struct list_head gc_list;
|
| 165 | struct list_head managed_list;
|
| 166 | struct rcu_head rcu;
|
| 167 | struct net_device *dev;
|
| 168 | netdevice_tracker dev_tracker;
|
| 169 | u8 primary_key[];
|
| 170 | } __randomize_layout;
|
| 171 |
|
| 172 | struct neigh_ops {
|
| 173 | int family;
|
| 174 | void (*solicit)(struct neighbour *, struct sk_buff *);
|
| 175 | void (*error_report)(struct neighbour *, struct sk_buff *);
|
| 176 | int (*output)(struct neighbour *, struct sk_buff *);
|
| 177 | int (*connected_output)(struct neighbour *, struct sk_buff *);
|
| 178 | };
|
| 179 |
|
| 180 | struct pneigh_entry {
|
| 181 | struct pneigh_entry __rcu *next;
|
| 182 | possible_net_t net;
|
| 183 | struct net_device *dev;
|
| 184 | netdevice_tracker dev_tracker;
|
| 185 | union {
|
| 186 | struct list_head free_node;
|
| 187 | struct rcu_head rcu;
|
| 188 | };
|
| 189 | u32 flags;
|
| 190 | u8 protocol;
|
| 191 | bool permanent;
|
| 192 | u32 key[];
|
| 193 | };
|
| 194 |
|
| 195 | |
| 196 | * neighbour table manipulation
|
| 197 |
|
| 198 |
|
| 199 | #define NEIGH_NUM_HASH_RND 4
|
| 200 |
|
| 201 | struct neigh_hash_table {
|
| 202 | struct hlist_head *hash_heads;
|
| 203 | unsigned int hash_shift;
|
| 204 | __u32 hash_rnd[NEIGH_NUM_HASH_RND];
|
| 205 | struct rcu_head rcu;
|
| 206 | };
|
| 207 |
|
| 208 |
|
| 209 | struct neigh_table {
|
| 210 | int family;
|
| 211 | unsigned int entry_size;
|
| 212 | unsigned int key_len;
|
| 213 | __be16 protocol;
|
| 214 | __u32 (*hash)(const void *pkey,
|
| 215 | const struct net_device *dev,
|
| 216 | __u32 *hash_rnd);
|
| 217 | bool (*key_eq)(const struct neighbour *, const void *pkey);
|
| 218 | int (*constructor)(struct neighbour *);
|
| 219 | int (*pconstructor)(struct pneigh_entry *);
|
| 220 | void (*pdestructor)(struct pneigh_entry *);
|
| 221 | void (*proxy_redo)(struct sk_buff *skb);
|
| 222 | int (*is_multicast)(const void *pkey);
|
| 223 | bool (*allow_add)(const struct net_device *dev,
|
| 224 | struct netlink_ext_ack *extack);
|
| 225 | char *id;
|
| 226 | struct neigh_parms parms;
|
| 227 | struct list_head parms_list;
|
| 228 | int gc_interval;
|
| 229 | int gc_thresh1;
|
| 230 | int gc_thresh2;
|
| 231 | int gc_thresh3;
|
| 232 | unsigned long last_flush;
|
| 233 | struct delayed_work gc_work;
|
| 234 | struct delayed_work managed_work;
|
| 235 | struct timer_list proxy_timer;
|
| 236 | struct sk_buff_head proxy_queue;
|
| 237 | atomic_t entries;
|
| 238 | atomic_t gc_entries;
|
| 239 | struct list_head gc_list;
|
| 240 | struct list_head managed_list;
|
| 241 | spinlock_t lock;
|
| 242 | unsigned long last_rand;
|
| 243 | struct neigh_statistics __percpu *stats;
|
| 244 | struct neigh_hash_table __rcu *nht;
|
| 245 | struct mutex phash_lock;
|
| 246 | struct pneigh_entry __rcu **phash_buckets;
|
| 247 | };
|
| 248 |
|
| 249 | static inline int neigh_parms_family(struct neigh_parms *p)
|
| 250 | {
|
| 251 | return p->tbl->family;
|
| 252 | }
|
| 253 |
|
| 254 | #define NEIGH_PRIV_ALIGN sizeof(long long)
|
| 255 | #define NEIGH_ENTRY_SIZE(size) ALIGN((size), NEIGH_PRIV_ALIGN)
|
| 256 |
|
| 257 | static inline void *neighbour_priv(const struct neighbour *n)
|
| 258 | {
|
| 259 | return (char *)n + n->tbl->entry_size;
|
| 260 | }
|
| 261 |
|
| 262 |
|
| 263 | #define NEIGH_UPDATE_F_OVERRIDE BIT(0)
|
| 264 | #define NEIGH_UPDATE_F_WEAK_OVERRIDE BIT(1)
|
| 265 | #define NEIGH_UPDATE_F_OVERRIDE_ISROUTER BIT(2)
|
| 266 | #define NEIGH_UPDATE_F_USE BIT(3)
|
| 267 | #define NEIGH_UPDATE_F_MANAGED BIT(4)
|
| 268 | #define NEIGH_UPDATE_F_EXT_LEARNED BIT(5)
|
| 269 | #define NEIGH_UPDATE_F_ISROUTER BIT(6)
|
| 270 | #define NEIGH_UPDATE_F_ADMIN BIT(7)
|
| 271 | #define NEIGH_UPDATE_F_EXT_VALIDATED BIT(8)
|
| 272 |
|
| 273 |
|
| 274 | #define NTF_OLD_MASK 0xff
|
| 275 | #define NTF_EXT_SHIFT 8
|
| 276 | #define NTF_EXT_MASK (NTF_EXT_MANAGED | NTF_EXT_EXT_VALIDATED)
|
| 277 |
|
| 278 | #define NTF_MANAGED (NTF_EXT_MANAGED << NTF_EXT_SHIFT)
|
| 279 | #define NTF_EXT_VALIDATED (NTF_EXT_EXT_VALIDATED << NTF_EXT_SHIFT)
|
| 280 |
|
| 281 | extern const struct nla_policy nda_policy[];
|
| 282 |
|
| 283 | #define neigh_for_each_in_bucket(pos, head) hlist_for_each_entry(pos, head, hash)
|
| 284 | #define neigh_for_each_in_bucket_rcu(pos, head) \
|
| 285 | hlist_for_each_entry_rcu(pos, head, hash)
|
| 286 | #define neigh_for_each_in_bucket_safe(pos, tmp, head) \
|
| 287 | hlist_for_each_entry_safe(pos, tmp, head, hash)
|
| 288 |
|
| 289 | static inline bool neigh_key_eq32(const struct neighbour *n, const void *pkey)
|
| 290 | {
|
| 291 | return *(const u32 *)n->primary_key == *(const u32 *)pkey;
|
| 292 | }
|
| 293 |
|
| 294 | static inline bool neigh_key_eq128(const struct neighbour *n, const void *pkey)
|
| 295 | {
|
| 296 | const u32 *n32 = (const u32 *)n->primary_key;
|
| 297 | const u32 *p32 = pkey;
|
| 298 |
|
| 299 | return ((n32[0] ^ p32[0]) | (n32[1] ^ p32[1]) |
|
| 300 | (n32[2] ^ p32[2]) | (n32[3] ^ p32[3])) == 0;
|
| 301 | }
|
| 302 |
|
| 303 | static inline struct neighbour *___neigh_lookup_noref(
|
| 304 | struct neigh_table *tbl,
|
| 305 | bool (*key_eq)(const struct neighbour *n, const void *pkey),
|
| 306 | __u32 (*hash)(const void *pkey,
|
| 307 | const struct net_device *dev,
|
| 308 | __u32 *hash_rnd),
|
| 309 | const void *pkey,
|
| 310 | struct net_device *dev)
|
| 311 | {
|
| 312 | struct neigh_hash_table *nht = rcu_dereference(tbl->nht);
|
| 313 | struct neighbour *n;
|
| 314 | u32 hash_val;
|
| 315 |
|
| 316 | hash_val = hash(pkey, dev, nht->hash_rnd) >> (32 - nht->hash_shift);
|
| 317 | neigh_for_each_in_bucket_rcu(n, &nht->hash_heads[hash_val])
|
| 318 | if (n->dev == dev && key_eq(n, pkey))
|
| 319 | return n;
|
| 320 |
|
| 321 | return NULL;
|
| 322 | }
|
| 323 |
|
| 324 | static inline struct neighbour *__neigh_lookup_noref(struct neigh_table *tbl,
|
| 325 | const void *pkey,
|
| 326 | struct net_device *dev)
|
| 327 | {
|
| 328 | return ___neigh_lookup_noref(tbl, tbl->key_eq, tbl->hash, pkey, dev);
|
| 329 | }
|
| 330 |
|
| 331 | static inline void neigh_confirm(struct neighbour *n)
|
| 332 | {
|
| 333 | if (n) {
|
| 334 | unsigned long now = jiffies;
|
| 335 |
|
| 336 |
|
| 337 | if (READ_ONCE(n->confirmed) != now)
|
| 338 | WRITE_ONCE(n->confirmed, now);
|
| 339 | }
|
| 340 | }
|
| 341 |
|
| 342 | void neigh_table_init(int index, struct neigh_table *tbl);
|
| 343 | int neigh_table_clear(int index, struct neigh_table *tbl);
|
| 344 | struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey,
|
| 345 | struct net_device *dev);
|
| 346 | struct neighbour *__neigh_create(struct neigh_table *tbl, const void *pkey,
|
| 347 | struct net_device *dev, bool want_ref);
|
| 348 | static inline struct neighbour *neigh_create(struct neigh_table *tbl,
|
| 349 | const void *pkey,
|
| 350 | struct net_device *dev)
|
| 351 | {
|
| 352 | return __neigh_create(tbl, pkey, dev, true);
|
| 353 | }
|
| 354 | void neigh_destroy(struct neighbour *neigh);
|
| 355 | int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb,
|
| 356 | const bool immediate_ok);
|
| 357 | int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, u32 flags,
|
| 358 | u32 nlmsg_pid);
|
| 359 | void __neigh_set_probe_once(struct neighbour *neigh);
|
| 360 | bool neigh_remove_one(struct neighbour *ndel);
|
| 361 | void neigh_changeaddr(struct neigh_table *tbl, struct net_device *dev);
|
| 362 | int neigh_ifdown(struct neigh_table *tbl, struct net_device *dev);
|
| 363 | int neigh_carrier_down(struct neigh_table *tbl, struct net_device *dev);
|
| 364 | int neigh_resolve_output(struct neighbour *neigh, struct sk_buff *skb);
|
| 365 | int neigh_connected_output(struct neighbour *neigh, struct sk_buff *skb);
|
| 366 | int neigh_direct_output(struct neighbour *neigh, struct sk_buff *skb);
|
| 367 | struct neighbour *neigh_event_ns(struct neigh_table *tbl,
|
| 368 | u8 *lladdr, void *saddr,
|
| 369 | struct net_device *dev);
|
| 370 |
|
| 371 | struct neigh_parms *neigh_parms_alloc(struct net_device *dev,
|
| 372 | struct neigh_table *tbl);
|
| 373 | void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms);
|
| 374 |
|
| 375 | static inline
|
| 376 | struct net *neigh_parms_net(const struct neigh_parms *parms)
|
| 377 | {
|
| 378 | return read_pnet(&parms->net);
|
| 379 | }
|
| 380 |
|
| 381 | unsigned long neigh_rand_reach_time(unsigned long base);
|
| 382 |
|
| 383 | static inline void neigh_set_reach_time(struct neigh_parms *p)
|
| 384 | {
|
| 385 | unsigned long base = NEIGH_VAR(p, BASE_REACHABLE_TIME);
|
| 386 |
|
| 387 | WRITE_ONCE(p->reachable_time, neigh_rand_reach_time(base));
|
| 388 | }
|
| 389 |
|
| 390 | void pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p,
|
| 391 | struct sk_buff *skb);
|
| 392 | struct pneigh_entry *pneigh_lookup(struct neigh_table *tbl, struct net *net,
|
| 393 | const void *key, struct net_device *dev);
|
| 394 | int pneigh_create(struct neigh_table *tbl, struct net *net, const void *key,
|
| 395 | struct net_device *dev, u32 flags, u8 protocol,
|
| 396 | bool permanent);
|
| 397 | int pneigh_delete(struct neigh_table *tbl, struct net *net, const void *key,
|
| 398 | struct net_device *dev);
|
| 399 |
|
| 400 | static inline struct net *pneigh_net(const struct pneigh_entry *pneigh)
|
| 401 | {
|
| 402 | return read_pnet(&pneigh->net);
|
| 403 | }
|
| 404 |
|
| 405 | void neigh_app_ns(struct neighbour *n);
|
| 406 | void neigh_for_each(struct neigh_table *tbl,
|
| 407 | void (*cb)(struct neighbour *, void *), void *cookie);
|
| 408 | void __neigh_for_each_release(struct neigh_table *tbl,
|
| 409 | int (*cb)(struct neighbour *));
|
| 410 | int neigh_xmit(int fam, struct net_device *, const void *, struct sk_buff *);
|
| 411 |
|
| 412 | struct neigh_seq_state {
|
| 413 | struct seq_net_private p;
|
| 414 | struct neigh_table *tbl;
|
| 415 | struct neigh_hash_table *nht;
|
| 416 | void *(*neigh_sub_iter)(struct neigh_seq_state *state,
|
| 417 | struct neighbour *n, loff_t *pos);
|
| 418 | unsigned int bucket;
|
| 419 | unsigned int flags;
|
| 420 | #define NEIGH_SEQ_NEIGH_ONLY 0x00000001
|
| 421 | #define NEIGH_SEQ_IS_PNEIGH 0x00000002
|
| 422 | #define NEIGH_SEQ_SKIP_NOARP 0x00000004
|
| 423 | };
|
| 424 | void *neigh_seq_start(struct seq_file *, loff_t *, struct neigh_table *,
|
| 425 | unsigned int);
|
| 426 | void *neigh_seq_next(struct seq_file *, void *, loff_t *);
|
| 427 | void neigh_seq_stop(struct seq_file *, void *);
|
| 428 |
|
| 429 | int neigh_proc_dointvec(const struct ctl_table *ctl, int write,
|
| 430 | void *buffer, size_t *lenp, loff_t *ppos);
|
| 431 | int neigh_proc_dointvec_jiffies(const struct ctl_table *ctl, int write,
|
| 432 | void *buffer,
|
| 433 | size_t *lenp, loff_t *ppos);
|
| 434 | int neigh_proc_dointvec_ms_jiffies(const struct ctl_table *ctl, int write,
|
| 435 | void *buffer, size_t *lenp, loff_t *ppos);
|
| 436 |
|
| 437 | int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p,
|
| 438 | proc_handler *proc_handler);
|
| 439 | void neigh_sysctl_unregister(struct neigh_parms *p);
|
| 440 |
|
| 441 | static inline void __neigh_parms_put(struct neigh_parms *parms)
|
| 442 | {
|
| 443 | refcount_dec(&parms->refcnt);
|
| 444 | }
|
| 445 |
|
| 446 | static inline struct neigh_parms *neigh_parms_clone(struct neigh_parms *parms)
|
| 447 | {
|
| 448 | refcount_inc(&parms->refcnt);
|
| 449 | return parms;
|
| 450 | }
|
| 451 |
|
| 452 | |
| 453 | * Neighbour references
|
| 454 |
|
| 455 |
|
| 456 | static inline void neigh_release(struct neighbour *neigh)
|
| 457 | {
|
| 458 | if (refcount_dec_and_test(&neigh->refcnt))
|
| 459 | neigh_destroy(neigh);
|
| 460 | }
|
| 461 |
|
| 462 | static inline struct neighbour * neigh_clone(struct neighbour *neigh)
|
| 463 | {
|
| 464 | if (neigh)
|
| 465 | refcount_inc(&neigh->refcnt);
|
| 466 | return neigh;
|
| 467 | }
|
| 468 |
|
| 469 | #define neigh_hold(n) refcount_inc(&(n)->refcnt)
|
| 470 |
|
| 471 | static __always_inline int neigh_event_send_probe(struct neighbour *neigh,
|
| 472 | struct sk_buff *skb,
|
| 473 | const bool immediate_ok)
|
| 474 | {
|
| 475 | unsigned long now = jiffies;
|
| 476 |
|
| 477 | if (READ_ONCE(neigh->used) != now)
|
| 478 | WRITE_ONCE(neigh->used, now);
|
| 479 | if (!(READ_ONCE(neigh->nud_state) & (NUD_CONNECTED | NUD_DELAY | NUD_PROBE)))
|
| 480 | return __neigh_event_send(neigh, skb, immediate_ok);
|
| 481 | return 0;
|
| 482 | }
|
| 483 |
|
| 484 | static inline int neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
|
| 485 | {
|
| 486 | return neigh_event_send_probe(neigh, skb, true);
|
| 487 | }
|
| 488 |
|
| 489 | #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
|
| 490 | static inline int neigh_hh_bridge(struct hh_cache *hh, struct sk_buff *skb)
|
| 491 | {
|
| 492 | unsigned int seq, hh_alen = HH_DATA_ALIGN(ETH_HLEN);
|
| 493 | int err;
|
| 494 |
|
| 495 | err = skb_cow_head(skb, hh_alen);
|
| 496 | if (err)
|
| 497 | return err;
|
| 498 |
|
| 499 | do {
|
| 500 | seq = read_seqbegin(&hh->hh_lock);
|
| 501 | memcpy(skb->data - hh_alen, hh->hh_data, ETH_ALEN + hh_alen - ETH_HLEN);
|
| 502 | } while (read_seqretry(&hh->hh_lock, seq));
|
| 503 | return 0;
|
| 504 | }
|
| 505 | #endif
|
| 506 |
|
| 507 | static inline int neigh_hh_output(const struct hh_cache *hh, struct sk_buff *skb)
|
| 508 | {
|
| 509 | unsigned int hh_alen = 0;
|
| 510 | unsigned int seq;
|
| 511 | unsigned int hh_len;
|
| 512 |
|
| 513 | do {
|
| 514 | seq = read_seqbegin(&hh->hh_lock);
|
| 515 | hh_len = READ_ONCE(hh->hh_len);
|
| 516 | if (likely(hh_len <= HH_DATA_MOD)) {
|
| 517 | hh_alen = HH_DATA_MOD;
|
| 518 |
|
| 519 | |
| 520 | * the unaligned size but not for the aligned size:
|
| 521 | * check headroom explicitly.
|
| 522 |
|
| 523 | if (likely(skb_headroom(skb) >= HH_DATA_MOD)) {
|
| 524 |
|
| 525 | memcpy(skb->data - HH_DATA_MOD, hh->hh_data,
|
| 526 | HH_DATA_MOD);
|
| 527 | }
|
| 528 | } else {
|
| 529 | hh_alen = HH_DATA_ALIGN(hh_len);
|
| 530 |
|
| 531 | if (likely(skb_headroom(skb) >= hh_alen)) {
|
| 532 | memcpy(skb->data - hh_alen, hh->hh_data,
|
| 533 | hh_alen);
|
| 534 | }
|
| 535 | }
|
| 536 | } while (read_seqretry(&hh->hh_lock, seq));
|
| 537 |
|
| 538 | if (WARN_ON_ONCE(skb_headroom(skb) < hh_alen)) {
|
| 539 | kfree_skb(skb);
|
| 540 | return NET_XMIT_DROP;
|
| 541 | }
|
| 542 |
|
| 543 | __skb_push(skb, hh_len);
|
| 544 | return dev_queue_xmit(skb);
|
| 545 | }
|
| 546 |
|
| 547 | static inline int neigh_output(struct neighbour *n, struct sk_buff *skb,
|
| 548 | bool skip_cache)
|
| 549 | {
|
| 550 | const struct hh_cache *hh = &n->hh;
|
| 551 |
|
| 552 | |
| 553 | * neigh_hh_output() is taking care of the race later.
|
| 554 |
|
| 555 | if (!skip_cache &&
|
| 556 | (READ_ONCE(n->nud_state) & NUD_CONNECTED) &&
|
| 557 | READ_ONCE(hh->hh_len))
|
| 558 | return neigh_hh_output(hh, skb);
|
| 559 |
|
| 560 | return READ_ONCE(n->output)(n, skb);
|
| 561 | }
|
| 562 |
|
| 563 | static inline struct neighbour *
|
| 564 | __neigh_lookup(struct neigh_table *tbl, const void *pkey, struct net_device *dev, int creat)
|
| 565 | {
|
| 566 | struct neighbour *n = neigh_lookup(tbl, pkey, dev);
|
| 567 |
|
| 568 | if (n || !creat)
|
| 569 | return n;
|
| 570 |
|
| 571 | n = neigh_create(tbl, pkey, dev);
|
| 572 | return IS_ERR(n) ? NULL : n;
|
| 573 | }
|
| 574 |
|
| 575 | static inline struct neighbour *
|
| 576 | __neigh_lookup_errno(struct neigh_table *tbl, const void *pkey,
|
| 577 | struct net_device *dev)
|
| 578 | {
|
| 579 | struct neighbour *n = neigh_lookup(tbl, pkey, dev);
|
| 580 |
|
| 581 | if (n)
|
| 582 | return n;
|
| 583 |
|
| 584 | return neigh_create(tbl, pkey, dev);
|
| 585 | }
|
| 586 |
|
| 587 | struct neighbour_cb {
|
| 588 | unsigned long sched_next;
|
| 589 | unsigned int flags;
|
| 590 | };
|
| 591 |
|
| 592 | #define LOCALLY_ENQUEUED 0x1
|
| 593 |
|
| 594 | #define NEIGH_CB(skb) ((struct neighbour_cb *)(skb)->cb)
|
| 595 |
|
| 596 | static inline void neigh_ha_snapshot(char *dst, const struct neighbour *n,
|
| 597 | const struct net_device *dev)
|
| 598 | {
|
| 599 | unsigned int seq;
|
| 600 |
|
| 601 | do {
|
| 602 | seq = read_seqbegin(&n->ha_lock);
|
| 603 | memcpy(dst, n->ha, dev->addr_len);
|
| 604 | } while (read_seqretry(&n->ha_lock, seq));
|
| 605 | }
|
| 606 |
|
| 607 | static inline void neigh_update_is_router(struct neighbour *neigh, u32 flags,
|
| 608 | int *notify)
|
| 609 | {
|
| 610 | u8 ndm_flags = 0;
|
| 611 |
|
| 612 | ndm_flags |= (flags & NEIGH_UPDATE_F_ISROUTER) ? NTF_ROUTER : 0;
|
| 613 | if ((neigh->flags ^ ndm_flags) & NTF_ROUTER) {
|
| 614 | if (ndm_flags & NTF_ROUTER)
|
| 615 | neigh->flags |= NTF_ROUTER;
|
| 616 | else
|
| 617 | neigh->flags &= ~NTF_ROUTER;
|
| 618 | *notify = 1;
|
| 619 | }
|
| 620 | }
|
| 621 | #endif
|