Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

core: add stat to track unresolved discards in neighbor cache

in __neigh_event_send, if we have a neighbour entry which is in
NUD_INCOMPLETE state, we enqueue any outbound frames to that neighbour
to the neighbours arp_queue, which is default capped to a length of 3
skbs. If that queue exceeds its set length, it will drop an skb on
the queue to enqueue the newly arrived skb. This results in a drop
for which we have no statistics incremented. This patch adds an
unresolved_discards stat to /proc/net/stat/ndisc_cache to track these
lost frames.

Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Neil Horman and committed by
David S. Miller
9a6d276e ed88098e

+8 -4
+3 -1
include/net/neighbour.h
··· 75 75 unsigned long destroys; /* number of destroyed neighs */ 76 76 unsigned long hash_grows; /* number of hash resizes */ 77 77 78 - unsigned long res_failed; /* nomber of failed resolutions */ 78 + unsigned long res_failed; /* number of failed resolutions */ 79 79 80 80 unsigned long lookups; /* number of lookups */ 81 81 unsigned long hits; /* number of hits (among lookups) */ ··· 85 85 86 86 unsigned long periodic_gc_runs; /* number of periodic GC runs */ 87 87 unsigned long forced_gc_runs; /* number of forced GC runs */ 88 + 89 + unsigned long unres_discards; /* number of unresolved drops */ 88 90 }; 89 91 90 92 #define NEIGH_CACHE_STAT_INC(tbl, field) \
+5 -3
net/core/neighbour.c
··· 930 930 buff = neigh->arp_queue.next; 931 931 __skb_unlink(buff, &neigh->arp_queue); 932 932 kfree_skb(buff); 933 + NEIGH_CACHE_STAT_INC(neigh->tbl, unres_discards); 933 934 } 934 935 __skb_queue_tail(&neigh->arp_queue, skb); 935 936 } ··· 2463 2462 struct neigh_statistics *st = v; 2464 2463 2465 2464 if (v == SEQ_START_TOKEN) { 2466 - seq_printf(seq, "entries allocs destroys hash_grows lookups hits res_failed rcv_probes_mcast rcv_probes_ucast periodic_gc_runs forced_gc_runs\n"); 2465 + seq_printf(seq, "entries allocs destroys hash_grows lookups hits res_failed rcv_probes_mcast rcv_probes_ucast periodic_gc_runs forced_gc_runs unresolved_discards\n"); 2467 2466 return 0; 2468 2467 } 2469 2468 2470 2469 seq_printf(seq, "%08x %08lx %08lx %08lx %08lx %08lx %08lx " 2471 - "%08lx %08lx %08lx %08lx\n", 2470 + "%08lx %08lx %08lx %08lx %08lx\n", 2472 2471 atomic_read(&tbl->entries), 2473 2472 2474 2473 st->allocs, ··· 2484 2483 st->rcv_probes_ucast, 2485 2484 2486 2485 st->periodic_gc_runs, 2487 - st->forced_gc_runs 2486 + st->forced_gc_runs, 2487 + st->unres_discards 2488 2488 ); 2489 2489 2490 2490 return 0;