Import ts(1) - a timestamp utility

2022-06-28 Thread Job Snijders
Dear all,

The below changeset is a from scratch & pledged C implementation of the
'ts' perl utility found in the moreutils collection by Joey Hess.

OK to add to /usr/bin?

Kind regards,

Job

Index: ts/Makefile
===
RCS file: ts/Makefile
diff -N ts/Makefile
--- /dev/null   1 Jan 1970 00:00:00 -
+++ ts/Makefile 28 Jun 2022 22:32:32 -
@@ -0,0 +1,5 @@
+#  $OpenBSD: Makefile,v 1.4 2017/02/19 00:46:57 jca Exp $
+
+PROG=  ts
+
+.include 
Index: ts/ts.1
===
RCS file: ts/ts.1
diff -N ts/ts.1
--- /dev/null   1 Jan 1970 00:00:00 -
+++ ts/ts.1 28 Jun 2022 22:32:32 -
@@ -0,0 +1,93 @@
+.\"$OpenBSD$
+.\"
+.\" Copyright (c) 2022 Job Snijders 
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd $Mdocdate: June 28 2022 $
+.Dt TS 1
+.Os
+.Sh NAME
+.Nm ts 
+.Nd timestamp input
+.Sh SYNOPSIS
+.Nm ts
+.Op Fl i | s
+.Op Ar format
+.Sh DESCRIPTION
+When invoked, the
+.Nm
+utility adds a timestamp to the beginning of each line of input.
+The optional
+.Ar format
+argument controls how the timestamp is displayed, according to the conversion
+specifications described in the
+.Xr strftime 3
+manual page.
+The default format is
+.Qq %b %d %H:%M:%S .
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl i
+Display time elapsed since the last timestamp.
+.It Fl s
+Display time elapsed since the start of the program.
+.El
+.Pp
+When an option is used, the default format changes to
+.Qq %H:%M:%S .
+.Sh EXAMPLES
+.Bd -literal -offset indent
+$ (echo foo; sleep 2; echo bar) | ts 
+Jun 28 12:13:38 foo
+Jun 28 12:13:40 bar
+
+$ ls | ts %.s
+1656455386.515542 Makefile
+1656455386.516082 ts.1
+1656455386.516089 ts.c
+.Ed
+.Sh STANDARDS
+The following non-standard conversion specifications append millisecond
+resolution:
+.Cm \&%.S ,
+.Cm \&%.s ,
+and
+.Cm \&%.T ;
+which are similar to
+.Cm \&%S ,
+.Cm \&%s ,
+and
+.Cm \&%T .
+Examples:
+.Qq 10.1 ,
+.Qq 1656427781.1 ,
+and
+.Qq 4:20:00.1 .
+.Sh HISTORY
+A
+.Nm
+utility first appeared in the moreutils collection by Joey Hess, and was
+rewritten from scratch for
+.Ox 7.2
+for licensing reasons.
+.Sh AUTHORS
+This
+.Nm
+utility was written by
+.An Job Snijders Aq Mt j...@openbsd.org
+and
+.An Claudio Jeker Aq Mt clau...@openbsd.org
+while burning midnight fuel at
+.Em r2k22 .
Index: ts/ts.c
===
RCS file: ts/ts.c
diff -N ts/ts.c
--- /dev/null   1 Jan 1970 00:00:00 -
+++ ts/ts.c 28 Jun 2022 22:32:32 -
@@ -0,0 +1,164 @@
+/* $OpenBSD$   */
+/*
+ * Copyright (c) 2022 Job Snijders 
+ * Copyright (c) 2022 Claudio Jeker 
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static char*format = "%b %d %H:%M:%S";
+static char*buf;
+static char*outbuf;
+static size_t   bufsize;
+
+static void fmtfmt(struct tm *, long);
+static void __dead  usage(void);
+
+int
+main(int argc, char *argv[])
+{
+   int iflag, sflag;
+   int ch, prev;
+   struct timespec start, now, elapsed;
+   struct tm *lt, tm;
+
+   if (pledge("stdio", NULL) == -1)
+   err(1, "pledge");
+
+   iflag = sflag = 0;
+
+   while ((ch = getopt(argc, argv, "is")) != -1) {
+   switch (ch) {
+   case 'i':
+   iflag = 1;
+   format = "%H:%M:%S";
+

Re: ip6 hbhchcheck mbuf pointer

2022-06-28 Thread Alexandr Nedvedicky
Hello,

I like the idea. I would just consider to make ip6_hbhchcheck()
to always free mp on error and set NULL as return value.

for example here in current ip6_input_if() we may leak memory
on error:

 308 int
 309 ip6_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet 
*ifp)
 310 {

 423 #ifdef MROUTING
 424 if (ip6_mforwarding && ip6_mrouter[ifp->if_rdomain]) {
 425 int error;
 426 
 427 nxt = ip6_hbhchcheck(&m, offp, &ours);
 428 if (nxt == IPPROTO_DONE)
 429 goto out;
 430 

 575 return IPPROTO_DONE;
 576  bad:
 577 nxt = IPPROTO_DONE;
 578 m_freemp(mp);
 579  out:
 580 rtfree(rt);
 581 return nxt;
 582 }

another option would be to revisit all places where we call ip6_hbhchcheck()
and adjust caller accordingly. In my opinion all places where we
making ip6_hbhchcheck() to also free packet on error should be the
right thing to do.

other than that diff reads OK to me.

thanks and
regards
sashan


On Tue, Jun 28, 2022 at 11:50:03PM +0200, Alexander Bluhm wrote:
> Hi,
> 
> Deep in ip6_hbhchcheck() may modify the mbuf pointer.  Instead of
> having dangling pointer that we must not use, pass pointer to mbuf
> pointer and keep it consistent in the caller.
> 
> ok?
> 
> bluhm
> 
> Index: netinet6/ip6_input.c
> ===
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/ip6_input.c,v
> retrieving revision 1.246
> diff -u -p -r1.246 ip6_input.c
> --- netinet6/ip6_input.c  28 Jun 2022 08:24:29 -  1.246
> +++ netinet6/ip6_input.c  28 Jun 2022 10:51:43 -
> @@ -122,7 +122,7 @@ uint8_t ip6_soiikey[IP6_SOIIKEY_LEN];
>  int ip6_ours(struct mbuf **, int *, int, int);
>  int ip6_local(struct mbuf **, int *, int, int);
>  int ip6_check_rh0hdr(struct mbuf *, int *);
> -int ip6_hbhchcheck(struct mbuf *, int *, int *);
> +int ip6_hbhchcheck(struct mbuf **, int *, int *);
>  int ip6_hopopts_input(u_int32_t *, u_int32_t *, struct mbuf **, int *);
>  struct mbuf *ip6_pullexthdr(struct mbuf *, size_t, int);
>  int ip6_sysctl_soiikey(void *, size_t *, void *, size_t);
> @@ -424,7 +424,7 @@ ip6_input_if(struct mbuf **mp, int *offp
>   if (ip6_mforwarding && ip6_mrouter[ifp->if_rdomain]) {
>   int error;
>  
> - nxt = ip6_hbhchcheck(m, offp, &ours);
> + nxt = ip6_hbhchcheck(&m, offp, &ours);
>   if (nxt == IPPROTO_DONE)
>   goto out;
>  
> @@ -544,7 +544,7 @@ ip6_input_if(struct mbuf **mp, int *offp
>   goto bad;
>   }
>  
> - nxt = ip6_hbhchcheck(m, offp, &ours);
> + nxt = ip6_hbhchcheck(&m, offp, &ours);
>   if (nxt == IPPROTO_DONE)
>   goto out;
>  
> @@ -586,7 +586,7 @@ ip6_local(struct mbuf **mp, int *offp, i
>  {
>   NET_ASSERT_WLOCKED();
>  
> - nxt = ip6_hbhchcheck(*mp, offp, NULL);
> + nxt = ip6_hbhchcheck(mp, offp, NULL);
>   if (nxt == IPPROTO_DONE)
>   return IPPROTO_DONE;
>  
> @@ -597,13 +597,13 @@ ip6_local(struct mbuf **mp, int *offp, i
>  }
>  
>  int
> -ip6_hbhchcheck(struct mbuf *m, int *offp, int *oursp)
> +ip6_hbhchcheck(struct mbuf **mp, int *offp, int *oursp)
>  {
>   struct ip6_hdr *ip6;
>   u_int32_t plen, rtalert = ~0;
>   int nxt;
>  
> - ip6 = mtod(m, struct ip6_hdr *);
> + ip6 = mtod(*mp, struct ip6_hdr *);
>  
>   /*
>* Process Hop-by-Hop options header if it's contained.
> @@ -615,12 +615,11 @@ ip6_hbhchcheck(struct mbuf *m, int *offp
>   if (ip6->ip6_nxt == IPPROTO_HOPOPTS) {
>   struct ip6_hbh *hbh;
>  
> - if (ip6_hopopts_input(&plen, &rtalert, &m, offp)) {
> + if (ip6_hopopts_input(&plen, &rtalert, mp, offp))
>   goto bad;   /* m have already been freed */
> - }
>  
>   /* adjust pointer */
> - ip6 = mtod(m, struct ip6_hdr *);
> + ip6 = mtod(*mp, struct ip6_hdr *);
>  
>   /*
>* if the payload length field is 0 and the next header field
> @@ -634,13 +633,13 @@ ip6_hbhchcheck(struct mbuf *m, int *offp
>* (non-zero) payload length to the variable plen.
>*/
>   ip6stat_inc(ip6s_badoptions);
> - icmp6_error(m, ICMP6_PARAM_PROB,
> + icmp6_error(*mp, ICMP6_PARAM_PROB,
>   ICMP6_PARAMPROB_HEADER,
>   (caddr_t)&ip6->ip6_plen - (caddr_t)ip6);
>   goto bad;
>   }
> - IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, sizeof(struct ip6_hdr),
> - sizeof(struct ip6_hbh));
> + IP6_EXTHDR_GET(hbh, struct ip6_hbh *, *mp,
> + sizeof(struct ip6_hdr

ip6 hbhchcheck mbuf pointer

2022-06-28 Thread Alexander Bluhm
Hi,

Deep in ip6_hbhchcheck() may modify the mbuf pointer.  Instead of
having dangling pointer that we must not use, pass pointer to mbuf
pointer and keep it consistent in the caller.

ok?

bluhm

Index: netinet6/ip6_input.c
===
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/ip6_input.c,v
retrieving revision 1.246
diff -u -p -r1.246 ip6_input.c
--- netinet6/ip6_input.c28 Jun 2022 08:24:29 -  1.246
+++ netinet6/ip6_input.c28 Jun 2022 10:51:43 -
@@ -122,7 +122,7 @@ uint8_t ip6_soiikey[IP6_SOIIKEY_LEN];
 int ip6_ours(struct mbuf **, int *, int, int);
 int ip6_local(struct mbuf **, int *, int, int);
 int ip6_check_rh0hdr(struct mbuf *, int *);
-int ip6_hbhchcheck(struct mbuf *, int *, int *);
+int ip6_hbhchcheck(struct mbuf **, int *, int *);
 int ip6_hopopts_input(u_int32_t *, u_int32_t *, struct mbuf **, int *);
 struct mbuf *ip6_pullexthdr(struct mbuf *, size_t, int);
 int ip6_sysctl_soiikey(void *, size_t *, void *, size_t);
@@ -424,7 +424,7 @@ ip6_input_if(struct mbuf **mp, int *offp
if (ip6_mforwarding && ip6_mrouter[ifp->if_rdomain]) {
int error;
 
-   nxt = ip6_hbhchcheck(m, offp, &ours);
+   nxt = ip6_hbhchcheck(&m, offp, &ours);
if (nxt == IPPROTO_DONE)
goto out;
 
@@ -544,7 +544,7 @@ ip6_input_if(struct mbuf **mp, int *offp
goto bad;
}
 
-   nxt = ip6_hbhchcheck(m, offp, &ours);
+   nxt = ip6_hbhchcheck(&m, offp, &ours);
if (nxt == IPPROTO_DONE)
goto out;
 
@@ -586,7 +586,7 @@ ip6_local(struct mbuf **mp, int *offp, i
 {
NET_ASSERT_WLOCKED();
 
-   nxt = ip6_hbhchcheck(*mp, offp, NULL);
+   nxt = ip6_hbhchcheck(mp, offp, NULL);
if (nxt == IPPROTO_DONE)
return IPPROTO_DONE;
 
@@ -597,13 +597,13 @@ ip6_local(struct mbuf **mp, int *offp, i
 }
 
 int
-ip6_hbhchcheck(struct mbuf *m, int *offp, int *oursp)
+ip6_hbhchcheck(struct mbuf **mp, int *offp, int *oursp)
 {
struct ip6_hdr *ip6;
u_int32_t plen, rtalert = ~0;
int nxt;
 
-   ip6 = mtod(m, struct ip6_hdr *);
+   ip6 = mtod(*mp, struct ip6_hdr *);
 
/*
 * Process Hop-by-Hop options header if it's contained.
@@ -615,12 +615,11 @@ ip6_hbhchcheck(struct mbuf *m, int *offp
if (ip6->ip6_nxt == IPPROTO_HOPOPTS) {
struct ip6_hbh *hbh;
 
-   if (ip6_hopopts_input(&plen, &rtalert, &m, offp)) {
+   if (ip6_hopopts_input(&plen, &rtalert, mp, offp))
goto bad;   /* m have already been freed */
-   }
 
/* adjust pointer */
-   ip6 = mtod(m, struct ip6_hdr *);
+   ip6 = mtod(*mp, struct ip6_hdr *);
 
/*
 * if the payload length field is 0 and the next header field
@@ -634,13 +633,13 @@ ip6_hbhchcheck(struct mbuf *m, int *offp
 * (non-zero) payload length to the variable plen.
 */
ip6stat_inc(ip6s_badoptions);
-   icmp6_error(m, ICMP6_PARAM_PROB,
+   icmp6_error(*mp, ICMP6_PARAM_PROB,
ICMP6_PARAMPROB_HEADER,
(caddr_t)&ip6->ip6_plen - (caddr_t)ip6);
goto bad;
}
-   IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, sizeof(struct ip6_hdr),
-   sizeof(struct ip6_hbh));
+   IP6_EXTHDR_GET(hbh, struct ip6_hbh *, *mp,
+   sizeof(struct ip6_hdr), sizeof(struct ip6_hbh));
if (hbh == NULL) {
ip6stat_inc(ip6s_tooshort);
goto bad;
@@ -662,18 +661,18 @@ ip6_hbhchcheck(struct mbuf *m, int *offp
 * Trim mbufs if longer than we expect.
 * Drop packet if shorter than we expect.
 */
-   if (m->m_pkthdr.len - sizeof(struct ip6_hdr) < plen) {
+   if ((*mp)->m_pkthdr.len - sizeof(struct ip6_hdr) < plen) {
ip6stat_inc(ip6s_tooshort);
-   m_freem(m);
+   m_freemp(mp);
goto bad;
}
-   if (m->m_pkthdr.len > sizeof(struct ip6_hdr) + plen) {
-   if (m->m_len == m->m_pkthdr.len) {
-   m->m_len = sizeof(struct ip6_hdr) + plen;
-   m->m_pkthdr.len = sizeof(struct ip6_hdr) + plen;
+   if ((*mp)->m_pkthdr.len > sizeof(struct ip6_hdr) + plen) {
+   if ((*mp)->m_len == (*mp)->m_pkthdr.len) {
+   (*mp)->m_len = sizeof(struct ip6_hdr) + plen;
+   (*mp)->m_pkthdr.len = sizeof(struct ip6_hdr) + plen;
} else {
-   m_adj(m,
-   sizeof(struct ip6_hdr) + plen - m->m_pkthdr.len);
+

Re: Unlocking pledge(2)

2022-06-28 Thread Jeremie Courreges-Anglas
On Tue, Jun 28 2022, Martin Pieuchot  wrote:
> On 28/06/22(Tue) 18:17, Jeremie Courreges-Anglas wrote:
>> 
>> Initially I just wandered in syscall_mi.h and found the locking scheme
>> super weird, even if technically correct.  pledge_syscall() better be
>> safe to call without the kernel lock so I don't understand why we're
>> sometimes calling it with the kernel lock and sometimes not.
>> 
>> ps_pledge is 64 bits so it's not possible to unset bits in an atomic
>> manner on all architectures.  Even if we're only removing bits and there
>> is probably no way to see a completely garbage value, it makes sense to
>> just protect ps_pledge (and ps_execpledge) in the usual manner so that
>> we can unlock the syscall.  The diff below protects the fields using
>> ps_mtx even though I initially used a dedicated ps_pledge_mtx.
>> unveil_destroy() needs to be moved after the critical section.
>> regress/sys/kern/pledge looks happy with this.  The sys/syscall_mi.h
>> change can be committed in a separate step.
>> 
>> Input and oks welcome.
>
> This looks nice.  I doubt there's any existing program where you can
> really test this.  Even firefox and chromium should do things
> correctly.
>
> Maybe you should write a regress test that tries to break the kernel.

That would need some pondering, I'm not sure what kind of breakage
you're envisioning.  The obvious check to perform would be to ensure
that we're not increasing the promises but the code already does it.
Hmm.

For now, here's the latest diff based on input from the hackroom, which
basically amounts to:
- don't take the mutex to read the value.  Even on 32 bits machines that
  can't write an 8 byte value in a single go we don't expect garbage to
  on a read crossing a write, since we only remove bits and never add
  some.
- use READ_ONCE when we're storing the value in a local variable, to
  prevent possible reloading from memory.  In the current code it would
  not be a problem but ensuring that we do not reload from memory is
  just good practice for stuff that can be modified concurrently.
  (This part can be committed in a second step, just like the
  syscall_mi.h change.)

ok?


Index: kern/init_sysent.c
===
RCS file: /home/cvs/src/sys/kern/init_sysent.c,v
retrieving revision 1.238
diff -u -p -r1.238 init_sysent.c
--- kern/init_sysent.c  27 Jun 2022 14:26:05 -  1.238
+++ kern/init_sysent.c  28 Jun 2022 15:18:25 -
@@ -1,10 +1,10 @@
-/* $OpenBSD: init_sysent.c,v 1.238 2022/06/27 14:26:05 cheloha Exp $   
*/
+/* $OpenBSD$   */
 
 /*
  * System call switch table.
  *
  * DO NOT EDIT-- this file is automatically generated.
- * created from;   OpenBSD: syscalls.master,v 1.224 2022/05/16 07:36:04 
mvs Exp 
+ * created from;   OpenBSD: syscalls.master,v 1.225 2022/06/27 14:26:05 
cheloha Exp 
  */
 
 #include 
@@ -248,7 +248,7 @@ const struct sysent sysent[] = {
sys_listen },   /* 106 = listen */
{ 4, s(struct sys_chflagsat_args), 0,
sys_chflagsat },/* 107 = chflagsat */
-   { 2, s(struct sys_pledge_args), 0,
+   { 2, s(struct sys_pledge_args), SY_NOLOCK | 0,
sys_pledge },   /* 108 = pledge */
{ 4, s(struct sys_ppoll_args), 0,
sys_ppoll },/* 109 = ppoll */
Index: kern/kern_pledge.c
===
RCS file: /home/cvs/src/sys/kern/kern_pledge.c,v
retrieving revision 1.282
diff -u -p -r1.282 kern_pledge.c
--- kern/kern_pledge.c  26 Jun 2022 06:11:49 -  1.282
+++ kern/kern_pledge.c  28 Jun 2022 17:00:51 -
@@ -21,6 +21,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -465,13 +466,26 @@ sys_pledge(struct proc *p, void *v, regi
struct process *pr = p->p_p;
uint64_t promises, execpromises;
int error;
+   int unveil_cleanup = 0;
 
+   /* Check for any error in user input */
if (SCARG(uap, promises)) {
error = parsepledges(p, "pledgereq",
SCARG(uap, promises), &promises);
if (error)
return (error);
+   }
+   if (SCARG(uap, execpromises)) {
+   error = parsepledges(p, "pledgeexecreq",
+   SCARG(uap, execpromises), &execpromises);
+   if (error)
+   return (error);
+   }
+
+   mtx_enter(&pr->ps_mtx);
 
+   /* Check for any error wrt current promises */
+   if (SCARG(uap, promises)) {
/* In "error" mode, ignore promise increase requests,
 * but accept promise decrease requests */
if (ISSET(pr->ps_flags, PS_PLEDGE) &&
@@ -480,37 +494,47 @@ sys_pledge(struct proc *p, void *v, regi
 
/* Only permit reductions */
if (ISSET(pr->ps_flags, PS_PLEDGE) &&
-  

Re: pipex(4): use per-session `pxs_mtx' mutex(9) for protection

2022-06-28 Thread Vitaliy Makkoveev
On Tue, Jun 28, 2022 at 09:05:09PM +0300, Vitaliy Makkoveev wrote:
> The updated diff. It was triggered by Hrvoje Popovski, we could do
> direct (*if_qstart)() call in pipex(4) PPPOE input path, and this
> provides deadlock. The updated diff uses ip{,6}_send() instead of
> ipv{4,6}_input().
>

I think, I found better solution. The diff below still uses
ipv{4,6}_input(), but introduces custom pipex_if_enqueue()
(*if_enqueue)() handler. Now we can be sure, our (*if_qstart)() handlers
will never be called directly. Also we can be sure about netlock state
within our (*if_qstart)() handlers and remove pipexintr().

We do direct (*if_qstart)() call only if we overflow `if_snd' queue, and
of course we loose packets in this case, so the behavior mostly the
same.

Index: sys/net/if_pppx.c
===
RCS file: /cvs/src/sys/net/if_pppx.c,v
retrieving revision 1.117
diff -u -p -r1.117 if_pppx.c
--- sys/net/if_pppx.c   26 Jun 2022 22:51:58 -  1.117
+++ sys/net/if_pppx.c   28 Jun 2022 19:56:47 -
@@ -651,6 +651,7 @@ pppx_add_session(struct pppx_dev *pxd, s
ifp->if_mtu = req->pr_peer_mru; /* XXX */
ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST | IFF_UP;
ifp->if_xflags = IFXF_CLONED | IFXF_MPSAFE;
+   ifp->if_enqueue = pipex_if_enqueue;
ifp->if_qstart = pppx_if_qstart;
ifp->if_output = pppx_if_output;
ifp->if_ioctl = pppx_if_ioctl;
@@ -659,8 +660,6 @@ pppx_add_session(struct pppx_dev *pxd, s
ifp->if_softc = pxi;
/* ifp->if_rdomain = req->pr_rdomain; */
if_counters_alloc(ifp);
-   /* XXXSMP: be sure pppx_if_qstart() called with NET_LOCK held */
-   ifq_set_maxlen(&ifp->if_snd, 1);
 
/* XXXSMP breaks atomicity */
NET_UNLOCK();
@@ -801,13 +800,16 @@ pppx_if_qstart(struct ifqueue *ifq)
struct mbuf *m;
int proto;
 
-   NET_ASSERT_LOCKED();
+   mtx_enter(&pxi->pxi_session->pxs_mtx);
+
while ((m = ifq_dequeue(ifq)) != NULL) {
proto = *mtod(m, int *);
m_adj(m, sizeof(proto));
 
pipex_ppp_output(m, pxi->pxi_session, proto);
}
+
+   mtx_leave(&pxi->pxi_session->pxs_mtx);
 }
 
 int
@@ -1041,11 +1043,10 @@ pppacopen(dev_t dev, int flags, int mode
ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST;
ifp->if_xflags = IFXF_CLONED | IFXF_MPSAFE;
ifp->if_rtrequest = p2p_rtrequest; /* XXX */
+   ifp->if_enqueue = pipex_if_enqueue;
ifp->if_output = pppac_output;
ifp->if_qstart = pppac_qstart;
ifp->if_ioctl = pppac_ioctl;
-   /* XXXSMP: be sure pppac_qstart() called with NET_LOCK held */
-   ifq_set_maxlen(&ifp->if_snd, 1);
 
if_counters_alloc(ifp);
if_attach(ifp);
@@ -1441,7 +1442,6 @@ pppac_qstart(struct ifqueue *ifq)
struct ip ip;
int rv;
 
-   NET_ASSERT_LOCKED();
while ((m = ifq_dequeue(ifq)) != NULL) {
 #if NBPFILTER > 0
if (ifp->if_bpf) {
Index: sys/net/pipex.c
===
RCS file: /cvs/src/sys/net/pipex.c,v
retrieving revision 1.142
diff -u -p -r1.142 pipex.c
--- sys/net/pipex.c 28 Jun 2022 08:01:40 -  1.142
+++ sys/net/pipex.c 28 Jun 2022 19:56:47 -
@@ -91,7 +91,6 @@ struct pool mppe_key_pool;
  * Locks used to protect global data
  *   A   atomic operation
  *   I   immutable after creation
- *   N   net lock
  *   L   pipex_list_mtx
  */
 
@@ -172,7 +171,6 @@ pipex_ioctl(void *ownersc, u_long cmd, c
 {
int ret = 0;
 
-   NET_ASSERT_LOCKED();
switch (cmd) {
case PIPEXCSESSION:
ret = pipex_config_session(
@@ -197,6 +195,19 @@ pipex_ioctl(void *ownersc, u_long cmd, c
return (ret);
 }
 
+int
+pipex_if_enqueue(struct ifnet *ifp, struct mbuf *m)
+{
+   struct ifqueue *ifq = &ifp->if_snd;
+   int error;
+
+   if ((error = ifq_enqueue(ifq, m)) != 0)
+   return (error);
+   task_add(ifq->ifq_softnet, &ifq->ifq_bundle);
+
+   return (0);
+}
+
 /
  * Software Interrupt Handler
  /
@@ -575,18 +586,20 @@ pipex_config_session(struct pipex_sessio
struct pipex_session *session;
int error = 0;
 
-   NET_ASSERT_LOCKED();
-
session = pipex_lookup_by_session_id(req->pcr_protocol,
req->pcr_session_id);
if (session == NULL)
return (EINVAL);
 
if (session->ownersc == ownersc) {
+   mtx_enter(&session->pxs_mtx);
+
if (req->pcr_ip_forward != 0)
session->flags |= PIPEX_SFLAGS_IP_FORWARD;
else
session->flags &= ~PIPEX_SFLAGS_IP_FORWARD;
+
+   mtx_leave(&session->pxs_mtx);
} else

Re: Unlocking pledge(2)

2022-06-28 Thread Martin Pieuchot
On 28/06/22(Tue) 18:17, Jeremie Courreges-Anglas wrote:
> 
> Initially I just wandered in syscall_mi.h and found the locking scheme
> super weird, even if technically correct.  pledge_syscall() better be
> safe to call without the kernel lock so I don't understand why we're
> sometimes calling it with the kernel lock and sometimes not.
> 
> ps_pledge is 64 bits so it's not possible to unset bits in an atomic
> manner on all architectures.  Even if we're only removing bits and there
> is probably no way to see a completely garbage value, it makes sense to
> just protect ps_pledge (and ps_execpledge) in the usual manner so that
> we can unlock the syscall.  The diff below protects the fields using
> ps_mtx even though I initially used a dedicated ps_pledge_mtx.
> unveil_destroy() needs to be moved after the critical section.
> regress/sys/kern/pledge looks happy with this.  The sys/syscall_mi.h
> change can be committed in a separate step.
> 
> Input and oks welcome.

This looks nice.  I doubt there's any existing program where you can
really test this.  Even firefox and chromium should do things
correctly.

Maybe you should write a regress test that tries to break the kernel.

> Index: arch/amd64/amd64/vmm.c
> ===
> RCS file: /home/cvs/src/sys/arch/amd64/amd64/vmm.c,v
> retrieving revision 1.315
> diff -u -p -r1.315 vmm.c
> --- arch/amd64/amd64/vmm.c27 Jun 2022 15:12:14 -  1.315
> +++ arch/amd64/amd64/vmm.c28 Jun 2022 13:54:25 -
> @@ -713,7 +713,7 @@ pledge_ioctl_vmm(struct proc *p, long co
>   case VMM_IOC_CREATE:
>   case VMM_IOC_INFO:
>   /* The "parent" process in vmd forks and manages VMs */
> - if (p->p_p->ps_pledge & PLEDGE_PROC)
> + if (pledge_get(p->p_p) & PLEDGE_PROC)
>   return (0);
>   break;
>   case VMM_IOC_TERM:
> @@ -1312,7 +1312,7 @@ vm_find(uint32_t id, struct vm **res)
>* The managing vmm parent process can lookup all
>* all VMs and is indicated by PLEDGE_PROC.
>*/
> - if (((p->p_p->ps_pledge &
> + if (((pledge_get(p->p_p) &
>   (PLEDGE_VMM | PLEDGE_PROC)) == PLEDGE_VMM) &&
>   (vm->vm_creator_pid != p->p_p->ps_pid))
>   return (pledge_fail(p, EPERM, PLEDGE_VMM));
> Index: kern/init_sysent.c
> ===
> RCS file: /home/cvs/src/sys/kern/init_sysent.c,v
> retrieving revision 1.238
> diff -u -p -r1.238 init_sysent.c
> --- kern/init_sysent.c27 Jun 2022 14:26:05 -  1.238
> +++ kern/init_sysent.c28 Jun 2022 15:18:25 -
> @@ -1,10 +1,10 @@
> -/*   $OpenBSD: init_sysent.c,v 1.238 2022/06/27 14:26:05 cheloha Exp $   
> */
> +/*   $OpenBSD$   */
>  
>  /*
>   * System call switch table.
>   *
>   * DO NOT EDIT-- this file is automatically generated.
> - * created from; OpenBSD: syscalls.master,v 1.224 2022/05/16 07:36:04 
> mvs Exp 
> + * created from; OpenBSD: syscalls.master,v 1.225 2022/06/27 14:26:05 
> cheloha Exp 
>   */
>  
>  #include 
> @@ -248,7 +248,7 @@ const struct sysent sysent[] = {
>   sys_listen },   /* 106 = listen */
>   { 4, s(struct sys_chflagsat_args), 0,
>   sys_chflagsat },/* 107 = chflagsat */
> - { 2, s(struct sys_pledge_args), 0,
> + { 2, s(struct sys_pledge_args), SY_NOLOCK | 0,
>   sys_pledge },   /* 108 = pledge */
>   { 4, s(struct sys_ppoll_args), 0,
>   sys_ppoll },/* 109 = ppoll */
> Index: kern/kern_event.c
> ===
> RCS file: /home/cvs/src/sys/kern/kern_event.c,v
> retrieving revision 1.191
> diff -u -p -r1.191 kern_event.c
> --- kern/kern_event.c 27 Jun 2022 13:35:21 -  1.191
> +++ kern/kern_event.c 28 Jun 2022 13:55:18 -
> @@ -331,7 +331,7 @@ filt_procattach(struct knote *kn)
>   int s;
>  
>   if ((curproc->p_p->ps_flags & PS_PLEDGE) &&
> - (curproc->p_p->ps_pledge & PLEDGE_PROC) == 0)
> + (pledge_get(curproc->p_p) & PLEDGE_PROC) == 0)
>   return pledge_fail(curproc, EPERM, PLEDGE_PROC);
>  
>   if (kn->kn_id > PID_MAX)
> Index: kern/kern_pledge.c
> ===
> RCS file: /home/cvs/src/sys/kern/kern_pledge.c,v
> retrieving revision 1.282
> diff -u -p -r1.282 kern_pledge.c
> --- kern/kern_pledge.c26 Jun 2022 06:11:49 -  1.282
> +++ kern/kern_pledge.c28 Jun 2022 15:21:46 -
> @@ -21,6 +21,7 @@
>  
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -465,13 +466,26 @@ sys_pledge(struct proc *p, void *v, regi
>   struct process *pr = p->p_p;
>   uint64_t p

Re: pipex(4): use per-session `pxs_mtx' mutex(9) for protection

2022-06-28 Thread Vitaliy Makkoveev
The updated diff. It was triggered by Hrvoje Popovski, we could do
direct (*if_qstart)() call in pipex(4) PPPOE input path, and this
provides deadlock. The updated diff uses ip{,6}_send() instead of
ipv{4,6}_input().

r420-1# witness: acquiring duplicate lock of same type: "&session->pxs_mtx"
 1st &session->pxs_mtx
 2nd &session->pxs_mtx
Starting stack trace...
witness_checkorder(80002275f478,9,0) at witness_checkorder+0x8ac
mtx_enter(80002275f468) at mtx_enter+0x34
pipex_ip_output(fd80cccfb900,80002275f3a0) at pipex_ip_output+0x3a
pppac_qstart(80ff2ab0) at pppac_qstart+0x67
ifq_serialize(80ff2ab0,80ff2bd0) at ifq_serialize+0xfd
if_enqueue_ifq(80ff2800,fd80c6b9f000) at if_enqueue_ifq+0x6b
ip_output(fd80c6b9f000,0,8000226a5788,1,0,0,c9790ec822d038fa) at
ip_output+0x8ee
ip_forward(fd80c6b9f000,80ff2800,fd85711c1238,0) at
ip_forward+0x2da
ip_input_if(8000226a58c8,8000226a58d4,4,0,80ff2800) at
ip_input_if+0x353
ipv4_input(80ff2800,fd80c6b9f000) at ipv4_input+0x39
pipex_ip_input(fd80c6b9f000,80002275e000) at pipex_ip_input+0x207
pipex_ppp_input(fd80c6b9f000,80002275e000,0) at
pipex_ppp_input+0x1f2
pipex_common_input(80002275e000,fd80c6b9f000,14,36) at
pipex_common_input+0x1ed
pipex_pppoe_input(fd80c6b9f000,80002275e000) at
pipex_pppoe_input+0x6a
ether_input(800a5048,fd80c6b9f000) at ether_input+0x2f8
if_input_process(800a5048,8000226a5b38) at if_input_process+0x6f
ifiq_process(800a5498) at ifiq_process+0x69
taskq_thread(80031000) at taskq_thread+0x11a
end trace frame: 0x0, count: 239
End of stack trace.
panic: mtx 0x80002275e0c8: locking against myself
Stopped at  db_enter+0x10:  popq%rbp
TIDPIDUID PRFLAGS PFLAGS  CPU  COMMAND
 145021  16649 73   0x1100010  03K syslogd
* 98910  86015  0 0x14000  0x2002  softnet


Index: sys/net/if_pppx.c
===
RCS file: /cvs/src/sys/net/if_pppx.c,v
retrieving revision 1.117
diff -u -p -r1.117 if_pppx.c
--- sys/net/if_pppx.c   26 Jun 2022 22:51:58 -  1.117
+++ sys/net/if_pppx.c   28 Jun 2022 17:53:23 -
@@ -659,8 +659,6 @@ pppx_add_session(struct pppx_dev *pxd, s
ifp->if_softc = pxi;
/* ifp->if_rdomain = req->pr_rdomain; */
if_counters_alloc(ifp);
-   /* XXXSMP: be sure pppx_if_qstart() called with NET_LOCK held */
-   ifq_set_maxlen(&ifp->if_snd, 1);
 
/* XXXSMP breaks atomicity */
NET_UNLOCK();
@@ -801,13 +799,16 @@ pppx_if_qstart(struct ifqueue *ifq)
struct mbuf *m;
int proto;
 
-   NET_ASSERT_LOCKED();
+   mtx_enter(&pxi->pxi_session->pxs_mtx);
+
while ((m = ifq_dequeue(ifq)) != NULL) {
proto = *mtod(m, int *);
m_adj(m, sizeof(proto));
 
pipex_ppp_output(m, pxi->pxi_session, proto);
}
+
+   mtx_leave(&pxi->pxi_session->pxs_mtx);
 }
 
 int
@@ -1044,8 +1045,6 @@ pppacopen(dev_t dev, int flags, int mode
ifp->if_output = pppac_output;
ifp->if_qstart = pppac_qstart;
ifp->if_ioctl = pppac_ioctl;
-   /* XXXSMP: be sure pppac_qstart() called with NET_LOCK held */
-   ifq_set_maxlen(&ifp->if_snd, 1);
 
if_counters_alloc(ifp);
if_attach(ifp);
@@ -1441,7 +1440,6 @@ pppac_qstart(struct ifqueue *ifq)
struct ip ip;
int rv;
 
-   NET_ASSERT_LOCKED();
while ((m = ifq_dequeue(ifq)) != NULL) {
 #if NBPFILTER > 0
if (ifp->if_bpf) {
Index: sys/net/pipex.c
===
RCS file: /cvs/src/sys/net/pipex.c,v
retrieving revision 1.142
diff -u -p -r1.142 pipex.c
--- sys/net/pipex.c 28 Jun 2022 08:01:40 -  1.142
+++ sys/net/pipex.c 28 Jun 2022 17:53:23 -
@@ -91,7 +91,6 @@ struct pool mppe_key_pool;
  * Locks used to protect global data
  *   A   atomic operation
  *   I   immutable after creation
- *   N   net lock
  *   L   pipex_list_mtx
  */
 
@@ -172,7 +171,6 @@ pipex_ioctl(void *ownersc, u_long cmd, c
 {
int ret = 0;
 
-   NET_ASSERT_LOCKED();
switch (cmd) {
case PIPEXCSESSION:
ret = pipex_config_session(
@@ -575,18 +573,20 @@ pipex_config_session(struct pipex_sessio
struct pipex_session *session;
int error = 0;
 
-   NET_ASSERT_LOCKED();
-
session = pipex_lookup_by_session_id(req->pcr_protocol,
req->pcr_session_id);
if (session == NULL)
return (EINVAL);
 
if (session->ownersc == ownersc) {
+   mtx_enter(&session->pxs_mtx);
+
if (req->pcr_ip_forward != 0)
session->flags |= PIPEX_SFLAGS_IP_FORWARD;
else
session->flags &= ~PIPEX_SFLAGS_IP_FORWARD;
+
+

Unlocking pledge(2)

2022-06-28 Thread Jeremie Courreges-Anglas


Initially I just wandered in syscall_mi.h and found the locking scheme
super weird, even if technically correct.  pledge_syscall() better be
safe to call without the kernel lock so I don't understand why we're
sometimes calling it with the kernel lock and sometimes not.

ps_pledge is 64 bits so it's not possible to unset bits in an atomic
manner on all architectures.  Even if we're only removing bits and there
is probably no way to see a completely garbage value, it makes sense to
just protect ps_pledge (and ps_execpledge) in the usual manner so that
we can unlock the syscall.  The diff below protects the fields using
ps_mtx even though I initially used a dedicated ps_pledge_mtx.
unveil_destroy() needs to be moved after the critical section.
regress/sys/kern/pledge looks happy with this.  The sys/syscall_mi.h
change can be committed in a separate step.

Input and oks welcome.



Index: arch/amd64/amd64/vmm.c
===
RCS file: /home/cvs/src/sys/arch/amd64/amd64/vmm.c,v
retrieving revision 1.315
diff -u -p -r1.315 vmm.c
--- arch/amd64/amd64/vmm.c  27 Jun 2022 15:12:14 -  1.315
+++ arch/amd64/amd64/vmm.c  28 Jun 2022 13:54:25 -
@@ -713,7 +713,7 @@ pledge_ioctl_vmm(struct proc *p, long co
case VMM_IOC_CREATE:
case VMM_IOC_INFO:
/* The "parent" process in vmd forks and manages VMs */
-   if (p->p_p->ps_pledge & PLEDGE_PROC)
+   if (pledge_get(p->p_p) & PLEDGE_PROC)
return (0);
break;
case VMM_IOC_TERM:
@@ -1312,7 +1312,7 @@ vm_find(uint32_t id, struct vm **res)
 * The managing vmm parent process can lookup all
 * all VMs and is indicated by PLEDGE_PROC.
 */
-   if (((p->p_p->ps_pledge &
+   if (((pledge_get(p->p_p) &
(PLEDGE_VMM | PLEDGE_PROC)) == PLEDGE_VMM) &&
(vm->vm_creator_pid != p->p_p->ps_pid))
return (pledge_fail(p, EPERM, PLEDGE_VMM));
Index: kern/init_sysent.c
===
RCS file: /home/cvs/src/sys/kern/init_sysent.c,v
retrieving revision 1.238
diff -u -p -r1.238 init_sysent.c
--- kern/init_sysent.c  27 Jun 2022 14:26:05 -  1.238
+++ kern/init_sysent.c  28 Jun 2022 15:18:25 -
@@ -1,10 +1,10 @@
-/* $OpenBSD: init_sysent.c,v 1.238 2022/06/27 14:26:05 cheloha Exp $   
*/
+/* $OpenBSD$   */
 
 /*
  * System call switch table.
  *
  * DO NOT EDIT-- this file is automatically generated.
- * created from;   OpenBSD: syscalls.master,v 1.224 2022/05/16 07:36:04 
mvs Exp 
+ * created from;   OpenBSD: syscalls.master,v 1.225 2022/06/27 14:26:05 
cheloha Exp 
  */
 
 #include 
@@ -248,7 +248,7 @@ const struct sysent sysent[] = {
sys_listen },   /* 106 = listen */
{ 4, s(struct sys_chflagsat_args), 0,
sys_chflagsat },/* 107 = chflagsat */
-   { 2, s(struct sys_pledge_args), 0,
+   { 2, s(struct sys_pledge_args), SY_NOLOCK | 0,
sys_pledge },   /* 108 = pledge */
{ 4, s(struct sys_ppoll_args), 0,
sys_ppoll },/* 109 = ppoll */
Index: kern/kern_event.c
===
RCS file: /home/cvs/src/sys/kern/kern_event.c,v
retrieving revision 1.191
diff -u -p -r1.191 kern_event.c
--- kern/kern_event.c   27 Jun 2022 13:35:21 -  1.191
+++ kern/kern_event.c   28 Jun 2022 13:55:18 -
@@ -331,7 +331,7 @@ filt_procattach(struct knote *kn)
int s;
 
if ((curproc->p_p->ps_flags & PS_PLEDGE) &&
-   (curproc->p_p->ps_pledge & PLEDGE_PROC) == 0)
+   (pledge_get(curproc->p_p) & PLEDGE_PROC) == 0)
return pledge_fail(curproc, EPERM, PLEDGE_PROC);
 
if (kn->kn_id > PID_MAX)
Index: kern/kern_pledge.c
===
RCS file: /home/cvs/src/sys/kern/kern_pledge.c,v
retrieving revision 1.282
diff -u -p -r1.282 kern_pledge.c
--- kern/kern_pledge.c  26 Jun 2022 06:11:49 -  1.282
+++ kern/kern_pledge.c  28 Jun 2022 15:21:46 -
@@ -21,6 +21,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -465,13 +466,26 @@ sys_pledge(struct proc *p, void *v, regi
struct process *pr = p->p_p;
uint64_t promises, execpromises;
int error;
+   int unveil_cleanup = 0;
 
+   /* Check for any error in user input */
if (SCARG(uap, promises)) {
error = parsepledges(p, "pledgereq",
SCARG(uap, promises), &promises);
if (error)
return (error);
+   }
+   if (SCARG(uap, execpromises)) {
+   error = parsepledges(p, "pl

Re: Fix the swapper

2022-06-28 Thread Martin Pieuchot
On 27/06/22(Mon) 15:44, Martin Pieuchot wrote:
> Diff below contain 3 parts that can be committed independently.  The 3
> of them are necessary to allow the pagedaemon to make progress in OOM
> situation and to satisfy all the allocations waiting for pages in
> specific ranges.
> 
> * uvm/uvm_pager.c part reserves a second segment for the page daemon.
>   This is necessary to ensure the two uvm_pagermapin() calls needed by
>   uvm_swap_io() succeed in emergency OOM situation.  (the 2nd segment is
>   necessary when encryption or bouncing is required)
> 
> * uvm/uvm_swap.c part pre-allocates 16 pages in the DMA-reachable region
>   for the same reason.  Note that a sleeping point is introduced because
>   the pagedaemon is faster than the asynchronous I/O and in OOM
>   situation it tends to stay busy building cluster that it then discard
>   because no memory is available.
> 
> * uvm/uvm_pdaemon.c part changes the inner-loop scanning the inactive 
>   list of pages to account for a given memory range.  Without this the
>   daemon could spin infinitely doing nothing because the global limits
>   are reached.

Here's an updated diff with a fix on top:

 * in uvm/uvm_swap.c make sure uvm_swap_allocpages() is allowed to sleep
   when coming from uvm_fault().  This makes the faulting process wait
   instead of dying when there isn't any free pages to do the bouncing.

I'd appreciate more reviews and tests !

Index: uvm/uvm_pager.c
===
RCS file: /cvs/src/sys/uvm/uvm_pager.c,v
retrieving revision 1.80
diff -u -p -r1.80 uvm_pager.c
--- uvm/uvm_pager.c 28 Jun 2022 12:10:37 -  1.80
+++ uvm/uvm_pager.c 28 Jun 2022 15:25:30 -
@@ -58,8 +58,8 @@ const struct uvm_pagerops *uvmpagerops[]
  * The number of uvm_pseg instances is dynamic using an array segs.
  * At most UVM_PSEG_COUNT instances can exist.
  *
- * psegs[0] always exists (so that the pager can always map in pages).
- * psegs[0] element 0 is always reserved for the pagedaemon.
+ * psegs[0/1] always exist (so that the pager can always map in pages).
+ * psegs[0/1] element 0 are always reserved for the pagedaemon.
  *
  * Any other pseg is automatically created when no space is available
  * and automatically destroyed when it is no longer in use.
@@ -93,6 +93,7 @@ uvm_pager_init(void)
 
/* init pager map */
uvm_pseg_init(&psegs[0]);
+   uvm_pseg_init(&psegs[1]);
mtx_init(&uvm_pseg_lck, IPL_VM);
 
/* init ASYNC I/O queue */
@@ -168,9 +169,10 @@ pager_seg_restart:
goto pager_seg_fail;
}
 
-   /* Keep index 0 reserved for pagedaemon. */
-   if (pseg == &psegs[0] && curproc != uvm.pagedaemon_proc)
-   i = 1;
+   /* Keep indexes 0,1 reserved for pagedaemon. */
+   if ((pseg == &psegs[0] || pseg == &psegs[1]) &&
+   (curproc != uvm.pagedaemon_proc))
+   i = 2;
else
i = 0;
 
@@ -229,7 +231,7 @@ uvm_pseg_release(vaddr_t segaddr)
pseg->use &= ~(1 << id);
wakeup(&psegs);
 
-   if (pseg != &psegs[0] && UVM_PSEG_EMPTY(pseg)) {
+   if ((pseg != &psegs[0] && pseg != &psegs[1]) && UVM_PSEG_EMPTY(pseg)) {
va = pseg->start;
pseg->start = 0;
}
Index: uvm/uvm_pdaemon.c
===
RCS file: /cvs/src/sys/uvm/uvm_pdaemon.c,v
retrieving revision 1.99
diff -u -p -r1.99 uvm_pdaemon.c
--- uvm/uvm_pdaemon.c   12 May 2022 12:49:31 -  1.99
+++ uvm/uvm_pdaemon.c   28 Jun 2022 13:59:49 -
@@ -101,8 +101,8 @@ extern void drmbackoff(long);
  * local prototypes
  */
 
-void   uvmpd_scan(void);
-boolean_t  uvmpd_scan_inactive(struct pglist *);
+void   uvmpd_scan(struct uvm_pmalloc *);
+boolean_t  uvmpd_scan_inactive(struct uvm_pmalloc *, struct pglist *);
 void   uvmpd_tune(void);
 void   uvmpd_drop(struct pglist *);
 
@@ -281,7 +281,7 @@ uvm_pageout(void *arg)
if (pma != NULL ||
((uvmexp.free - BUFPAGES_DEFICIT) < uvmexp.freetarg) ||
((uvmexp.inactive + BUFPAGES_INACT) < uvmexp.inactarg)) {
-   uvmpd_scan();
+   uvmpd_scan(pma);
}
 
/*
@@ -379,15 +379,15 @@ uvm_aiodone_daemon(void *arg)
  */
 
 boolean_t
-uvmpd_scan_inactive(struct pglist *pglst)
+uvmpd_scan_inactive(struct uvm_pmalloc *pma, struct pglist *pglst)
 {
boolean_t retval = FALSE;   /* assume we haven't hit target */
int free, result;
struct vm_page *p, *nextpg;
struct uvm_object *uobj;
-   struct vm_page *pps[MAXBSIZE >> PAGE_SHIFT], **ppsp;
+   struct vm_page *pps[SWCLUSTPAGES], **ppsp;
int npages;
-   struct vm_page *swpps[MAXBSIZE >> PAGE_SHIFT];  /* XXX: see below */
+  

bgplgd - a JSON frontend to bgpd

2022-06-28 Thread Claudio Jeker
This is bgplgd that can be used to provide a JSON REST API for bgpd.
It can be used to integrate bgpd into external looking glasses.
The bgplgd uses a modified version of slowcgi. It forks bgpctl per request
and returns the output via the slowcgi socket.

Securing the API needs to be done in the http server that is handling the
fcgi requests.

-- 
:wq Claudio

Index: Makefile
===
RCS file: Makefile
diff -N Makefile
--- /dev/null   1 Jan 1970 00:00:00 -
+++ Makefile1 Mar 2022 17:00:06 -
@@ -0,0 +1,14 @@
+#  $OpenBSD: Makefile,v 1.2 2014/12/23 19:32:16 pascal Exp $
+
+PROG=  bgplgd
+SRCS=  bgplgd.c slowcgi.c qs.c
+CFLAGS+=   -Wall
+CFLAGS+=   -Wstrict-prototypes -Wmissing-prototypes
+CLFAGS+=   -Wmissing-declarations -Wredundant-decls
+CFLAGS+=   -Wshadow -Wpointer-arith -Wcast-qual
+CFLAGS+=   -Wsign-compare
+LDADD=  -levent
+DPADD=  ${LIBEVENT}
+MAN=   bgplgd.8
+
+.include 
Index: bgplgd.8
===
RCS file: bgplgd.8
diff -N bgplgd.8
--- /dev/null   1 Jan 1970 00:00:00 -
+++ bgplgd.828 Jun 2022 14:43:39 -
@@ -0,0 +1,179 @@
+.\" $OpenBSD$
+.\"
+.\" Copyright (c) 2021 Claudio Jeker 
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd $Mdocdate$
+.Dt BGPLGD 8
+.Os
+.Sh NAME
+.Nm bgplgd
+.Nd a bgpctl FastCGI server
+.Sh SYNOPSIS
+.Nm
+.Op Fl d
+.Op Fl p Ar path
+.Op Fl S Ar socket
+.Op Fl s Ar socket
+.Op Fl U Ar user
+.Op Fl u Ar user
+.Sh DESCRIPTION
+.Nm
+is a server which implements the FastCGI Protocol to execute
+.Xr bgpctl 8
+commands.
+.Nm
+is a simple server that implements a simple web API to query
+.Xr bgpd 8 .
+.Pp
+.Nm
+opens a socket at
+.Pa /var/www/run/bgplgd.sock ,
+owned by www:www,
+with permissions 0660.
+It will then
+and drop privileges to user
+.Qq www ,
+.Xr unveil 2
+the
+.Xr bgpctl 8
+binary
+and restrict itself with
+.Xr pledge 2 .
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl d
+Do not daemonize.
+If this option is specified,
+.Nm
+will run in the foreground and log to stderr.
+.It Fl p Ar path
+Use
+.Ar path
+instead of
+.Xr bgpctl 8
+to query
+.Xr bgpd 8 .
+.It Fl S Ar socket
+Use
+.Ar socket
+instead of the default
+.Pa /var/run/bgpd.rsock
+to communicate with
+.Xr bgpd 8 .
+.It Fl s Ar socket
+Create and bind to alternative local socket at
+.Ar socket .
+.It Fl U Ar user
+Change the owner of
+.Pa /var/www/run/bgplgd.sock
+to
+.Ar user
+and its primary group instead of the default www:www.
+.El
+.Pp
+.Nm
+provides the following API endpoints.
+Unless further specified the endpoints do not take any parameters:
+.Bl -tag -width Ds
+.It Pa /interfaces
+Show the interface states.
+.It Pa /memory
+Show RIB memory statistics.
+.It Pa /neighbors
+Show detailed neighbors information.
+The output can be limited with the following parameters:
+.Pp
+.Bl -tag -width "neighbor=peer" -compact
+.It Cm neighbor Ns = Ns Ar peer
+Show infromation for a specific neighbor.
+.Ar peer
+may be the neighbor's address or description.
+.It Cm group Ns = Ns Ar name
+Show only entries from the specified peer group.
+.El
+.It Pa /nexthops
+Show the list of BGP nexthops and the result of their validity check.
+.It Pa /rib
+Show routes from the bgpd(8) Routing Information Base.
+The following parameters can be used to filter the output:
+.Pp
+.Bl -tag -width "neighbor=peer" -compact
+.It Cm neighbor Ns = Ns Ar peer
+Show infromation for a specific neighbor.
+.Ar peer
+may be the neighbor's address or description.
+.It Cm group Ns = Ns Ar name
+Show only entries from the specified peer group.
+.It Cm as Ns = Ns Ar number
+Show only entries with the specified source AS number.
+.It Cm community Ns = Ns Ar string
+.It Cm ext-community Ns = Ns Ar string
+.It Cm large-community Ns = Ns Ar string
+Show only entries that match the specified community.
+.It Xo
+.Ic af Ns = Ns
+.Pq Ic ipv4 | ipv6 | vpnv4 | vpnv6
+.Xc
+Show only entries that match the specified address family.
+.It Cm rib Ns = Ns Ar name
+Show only entries from the RIB with name
+.Ar name .
+.It Xo
+.Ic ovs Ns = Ns
+.Pq Ic valid | not-found | invalid
+.Xc
+Show only prefixes that match the specified Origin Validation State.
+.It Cm best Ns = Ns 1
+S

pipex(4): use per-session `pxs_mtx' mutex(9) for protection

2022-06-28 Thread Vitaliy Makkoveev
We can't predict netlock state when we executing pipex(4) related
(*if_qstart)() handlers, so we can't use netlock for pipex(4)
protection.

We already use `pipex_list_mtx' for global pipex(4) data, so

Use per-session `pxs_mtx' mutex(9) for pipex session context protection.
We already use `pipex_list_mtx' for global pipex(4) data, so now netlock
protects nothing in the pipex(4) layer.

Please note, the MPPE related `pxm_mtx' mutex(9) looks unnecessary,
because we always lock it when `pxs_mtx' is locked. I want to keep it as
is until we decide, what to do with PIPEX_SFLAGS_IP_FORWARD flag in the
pipex(4) output paths. If we decide to not check it, the current
per-session locking could be more fine grained.

Also pppx(4) layer still uses netlock for protection. This made sense
when netlock was used to protect pipex(4) layer, but now it should be
removed from here. This will be done with the next diffs.

Hrvoje, could you test this diff please?

Index: sys/net/if_pppx.c
===
RCS file: /cvs/src/sys/net/if_pppx.c,v
retrieving revision 1.117
diff -u -p -r1.117 if_pppx.c
--- sys/net/if_pppx.c   26 Jun 2022 22:51:58 -  1.117
+++ sys/net/if_pppx.c   28 Jun 2022 13:47:09 -
@@ -659,8 +659,6 @@ pppx_add_session(struct pppx_dev *pxd, s
ifp->if_softc = pxi;
/* ifp->if_rdomain = req->pr_rdomain; */
if_counters_alloc(ifp);
-   /* XXXSMP: be sure pppx_if_qstart() called with NET_LOCK held */
-   ifq_set_maxlen(&ifp->if_snd, 1);
 
/* XXXSMP breaks atomicity */
NET_UNLOCK();
@@ -801,13 +799,16 @@ pppx_if_qstart(struct ifqueue *ifq)
struct mbuf *m;
int proto;
 
-   NET_ASSERT_LOCKED();
+   mtx_enter(&pxi->pxi_session->pxs_mtx);
+
while ((m = ifq_dequeue(ifq)) != NULL) {
proto = *mtod(m, int *);
m_adj(m, sizeof(proto));
 
pipex_ppp_output(m, pxi->pxi_session, proto);
}
+
+   mtx_leave(&pxi->pxi_session->pxs_mtx);
 }
 
 int
@@ -1044,8 +1045,6 @@ pppacopen(dev_t dev, int flags, int mode
ifp->if_output = pppac_output;
ifp->if_qstart = pppac_qstart;
ifp->if_ioctl = pppac_ioctl;
-   /* XXXSMP: be sure pppac_qstart() called with NET_LOCK held */
-   ifq_set_maxlen(&ifp->if_snd, 1);
 
if_counters_alloc(ifp);
if_attach(ifp);
@@ -1441,7 +1440,6 @@ pppac_qstart(struct ifqueue *ifq)
struct ip ip;
int rv;
 
-   NET_ASSERT_LOCKED();
while ((m = ifq_dequeue(ifq)) != NULL) {
 #if NBPFILTER > 0
if (ifp->if_bpf) {
Index: sys/net/pipex.c
===
RCS file: /cvs/src/sys/net/pipex.c,v
retrieving revision 1.142
diff -u -p -r1.142 pipex.c
--- sys/net/pipex.c 28 Jun 2022 08:01:40 -  1.142
+++ sys/net/pipex.c 28 Jun 2022 13:47:09 -
@@ -91,7 +91,6 @@ struct pool mppe_key_pool;
  * Locks used to protect global data
  *   A   atomic operation
  *   I   immutable after creation
- *   N   net lock
  *   L   pipex_list_mtx
  */
 
@@ -172,7 +171,6 @@ pipex_ioctl(void *ownersc, u_long cmd, c
 {
int ret = 0;
 
-   NET_ASSERT_LOCKED();
switch (cmd) {
case PIPEXCSESSION:
ret = pipex_config_session(
@@ -575,18 +573,20 @@ pipex_config_session(struct pipex_sessio
struct pipex_session *session;
int error = 0;
 
-   NET_ASSERT_LOCKED();
-
session = pipex_lookup_by_session_id(req->pcr_protocol,
req->pcr_session_id);
if (session == NULL)
return (EINVAL);
 
if (session->ownersc == ownersc) {
+   mtx_enter(&session->pxs_mtx);
+
if (req->pcr_ip_forward != 0)
session->flags |= PIPEX_SFLAGS_IP_FORWARD;
else
session->flags &= ~PIPEX_SFLAGS_IP_FORWARD;
+
+   mtx_leave(&session->pxs_mtx);
} else
error = EINVAL;
 
@@ -601,8 +601,6 @@ pipex_get_stat(struct pipex_session_stat
struct pipex_session *session;
int error = 0;
 
-   NET_ASSERT_LOCKED();
-
session = pipex_lookup_by_session_id(req->psr_protocol,
req->psr_session_id);
if (session == NULL)
@@ -811,6 +809,9 @@ pipex_ip_output(struct mbuf *m0, struct 
/*
 * Multicast packet is a idle packet and it's not TCP.
 */
+
+   mtx_enter(&session->pxs_mtx);
+
if ((session->flags & (PIPEX_SFLAGS_IP_FORWARD |
PIPEX_SFLAGS_IP6_FORWARD)) == 0)
goto drop;
@@ -837,6 +838,8 @@ pipex_ip_output(struct mbuf *m0, struct 
}
 
pipex_ppp_output(m0, session, PPP_IP);
+
+   mtx_leave(&session->pxs_mtx);
} else {
struct pipex_session *session_tmp;
struc

Re: rewrite amd64 cache printing

2022-06-28 Thread Jonathan Gray
On Sat, Jun 25, 2022 at 04:21:54AM -0700, Mike Larkin wrote:
> On Fri, Jun 24, 2022 at 07:19:47PM +1000, Jonathan Gray wrote:
> > +void
> > +amd_cpu_cacheinfo(struct cpu_info *ci)
> > +{
> > +   u_int eax, ebx, ecx, edx;
> > +
> > +   /* used by vmm */
> > +
> 
> If this is the only user of these fields, we can just have vmm(4) issue CPUID 
> on
> each guest CPUID for these features. I think I was just trying to save some
> cycles.
> 
> I'll send out a diff to remove these fields unless you want to tackle it.

sounds good to me

> 
> The diff here is ok mlarkin in any case.

thanks, committed

> 
> 
> > +   if (ci->ci_pnfeatset >= 0x8005) {
> > +   CPUID(0x8005, eax, ebx, ecx, edx);
> > +   ci->ci_amdcacheinfo[0] = eax;
> > +   ci->ci_amdcacheinfo[1] = ebx;
> > +   ci->ci_amdcacheinfo[2] = ecx;
> > +   ci->ci_amdcacheinfo[3] = edx;
> > +   }
> > +
> > +   if (ci->ci_pnfeatset >= 0x8006) {
> > +   CPUID(0x8006, eax, ebx, ecx, edx);
> > +   ci->ci_extcacheinfo[0] = eax;
> > +   ci->ci_extcacheinfo[1] = ebx;
> > +   ci->ci_extcacheinfo[2] = ecx;
> > +   ci->ci_extcacheinfo[3] = edx;
> > +   }
> > +}



Introduce uvm_pagewait()

2022-06-28 Thread Martin Pieuchot
I'd like to abstract the use of PG_WANTED to start unifying & cleaning
the various cases where a code path is waiting for a busy page.  Here's
the first step.

ok?

Index: uvm/uvm_amap.c
===
RCS file: /cvs/src/sys/uvm/uvm_amap.c,v
retrieving revision 1.90
diff -u -p -r1.90 uvm_amap.c
--- uvm/uvm_amap.c  30 Aug 2021 16:59:17 -  1.90
+++ uvm/uvm_amap.c  28 Jun 2022 11:53:08 -
@@ -781,9 +781,7 @@ ReStart:
 * it and then restart.
 */
if (pg->pg_flags & PG_BUSY) {
-   atomic_setbits_int(&pg->pg_flags, PG_WANTED);
-   rwsleep_nsec(pg, amap->am_lock, PVM | PNORELOCK,
-   "cownow", INFSLP);
+   uvm_pagewait(pg, amap->am_lock, "cownow");
goto ReStart;
}
 
Index: uvm/uvm_aobj.c
===
RCS file: /cvs/src/sys/uvm/uvm_aobj.c,v
retrieving revision 1.103
diff -u -p -r1.103 uvm_aobj.c
--- uvm/uvm_aobj.c  29 Dec 2021 20:22:06 -  1.103
+++ uvm/uvm_aobj.c  28 Jun 2022 11:53:08 -
@@ -835,9 +835,8 @@ uao_detach(struct uvm_object *uobj)
while ((pg = RBT_ROOT(uvm_objtree, &uobj->memt)) != NULL) {
pmap_page_protect(pg, PROT_NONE);
if (pg->pg_flags & PG_BUSY) {
-   atomic_setbits_int(&pg->pg_flags, PG_WANTED);
-   rwsleep_nsec(pg, uobj->vmobjlock, PVM, "uao_det",
-   INFSLP);
+   uvm_pagewait(pg, uobj->vmobjlock, "uao_det");
+   rw_enter(uobj->vmobjlock, RW_WRITE);
continue;
}
uao_dropswap(&aobj->u_obj, pg->offset >> PAGE_SHIFT);
@@ -909,9 +908,8 @@ uao_flush(struct uvm_object *uobj, voff_
 
/* Make sure page is unbusy, else wait for it. */
if (pg->pg_flags & PG_BUSY) {
-   atomic_setbits_int(&pg->pg_flags, PG_WANTED);
-   rwsleep_nsec(pg, uobj->vmobjlock, PVM, "uaoflsh",
-   INFSLP);
+   uvm_pagewait(pg, uobj->vmobjlock, "uaoflsh");
+   rw_enter(uobj->vmobjlock, RW_WRITE);
curoff -= PAGE_SIZE;
continue;
}
@@ -1147,9 +1145,8 @@ uao_get(struct uvm_object *uobj, voff_t 
 
/* page is there, see if we need to wait on it */
if ((ptmp->pg_flags & PG_BUSY) != 0) {
-   atomic_setbits_int(&ptmp->pg_flags, PG_WANTED);
-   rwsleep_nsec(ptmp, uobj->vmobjlock, PVM,
-   "uao_get", INFSLP);
+   uvm_pagewait(ptmp, uobj->vmobjlock, "uao_get");
+   rw_enter(uobj->vmobjlock, RW_WRITE);
continue;   /* goto top of pps while loop */
}
 
Index: uvm/uvm_km.c
===
RCS file: /cvs/src/sys/uvm/uvm_km.c,v
retrieving revision 1.150
diff -u -p -r1.150 uvm_km.c
--- uvm/uvm_km.c7 Jun 2022 12:07:45 -   1.150
+++ uvm/uvm_km.c28 Jun 2022 11:53:08 -
@@ -255,9 +255,8 @@ uvm_km_pgremove(struct uvm_object *uobj,
for (curoff = start ; curoff < end ; curoff += PAGE_SIZE) {
pp = uvm_pagelookup(uobj, curoff);
if (pp && pp->pg_flags & PG_BUSY) {
-   atomic_setbits_int(&pp->pg_flags, PG_WANTED);
-   rwsleep_nsec(pp, uobj->vmobjlock, PVM, "km_pgrm",
-   INFSLP);
+   uvm_pagewait(pp, uobj->vmobjlock, "km_pgrm");
+   rw_enter(uobj->vmobjlock, RW_WRITE);
curoff -= PAGE_SIZE; /* loop back to us */
continue;
}
Index: uvm/uvm_page.c
===
RCS file: /cvs/src/sys/uvm/uvm_page.c,v
retrieving revision 1.166
diff -u -p -r1.166 uvm_page.c
--- uvm/uvm_page.c  12 May 2022 12:48:36 -  1.166
+++ uvm/uvm_page.c  28 Jun 2022 11:57:42 -
@@ -1087,6 +1087,23 @@ uvm_page_unbusy(struct vm_page **pgs, in
}
 }
 
+/*
+ * uvm_pagewait: wait for a busy page
+ *
+ * => page must be known PG_BUSY
+ * => object must be locked
+ * => object will be unlocked on return
+ */
+void
+uvm_pagewait(struct vm_page *pg, struct rwlock *lock, const char *wmesg)
+{
+   KASSERT(rw_lock_held(lock));
+   KASSERT((pg->pg_flags & PG_BUSY) != 0);
+
+   atomic_setbits_int(&pg->pg_flags, PG_WANTED);
+   rwsleep_nsec(pg, lock, PVM | PNORELOCK, wmesg, INFSLP);
+}
+
 #if defined(UVM_PAGE_TRKOW

install.sub: don't ask about vlan0 unless some other interface exists

2022-06-28 Thread Stuart Henderson
The current handling of network interfaces in the installer is rather
confusing when somebody has an unsupported network device - it offers
to configure vlan0, but there is no interface on which a vlan can run
anyway.

Available network interfaces are: vlan0.
Which network interface do you wish to configure? (or 'done') [vlan0] 

This changes to only ask the question if some other network interfaces
is found.

amd64 installer iso with this at https://junkpile.org/cd71-netconf-novlan0.iso

comments? ok?

Index: install.sub
===
RCS file: /cvs/src/distrib/miniroot/install.sub,v
retrieving revision 1.1201
diff -u -p -r1.1201 install.sub
--- install.sub 27 Jun 2022 13:48:38 -  1.1201
+++ install.sub 28 Jun 2022 11:37:06 -
@@ -1296,7 +1296,7 @@ ieee80211_config() {
 
 # Set up IPv4 and IPv6 interface configuration.
 configure_ifs() {
-   local _first _hn _if _name _p _vi
+   local _first _hn _if _name _p _vi _vn
 
# Always need lo0 configured.
ifconfig lo0 inet 127.0.0.1/8
@@ -1309,9 +1309,10 @@ configure_ifs() {
# minor for the next offered vlan interface.
_vi=$(get_ifs vlan | sed '$!d;s/^vlan//')
[[ -n $_vi ]] && ((_vi++))
+   [[ -n $(get_ifs) ]] && _vn="vlan${_vi:-0}"
 
ask_which "network interface" "do you wish to configure" \
-   "\$(get_ifs) vlan${_vi:-0}" \
+   "\$(get_ifs) $_vn" \
${_p:-'$( (get_ifs netboot; get_ifs) | sed q )'}
[[ $resp == done ]] && break
 



Re: do pppoe(4) input through netisr

2022-06-28 Thread Alexander Bluhm
On Tue, Jun 28, 2022 at 12:44:30PM +0300, Vitaliy Makkoveev wrote:
> ether_input() called with shared netlock, but pppoe(4) wants it to be
> exclusive. Do the pppoe(4) input within netisr handler with exclusive
> netlok held, and remove kernel lock hack from ether_input().
> 
> This is the step back, but it makes ether_input() path better then it
> is now.
> 
> ok?

OK bluhm@

> +#if NPPPOE > 0
> + if (n & (1 << NETISR_PPPOE)) {
> + pppoeintr();
> + }
>  #endif

You don't need the { }



Re: snmpd(8): Add blocklist feature

2022-06-28 Thread Martijn van Duren
On Tue, 2022-06-28 at 12:21 +0200, Martijn van Duren wrote:
> On Tue, 2022-06-28 at 10:21 +0200, Martijn van Duren wrote:
> > Back in 2020 florian@ added the filter-pf-addresses keyword.
> > Although useful, I always felt it was a bit too case-specific. The diff
> > below adds a new blocklist feature/backend, which takes hold of an
> > entire subtree, effectively removing it from the tree.
> > 
> > With this I've deprecated the filter-pf-address case and should
> > probably be removed somewhere after 7.4. The filter-routes case can't
> > be removed unfortunately, since its behaviour is not identical, and
> > instead adds filters to the routing socket, preventing updates being
> > pushed to snmpd(8).
> > 
> > Feedback/OK?
> > 
> > martijn@
> > 
> Also clean up after ourselves if appl_exception fails.
> 
*sigh* Missed a return.

Index: Makefile
===
RCS file: /cvs/src/usr.sbin/snmpd/Makefile,v
retrieving revision 1.18
diff -u -p -r1.18 Makefile
--- Makefile19 Jan 2022 11:00:56 -  1.18
+++ Makefile28 Jun 2022 10:32:40 -
@@ -3,6 +3,7 @@
 PROG=  snmpd
 MAN=   snmpd.8 snmpd.conf.5
 SRCS=  parse.y log.c snmpe.c application.c application_legacy.c \
+   application_blocklist.c \
mps.c trap.c mib.c smi.c kroute.c snmpd.c timer.c \
pf.c proc.c usm.c traphandler.c util.c
 
Index: application.c
===
RCS file: /cvs/src/usr.sbin/snmpd/application.c,v
retrieving revision 1.5
diff -u -p -r1.5 application.c
--- application.c   27 Jun 2022 10:31:17 -  1.5
+++ application.c   28 Jun 2022 10:32:40 -
@@ -148,6 +148,7 @@ RB_PROTOTYPE_STATIC(appl_requests, appl_
 void
 appl_init(void)
 {
+   appl_blocklist_init();
appl_legacy_init();
 }
 
Index: application.h
===
RCS file: /cvs/src/usr.sbin/snmpd/application.h,v
retrieving revision 1.1
diff -u -p -r1.1 application.h
--- application.h   19 Jan 2022 10:59:35 -  1.1
+++ application.h   28 Jun 2022 10:32:40 -
@@ -133,3 +133,6 @@ struct ber_element *appl_exception(enum 
 /* application_legacy.c */
 voidappl_legacy_init(void);
 voidappl_legacy_shutdown(void);
+
+/* application_blocklist.c */
+voidappl_blocklist_init(void);
Index: application_blocklist.c
===
RCS file: application_blocklist.c
diff -N application_blocklist.c
--- /dev/null   1 Jan 1970 00:00:00 -
+++ application_blocklist.c 28 Jun 2022 10:32:40 -
@@ -0,0 +1,134 @@
+/* $OpenBSD: application.c,v 1.5 2022/06/27 10:31:17 martijn Exp $ */
+
+/*
+ * Copyright (c) 2022 Martijn van Duren 
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include 
+#include 
+
+#include "application.h"
+#include "snmpd.h"
+
+struct appl_varbind *appl_blocklist_response(size_t);
+void appl_blocklist_get(struct appl_backend *, int32_t, int32_t, const char *,
+struct appl_varbind *);
+void appl_blocklist_getnext(struct appl_backend *, int32_t, int32_t,
+const char *, struct appl_varbind *);
+
+struct appl_backend_functions appl_blocklist_functions = {
+   .ab_get = appl_blocklist_get,
+   .ab_getnext = appl_blocklist_getnext,
+   .ab_getbulk = NULL,
+};
+
+struct appl_backend appl_blocklist = {
+   .ab_name = "blocklist",
+   .ab_cookie = NULL,
+   .ab_retries = 0,
+   .ab_fn = &appl_blocklist_functions
+};
+
+static struct appl_varbind *response = NULL;
+static size_t responsesz = 0;
+
+struct appl_varbind *
+appl_blocklist_response(size_t nvarbind)
+{
+   struct appl_varbind *tmp;
+   size_t i;
+
+   if (responsesz < nvarbind) {
+   if ((tmp = recallocarray(response, responsesz, nvarbind,
+   sizeof(*response))) == NULL) {
+   log_warn(NULL);
+   return NULL;
+   }
+   responsesz = nvarbind;
+   response = tmp;
+   }
+   for (i = 0; i < nvarbind; i++)
+   response[i].av_next = i + 1 == nvarbind ?
+   NULL : &(response[i + 1]);
+   return response;
+

Re: snmpd(8): Add blocklist feature

2022-06-28 Thread Martijn van Duren
On Tue, 2022-06-28 at 10:21 +0200, Martijn van Duren wrote:
> Back in 2020 florian@ added the filter-pf-addresses keyword.
> Although useful, I always felt it was a bit too case-specific. The diff
> below adds a new blocklist feature/backend, which takes hold of an
> entire subtree, effectively removing it from the tree.
> 
> With this I've deprecated the filter-pf-address case and should
> probably be removed somewhere after 7.4. The filter-routes case can't
> be removed unfortunately, since its behaviour is not identical, and
> instead adds filters to the routing socket, preventing updates being
> pushed to snmpd(8).
> 
> Feedback/OK?
> 
> martijn@
> 
Also clean up after ourselves if appl_exception fails.

Index: Makefile
===
RCS file: /cvs/src/usr.sbin/snmpd/Makefile,v
retrieving revision 1.18
diff -u -p -r1.18 Makefile
--- Makefile19 Jan 2022 11:00:56 -  1.18
+++ Makefile28 Jun 2022 10:20:23 -
@@ -3,6 +3,7 @@
 PROG=  snmpd
 MAN=   snmpd.8 snmpd.conf.5
 SRCS=  parse.y log.c snmpe.c application.c application_legacy.c \
+   application_blocklist.c \
mps.c trap.c mib.c smi.c kroute.c snmpd.c timer.c \
pf.c proc.c usm.c traphandler.c util.c
 
Index: application.c
===
RCS file: /cvs/src/usr.sbin/snmpd/application.c,v
retrieving revision 1.5
diff -u -p -r1.5 application.c
--- application.c   27 Jun 2022 10:31:17 -  1.5
+++ application.c   28 Jun 2022 10:20:23 -
@@ -148,6 +148,7 @@ RB_PROTOTYPE_STATIC(appl_requests, appl_
 void
 appl_init(void)
 {
+   appl_blocklist_init();
appl_legacy_init();
 }
 
Index: application.h
===
RCS file: /cvs/src/usr.sbin/snmpd/application.h,v
retrieving revision 1.1
diff -u -p -r1.1 application.h
--- application.h   19 Jan 2022 10:59:35 -  1.1
+++ application.h   28 Jun 2022 10:20:23 -
@@ -133,3 +133,6 @@ struct ber_element *appl_exception(enum 
 /* application_legacy.c */
 voidappl_legacy_init(void);
 voidappl_legacy_shutdown(void);
+
+/* application_blocklist.c */
+voidappl_blocklist_init(void);
Index: application_blocklist.c
===
RCS file: application_blocklist.c
diff -N application_blocklist.c
--- /dev/null   1 Jan 1970 00:00:00 -
+++ application_blocklist.c 28 Jun 2022 10:20:23 -
@@ -0,0 +1,132 @@
+/* $OpenBSD: application.c,v 1.5 2022/06/27 10:31:17 martijn Exp $ */
+
+/*
+ * Copyright (c) 2022 Martijn van Duren 
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include 
+#include 
+
+#include "application.h"
+#include "snmpd.h"
+
+struct appl_varbind *appl_blocklist_response(size_t);
+void appl_blocklist_get(struct appl_backend *, int32_t, int32_t, const char *,
+struct appl_varbind *);
+void appl_blocklist_getnext(struct appl_backend *, int32_t, int32_t,
+const char *, struct appl_varbind *);
+
+struct appl_backend_functions appl_blocklist_functions = {
+   .ab_get = appl_blocklist_get,
+   .ab_getnext = appl_blocklist_getnext,
+   .ab_getbulk = NULL,
+};
+
+struct appl_backend appl_blocklist = {
+   .ab_name = "blocklist",
+   .ab_cookie = NULL,
+   .ab_retries = 0,
+   .ab_fn = &appl_blocklist_functions
+};
+
+static struct appl_varbind *response = NULL;
+static size_t responsesz = 0;
+
+struct appl_varbind *
+appl_blocklist_response(size_t nvarbind)
+{
+   struct appl_varbind *tmp;
+   size_t i;
+
+   if (responsesz < nvarbind) {
+   if ((tmp = recallocarray(response, responsesz, nvarbind,
+   sizeof(*response))) == NULL) {
+   log_warn(NULL);
+   return NULL;
+   }
+   responsesz = nvarbind;
+   response = tmp;
+   }
+   for (i = 0; i < nvarbind; i++)
+   response[i].av_next = i + 1 == nvarbind ?
+   NULL : &(response[i + 1]);
+   return response;
+}
+
+void
+appl_blocklist_init(void)
+{
+   extern struct snmpd *snmpd_env;
+   size_t i;
+
+   for (i = 0; i

Re: arpintr without kernel lock

2022-06-28 Thread Alexander Bluhm
On Tue, Jun 28, 2022 at 10:51:29AM +0200, Alexander Bluhm wrote:
> arpintr() looks MP safe and I cannot trigger a crash with this diff.

Running parallel forwarding and arp -d in a loop triggers route
NULL pointer dereference after a while.  I have to figure out if
it is related to this diff.

bluhm

root@ot31:.../~# while :; do arp -nd 10.6.16.36 >/dev/null; done 
arp: delete: can't locate 10.6.16.36
arp: delete: can't locate 10.6.16.36
arp: delete: can't locate 10.6.16.36
arp: delete: can't locate 10.6.16.36
uvmp_afnaicu:lt  (0 x  f ff  f ff f  f 8 31  a 59 9  8 ,   0 x6  0,0,2 
)  -  >  e  
kkeerrnneell:pdagieag fnoasultict   t ra  p ,  c  o de  = 0 a
Stopped at  rtref+0x11: lock incl   0x60(%rdi)   s
TIDPIDUID PRFLAGS PFLAGS  CPU  COMMAND
 202508  43068  00x13  03  arp
  37126  11508 91   0x112  05  snmpd
 340135  94731  0 0x14000  0x2001  softnet
 230690  38637  0 0x14000  0x2002  softnet
  33711215  0 0x14000  0x2004  softnet
*104852  83709  0 0x14000  0x2006  softnet
rtref(0) at rtref+0x11
rtable_match(0,8000246b6e98,fd800b58e658) at rtable_match+0xb9
rtalloc_mpath(8000246b6e98,fd800b58e658,0) at rtalloc_mpath+0x2e
in_ouraddr(fd80b278d300,8077d048,8000246b6f18) at in_ouraddr+0x
84
ip_input_if(8000246b6fb8,8000246b6fc4,4,0,8077d048) at ip_input
_if+0x1cd
ipv4_input(8077d048,fd80b278d300) at ipv4_input+0x39
ether_input(8077d048,fd80b278d300) at ether_input+0x3ad
if_input_process(8077d048,8000246b70a8) at if_input_process+0x6f
ifiq_process(80781100) at ifiq_process+0x69
taskq_thread(80036080) at taskq_thread+0x100
end trace frame: 0x0, count: 5
https://www.openbsd.org/ddb.html describes the minimum info required in bug
reports.  Insufficient info makes it difficult to find and fix bugs.
ddb{6}> show register
rdi0
rsi   0xfd8834a02590
rbp   0x8000246b6dc0
rbx   0x8000246b6dd8
rdx0
rcx   0x8000224377e0
rax0
r8 0
r9   0x4
r10 0x24
r11   0xf4ba682f767b269e
r12   0xfd8834a02590
r13   0x8000246b6e98
r140
r15   0xfd800b58e658
rip   0x813b2691rtref+0x11
cs   0x8
rflags   0x10282__ALIGN_SIZE+0xf282
rsp   0x8000246b6db0
ss  0x10
rtref+0x11: lock incl   0x60(%rdi)
ddb{6}> show panic
*cpu6: uvm_fault(0x831a5998, 0x60, 0, 2) -> e
 cpu2: kernel diagnostic assertion "(rt->rt_flags & RTF_MPATH) || mrt->rt_prior
ity != prio" failed: file "/usr/src/sys/net/rtable.c", line 613
ddb{6}> trace
rtref(0) at rtref+0x11
rtable_match(0,8000246b6e98,fd800b58e658) at rtable_match+0xb9
rtalloc_mpath(8000246b6e98,fd800b58e658,0) at rtalloc_mpath+0x2e
in_ouraddr(fd80b278d300,8077d048,8000246b6f18) at in_ouraddr+0x
84
ip_input_if(8000246b6fb8,8000246b6fc4,4,0,8077d048) at ip_input
_if+0x1cd
ipv4_input(8077d048,fd80b278d300) at ipv4_input+0x39
ether_input(8077d048,fd80b278d300) at ether_input+0x3ad
if_input_process(8077d048,8000246b70a8) at if_input_process+0x6f
ifiq_process(80781100) at ifiq_process+0x69
taskq_thread(80036080) at taskq_thread+0x100
end trace frame: 0x0, count: -10
ddb{6}> ps
   PID TID   PPIDUID  S   FLAGS  WAIT  COMMAND
 43068  202508  86288  0  70x13arp
 16981  183305  55181  0  30x100083  kqreadtop
 55181  168823  55818  0  30x10008b  sigsusp   ksh
 55818  177517  59472  0  30x9a  kqreadsshd
 61572   18246  0  0  3 0x14200  bored sosplice
 86288  511512  1  0  30x10008b  sigsusp   ksh
 88947   37559  1  0  30x100098  kqreadcron
 33580  243044  1 99  3   0x1100090  kqreadsndiod
 96861  268522  1110  30x100090  kqreadsndiod
 78020  360065  25250 95  3   0x1100092  kqreadsmtpd
 21363  422206  25250103  3   0x1100092  kqreadsmtpd
 26374  175617  25250 95  3   0x1100092  kqreadsmtpd
 50987  371703  25250 95  30x100092  kqreadsmtpd
 93507  389621  25250 95  3   0x1100092  kqreadsmtpd
 79576  150347  25250 95  3   0x1100092  kqreadsmtpd
 25250  448177  1  0  30x100080  kqreadsmtpd
  8305  136296  1  0  30x80  kqreadrelayd
 33505  102618  1 89  3   0x1100092  kqreadrelayd
  2184  36427

pkg_create tweak for PORTSDIR_PATH

2022-06-28 Thread Marc Espie
As noticed by landry, going to the ports tree for dependencies can fail
hilariously in case of a PORTSDIR_PATH.

Most specifically, assuming you are building something like firefox-102
in one of your ports directory, when building the debug package,
dependency look-up in pkg_create is going to follow PORTSDIR_PATH, thus 
ending up possibly in another firefox directory which contains firefox-100.

And since debug packages dependencies are tight, this will fail every time.

We're already checking for dependency pkgpath matching the pkgpath we're
building, so it's mostly a question of deducing the ports root from the
current directory.

and overriding PORTSDIR_PATH in ask_tree.

(another possibility would be to actively parse the dependency, not go back
to the ports tree, and just set FLAVOR and SUBPACKAGE correctly, but this
is somewhat more complicated and this appears to work).

Note the "Overriding..." print. This is intended as checking that things work
as expected and not intended for commit.

(I've also added an extra check on plist->pkgname and error message display
while debugging that thingy, along with moving the full action tweaks in
the father, so the messages reflect what has actually been run)

Okay ?


Index: OpenBSD/PkgCreate.pm
===
RCS file: /cvs/src/usr.sbin/pkg_add/OpenBSD/PkgCreate.pm,v
retrieving revision 1.182
diff -u -p -r1.182 PkgCreate.pm
--- OpenBSD/PkgCreate.pm28 Jun 2022 09:01:45 -  1.182
+++ OpenBSD/PkgCreate.pm28 Jun 2022 09:59:24 -
@@ -980,6 +980,7 @@ sub really_solve_dependency
$state->progress->message($dep->{pkgpath});
 
my $v;
+   my $path;
 
# look in installed packages, but only for different paths
my $p1 = $dep->{pkgpath};
@@ -987,7 +988,16 @@ sub really_solve_dependency
$p1 =~ s/\,.*//;
$p2 =~ s/\,.*//;
$p2 =~ s,^debug/,,;
-   if ($p1 ne $p2) {
+   if ($p1 eq $p2) {
+   # try to figure out where we live
+   require Cwd;
+   my $dir = Cwd::getcwd();
+   if (defined $dir) {
+   if ($dir =~ s,/\Q$p1\E$,,) {
+   $path = $dir;
+   }
+   }
+   } else {
# look in installed packages
$v = $self->find_dep_in_installed($state, $dep);
}
@@ -997,7 +1007,7 @@ sub really_solve_dependency
 
# and in portstree otherwise
if (!defined $v) {
-   $v = $self->solve_from_ports($state, $dep, $package);
+   $v = $self->solve_from_ports($state, $dep, $package, $path);
}
return $v;
 }
@@ -1032,13 +1042,19 @@ sub to_cache
 
 sub ask_tree
 {
-   my ($self, $state, $pkgpath, $portsdir, $data, @action) = @_;
+   my ($self, $state, $pkgpath, $portsdir, $path, $data, @action) = @_;
 
my $make = OpenBSD::Paths->make;
my $errors = OpenBSD::Temp->file;
if (!defined $errors) {
$state->fatal(OpenBSD::Temp->last_error);
}
+   push(@action, 'PORTS_PRIVSEP=No');
+   if (defined $path) {
+   push(@action, "PORTSDIR_PATH=$path");
+   $state->say("Overriding PORTSDIR_PATH=#1 for dependency #2", 
+   $path, $pkgpath);
+   }
my $pid = open(my $fh, "-|");
if (!defined $pid) {
$state->fatal("cannot fork: #1", $!);
@@ -1059,7 +1075,6 @@ sub ask_tree
$( = $); $< = $>;
# XXX we're already running as ${BUILD_USER}
# so we can't do this again
-   push(@action, 'PORTS_PRIVSEP=No');
$DB::inhibit_exit = 0;
exec $make ('make', @action);
}
@@ -1067,7 +1082,7 @@ sub ask_tree
while(<$fh>) {  # XXX avoid spurious errors from child
}
close($fh);
-   if ($? != 0) {
+   if ($? != 0 || !defined $plist || !defined $plist->pkgname) {
$state->errsay("child running '#2' failed: #1", 
$state->child_error,
join(' ', 'make', @action));
@@ -1084,7 +1099,7 @@ sub ask_tree
 
 sub really_solve_from_ports
 {
-   my ($self, $state, $dep, $portsdir) = @_;
+   my ($self, $state, $dep, $portsdir, $path) = @_;
 
my $diskcache = $self->diskcachename($dep);
my $plist;
@@ -1093,6 +1108,7 @@ sub really_solve_from_ports
$plist = OpenBSD::PackingList->fromfile($diskcache);
} else {
$plist = $self->ask_tree($state, $dep->{pkgpath}, $portsdir,
+   $path,
\&OpenBSD::PackingList::PrelinkStuffOnly,
'print-plist-libs-with-depends',
'wantlib_args=no-wantlib-args');
@@ -1113,7 +1129,7 @@ my $cache = {};
 
 sub solve_from_ports
 {
-   my ($self, $state, $dep, $package) = @_;
+   my ($self, $state, $dep, $package, $pat

do pppoe(4) input through netisr

2022-06-28 Thread Vitaliy Makkoveev
ether_input() called with shared netlock, but pppoe(4) wants it to be
exclusive. Do the pppoe(4) input within netisr handler with exclusive
netlok held, and remove kernel lock hack from ether_input().

This is the step back, but it makes ether_input() path better then it
is now.

ok?

Index: sys/net/if.c
===
RCS file: /cvs/src/sys/net/if.c,v
retrieving revision 1.655
diff -u -p -r1.655 if.c
--- sys/net/if.c28 Jun 2022 08:01:40 -  1.655
+++ sys/net/if.c28 Jun 2022 09:27:29 -
@@ -68,6 +68,7 @@
 #include "pf.h"
 #include "pfsync.h"
 #include "ppp.h"
+#include "pppoe.h"
 #include "if_wg.h"
 
 #include 
@@ -917,6 +918,11 @@ if_netisr(void *unused)
 #ifdef PIPEX
if (n & (1 << NETISR_PIPEX))
pipexintr();
+#endif
+#if NPPPOE > 0
+   if (n & (1 << NETISR_PPPOE)) {
+   pppoeintr();
+   }
 #endif
t |= n;
}
Index: sys/net/if_ethersubr.c
===
RCS file: /cvs/src/sys/net/if_ethersubr.c,v
retrieving revision 1.282
diff -u -p -r1.282 if_ethersubr.c
--- sys/net/if_ethersubr.c  27 Jun 2022 20:47:10 -  1.282
+++ sys/net/if_ethersubr.c  28 Jun 2022 09:27:29 -
@@ -546,12 +546,13 @@ ether_input(struct ifnet *ifp, struct mb
pipex_rele_session(session);
}
 #endif
-   KERNEL_LOCK();
-   if (etype == ETHERTYPE_PPPOEDISC)
-   pppoe_disc_input(m);
-   else
-   pppoe_data_input(m);
-   KERNEL_UNLOCK();
+   if (etype == ETHERTYPE_PPPOEDISC) {
+   if (mq_enqueue(&pppoediscinq, m) == 0)
+   schednetisr(NETISR_PPPOE);
+   } else {
+   if (mq_enqueue(&pppoeinq, m) == 0)
+   schednetisr(NETISR_PPPOE);
+   }
return;
 #endif
 #ifdef MPLS
Index: sys/net/if_pppoe.c
===
RCS file: /cvs/src/sys/net/if_pppoe.c,v
retrieving revision 1.80
diff -u -p -r1.80 if_pppoe.c
--- sys/net/if_pppoe.c  14 May 2022 09:46:15 -  1.80
+++ sys/net/if_pppoe.c  28 Jun 2022 09:27:29 -
@@ -144,6 +144,8 @@ struct pppoe_softc {
 };
 
 /* input routines */
+void pppoe_disc_input(struct mbuf *);
+void pppoe_data_input(struct mbuf *);
 static void pppoe_dispatch_disc_pkt(struct mbuf *);
 
 /* management routines */
@@ -181,6 +183,26 @@ int pppoe_clone_destroy(struct ifnet *);
 struct if_clone pppoe_cloner =
 IF_CLONE_INITIALIZER("pppoe", pppoe_clone_create, pppoe_clone_destroy);
 
+struct mbuf_queue pppoediscinq = MBUF_QUEUE_INITIALIZER(
+   IFQ_MAXLEN, IPL_SOFTNET);
+struct mbuf_queue pppoeinq = MBUF_QUEUE_INITIALIZER(
+   IFQ_MAXLEN, IPL_SOFTNET);
+
+void pppoeintr(void)
+{
+   struct mbuf_list ml;
+   struct mbuf *m;
+
+   NET_ASSERT_LOCKED();
+
+   mq_delist(&pppoediscinq, &ml);
+   while ((m = ml_dequeue(&ml)) != NULL)
+   pppoe_disc_input(m);
+
+   mq_delist(&pppoeinq, &ml);
+   while ((m = ml_dequeue(&ml)) != NULL)
+   pppoe_data_input(m);
+}
 
 void
 pppoeattach(int count)
Index: sys/net/if_pppoe.h
===
RCS file: /cvs/src/sys/net/if_pppoe.h,v
retrieving revision 1.7
diff -u -p -r1.7 if_pppoe.h
--- sys/net/if_pppoe.h  4 Jan 2021 21:21:41 -   1.7
+++ sys/net/if_pppoe.h  28 Jun 2022 09:27:29 -
@@ -66,8 +66,8 @@ struct pppoeconnectionstate {
 
 #ifdef _KERNEL
 
-void pppoe_disc_input(struct mbuf *);
-void pppoe_data_input(struct mbuf *);
+extern struct mbuf_queue pppoediscinq;
+extern struct mbuf_queue pppoeinq;
 
 #endif /* _KERNEL */
 #endif /* _NET_IF_PPPOE_H_ */
Index: sys/net/netisr.h
===
RCS file: /cvs/src/sys/net/netisr.h,v
retrieving revision 1.57
diff -u -p -r1.57 netisr.h
--- sys/net/netisr.h28 Jun 2022 08:01:40 -  1.57
+++ sys/net/netisr.h28 Jun 2022 09:27:29 -
@@ -48,6 +48,7 @@
 #defineNETISR_PIPEX27  /* for pipex processing */
 #defineNETISR_PPP  28  /* for PPP processing */
 #defineNETISR_BRIDGE   29  /* for bridge processing */
+#defineNETISR_PPPOE30  /* for pppoe processing */
 #defineNETISR_SWITCH   31  /* for switch dataplane */
 
 #ifndef _LOCORE
@@ -67,6 +68,7 @@ void  bridgeintr(void);
 void   switchintr(void);
 void   pfsyncintr(void);
 void   pipexintr(void);
+void   pppoeintr(void);
 
 #defineschednetisr(anisr)  
\
 do {   \



Re: bcmdmac: minor nit

2022-06-28 Thread Mark Kettenis
ok kettenis@

> Op 28-06-2022 07:20 schreef Anton Lindqvist :
> 
>  
> Hi,
> No need to pass a copy of the bcmdmac_channel structure to predicate
> routines.
> 
> Comments? OK?
> 
> diff --git sys/dev/fdt/bcm2835_dmac.c sys/dev/fdt/bcm2835_dmac.c
> index 145810dd7af..e9b31af568c 100644
> --- sys/dev/fdt/bcm2835_dmac.c
> +++ sys/dev/fdt/bcm2835_dmac.c
> @@ -97,18 +97,18 @@ struct cfdriver bcmdmac_cd = { NULL, "bcmdmac", DV_DULL };
>  
>  /* utilities */
>  enum bcmdmac_type
> -bcmdmac_channel_type(struct bcmdmac_channel ch)
> +bcmdmac_channel_type(struct bcmdmac_channel *ch)
>  {
> - if (ISSET(ch.ch_debug, DMAC_DEBUG_LITE))
> + if (ISSET(ch->ch_debug, DMAC_DEBUG_LITE))
>   return BCMDMAC_TYPE_LITE;
>   else
>   return BCMDMAC_TYPE_NORMAL;
>  }
>  
>  int
> -bcmdmac_channel_used(struct bcmdmac_channel ch)
> +bcmdmac_channel_used(struct bcmdmac_channel *ch)
>  {
> - return ch.ch_callback != NULL;
> + return ch->ch_callback != NULL;
>  }
>  
>  void
> @@ -233,9 +233,9 @@ bcmdmac_alloc(enum bcmdmac_type type, int ipl,
>   for (index = 0; index < sc->sc_nchannels; index++) {
>   if (!ISSET(sc->sc_channelmask, (1 << index)))
>   continue;
> - if (bcmdmac_channel_type(sc->sc_channels[index]) != type)
> + if (bcmdmac_channel_type(&sc->sc_channels[index]) != type)
>   continue;
> - if (bcmdmac_channel_used(sc->sc_channels[index]))
> + if (bcmdmac_channel_used(&sc->sc_channels[index]))
>   continue;
>  
>   ch = &sc->sc_channels[index];



Re: com at acpi: minor nit

2022-06-28 Thread Mark Kettenis
meh

not really worth fixing, but since you already wrote the diff

ok kettenis@

> Op 28-06-2022 07:23 schreef Anton Lindqvist :
> 
>  
> Hi,
> A com_acpi_softc pointer is used as the interrupt callback cookie which
> is later on interpreted as a com_softc pointer. This is not a problem in
> practice as a com_softc structure is the first member of the
> com_acpi_softc structure.
> 
> Using the actual types consistently yields a better symmetry in my
> opinion between registering the interrupt and the corresponding
> interrupt handler.
> 
> Comments? OK?
> 
> diff --git sys/dev/acpi/com_acpi.c sys/dev/acpi/com_acpi.c
> index 9c1e4af0426..b9f2a14edd3 100644
> --- sys/dev/acpi/com_acpi.c
> +++ sys/dev/acpi/com_acpi.c
> @@ -159,9 +159,9 @@ com_acpi_is_designware(const char *hid)
>  int
>  com_acpi_intr_designware(void *cookie)
>  {
> - struct com_softc *sc = cookie;
> + struct com_acpi_softc *sc = cookie;
>  
> - com_read_reg(sc, com_usr);
> + com_read_reg(&sc->sc, com_usr);
>  
> - return comintr(sc);
> + return comintr(&sc->sc);
>  }



snmpd(8): Allow for symbolic OID names in snmpd.conf

2022-06-28 Thread Martijn van Duren
When playing with the blocklist I noticed that the oid directive only
supports numeric OIDs. So if florian wants to use filter-pf-table in the
future he'd have to set:
blocklist 1.3.6.1.4.1.30155.1.9.129
which is pure insanity, if:
blocklist pfTblAddrTable
could be an option.

Diff below changes the "oid" parse.y definition from ober_string2oid to
smi_string2oid, which allows for the locally known symbolic names.
This also helps out with existing statements ("system oid",
"trap handle oid", and "trap receiver", and "oid").

While here, rename sysoid to oid, since it's not used by the system
oid anymore and do a little KNF.

OK?

martijn@

Index: parse.y
===
RCS file: /cvs/src/usr.sbin/snmpd/parse.y,v
retrieving revision 1.73
diff -u -p -r1.73 parse.y
--- parse.y 21 Nov 2021 13:33:53 -  1.73
+++ parse.y 28 Jun 2022 09:02:36 -
@@ -666,21 +666,20 @@ optwrite  : READONLY  { $$ = 
0; }
;
 
 oid: STRING{
-   struct ber_oid  *sysoid;
-   if ((sysoid =
-   calloc(1, sizeof(*sysoid))) == NULL) {
+   struct ber_oid  *oid;
+   if ((oid = calloc(1, sizeof(*oid))) == NULL) {
yyerror("calloc");
free($1);
YYERROR;
}
-   if (ober_string2oid($1, sysoid) == -1) {
+   if (smi_string2oid($1, oid) == -1) {
yyerror("invalid OID: %s", $1);
-   free(sysoid);
+   free(oid);
free($1);
YYERROR;
}
free($1);
-   $$ = sysoid;
+   $$ = oid;
}
;
 



arpintr without kernel lock

2022-06-28 Thread Alexander Bluhm
Hi,

arpintr() looks MP safe and I cannot trigger a crash with this diff.

Hrvoje, can you try it?

bluhm

Index: net/if.c
===
RCS file: /data/mirror/openbsd/cvs/src/sys/net/if.c,v
retrieving revision 1.654
diff -u -p -r1.654 if.c
--- net/if.c27 Jun 2022 15:11:23 -  1.654
+++ net/if.c27 Jun 2022 23:47:22 -
@@ -891,11 +891,8 @@ if_netisr(void *unused)
atomic_clearbits_int(&netisr, n);
 
 #if NETHER > 0
-   if (n & (1 << NETISR_ARP)) {
-   KERNEL_LOCK();
+   if (n & (1 << NETISR_ARP))
arpintr();
-   KERNEL_UNLOCK();
-   }
 #endif
if (n & (1 << NETISR_IP))
ipintr();



snmpd(8): Add blocklist feature

2022-06-28 Thread Martijn van Duren
Back in 2020 florian@ added the filter-pf-addresses keyword.
Although useful, I always felt it was a bit too case-specific. The diff
below adds a new blocklist feature/backend, which takes hold of an
entire subtree, effectively removing it from the tree.

With this I've deprecated the filter-pf-address case and should
probably be removed somewhere after 7.4. The filter-routes case can't
be removed unfortunately, since its behaviour is not identical, and
instead adds filters to the routing socket, preventing updates being
pushed to snmpd(8).

Feedback/OK?

martijn@

Index: Makefile
===
RCS file: /cvs/src/usr.sbin/snmpd/Makefile,v
retrieving revision 1.18
diff -u -p -r1.18 Makefile
--- Makefile19 Jan 2022 11:00:56 -  1.18
+++ Makefile28 Jun 2022 08:18:17 -
@@ -3,6 +3,7 @@
 PROG=  snmpd
 MAN=   snmpd.8 snmpd.conf.5
 SRCS=  parse.y log.c snmpe.c application.c application_legacy.c \
+   application_blocklist.c \
mps.c trap.c mib.c smi.c kroute.c snmpd.c timer.c \
pf.c proc.c usm.c traphandler.c util.c
 
Index: application.c
===
RCS file: /cvs/src/usr.sbin/snmpd/application.c,v
retrieving revision 1.5
diff -u -p -r1.5 application.c
--- application.c   27 Jun 2022 10:31:17 -  1.5
+++ application.c   28 Jun 2022 08:18:17 -
@@ -148,6 +148,7 @@ RB_PROTOTYPE_STATIC(appl_requests, appl_
 void
 appl_init(void)
 {
+   appl_blocklist_init();
appl_legacy_init();
 }
 
Index: application.h
===
RCS file: /cvs/src/usr.sbin/snmpd/application.h,v
retrieving revision 1.1
diff -u -p -r1.1 application.h
--- application.h   19 Jan 2022 10:59:35 -  1.1
+++ application.h   28 Jun 2022 08:18:17 -
@@ -133,3 +133,6 @@ struct ber_element *appl_exception(enum 
 /* application_legacy.c */
 voidappl_legacy_init(void);
 voidappl_legacy_shutdown(void);
+
+/* application_blocklist.c */
+voidappl_blocklist_init(void);
Index: application_blocklist.c
===
RCS file: application_blocklist.c
diff -N application_blocklist.c
--- /dev/null   1 Jan 1970 00:00:00 -
+++ application_blocklist.c 28 Jun 2022 08:18:17 -
@@ -0,0 +1,122 @@
+/* $OpenBSD: application.c,v 1.5 2022/06/27 10:31:17 martijn Exp $ */
+
+/*
+ * Copyright (c) 2022 Martijn van Duren 
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include 
+#include 
+
+#include "application.h"
+#include "snmpd.h"
+
+struct appl_varbind *appl_blocklist_response(size_t);
+void appl_blocklist_get(struct appl_backend *, int32_t, int32_t, const char *,
+struct appl_varbind *);
+void appl_blocklist_getnext(struct appl_backend *, int32_t, int32_t,
+const char *, struct appl_varbind *);
+
+struct appl_backend_functions appl_blocklist_functions = {
+   .ab_get = appl_blocklist_get,
+   .ab_getnext = appl_blocklist_getnext,
+   .ab_getbulk = NULL,
+};
+
+struct appl_backend appl_blocklist = {
+   .ab_name = "blocklist",
+   .ab_cookie = NULL,
+   .ab_retries = 0,
+   .ab_fn = &appl_blocklist_functions
+};
+
+static struct appl_varbind *response = NULL;
+static size_t responsesz = 0;
+
+struct appl_varbind *
+appl_blocklist_response(size_t nvarbind)
+{
+   struct appl_varbind *tmp;
+   size_t i;
+
+   if (responsesz < nvarbind) {
+   if ((tmp = recallocarray(response, responsesz, nvarbind,
+   sizeof(*response))) == NULL) {
+   log_warn(NULL);
+   return NULL;
+   }
+   responsesz = nvarbind;
+   response = tmp;
+   }
+   for (i = 0; i < nvarbind; i++)
+   response[i].av_next = i + 1 == nvarbind ?
+   NULL : &(response[i + 1]);
+   return response;
+}
+
+void
+appl_blocklist_init(void)
+{
+   extern struct snmpd *snmpd_env;
+   size_t i;
+
+   for (i = 0; i < snmpd_env->sc_nblocklist; i++)
+   appl_register(NULL, 150, 1, &(snmpd_env->sc_blocklist[i]),
+   0, 1, 0, 0, &appl

Re: acpitz(4): perform passive cooling only when perfpolicy is AUTO

2022-06-28 Thread Theo de Raadt
Stefan Hagen  wrote:

> Stuart Henderson wrote (2022-06-28 08:13 CEST):
> > On 2022/06/27 17:12, Bryan Steele wrote:
> > > 
> > > Shouldn't this also take into consideration hw.power as well? If it
> > > doesn't make sense for perfpolicy=high then it probably doesn't for
> > > perfpolicy=auto when on AC power?
> > 
> > Why so? perfpolicy=high says to me, "I want it fast, I don't care about
> > fan noise etc", but perfpolicy=auto (whether on ac or not) suggests there
> > are considerations other than speed.
> >
> 
> perfpolicy=auto+AC sets perflevel=100, which is the equivalent
> to perfpolicy=high.
> 
> I believe this is a discussion we have other threads for.
> 
> But in my opinion as long as perfpolicy=auto+AC sets max speed, it 
> should be the same as perfpolicy=high and not something "almost 
> perfpolicy=high".

The reason I changed it that way last year, is because auto was behaving
on too many machines as dog-slow.

I did not believe I could repair auto on my own, so I chose to create a
reaction --- such that the whole team would work together on algorithm
changes so that auto would once again be effective -- some sort of blend
of desired behaviour between everyone.  It should scale up performance
as soon as it is required (not slowly, even now, I think it is too slow because
it requires compute to occur slowly, which eventually bogs up the scheduler
data structures, which eventually causes it to speedup, but in the meantime
those first immediate chunks of compute happened in very slow mode).

I think what changed in newer machines is that the gap between slowest and
fastest is far greater than in previous machines, so choosing "slowest" and
upgrading with such a pessimistic method is a bad idea.