.. | .. |
---|
242 | 242 | (n->nud_state == NUD_NOARP) || |
---|
243 | 243 | (tbl->is_multicast && |
---|
244 | 244 | tbl->is_multicast(n->primary_key)) || |
---|
245 | | - time_after(tref, n->updated)) |
---|
| 245 | + !time_in_range(n->updated, tref, jiffies)) |
---|
246 | 246 | remove = true; |
---|
247 | 247 | write_unlock(&n->lock); |
---|
248 | 248 | |
---|
.. | .. |
---|
262 | 262 | |
---|
263 | 263 | static void neigh_add_timer(struct neighbour *n, unsigned long when) |
---|
264 | 264 | { |
---|
| 265 | + /* Use safe distance from the jiffies - LONG_MAX point while timer |
---|
| 266 | + * is running in DELAY/PROBE state but still show to user space |
---|
| 267 | + * large times in the past. |
---|
| 268 | + */ |
---|
| 269 | + unsigned long mint = jiffies - (LONG_MAX - 86400 * HZ); |
---|
| 270 | + |
---|
265 | 271 | neigh_hold(n); |
---|
| 272 | + if (!time_in_range(n->confirmed, mint, jiffies)) |
---|
| 273 | + n->confirmed = mint; |
---|
| 274 | + if (time_before(n->used, n->confirmed)) |
---|
| 275 | + n->used = n->confirmed; |
---|
266 | 276 | if (unlikely(mod_timer(&n->timer, when))) { |
---|
267 | 277 | printk("NEIGH: BUG, double timer add, state is %x\n", |
---|
268 | 278 | n->nud_state); |
---|
.. | .. |
---|
560 | 570 | return n; |
---|
561 | 571 | } |
---|
562 | 572 | EXPORT_SYMBOL(neigh_lookup); |
---|
563 | | - |
---|
564 | | -struct neighbour *neigh_lookup_nodev(struct neigh_table *tbl, struct net *net, |
---|
565 | | - const void *pkey) |
---|
566 | | -{ |
---|
567 | | - struct neighbour *n; |
---|
568 | | - unsigned int key_len = tbl->key_len; |
---|
569 | | - u32 hash_val; |
---|
570 | | - struct neigh_hash_table *nht; |
---|
571 | | - |
---|
572 | | - NEIGH_CACHE_STAT_INC(tbl, lookups); |
---|
573 | | - |
---|
574 | | - rcu_read_lock_bh(); |
---|
575 | | - nht = rcu_dereference_bh(tbl->nht); |
---|
576 | | - hash_val = tbl->hash(pkey, NULL, nht->hash_rnd) >> (32 - nht->hash_shift); |
---|
577 | | - |
---|
578 | | - for (n = rcu_dereference_bh(nht->hash_buckets[hash_val]); |
---|
579 | | - n != NULL; |
---|
580 | | - n = rcu_dereference_bh(n->next)) { |
---|
581 | | - if (!memcmp(n->primary_key, pkey, key_len) && |
---|
582 | | - net_eq(dev_net(n->dev), net)) { |
---|
583 | | - if (!refcount_inc_not_zero(&n->refcnt)) |
---|
584 | | - n = NULL; |
---|
585 | | - NEIGH_CACHE_STAT_INC(tbl, hits); |
---|
586 | | - break; |
---|
587 | | - } |
---|
588 | | - } |
---|
589 | | - |
---|
590 | | - rcu_read_unlock_bh(); |
---|
591 | | - return n; |
---|
592 | | -} |
---|
593 | | -EXPORT_SYMBOL(neigh_lookup_nodev); |
---|
594 | 573 | |
---|
595 | 574 | static struct neighbour * |
---|
596 | 575 | ___neigh_create(struct neigh_table *tbl, const void *pkey, |
---|
.. | .. |
---|
948 | 927 | goto next_elt; |
---|
949 | 928 | } |
---|
950 | 929 | |
---|
951 | | - if (time_before(n->used, n->confirmed)) |
---|
| 930 | + if (time_before(n->used, n->confirmed) && |
---|
| 931 | + time_is_before_eq_jiffies(n->confirmed)) |
---|
952 | 932 | n->used = n->confirmed; |
---|
953 | 933 | |
---|
954 | 934 | if (refcount_read(&n->refcnt) == 1 && |
---|
955 | 935 | (state == NUD_FAILED || |
---|
956 | | - time_after(jiffies, n->used + NEIGH_VAR(n->parms, GC_STALETIME)))) { |
---|
957 | | - *np = n->next; |
---|
| 936 | + !time_in_range_open(jiffies, n->used, |
---|
| 937 | + n->used + NEIGH_VAR(n->parms, GC_STALETIME)))) { |
---|
| 938 | + rcu_assign_pointer(*np, |
---|
| 939 | + rcu_dereference_protected(n->next, |
---|
| 940 | + lockdep_is_held(&tbl->lock))); |
---|
958 | 941 | neigh_mark_dead(n); |
---|
959 | 942 | write_unlock(&n->lock); |
---|
960 | 943 | neigh_cleanup_and_release(n); |
---|
.. | .. |
---|
1789 | 1772 | break; |
---|
1790 | 1773 | case AF_INET6: |
---|
1791 | 1774 | tbl = neigh_tables[NEIGH_ND_TABLE]; |
---|
1792 | | - break; |
---|
1793 | | - case AF_DECnet: |
---|
1794 | | - tbl = neigh_tables[NEIGH_DN_TABLE]; |
---|
1795 | 1775 | break; |
---|
1796 | 1776 | } |
---|
1797 | 1777 | |
---|