this lets read and write the backpressure variables in the interface rx
queue (ifiq) handling:

dlg@ix ~$ sysctl net.link.ifrxq
net.link.ifrxq.pressure_return=6
net.link.ifrxq.pressure_drop=8

ideally this would be temporary, ie, id remove it from the tree once
everyone's happy with these numbers.  6 and 8 are the least worst
values ive come up with so far, but it is handy to move them around
for testing purposes.

Index: sys/net/ifq.c
===================================================================
RCS file: /cvs/src/sys/net/ifq.c,v
retrieving revision 1.32
diff -u -p -r1.32 ifq.c
--- sys/net/ifq.c       1 Jul 2019 00:44:29 -0000       1.32
+++ sys/net/ifq.c       1 Jul 2019 00:48:30 -0000
@@ -23,6 +23,7 @@
 #include <sys/socket.h>
 #include <sys/mbuf.h>
 #include <sys/proc.h>
+#include <sys/sysctl.h>
 
 #include <net/if.h>
 #include <net/if_var.h>
@@ -605,6 +606,43 @@ ifiq_process(void *arg)
        mtx_leave(&ifiq->ifiq_mtx);
 
        if_input_process(ifiq->ifiq_if, &ml);
+}
+
+int
+net_ifiq_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, 
+    void *newp, size_t newlen)
+{
+       int val;
+       int error;
+
+       if (namelen != 1)
+               return (EISDIR);
+
+       switch (name[0]) {
+       case NET_LINK_IFRXQ_PRESSURE_RETURN:
+               val = ifiq_pressure_return;
+               error = sysctl_int(oldp, oldlenp, newp, newlen, &val);
+               if (error != 0)
+                       return (error);
+               if (val < 1 || val > ifiq_pressure_drop)
+                       return (EINVAL);
+               ifiq_pressure_return = val;
+               break;
+       case NET_LINK_IFRXQ_PRESSURE_DROP:
+               val = ifiq_pressure_drop;
+               error = sysctl_int(oldp, oldlenp, newp, newlen, &val);
+               if (error != 0)
+                       return (error);
+               if (ifiq_pressure_return > val)
+                       return (EINVAL);
+               ifiq_pressure_drop = val;
+               break;
+       default:
+               error = EOPNOTSUPP;
+               break;
+       }
+
+       return (error);
 }
 
 /*
Index: sbin/sysctl/sysctl.c
===================================================================
RCS file: /cvs/src/sbin/sysctl/sysctl.c,v
retrieving revision 1.241
diff -u -p -r1.241 sysctl.c
--- sbin/sysctl/sysctl.c        21 Feb 2019 16:37:13 -0000      1.241
+++ sbin/sysctl/sysctl.c        1 Jul 2019 00:48:30 -0000
@@ -192,6 +192,7 @@ void usage(void);
 int findname(char *, char *, char **, struct list *);
 int sysctl_inet(char *, char **, int *, int, int *);
 int sysctl_inet6(char *, char **, int *, int, int *);
+int sysctl_link(char *, char **, int *, int, int *);
 int sysctl_bpf(char *, char **, int *, int, int *);
 int sysctl_mpls(char *, char **, int *, int, int *);
 int sysctl_pipex(char *, char **, int *, int, int *);
@@ -647,6 +648,12 @@ parse(char *string, int flags)
                        }
                        break;
                }
+               if (mib[1] == PF_LINK) {
+                       len = sysctl_link(string, &bufp, mib, flags, &type);
+                       if (len < 0)
+                               return;
+                       break;
+               }
                if (mib[1] == PF_BPF) {
                        len = sysctl_bpf(string, &bufp, mib, flags, &type);
                        if (len < 0)
@@ -2230,6 +2237,46 @@ sysctl_inet6(char *string, char **bufpp,
                *typep = lp->list[tindx].ctl_type;
                return(5);
        }
+       return (4);
+}
+
+/* handle net.link requests */
+struct ctlname netlinkname[] = CTL_NET_LINK_NAMES;
+struct ctlname ifrxqname[] = CTL_NET_LINK_IFRXQ_NAMES;
+struct list netlinklist = { netlinkname, NET_LINK_MAXID };
+struct list netlinkvars[] = {
+       [NET_LINK_IFRXQ] = { ifrxqname, NET_LINK_IFRXQ_MAXID },
+};
+
+int
+sysctl_link(char *string, char **bufpp, int mib[], int flags, int *typep)
+{
+       struct list *lp;
+       int indx;
+
+       if (*bufpp == NULL) {
+               listall(string, &netlinklist);
+               return (-1);
+       }
+       if ((indx = findname(string, "third", bufpp, &netlinklist)) == -1)
+               return (-1);
+       mib[2] = indx;
+       if (indx < NET_LINK_MAXID && netlinkvars[indx].list != NULL)
+               lp = &netlinkvars[indx];
+       else if (!flags)
+               return (-1);
+       else {
+               warnx("%s: no variables defined for this protocol", string);
+               return (-1);
+       }
+       if (*bufpp == NULL) {
+               listall(string, lp);
+               return (-1);
+       }
+       if ((indx = findname(string, "fourth", bufpp, lp)) == -1)
+               return (-1);
+       mib[3] = indx;
+       *typep = lp->list[indx].ctl_type;
        return (4);
 }
 
