Hi,

While investigating packet loss through OpenBSD 6.3 firewalls I noticed
that a lot of packets were getting dropped by pf due to congestion, but
the net.inet.ip.ifq.drops counter wasn't increasing. After checking all
other niqueues for drops and not finding any, I applied the following
patch to expose the remaining ARP queue. This showed a significant
number of drops, and after setting the maxlen to a much higher value,
the packet loss vanished.

Please consider including this as not having the drops counter
available certainly made debugging harder.

Best regards,
Daniel

Index: sys/netinet/in.h
===================================================================
RCS file: /cvs/src/sys/netinet/in.h,v
retrieving revision 1.132
diff -u -r1.132 in.h
--- sys/netinet/in.h    11 Sep 2018 21:04:03 -0000      1.132
+++ sys/netinet/in.h    10 Oct 2018 12:02:50 -0000
@@ -688,7 +688,8 @@
 #define        IPCTL_MRTVIF            38
 #define        IPCTL_ARPTIMEOUT        39
 #define        IPCTL_ARPDOWN           40
-#define        IPCTL_MAXID             41
+#define        IPCTL_ARPQUEUE          41
+#define        IPCTL_MAXID             42
 
 #define        IPCTL_NAMES { \
        { 0, 0 }, \
@@ -732,6 +733,7 @@
        { "mrtvif", CTLTYPE_STRUCT }, \
        { "arptimeout", CTLTYPE_INT }, \
        { "arpdown", CTLTYPE_INT }, \
+       { "arpq", CTLTYPE_NODE }, \
 }
 #define        IPCTL_VARS { \
        NULL, \
@@ -775,6 +777,7 @@
        NULL, \
        &arpt_keep, \
        &arpt_down, \
+       NULL, \
 }
 
 #endif /* __BSD_VISIBLE */
Index: sys/netinet/ip_input.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_input.c,v
retrieving revision 1.341
diff -u -r1.341 ip_input.c
--- sys/netinet/ip_input.c      11 Sep 2018 21:04:03 -0000
1.341 +++ sys/netinet/ip_input.c        10 Oct 2018 12:02:50 -0000
@@ -120,6 +120,8 @@
 
 static struct mbuf_queue       ipsend_mq;
 
+extern struct niqueue          arpinq;
+
 int    ip_ours(struct mbuf **, int *, int, int);
 int    ip_local(struct mbuf **, int *, int, int);
 int    ip_dooptions(struct mbuf *, struct ifnet *);
@@ -1579,7 +1581,8 @@
 #endif
 
        /* Almost all sysctl names at this level are terminal. */
-       if (namelen != 1 && name[0] != IPCTL_IFQUEUE)
+       if (namelen != 1 && name[0] != IPCTL_IFQUEUE &&
+           name[0] != IPCTL_ARPQUEUE)
                return (ENOTDIR);
 
        switch (name[0]) {
@@ -1639,6 +1642,9 @@
        case IPCTL_IFQUEUE:
                return (sysctl_niq(name + 1, namelen - 1,
                    oldp, oldlenp, newp, newlen, &ipintrq));
+       case IPCTL_ARPQUEUE:
+               return (sysctl_niq(name + 1, namelen - 1,
+                   oldp, oldlenp, newp, newlen, &arpinq));
        case IPCTL_STATS:
                return (ip_sysctl_ipstat(oldp, oldlenp, newp));
 #ifdef MROUTING

Reply via email to