Index: sys/sys/sysctl.h
===================================================================
RCS file: /cvs/src/sys/sys/sysctl.h,v
retrieving revision 1.188
diff -u -p -r1.188 sysctl.h
--- sys/sys/sysctl.h    1 Jun 2019 14:11:18 -0000       1.188
+++ sys/sys/sysctl.h    1 Jul 2019 00:48:31 -0000
@@ -1012,6 +1012,7 @@ int sysctl_wdog(int *, u_int, void *, si
 extern int (*cpu_cpuspeed)(int *);
 extern void (*cpu_setperf)(int);
 
+int net_ifiq_sysctl(int *, u_int, void *, size_t *, void *, size_t);
 int bpf_sysctl(int *, u_int, void *, size_t *, void *, size_t);
 int pflow_sysctl(int *, u_int, void *, size_t *, void *, size_t);
 int pipex_sysctl(int *, u_int, void *, size_t *, void *, size_t);
Index: sys/sys/socket.h
===================================================================
RCS file: /cvs/src/sys/sys/socket.h,v
retrieving revision 1.96
diff -u -p -r1.96 socket.h
--- sys/sys/socket.h    8 Apr 2018 18:57:39 -0000       1.96
+++ sys/sys/socket.h    1 Jul 2019 00:48:31 -0000
@@ -330,7 +330,7 @@ struct sockpeercred {
        { "hylink", CTLTYPE_NODE }, \
        { "appletalk", CTLTYPE_NODE }, \
        { "route", CTLTYPE_NODE }, \
-       { "link_layer", CTLTYPE_NODE }, \
+       { "link", CTLTYPE_NODE }, \
        { "xtp", CTLTYPE_NODE }, \
        { "coip", CTLTYPE_NODE }, \
        { "cnt", CTLTYPE_NODE }, \
@@ -376,6 +376,29 @@ struct sockpeercred {
        { "stats", CTLTYPE_STRUCT }, \
        { "table", CTLTYPE_STRUCT }, \
        { "ifnames", CTLTYPE_STRUCT }, \
+}
+
+/*
+ * PF_LINK - link layer or device tunables
+ */
+#define NET_LINK_IFRXQ         1       /* net.link.ifrxq */
+#define NET_LINK_MAXID         2
+
+#define CTL_NET_LINK_NAMES { \
+       { 0, 0 }, \
+       { "ifrxq", CTLTYPE_NODE }, \
+}
+
+#define NET_LINK_IFRXQ_PRESSURE_RETURN \
+                               1       /* net.link.ifrxq.pressure_return */
+#define NET_LINK_IFRXQ_PRESSURE_DROP \
+                               2       /* net.link.ifrxq.pressure_drop */
+#define NET_LINK_IFRXQ_MAXID   3
+
+#define CTL_NET_LINK_IFRXQ_NAMES { \
+       { 0, 0 }, \
+       { "pressure_return", CTLTYPE_INT }, \
+       { "pressure_drop", CTLTYPE_INT }, \
 }
 
 /*
Index: sys/kern/uipc_domain.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_domain.c,v
retrieving revision 1.56
diff -u -p -r1.56 uipc_domain.c
--- sys/kern/uipc_domain.c      23 Jun 2018 14:38:59 -0000      1.56
+++ sys/kern/uipc_domain.c      1 Jul 2019 00:48:31 -0000
@@ -159,6 +159,37 @@ pffindproto(int family, int protocol, in
        return (maybe);
 }
 
+static int
+net_link_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
+    void *newp, size_t newlen)
+{
+       int node;
+       int error;
+
+       /*
+        * All sysctl names at this level are nonterminal.
+        */
+       if (namelen < 2)
+               return (EISDIR);                /* overloaded */
+       node = name[0];
+
+       namelen--;
+       name++;
+
+       switch (node) {
+       case NET_LINK_IFRXQ:
+               error = net_ifiq_sysctl(name, namelen, oldp, oldlenp,
+                   newp, newlen);
+               break;
+
+       default:
+               error = ENOPROTOOPT;
+               break;
+       }
+
+       return (error);
+}
+
 int
 net_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
     size_t newlen, struct proc *p)
@@ -178,6 +209,9 @@ net_sysctl(int *name, u_int namelen, voi
 
        if (family == PF_UNSPEC)
                return (0);
+       if (family == PF_LINK)
+               return (net_link_sysctl(name + 1, namelen - 1, oldp, oldlenp,
+                   newp, newlen));
 #if NBPFILTER > 0
        if (family == PF_BPF)
                return (bpf_sysctl(name + 1, namelen - 1, oldp, oldlenp,

Reply via email to