use shared socket^Wnet lock in get* syscalls

2022-11-28 Thread Klemens Nanni
so{,un}lock_shared() take the shared net lock for PF_INET and PF_INET6
while sticking to the exclusive rwlock elsewhere.

getsockopt(2), getsockname(2) and getpeername(2) (all UNLOCK) do not
write, so the exclusive net lock is overkill here.

Did I miss anything?
Feedback? OK?

diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index ddb612a8043..ea5b07b71e7 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -1268,9 +1268,9 @@ sys_getsockopt(struct proc *p, void *v, register_t 
*retval)
valsize = 0;
m = m_get(M_WAIT, MT_SOOPTS);
so = fp->f_data;
-   solock(so);
+   solock_shared(so);
error = sogetopt(so, SCARG(uap, level), SCARG(uap, name), m);
-   sounlock(so);
+   sounlock_shared(so);
if (error == 0 && SCARG(uap, val) && valsize && m != NULL) {
if (valsize > m->m_len)
valsize = m->m_len;
@@ -1320,9 +1320,9 @@ sys_getsockname(struct proc *p, void *v, register_t 
*retval)
goto bad;
}
m = m_getclr(M_WAIT, MT_SONAME);
-   solock(so);
+   solock_shared(so);
error = pru_sockaddr(so, m);
-   sounlock(so);
+   sounlock_shared(so);
if (error)
goto bad;
error = copyaddrout(p, m, SCARG(uap, asa), len, SCARG(uap, alen));
@@ -1367,9 +1367,9 @@ sys_getpeername(struct proc *p, void *v, register_t 
*retval)
if (error)
goto bad;
m = m_getclr(M_WAIT, MT_SONAME);
-   solock(so);
+   solock_shared(so);
error = pru_peeraddr(so, m);
-   sounlock(so);
+   sounlock_shared(so);
if (error)
goto bad;
error = copyaddrout(p, m, SCARG(uap, asa), len, SCARG(uap, alen));



Remove constant basereachable and retrans members from struct nd_ifinfo

2022-11-28 Thread Klemens Nanni
Both are initalised with compile-time constants and never written to.

They are part of the Neighbour Discovery machinery and only surface
through the single-user SIOCGIFINFO_IN6:
$ ndp -i lo0
basereachable=30s0ms, reachable=39s, retrans=1s0ms

These values are read-only since 2017 sys/netinet6/nd6.c r1.217
  usr.sbin/ndp/ndp.c r1.85
Remove knob and always do neighbor unreachable detection

Inline the macros (to keep meaningful names), shrink the per-interface
allocated struct nd_ifinfo to what is actually needed and inline
nd6_dad_starttimer()'s constant `msec' argument.

This makes it clear how SIOCGIFINFO_IN6 is less useful than it seems:
$ ./obj/ndp -i lo0
reachable=39s

Nothing else in base, incl. regress, uses SIOCGIFINFO_IN6 or `ndp -i'.


Feedback? Objection? OK?

(Sorry for the header/ABI churn, I could've cleaned this up earlier...
 if I had seen this right away between all the other dead code.)

diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c
index 10753026d4b..0a1d5fb24c7 100644
--- a/sys/netinet6/nd6.c
+++ b/sys/netinet6/nd6.c
@@ -124,9 +124,7 @@ nd6_ifattach(struct ifnet *ifp)
 
nd = malloc(sizeof(*nd), M_IP6NDP, M_WAITOK | M_ZERO);
 
-   nd->basereachable = REACHABLE_TIME;
-   nd->reachable = ND_COMPUTE_RTIME(nd->basereachable);
-   nd->retrans = RETRANS_TIMER;
+   nd->reachable = ND_COMPUTE_RTIME(REACHABLE_TIME);
 
ifp->if_nd = nd;
 }
@@ -349,7 +347,7 @@ nd6_llinfo_timer(struct rtentry *rt)
case ND6_LLINFO_INCOMPLETE:
if (ln->ln_asked < nd6_mmaxtries) {
ln->ln_asked++;
-   nd6_llinfo_settimer(ln, ifp->if_nd->retrans / 1000);
+   nd6_llinfo_settimer(ln, RETRANS_TIMER / 1000);
nd6_ns_output(ifp, NULL, >sin6_addr, ln, 0);
} else {
struct mbuf *m = ln->ln_hold;
@@ -396,13 +394,13 @@ nd6_llinfo_timer(struct rtentry *rt)
/* We need NUD */
ln->ln_asked = 1;
ln->ln_state = ND6_LLINFO_PROBE;
-   nd6_llinfo_settimer(ln, ifp->if_nd->retrans / 1000);
+   nd6_llinfo_settimer(ln, RETRANS_TIMER / 1000);
nd6_ns_output(ifp, >sin6_addr, >sin6_addr, ln, 0);
break;
case ND6_LLINFO_PROBE:
if (ln->ln_asked < nd6_umaxtries) {
ln->ln_asked++;
-   nd6_llinfo_settimer(ln, ifp->if_nd->retrans / 1000);
+   nd6_llinfo_settimer(ln, RETRANS_TIMER / 1000);
nd6_ns_output(ifp, >sin6_addr,
>sin6_addr, ln, 0);
} else {
@@ -1281,8 +1279,7 @@ nd6_slowtimo(void *ignored_arg)
 
TAILQ_FOREACH(ifp, , if_list) {
nd6if = ifp->if_nd;
-   if (nd6if->basereachable && /* already initialized */
-   (nd6if->recalctm -= ND6_SLOWTIMER_INTERVAL) <= 0) {
+   if ((nd6if->recalctm -= ND6_SLOWTIMER_INTERVAL) <= 0) {
/*
 * Since reachable time rarely changes by router
 * advertisements, we SHOULD insure that a new random
@@ -1290,7 +1287,7 @@ nd6_slowtimo(void *ignored_arg)
 * (RFC 2461, 6.3.4)
 */
nd6if->recalctm = ND6_RECALC_REACHTM_INTERVAL;
-   nd6if->reachable = 
ND_COMPUTE_RTIME(nd6if->basereachable);
+   nd6if->reachable = ND_COMPUTE_RTIME(REACHABLE_TIME);
}
}
NET_UNLOCK();
@@ -1399,7 +1396,7 @@ nd6_resolve(struct ifnet *ifp, struct rtentry *rt0, 
struct mbuf *m,
 */
if (!ND6_LLINFO_PERMANENT(ln) && ln->ln_asked == 0) {
ln->ln_asked++;
-   nd6_llinfo_settimer(ln, ifp->if_nd->retrans / 1000);
+   nd6_llinfo_settimer(ln, RETRANS_TIMER / 1000);
nd6_ns_output(ifp, NULL, (dst)->sin6_addr, ln, 0);
}
return (EAGAIN);
diff --git a/sys/netinet6/nd6.h b/sys/netinet6/nd6.h
index d55bab0027e..897147e5501 100644
--- a/sys/netinet6/nd6.h
+++ b/sys/netinet6/nd6.h
@@ -45,14 +45,11 @@
 
 /*
  *  Locks used to protect struct members in this file:
- * I   immutable after creation
  * N   net lock
  */
 
 struct nd_ifinfo {
-   u_int32_t basereachable;/* [I] BaseReachableTime */
u_int32_t reachable;/* [N] Reachable Time */
-   u_int32_t retrans;  /* [I] Retrans Timer */
int recalctm;   /* [N] BaseReachable recalc timer */
 };
 
diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c
index e68ccbd4944..6046b90dcb9 100644
--- a/sys/netinet6/nd6_nbr.c
+++ b/sys/netinet6/nd6_nbr.c
@@ -76,7 +76,7 @@ struct dadq {
 };
 
 struct dadq *nd6_dad_find(struct ifaddr *);
-void nd6_dad_starttimer(struct dadq 

Re: Improve rpki-client warnings on .mft files

2022-11-28 Thread Theo Buehler
On Mon, Nov 28, 2022 at 07:18:24PM +0100, Claudio Jeker wrote:
> On Mon, Nov 28, 2022 at 06:02:56PM +0100, Theo Buehler wrote:
> > On Mon, Nov 28, 2022 at 05:14:48PM +0100, Claudio Jeker wrote:
> > > On Mon, Nov 28, 2022 at 04:50:24PM +0100, Theo Buehler wrote:
> > > > On Mon, Nov 28, 2022 at 04:02:11PM +0100, Claudio Jeker wrote:
> > > > > Since a long time any problem that caused rpki-client to not load a
> > > > > manifest resulted in the non helpful:
> > > > > rpki-client: 
> > > > > rpki.afrinic.net/repository/member_repository/F36505B2/0569917622D711ED862FD6E0F1222468/0nALpPtwFyntPHjkS8xt-VQrqLw.mft:
> > > > >  no valid mft available
> > > > > 
> > > > > This hides in most cases the cause why the manifest verificatin 
> > > > > failed.
> > > > > The following diff exposes the error from valid_x509() and with that 
> > > > > some
> > > > > manifest errors change to e.g.:
> > > > > rpki-client: 
> > > > > parent.rov.koenvanhove.nl/repo/KoenvanHove/1/C1F7424F77FBF669FB750C6DC7B649C5969DCD55.mft:
> > > > >  CRL has expired
> > > > > 
> > > > > or if the CRL is missing
> > > > > 
> > > > > rpki-client: 
> > > > > repo.pedjoeang.group/repo/localname/0/EF79F8E55B6A248EF9CF4CE70FF60C017BF1A3B0.mft:
> > > > >  unable to get certificate CRL
> > > > > 
> > > > > If the certificate is pointing to a manifest that does not exist the 
> > > > > old
> > > > > "no valid mft available" is shown.
> > > > > 
> > > > > I tried to keep original behaviour as much as possible but I think
> > > > > filemode can be further improved. And maybe we can remove verbose from
> > > > > other warnings as well.
> > > > 
> > > > I like this a lot.
> > > > 
> > > > I was wondering if valid_x509() should have a const char **errstr
> > > > instead of an int * as last argument. valid_x509() could do the
> > > > conversion from error code to error string itself. This way we don't
> > > > have to sprinkle X509_verify_cert_error_string() calls everywhere.
> > > > 
> > > > Or we could introduce a warn_invalid_x509(const char *str, int err) that
> > > > does the conversion from err using X509_verify_cert_error_string().
> > > > 
> > > > One downside of X509_verify_cert_error_string() is that it isn't thread
> > > > safe since it might return a pointer to a static buffer -- it should
> > > > not, but who can be sure...
> > > 
> > > Tough call. It may also help other code paths to do the same. But in many
> > > cases a dynamic buffer would be needed.
> > > 
> > > Not sure if it makes sense to introduce warn_invalid_x509(). What I don't
> > > like is the verbose check before the warning. I wonder if we still need
> > > that. My last run has 11 failed roas and 51 failed mfts. The mft errors
> > > already show up. Shouldn't the roa errors be shown as well?
> > 
> > They should. Unless I'm completely confusing myself, this is a bug in
> > the diff and all the added if (verbose > 1) should be dropped.
> > 
> > If the last argument (nowarn) of valid_x509() was 0 (everywhere except
> > in proc_parser_pre()), valid_x509() would print the error independently
> > of verbose. verbose > 1 would force printing the warning also for mfts,
> > but there it would be drowned in the other noise.
> > 
> > -   if (!valid_x509(file, ctx, x509, a, crl, 0)) {
> > 
> > ...
> > 
> > -   if (!nowarn || verbose > 1)
> > -   warnx("%s: %s", file, X509_verify_cert_error_string(c));
> > 
> 
> Indeed. Better diff below.
> Still thinking about the idea with the const char **.

One of the main reasons for suggesting it was the amount of awkward line
wrapping. There's now much less of this. We can easily switch if you
should change your mind.

ok tb

> It seems OpenSSL made X509_verify_cert_error_string() thread safe by only
> returning static strings. So maybe we can ignore the issue and just assume
> all is well.
> 
> -- 
> :wq Claudio
> 
> Index: extern.h
> ===
> RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v
> retrieving revision 1.161
> diff -u -p -r1.161 extern.h
> --- extern.h  26 Nov 2022 12:02:36 -  1.161
> +++ extern.h  28 Nov 2022 10:42:11 -
> @@ -629,7 +629,7 @@ intvalid_filename(const char *, size_
>  int   valid_uri(const char *, size_t, const char *);
>  int   valid_origin(const char *, const char *);
>  int   valid_x509(char *, X509_STORE_CTX *, X509 *, struct auth *,
> - struct crl *, int);
> + struct crl *, int *);
>  int   valid_rsc(const char *, struct cert *, struct rsc *);
>  int   valid_econtent_version(const char *, const ASN1_INTEGER *);
>  int   valid_aspa(const char *, struct cert *, struct aspa *);
> Index: filemode.c
> ===
> RCS file: /cvs/src/usr.sbin/rpki-client/filemode.c,v
> retrieving revision 1.17
> diff -u -p -r1.17 filemode.c
> --- filemode.c26 Nov 2022 12:02:37 -  

Re: vmd: fix booting 7.2 ramdisks with >= 4G mem

2022-11-28 Thread Mark Kettenis
> Date: Mon, 28 Nov 2022 18:26:47 +0100
> From: Claudio Jeker 
> 
> On Mon, Nov 28, 2022 at 11:32:32AM -0500, Dave Voutila wrote:
> > tech@ et. al.,
> > 
> > When kettenis@ introduced a newer version of BOOTARG_CONSDEV to add
> > additional params for the AMD Ryzen V1000 family, vmd's code that
> > configures bootargs to support direct booting a ramdisk kernel didn't
> > adjust with it.
> > 
> > Mischa Peters found this and shared a simple reproducer on 7.2 and
> > -current:
> > 
> > # vmctl start -c -b /bsd.rd -m 4G test
> > 
> > Where /bsd.rd is a 7.2 or -current ramdisk kernel.
> > 
> > Interestingly, this is only seen when using 4G (or more) memory for the
> > guest. I think it's just a happy coincedence it works < 4G because of
> > the resulting BOOTARG_MEMMAP sizing things so the BOOTARG_CONSDEV works.
> > 
> > Diff below fixes the issue by simply zero'ing the BOOTARG_CONSDEV
> > structure before assigning to members.
> > 
> > While here, I also cleaned up some things like using literal values that
> > could be more descriptive boot arg names and also made the arithmetic
> > explicitly use the same type (uint32_t) throughout instead of mixing it
> > with int.
> > 
> > ok?
> 
> OK claudio@

ok kettenis@ too FWIW

> PS: diff did not apply, a space got stripped below diff should apply
> -- 
> :wq Claudio
> 
> Index: loadfile_elf.c
> ===
> RCS file: /cvs/src/usr.sbin/vmd/loadfile_elf.c,v
> retrieving revision 1.42
> diff -u -p -r1.42 loadfile_elf.c
> --- loadfile_elf.c28 Jan 2022 06:33:27 -  1.42
> +++ loadfile_elf.c28 Nov 2022 17:07:20 -
> @@ -382,9 +382,10 @@ create_bios_memmap(struct vm_create_para
>   * Parameters:
>   *  memmap: the BIOS memory map
>   *  n: number of entries in memmap
> + *  bootmac: optional PXE boot MAC address
>   *
>   * Return values:
> - *  The size of the bootargs
> + *  The size of the bootargs in bytes
>   */
>  static uint32_t
>  push_bootargs(bios_memmap_t *memmap, size_t n, bios_bootmac_t *bootmac)
> @@ -393,40 +394,41 @@ push_bootargs(bios_memmap_t *memmap, siz
>   bios_consdev_t consdev;
>   uint32_t ba[1024];
>  
> - memmap_sz = 3 * sizeof(int) + n * sizeof(bios_memmap_t);
> - ba[0] = 0x0;/* memory map */
> + memmap_sz = 3 * sizeof(uint32_t) + n * sizeof(bios_memmap_t);
> + ba[0] = BOOTARG_MEMMAP;
>   ba[1] = memmap_sz;
> - ba[2] = memmap_sz;  /* next */
> + ba[2] = memmap_sz;
>   memcpy([3], memmap, n * sizeof(bios_memmap_t));
> - i = memmap_sz / sizeof(int);
> + i = memmap_sz / sizeof(uint32_t);
>  
>   /* Serial console device, COM1 @ 0x3f8 */
> - consdev.consdev = makedev(8, 0);/* com1 @ 0x3f8 */
> + memset(, 0, sizeof(consdev));
> + consdev.consdev = makedev(8, 0);
>   consdev.conspeed = 115200;
>   consdev.consaddr = 0x3f8;
> - consdev.consfreq = 0;
>  
> - consdev_sz = 3 * sizeof(int) + sizeof(bios_consdev_t);
> - ba[i] = 0x5;   /* consdev */
> + consdev_sz = 3 * sizeof(uint32_t) + sizeof(bios_consdev_t);
> + ba[i] = BOOTARG_CONSDEV;
>   ba[i + 1] = consdev_sz;
>   ba[i + 2] = consdev_sz;
>   memcpy([i + 3], , sizeof(bios_consdev_t));
> - i += consdev_sz / sizeof(int);
> + i += consdev_sz / sizeof(uint32_t);
>  
>   if (bootmac) {
> - bootmac_sz = 3 * sizeof(int) + (sizeof(bios_bootmac_t) + 3) & 
> ~3;
> - ba[i] = 0x7;   /* bootmac */
> + bootmac_sz = 3 * sizeof(uint32_t) +
> + (sizeof(bios_bootmac_t) + 3) & ~3;
> + ba[i] = BOOTARG_BOOTMAC;
>   ba[i + 1] = bootmac_sz;
>   ba[i + 2] = bootmac_sz;
>   memcpy([i + 3], bootmac, sizeof(bios_bootmac_t));
> - i += bootmac_sz / sizeof(int);
> - } 
> + i += bootmac_sz / sizeof(uint32_t);
> + }
>  
>   ba[i++] = 0x; /* BOOTARG_END */
>  
>   write_mem(BOOTARGS_PAGE, ba, PAGE_SIZE);
>  
> - return (i * sizeof(int));
> + return (i * sizeof(uint32_t));
>  }
>  
>  /*
> 
> 



Re: Improve rpki-client warnings on .mft files

2022-11-28 Thread Claudio Jeker
On Mon, Nov 28, 2022 at 06:02:56PM +0100, Theo Buehler wrote:
> On Mon, Nov 28, 2022 at 05:14:48PM +0100, Claudio Jeker wrote:
> > On Mon, Nov 28, 2022 at 04:50:24PM +0100, Theo Buehler wrote:
> > > On Mon, Nov 28, 2022 at 04:02:11PM +0100, Claudio Jeker wrote:
> > > > Since a long time any problem that caused rpki-client to not load a
> > > > manifest resulted in the non helpful:
> > > > rpki-client: 
> > > > rpki.afrinic.net/repository/member_repository/F36505B2/0569917622D711ED862FD6E0F1222468/0nALpPtwFyntPHjkS8xt-VQrqLw.mft:
> > > >  no valid mft available
> > > > 
> > > > This hides in most cases the cause why the manifest verificatin failed.
> > > > The following diff exposes the error from valid_x509() and with that 
> > > > some
> > > > manifest errors change to e.g.:
> > > > rpki-client: 
> > > > parent.rov.koenvanhove.nl/repo/KoenvanHove/1/C1F7424F77FBF669FB750C6DC7B649C5969DCD55.mft:
> > > >  CRL has expired
> > > > 
> > > > or if the CRL is missing
> > > > 
> > > > rpki-client: 
> > > > repo.pedjoeang.group/repo/localname/0/EF79F8E55B6A248EF9CF4CE70FF60C017BF1A3B0.mft:
> > > >  unable to get certificate CRL
> > > > 
> > > > If the certificate is pointing to a manifest that does not exist the old
> > > > "no valid mft available" is shown.
> > > > 
> > > > I tried to keep original behaviour as much as possible but I think
> > > > filemode can be further improved. And maybe we can remove verbose from
> > > > other warnings as well.
> > > 
> > > I like this a lot.
> > > 
> > > I was wondering if valid_x509() should have a const char **errstr
> > > instead of an int * as last argument. valid_x509() could do the
> > > conversion from error code to error string itself. This way we don't
> > > have to sprinkle X509_verify_cert_error_string() calls everywhere.
> > > 
> > > Or we could introduce a warn_invalid_x509(const char *str, int err) that
> > > does the conversion from err using X509_verify_cert_error_string().
> > > 
> > > One downside of X509_verify_cert_error_string() is that it isn't thread
> > > safe since it might return a pointer to a static buffer -- it should
> > > not, but who can be sure...
> > 
> > Tough call. It may also help other code paths to do the same. But in many
> > cases a dynamic buffer would be needed.
> > 
> > Not sure if it makes sense to introduce warn_invalid_x509(). What I don't
> > like is the verbose check before the warning. I wonder if we still need
> > that. My last run has 11 failed roas and 51 failed mfts. The mft errors
> > already show up. Shouldn't the roa errors be shown as well?
> 
> They should. Unless I'm completely confusing myself, this is a bug in
> the diff and all the added if (verbose > 1) should be dropped.
> 
> If the last argument (nowarn) of valid_x509() was 0 (everywhere except
> in proc_parser_pre()), valid_x509() would print the error independently
> of verbose. verbose > 1 would force printing the warning also for mfts,
> but there it would be drowned in the other noise.
> 
> - if (!valid_x509(file, ctx, x509, a, crl, 0)) {
> 
> ...
> 
> - if (!nowarn || verbose > 1)
> - warnx("%s: %s", file, X509_verify_cert_error_string(c));
> 

Indeed. Better diff below.
Still thinking about the idea with the const char **.
It seems OpenSSL made X509_verify_cert_error_string() thread safe by only
returning static strings. So maybe we can ignore the issue and just assume
all is well.

-- 
:wq Claudio

Index: extern.h
===
RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v
retrieving revision 1.161
diff -u -p -r1.161 extern.h
--- extern.h26 Nov 2022 12:02:36 -  1.161
+++ extern.h28 Nov 2022 10:42:11 -
@@ -629,7 +629,7 @@ int  valid_filename(const char *, size_
 int valid_uri(const char *, size_t, const char *);
 int valid_origin(const char *, const char *);
 int valid_x509(char *, X509_STORE_CTX *, X509 *, struct auth *,
-   struct crl *, int);
+   struct crl *, int *);
 int valid_rsc(const char *, struct cert *, struct rsc *);
 int valid_econtent_version(const char *, const ASN1_INTEGER *);
 int valid_aspa(const char *, struct cert *, struct aspa *);
Index: filemode.c
===
RCS file: /cvs/src/usr.sbin/rpki-client/filemode.c,v
retrieving revision 1.17
diff -u -p -r1.17 filemode.c
--- filemode.c  26 Nov 2022 12:02:37 -  1.17
+++ filemode.c  28 Nov 2022 18:04:57 -
@@ -141,7 +141,7 @@ parse_load_certchain(char *uri)
struct cert *cert;
struct crl *crl;
struct auth *a;
-   int i;
+   int i, e;
 
for (i = 0; i < MAX_CERT_DEPTH; i++) {
filestack[i] = uri;
@@ -171,9 +171,11 @@ parse_load_certchain(char *uri)
uri = filestack[i];
 
crl = crl_get(, a);
-   if 

Re: vmd: fix booting 7.2 ramdisks with >= 4G mem

2022-11-28 Thread Mike Larkin
On Mon, Nov 28, 2022 at 11:32:32AM -0500, Dave Voutila wrote:
> tech@ et. al.,
>
> When kettenis@ introduced a newer version of BOOTARG_CONSDEV to add
> additional params for the AMD Ryzen V1000 family, vmd's code that
> configures bootargs to support direct booting a ramdisk kernel didn't
> adjust with it.
>
> Mischa Peters found this and shared a simple reproducer on 7.2 and
> -current:
>
> # vmctl start -c -b /bsd.rd -m 4G test
>
> Where /bsd.rd is a 7.2 or -current ramdisk kernel.
>
> Interestingly, this is only seen when using 4G (or more) memory for the
> guest. I think it's just a happy coincedence it works < 4G because of
> the resulting BOOTARG_MEMMAP sizing things so the BOOTARG_CONSDEV works.
>
> Diff below fixes the issue by simply zero'ing the BOOTARG_CONSDEV
> structure before assigning to members.
>
> While here, I also cleaned up some things like using literal values that
> could be more descriptive boot arg names and also made the arithmetic
> explicitly use the same type (uint32_t) throughout instead of mixing it
> with int.
>
> ok?
>

ok mlarkin

> -dv
>
> diff refs/heads/master refs/heads/vmd-ramdisk
> commit - 8cbcfb178c36f28f6fcb28289719a4f0547eabb4
> commit + 0be12dfaa063ded82837d3a6b2ce8df7ea7e1c2d
> blob - b367721e32b61892955bbf835b873034875c85ec
> blob + d560b8e8eb2cdd87a60c63e8ecb7fed56e5c60dc
> --- usr.sbin/vmd/loadfile_elf.c
> +++ usr.sbin/vmd/loadfile_elf.c
> @@ -382,9 +382,10 @@ create_bios_memmap(struct vm_create_params *vcp, bios_
>   * Parameters:
>   *  memmap: the BIOS memory map
>   *  n: number of entries in memmap
> + *  bootmac: optional PXE boot MAC address
>   *
>   * Return values:
> - *  The size of the bootargs
> + *  The size of the bootargs in bytes
>   */
>  static uint32_t
>  push_bootargs(bios_memmap_t *memmap, size_t n, bios_bootmac_t *bootmac)
> @@ -393,40 +394,41 @@ push_bootargs(bios_memmap_t *memmap, size_t n, bios_bo
>   bios_consdev_t consdev;
>   uint32_t ba[1024];
>
> - memmap_sz = 3 * sizeof(int) + n * sizeof(bios_memmap_t);
> - ba[0] = 0x0;/* memory map */
> + memmap_sz = 3 * sizeof(uint32_t) + n * sizeof(bios_memmap_t);
> + ba[0] = BOOTARG_MEMMAP;
>   ba[1] = memmap_sz;
> - ba[2] = memmap_sz;  /* next */
> + ba[2] = memmap_sz;
>   memcpy([3], memmap, n * sizeof(bios_memmap_t));
> - i = memmap_sz / sizeof(int);
> + i = memmap_sz / sizeof(uint32_t);
>
>   /* Serial console device, COM1 @ 0x3f8 */
> - consdev.consdev = makedev(8, 0);/* com1 @ 0x3f8 */
> + memset(, 0, sizeof(consdev));
> + consdev.consdev = makedev(8, 0);
>   consdev.conspeed = 115200;
>   consdev.consaddr = 0x3f8;
> - consdev.consfreq = 0;
>
> - consdev_sz = 3 * sizeof(int) + sizeof(bios_consdev_t);
> - ba[i] = 0x5;   /* consdev */
> + consdev_sz = 3 * sizeof(uint32_t) + sizeof(bios_consdev_t);
> + ba[i] = BOOTARG_CONSDEV;
>   ba[i + 1] = consdev_sz;
>   ba[i + 2] = consdev_sz;
>   memcpy([i + 3], , sizeof(bios_consdev_t));
> - i += consdev_sz / sizeof(int);
> + i += consdev_sz / sizeof(uint32_t);
>
>   if (bootmac) {
> - bootmac_sz = 3 * sizeof(int) + (sizeof(bios_bootmac_t) + 3) & 
> ~3;
> - ba[i] = 0x7;   /* bootmac */
> + bootmac_sz = 3 * sizeof(uint32_t) +
> + (sizeof(bios_bootmac_t) + 3) & ~3;
> + ba[i] = BOOTARG_BOOTMAC;
>   ba[i + 1] = bootmac_sz;
>   ba[i + 2] = bootmac_sz;
>   memcpy([i + 3], bootmac, sizeof(bios_bootmac_t));
> - i += bootmac_sz / sizeof(int);
> + i += bootmac_sz / sizeof(uint32_t);
>   }
>
>   ba[i++] = 0x; /* BOOTARG_END */
>
>   write_mem(BOOTARGS_PAGE, ba, PAGE_SIZE);
>
> - return (i * sizeof(int));
> + return (i * sizeof(uint32_t));
>  }
>
>  /*



Unlock getsockopt(2)

2022-11-28 Thread Vitaliy Makkoveev
Subj.

At sockets layer we touch only per-socket data, which is solock()
protected().

At protocol layer, unix(4) and key management sockets have no
(*pr_ctloutput)() handlers. route_ctloutput() touches only per socket
data, which is solock() protected. inet{,6} globals are protected by
netlock, which is solock() backend for corresponding sockets.

Index: sys/kern/syscalls.master
===
RCS file: /cvs/src/sys/kern/syscalls.master,v
retrieving revision 1.236
diff -u -p -r1.236 syscalls.master
--- sys/kern/syscalls.master9 Nov 2022 10:26:28 -   1.236
+++ sys/kern/syscalls.master28 Nov 2022 17:29:03 -
@@ -249,7 +249,7 @@
struct timespec *timeout); }
 117STD NOLOCK  { int sys_sendmmsg(int s,  struct mmsghdr *mmsg,\
unsigned int vlen, int flags); }
-118STD { int sys_getsockopt(int s, int level, int name, \
+118STD NOLOCK  { int sys_getsockopt(int s, int level, int name, \
void *val, socklen_t *avalsize); }
 119STD { int sys_thrkill(pid_t tid, int signum, void *tcb); }
 120STD NOLOCK  { ssize_t sys_readv(int fd, \



Re: vmd: fix booting 7.2 ramdisks with >= 4G mem

2022-11-28 Thread Claudio Jeker
On Mon, Nov 28, 2022 at 11:32:32AM -0500, Dave Voutila wrote:
> tech@ et. al.,
> 
> When kettenis@ introduced a newer version of BOOTARG_CONSDEV to add
> additional params for the AMD Ryzen V1000 family, vmd's code that
> configures bootargs to support direct booting a ramdisk kernel didn't
> adjust with it.
> 
> Mischa Peters found this and shared a simple reproducer on 7.2 and
> -current:
> 
> # vmctl start -c -b /bsd.rd -m 4G test
> 
> Where /bsd.rd is a 7.2 or -current ramdisk kernel.
> 
> Interestingly, this is only seen when using 4G (or more) memory for the
> guest. I think it's just a happy coincedence it works < 4G because of
> the resulting BOOTARG_MEMMAP sizing things so the BOOTARG_CONSDEV works.
> 
> Diff below fixes the issue by simply zero'ing the BOOTARG_CONSDEV
> structure before assigning to members.
> 
> While here, I also cleaned up some things like using literal values that
> could be more descriptive boot arg names and also made the arithmetic
> explicitly use the same type (uint32_t) throughout instead of mixing it
> with int.
> 
> ok?

OK claudio@
 
PS: diff did not apply, a space got stripped below diff should apply
-- 
:wq Claudio

Index: loadfile_elf.c
===
RCS file: /cvs/src/usr.sbin/vmd/loadfile_elf.c,v
retrieving revision 1.42
diff -u -p -r1.42 loadfile_elf.c
--- loadfile_elf.c  28 Jan 2022 06:33:27 -  1.42
+++ loadfile_elf.c  28 Nov 2022 17:07:20 -
@@ -382,9 +382,10 @@ create_bios_memmap(struct vm_create_para
  * Parameters:
  *  memmap: the BIOS memory map
  *  n: number of entries in memmap
+ *  bootmac: optional PXE boot MAC address
  *
  * Return values:
- *  The size of the bootargs
+ *  The size of the bootargs in bytes
  */
 static uint32_t
 push_bootargs(bios_memmap_t *memmap, size_t n, bios_bootmac_t *bootmac)
@@ -393,40 +394,41 @@ push_bootargs(bios_memmap_t *memmap, siz
bios_consdev_t consdev;
uint32_t ba[1024];
 
-   memmap_sz = 3 * sizeof(int) + n * sizeof(bios_memmap_t);
-   ba[0] = 0x0;/* memory map */
+   memmap_sz = 3 * sizeof(uint32_t) + n * sizeof(bios_memmap_t);
+   ba[0] = BOOTARG_MEMMAP;
ba[1] = memmap_sz;
-   ba[2] = memmap_sz;  /* next */
+   ba[2] = memmap_sz;
memcpy([3], memmap, n * sizeof(bios_memmap_t));
-   i = memmap_sz / sizeof(int);
+   i = memmap_sz / sizeof(uint32_t);
 
/* Serial console device, COM1 @ 0x3f8 */
-   consdev.consdev = makedev(8, 0);/* com1 @ 0x3f8 */
+   memset(, 0, sizeof(consdev));
+   consdev.consdev = makedev(8, 0);
consdev.conspeed = 115200;
consdev.consaddr = 0x3f8;
-   consdev.consfreq = 0;
 
-   consdev_sz = 3 * sizeof(int) + sizeof(bios_consdev_t);
-   ba[i] = 0x5;   /* consdev */
+   consdev_sz = 3 * sizeof(uint32_t) + sizeof(bios_consdev_t);
+   ba[i] = BOOTARG_CONSDEV;
ba[i + 1] = consdev_sz;
ba[i + 2] = consdev_sz;
memcpy([i + 3], , sizeof(bios_consdev_t));
-   i += consdev_sz / sizeof(int);
+   i += consdev_sz / sizeof(uint32_t);
 
if (bootmac) {
-   bootmac_sz = 3 * sizeof(int) + (sizeof(bios_bootmac_t) + 3) & 
~3;
-   ba[i] = 0x7;   /* bootmac */
+   bootmac_sz = 3 * sizeof(uint32_t) +
+   (sizeof(bios_bootmac_t) + 3) & ~3;
+   ba[i] = BOOTARG_BOOTMAC;
ba[i + 1] = bootmac_sz;
ba[i + 2] = bootmac_sz;
memcpy([i + 3], bootmac, sizeof(bios_bootmac_t));
-   i += bootmac_sz / sizeof(int);
-   } 
+   i += bootmac_sz / sizeof(uint32_t);
+   }
 
ba[i++] = 0x; /* BOOTARG_END */
 
write_mem(BOOTARGS_PAGE, ba, PAGE_SIZE);
 
-   return (i * sizeof(int));
+   return (i * sizeof(uint32_t));
 }
 
 /*



Re: Improve rpki-client warnings on .mft files

2022-11-28 Thread Theo Buehler
On Mon, Nov 28, 2022 at 05:14:48PM +0100, Claudio Jeker wrote:
> On Mon, Nov 28, 2022 at 04:50:24PM +0100, Theo Buehler wrote:
> > On Mon, Nov 28, 2022 at 04:02:11PM +0100, Claudio Jeker wrote:
> > > Since a long time any problem that caused rpki-client to not load a
> > > manifest resulted in the non helpful:
> > > rpki-client: 
> > > rpki.afrinic.net/repository/member_repository/F36505B2/0569917622D711ED862FD6E0F1222468/0nALpPtwFyntPHjkS8xt-VQrqLw.mft:
> > >  no valid mft available
> > > 
> > > This hides in most cases the cause why the manifest verificatin failed.
> > > The following diff exposes the error from valid_x509() and with that some
> > > manifest errors change to e.g.:
> > > rpki-client: 
> > > parent.rov.koenvanhove.nl/repo/KoenvanHove/1/C1F7424F77FBF669FB750C6DC7B649C5969DCD55.mft:
> > >  CRL has expired
> > > 
> > > or if the CRL is missing
> > > 
> > > rpki-client: 
> > > repo.pedjoeang.group/repo/localname/0/EF79F8E55B6A248EF9CF4CE70FF60C017BF1A3B0.mft:
> > >  unable to get certificate CRL
> > > 
> > > If the certificate is pointing to a manifest that does not exist the old
> > > "no valid mft available" is shown.
> > > 
> > > I tried to keep original behaviour as much as possible but I think
> > > filemode can be further improved. And maybe we can remove verbose from
> > > other warnings as well.
> > 
> > I like this a lot.
> > 
> > I was wondering if valid_x509() should have a const char **errstr
> > instead of an int * as last argument. valid_x509() could do the
> > conversion from error code to error string itself. This way we don't
> > have to sprinkle X509_verify_cert_error_string() calls everywhere.
> > 
> > Or we could introduce a warn_invalid_x509(const char *str, int err) that
> > does the conversion from err using X509_verify_cert_error_string().
> > 
> > One downside of X509_verify_cert_error_string() is that it isn't thread
> > safe since it might return a pointer to a static buffer -- it should
> > not, but who can be sure...
> 
> Tough call. It may also help other code paths to do the same. But in many
> cases a dynamic buffer would be needed.
> 
> Not sure if it makes sense to introduce warn_invalid_x509(). What I don't
> like is the verbose check before the warning. I wonder if we still need
> that. My last run has 11 failed roas and 51 failed mfts. The mft errors
> already show up. Shouldn't the roa errors be shown as well?

They should. Unless I'm completely confusing myself, this is a bug in
the diff and all the added if (verbose > 1) should be dropped.

If the last argument (nowarn) of valid_x509() was 0 (everywhere except
in proc_parser_pre()), valid_x509() would print the error independently
of verbose. verbose > 1 would force printing the warning also for mfts,
but there it would be drowned in the other noise.

-   if (!valid_x509(file, ctx, x509, a, crl, 0)) {

...

-   if (!nowarn || verbose > 1)
-   warnx("%s: %s", file, X509_verify_cert_error_string(c));


>  
> > > 
> > > -- 
> > > :wq Claudio
> > > 
> > > Index: extern.h
> > > ===
> > > RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v
> > > retrieving revision 1.161
> > > diff -u -p -r1.161 extern.h
> > > --- extern.h  26 Nov 2022 12:02:36 -  1.161
> > > +++ extern.h  28 Nov 2022 10:42:11 -
> > > @@ -629,7 +629,7 @@ intvalid_filename(const char *, size_
> > >  int   valid_uri(const char *, size_t, const char *);
> > >  int   valid_origin(const char *, const char *);
> > >  int   valid_x509(char *, X509_STORE_CTX *, X509 *, struct 
> > > auth *,
> > > - struct crl *, int);
> > > + struct crl *, int *);
> > >  int   valid_rsc(const char *, struct cert *, struct rsc *);
> > >  int   valid_econtent_version(const char *, const 
> > > ASN1_INTEGER *);
> > >  int   valid_aspa(const char *, struct cert *, struct aspa *);
> > > Index: filemode.c
> > > ===
> > > RCS file: /cvs/src/usr.sbin/rpki-client/filemode.c,v
> > > retrieving revision 1.17
> > > diff -u -p -r1.17 filemode.c
> > > --- filemode.c26 Nov 2022 12:02:37 -  1.17
> > > +++ filemode.c28 Nov 2022 11:08:31 -
> > > @@ -141,7 +141,7 @@ parse_load_certchain(char *uri)
> > >   struct cert *cert;
> > >   struct crl *crl;
> > >   struct auth *a;
> > > - int i;
> > > + int i, e;
> > >  
> > >   for (i = 0; i < MAX_CERT_DEPTH; i++) {
> > >   filestack[i] = uri;
> > > @@ -171,9 +171,13 @@ parse_load_certchain(char *uri)
> > >   uri = filestack[i];
> > >  
> > >   crl = crl_get(, a);
> > > - if (!valid_x509(uri, ctx, cert->x509, a, crl, 0) ||
> > > - !valid_cert(uri, a, cert))
> > > + if (!valid_x509(uri, ctx, cert->x509, a, crl, ) ||
> > > + !valid_cert(uri, a, cert)) {
> > > + 

vmd: fix booting 7.2 ramdisks with >= 4G mem

2022-11-28 Thread Dave Voutila
tech@ et. al.,

When kettenis@ introduced a newer version of BOOTARG_CONSDEV to add
additional params for the AMD Ryzen V1000 family, vmd's code that
configures bootargs to support direct booting a ramdisk kernel didn't
adjust with it.

Mischa Peters found this and shared a simple reproducer on 7.2 and
-current:

# vmctl start -c -b /bsd.rd -m 4G test

Where /bsd.rd is a 7.2 or -current ramdisk kernel.

Interestingly, this is only seen when using 4G (or more) memory for the
guest. I think it's just a happy coincedence it works < 4G because of
the resulting BOOTARG_MEMMAP sizing things so the BOOTARG_CONSDEV works.

Diff below fixes the issue by simply zero'ing the BOOTARG_CONSDEV
structure before assigning to members.

While here, I also cleaned up some things like using literal values that
could be more descriptive boot arg names and also made the arithmetic
explicitly use the same type (uint32_t) throughout instead of mixing it
with int.

ok?

-dv

diff refs/heads/master refs/heads/vmd-ramdisk
commit - 8cbcfb178c36f28f6fcb28289719a4f0547eabb4
commit + 0be12dfaa063ded82837d3a6b2ce8df7ea7e1c2d
blob - b367721e32b61892955bbf835b873034875c85ec
blob + d560b8e8eb2cdd87a60c63e8ecb7fed56e5c60dc
--- usr.sbin/vmd/loadfile_elf.c
+++ usr.sbin/vmd/loadfile_elf.c
@@ -382,9 +382,10 @@ create_bios_memmap(struct vm_create_params *vcp, bios_
  * Parameters:
  *  memmap: the BIOS memory map
  *  n: number of entries in memmap
+ *  bootmac: optional PXE boot MAC address
  *
  * Return values:
- *  The size of the bootargs
+ *  The size of the bootargs in bytes
  */
 static uint32_t
 push_bootargs(bios_memmap_t *memmap, size_t n, bios_bootmac_t *bootmac)
@@ -393,40 +394,41 @@ push_bootargs(bios_memmap_t *memmap, size_t n, bios_bo
bios_consdev_t consdev;
uint32_t ba[1024];

-   memmap_sz = 3 * sizeof(int) + n * sizeof(bios_memmap_t);
-   ba[0] = 0x0;/* memory map */
+   memmap_sz = 3 * sizeof(uint32_t) + n * sizeof(bios_memmap_t);
+   ba[0] = BOOTARG_MEMMAP;
ba[1] = memmap_sz;
-   ba[2] = memmap_sz;  /* next */
+   ba[2] = memmap_sz;
memcpy([3], memmap, n * sizeof(bios_memmap_t));
-   i = memmap_sz / sizeof(int);
+   i = memmap_sz / sizeof(uint32_t);

/* Serial console device, COM1 @ 0x3f8 */
-   consdev.consdev = makedev(8, 0);/* com1 @ 0x3f8 */
+   memset(, 0, sizeof(consdev));
+   consdev.consdev = makedev(8, 0);
consdev.conspeed = 115200;
consdev.consaddr = 0x3f8;
-   consdev.consfreq = 0;

-   consdev_sz = 3 * sizeof(int) + sizeof(bios_consdev_t);
-   ba[i] = 0x5;   /* consdev */
+   consdev_sz = 3 * sizeof(uint32_t) + sizeof(bios_consdev_t);
+   ba[i] = BOOTARG_CONSDEV;
ba[i + 1] = consdev_sz;
ba[i + 2] = consdev_sz;
memcpy([i + 3], , sizeof(bios_consdev_t));
-   i += consdev_sz / sizeof(int);
+   i += consdev_sz / sizeof(uint32_t);

if (bootmac) {
-   bootmac_sz = 3 * sizeof(int) + (sizeof(bios_bootmac_t) + 3) & 
~3;
-   ba[i] = 0x7;   /* bootmac */
+   bootmac_sz = 3 * sizeof(uint32_t) +
+   (sizeof(bios_bootmac_t) + 3) & ~3;
+   ba[i] = BOOTARG_BOOTMAC;
ba[i + 1] = bootmac_sz;
ba[i + 2] = bootmac_sz;
memcpy([i + 3], bootmac, sizeof(bios_bootmac_t));
-   i += bootmac_sz / sizeof(int);
+   i += bootmac_sz / sizeof(uint32_t);
}

ba[i++] = 0x; /* BOOTARG_END */

write_mem(BOOTARGS_PAGE, ba, PAGE_SIZE);

-   return (i * sizeof(int));
+   return (i * sizeof(uint32_t));
 }

 /*



Re: Improve rpki-client warnings on .mft files

2022-11-28 Thread Claudio Jeker
On Mon, Nov 28, 2022 at 04:50:24PM +0100, Theo Buehler wrote:
> On Mon, Nov 28, 2022 at 04:02:11PM +0100, Claudio Jeker wrote:
> > Since a long time any problem that caused rpki-client to not load a
> > manifest resulted in the non helpful:
> > rpki-client: 
> > rpki.afrinic.net/repository/member_repository/F36505B2/0569917622D711ED862FD6E0F1222468/0nALpPtwFyntPHjkS8xt-VQrqLw.mft:
> >  no valid mft available
> > 
> > This hides in most cases the cause why the manifest verificatin failed.
> > The following diff exposes the error from valid_x509() and with that some
> > manifest errors change to e.g.:
> > rpki-client: 
> > parent.rov.koenvanhove.nl/repo/KoenvanHove/1/C1F7424F77FBF669FB750C6DC7B649C5969DCD55.mft:
> >  CRL has expired
> > 
> > or if the CRL is missing
> > 
> > rpki-client: 
> > repo.pedjoeang.group/repo/localname/0/EF79F8E55B6A248EF9CF4CE70FF60C017BF1A3B0.mft:
> >  unable to get certificate CRL
> > 
> > If the certificate is pointing to a manifest that does not exist the old
> > "no valid mft available" is shown.
> > 
> > I tried to keep original behaviour as much as possible but I think
> > filemode can be further improved. And maybe we can remove verbose from
> > other warnings as well.
> 
> I like this a lot.
> 
> I was wondering if valid_x509() should have a const char **errstr
> instead of an int * as last argument. valid_x509() could do the
> conversion from error code to error string itself. This way we don't
> have to sprinkle X509_verify_cert_error_string() calls everywhere.
> 
> Or we could introduce a warn_invalid_x509(const char *str, int err) that
> does the conversion from err using X509_verify_cert_error_string().
> 
> One downside of X509_verify_cert_error_string() is that it isn't thread
> safe since it might return a pointer to a static buffer -- it should
> not, but who can be sure...

Tough call. It may also help other code paths to do the same. But in many
cases a dynamic buffer would be needed.

Not sure if it makes sense to introduce warn_invalid_x509(). What I don't
like is the verbose check before the warning. I wonder if we still need
that. My last run has 11 failed roas and 51 failed mfts. The mft errors
already show up. Shouldn't the roa errors be shown as well?
 
> > 
> > -- 
> > :wq Claudio
> > 
> > Index: extern.h
> > ===
> > RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v
> > retrieving revision 1.161
> > diff -u -p -r1.161 extern.h
> > --- extern.h26 Nov 2022 12:02:36 -  1.161
> > +++ extern.h28 Nov 2022 10:42:11 -
> > @@ -629,7 +629,7 @@ int  valid_filename(const char *, size_
> >  int valid_uri(const char *, size_t, const char *);
> >  int valid_origin(const char *, const char *);
> >  int valid_x509(char *, X509_STORE_CTX *, X509 *, struct 
> > auth *,
> > -   struct crl *, int);
> > +   struct crl *, int *);
> >  int valid_rsc(const char *, struct cert *, struct rsc *);
> >  int valid_econtent_version(const char *, const 
> > ASN1_INTEGER *);
> >  int valid_aspa(const char *, struct cert *, struct aspa *);
> > Index: filemode.c
> > ===
> > RCS file: /cvs/src/usr.sbin/rpki-client/filemode.c,v
> > retrieving revision 1.17
> > diff -u -p -r1.17 filemode.c
> > --- filemode.c  26 Nov 2022 12:02:37 -  1.17
> > +++ filemode.c  28 Nov 2022 11:08:31 -
> > @@ -141,7 +141,7 @@ parse_load_certchain(char *uri)
> > struct cert *cert;
> > struct crl *crl;
> > struct auth *a;
> > -   int i;
> > +   int i, e;
> >  
> > for (i = 0; i < MAX_CERT_DEPTH; i++) {
> > filestack[i] = uri;
> > @@ -171,9 +171,13 @@ parse_load_certchain(char *uri)
> > uri = filestack[i];
> >  
> > crl = crl_get(, a);
> > -   if (!valid_x509(uri, ctx, cert->x509, a, crl, 0) ||
> > -   !valid_cert(uri, a, cert))
> > +   if (!valid_x509(uri, ctx, cert->x509, a, crl, ) ||
> > +   !valid_cert(uri, a, cert)) {
> > +   if (verbose > 1)
> > +   warnx("%s: %s", uri,
> > +   X509_verify_cert_error_string(e));
> > goto fail;
> > +   }
> > cert->talid = a->cert->talid;
> > a = auth_insert(, cert, a);
> > stack[i] = NULL;
> > @@ -275,7 +279,7 @@ proc_parser_file(char *file, unsigned ch
> > char filehash[SHA256_DIGEST_LENGTH];
> > char *hash;
> > enum rtype type;
> > -   int is_ta = 0;
> > +   int is_ta = 0, e;
> >  
> > if (num++ > 0) {
> > if ((outformats & FORMAT_JSON) == 0)
> > @@ -418,7 +422,7 @@ proc_parser_file(char *file, unsigned ch
> > a = auth_find(, aki);
> > c = crl_get(, a);
> >  
> > -   if ((status = 

Re: pfsync panic after pf_purge backout

2022-11-28 Thread Alexandr Nedvedicky
Hello,


> 
> 
> Hi,
> 
> here's panic with WITNESS and this diff on tech@
> https://www.mail-archive.com/tech@openbsd.org/msg72582.html
> 
> I will stop now because I'm not sure what I'm doing and which diffs I'm
> testing...
> 
> 
> r620-1# uvm_fault(0x8248ea28, 0x17, 0, 2) -> e
> kernel: page fault trap, code=0
> Stopped at  pfsync_q_del+0x96:  movq%rdx,0x8(%rax)
> TIDPIDUID PRFLAGS PFLAGS  CPU  COMMAND
> *300703  35643  0 0x14000  0x2001K systq
>  237790  10061  0 0x14000 0x42000  softclock
> pfsync_q_del(fd8323dc3900) at pfsync_q_del+0x96
> pfsync_delete_state(fd8323dc3900) at pfsync_delete_state+0x118
> pf_remove_state(fd8323dc3900) at pf_remove_state+0x14e
> pf_purge_expired_states(c3501) at pf_purge_expired_states+0x1b3
> pf_purge(823ae080) at pf_purge+0x28
> taskq_thread(822cbe30) at taskq_thread+0x11a
> end trace frame: 0x0, count: 9
> 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{1}>
> 
> 

diff below should avoid panic above (and similar panics in pfsync_q_del().
It also prints some 'error' system message buffer (a.k.a. dmesg)

We panic because we attempt to remove state from psync queue which is
already empty. the pfsync_q_del() must be acting on some stale information
kept in `st` argument (state).

the information we print into dmesg buffer should help us understand
what's going on. At the moment I can not explain how does it come
there is a state which claims its presence on state queue, while the
queue in question is empty.

I'd like to ask you to give a try diff below and repeat your test.
Let it run for some time and collect 'dmesg' output for me after usual
uptime-to-panic elapses during a test run.

thanks a lot
regards
sashan

8<---8<---8<--8<
diff --git a/sys/net/if_pfsync.c b/sys/net/if_pfsync.c
index f69790ee98d..d4be84a1f57 100644
--- a/sys/net/if_pfsync.c
+++ b/sys/net/if_pfsync.c
@@ -2254,6 +2254,74 @@ pfsync_q_ins(struct pf_state *st, int q)
} while (0);
 }
 
+const char *
+pfsync_qname(int q)
+{
+   switch (q) {
+   case PFSYNC_S_IACK:
+   return ("PFSYNC_S_IACK");
+   
+   case PFSYNC_S_UPD_C:
+   return ("PFSYNC_S_UPD_C");
+
+   case PFSYNC_S_DEL:
+   return ("PFSYNC_S_DEL");
+
+   case PFSYNC_S_INS:
+   return ("PFSYNC_S_INS");
+
+   case PFSYNC_S_UPD:
+   return ("PFSYNC_S_UPD");
+
+   case PFSYNC_S_COUNT:
+   return ("PFSYNC_S_COUNT");
+
+   case PFSYNC_S_DEFER:
+   return ("PFSYNC_S_DEFER");
+
+   case PFSYNC_S_NONE:
+   return ("PFSYNC_S_NONE");
+
+   default:
+   return ("???");
+   }
+}
+
+const char *
+pfsync_timeout_name(unsigned int timeout)
+{
+   const char *timeout_name[] = {
+   "PFTM_TCP_FIRST_PACKET",
+   "PFTM_TCP_OPENING",
+   "PFTM_TCP_ESTABLISHED",
+   "PFTM_TCP_CLOSING",
+   "PFTM_TCP_FIN_WAIT",
+   "PFTM_TCP_CLOSED",
+   "PFTM_UDP_FIRST_PACKET",
+   "PFTM_UDP_SINGLE",
+   "PFTM_UDP_MULTIPLE",
+   "PFTM_ICMP_FIRST_PACKET",
+   "PFTM_ICMP_ERROR_REPLY",
+   "PFTM_OTHER_FIRST_PACKET",
+   "PFTM_OTHER_SINGLE",
+   "PFTM_OTHER_MULTIPLE",
+   "PFTM_FRAG",
+   "PFTM_INTERVAL",
+   "PFTM_ADAPTIVE_START",
+   "PFTM_ADAPTIVE_END",
+   "PFTM_SRC_NODE",
+   "PFTM_TS_DIFF",
+   "PFTM_MAX",
+   "PFTM_PURGE",
+   "PFTM_UNLINKED"
+   };
+
+   if (timeout > PFTM_UNLINKED)
+   return ("???");
+   else
+   return (timeout_name[timeout]);
+}
+
 void
 pfsync_q_del(struct pf_state *st)
 {
@@ -2273,6 +2341,19 @@ pfsync_q_del(struct pf_state *st)
mtx_leave(>sc_st_mtx);
return;
}
+
+   if (TAILQ_EMPTY(>sc_qs[q])) {
+   mtx_leave(>sc_st_mtx);
+   DPFPRINTF(LOG_ERR,
+   "%s: stale queue (%s) in state (id %llu)"
+   "nosync: %s unlinked: %s timeout: %s", __func__,
+   pfsync_qname(q), st->id,
+   (st->state_flags & PFSTATE_NOSYNC) ? "yes" : "no",
+   (st->timeout == PFTM_UNLINKED) ? "yes" : "no",
+   pfsync_timeout_name(st->timeout));
+   return;
+   }
+
atomic_sub_long(>sc_len, pfsync_qs[q].len);
TAILQ_REMOVE(>sc_qs[q], st, sync_list);
if (TAILQ_EMPTY(>sc_qs[q]))



Re: Improve rpki-client warnings on .mft files

2022-11-28 Thread Theo Buehler
On Mon, Nov 28, 2022 at 04:02:11PM +0100, Claudio Jeker wrote:
> Since a long time any problem that caused rpki-client to not load a
> manifest resulted in the non helpful:
> rpki-client: 
> rpki.afrinic.net/repository/member_repository/F36505B2/0569917622D711ED862FD6E0F1222468/0nALpPtwFyntPHjkS8xt-VQrqLw.mft:
>  no valid mft available
> 
> This hides in most cases the cause why the manifest verificatin failed.
> The following diff exposes the error from valid_x509() and with that some
> manifest errors change to e.g.:
> rpki-client: 
> parent.rov.koenvanhove.nl/repo/KoenvanHove/1/C1F7424F77FBF669FB750C6DC7B649C5969DCD55.mft:
>  CRL has expired
> 
> or if the CRL is missing
> 
> rpki-client: 
> repo.pedjoeang.group/repo/localname/0/EF79F8E55B6A248EF9CF4CE70FF60C017BF1A3B0.mft:
>  unable to get certificate CRL
> 
> If the certificate is pointing to a manifest that does not exist the old
> "no valid mft available" is shown.
> 
> I tried to keep original behaviour as much as possible but I think
> filemode can be further improved. And maybe we can remove verbose from
> other warnings as well.

I like this a lot.

I was wondering if valid_x509() should have a const char **errstr
instead of an int * as last argument. valid_x509() could do the
conversion from error code to error string itself. This way we don't
have to sprinkle X509_verify_cert_error_string() calls everywhere.

Or we could introduce a warn_invalid_x509(const char *str, int err) that
does the conversion from err using X509_verify_cert_error_string().

One downside of X509_verify_cert_error_string() is that it isn't thread
safe since it might return a pointer to a static buffer -- it should
not, but who can be sure...

> 
> -- 
> :wq Claudio
> 
> Index: extern.h
> ===
> RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v
> retrieving revision 1.161
> diff -u -p -r1.161 extern.h
> --- extern.h  26 Nov 2022 12:02:36 -  1.161
> +++ extern.h  28 Nov 2022 10:42:11 -
> @@ -629,7 +629,7 @@ intvalid_filename(const char *, size_
>  int   valid_uri(const char *, size_t, const char *);
>  int   valid_origin(const char *, const char *);
>  int   valid_x509(char *, X509_STORE_CTX *, X509 *, struct auth *,
> - struct crl *, int);
> + struct crl *, int *);
>  int   valid_rsc(const char *, struct cert *, struct rsc *);
>  int   valid_econtent_version(const char *, const ASN1_INTEGER *);
>  int   valid_aspa(const char *, struct cert *, struct aspa *);
> Index: filemode.c
> ===
> RCS file: /cvs/src/usr.sbin/rpki-client/filemode.c,v
> retrieving revision 1.17
> diff -u -p -r1.17 filemode.c
> --- filemode.c26 Nov 2022 12:02:37 -  1.17
> +++ filemode.c28 Nov 2022 11:08:31 -
> @@ -141,7 +141,7 @@ parse_load_certchain(char *uri)
>   struct cert *cert;
>   struct crl *crl;
>   struct auth *a;
> - int i;
> + int i, e;
>  
>   for (i = 0; i < MAX_CERT_DEPTH; i++) {
>   filestack[i] = uri;
> @@ -171,9 +171,13 @@ parse_load_certchain(char *uri)
>   uri = filestack[i];
>  
>   crl = crl_get(, a);
> - if (!valid_x509(uri, ctx, cert->x509, a, crl, 0) ||
> - !valid_cert(uri, a, cert))
> + if (!valid_x509(uri, ctx, cert->x509, a, crl, ) ||
> + !valid_cert(uri, a, cert)) {
> + if (verbose > 1)
> + warnx("%s: %s", uri,
> + X509_verify_cert_error_string(e));
>   goto fail;
> + }
>   cert->talid = a->cert->talid;
>   a = auth_insert(, cert, a);
>   stack[i] = NULL;
> @@ -275,7 +279,7 @@ proc_parser_file(char *file, unsigned ch
>   char filehash[SHA256_DIGEST_LENGTH];
>   char *hash;
>   enum rtype type;
> - int is_ta = 0;
> + int is_ta = 0, e;
>  
>   if (num++ > 0) {
>   if ((outformats & FORMAT_JSON) == 0)
> @@ -418,7 +422,7 @@ proc_parser_file(char *file, unsigned ch
>   a = auth_find(, aki);
>   c = crl_get(, a);
>  
> - if ((status = valid_x509(file, ctx, x509, a, c, 0))) {
> + if ((status = valid_x509(file, ctx, x509, a, c, ))) {
>   switch (type) {
>   case RTYPE_ROA:
>   status = roa->valid;
> @@ -438,8 +442,12 @@ proc_parser_file(char *file, unsigned ch
>   }
>   if (status)
>   printf("OK");
> - else
> + else {
> + if (verbose > 1)
> + warnx("%s: %s", file,
> + X509_verify_cert_error_string(e));
>   printf("Failed");
> + }
>   

Do not store unused ICMPv6 Option PREFIX_INFORMATION

2022-11-28 Thread Klemens Nanni
Dead since 2017 sys/netinet6/nd6_rtr.c r1.163
Remove sending of router solicitations and processing of router
advertisements from the kernel. It's handled by slaacd(8) these days.

Multiple prefixes are fine, so sysctl(2) net.inet6.icmp6.nd6_debug does not
warn about it like it does for, e.g., duplicate MTU options, so don't do
anything with this option.

Remove access macros for other unused options while here.
All under _KERNEL.

tcpdump(8)/rad(8)/slaacd(8) keep showing/sending/receiving this option when
running this diff on both router and client.

Feedback? Objection? OK?

NB:  I suspect that nd6.h's union nd_opt can be cleaned up/reduced in
size, but nd6.c's nd6_option() and nd6_options() are not trivial, so
here goes the option handling alone for now.

diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c
index 1c7bf7d985b..9c7f2c422ca 100644
--- a/sys/netinet6/nd6.c
+++ b/sys/netinet6/nd6.c
@@ -251,13 +251,6 @@ nd6_options(union nd_opts *ndopts)
}
break;
case ND_OPT_PREFIX_INFORMATION:
-   if (ndopts->nd_opt_array[nd_opt->nd_opt_type] == 0) {
-   ndopts->nd_opt_array[nd_opt->nd_opt_type]
-   = nd_opt;
-   }
-   ndopts->nd_opts_pi_end =
-   (struct nd_opt_prefix_info *)nd_opt;
-   break;
case ND_OPT_DNSSL:
case ND_OPT_RDNSS:
/* Don't warn */
diff --git a/sys/netinet6/nd6.h b/sys/netinet6/nd6.h
index 2b441bd97e7..8d67c66d961 100644
--- a/sys/netinet6/nd6.h
+++ b/sys/netinet6/nd6.h
@@ -127,10 +127,6 @@ union nd_opts {
 };
 #define nd_opts_src_lladdr nd_opt_each.src_lladdr
 #define nd_opts_tgt_lladdr nd_opt_each.tgt_lladdr
-#define nd_opts_pi nd_opt_each.pi_beg
-#define nd_opts_pi_end nd_opt_each.pi_end
-#define nd_opts_rh nd_opt_each.rh
-#define nd_opts_mtund_opt_each.mtu
 #define nd_opts_search nd_opt_each.search
 #define nd_opts_last   nd_opt_each.last
 #define nd_opts_done   nd_opt_each.done



Improve rpki-client warnings on .mft files

2022-11-28 Thread Claudio Jeker
Since a long time any problem that caused rpki-client to not load a
manifest resulted in the non helpful:
rpki-client: 
rpki.afrinic.net/repository/member_repository/F36505B2/0569917622D711ED862FD6E0F1222468/0nALpPtwFyntPHjkS8xt-VQrqLw.mft:
 no valid mft available

This hides in most cases the cause why the manifest verificatin failed.
The following diff exposes the error from valid_x509() and with that some
manifest errors change to e.g.:
rpki-client: 
parent.rov.koenvanhove.nl/repo/KoenvanHove/1/C1F7424F77FBF669FB750C6DC7B649C5969DCD55.mft:
 CRL has expired

or if the CRL is missing

rpki-client: 
repo.pedjoeang.group/repo/localname/0/EF79F8E55B6A248EF9CF4CE70FF60C017BF1A3B0.mft:
 unable to get certificate CRL

If the certificate is pointing to a manifest that does not exist the old
"no valid mft available" is shown.

I tried to keep original behaviour as much as possible but I think
filemode can be further improved. And maybe we can remove verbose from
other warnings as well.

-- 
:wq Claudio

Index: extern.h
===
RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v
retrieving revision 1.161
diff -u -p -r1.161 extern.h
--- extern.h26 Nov 2022 12:02:36 -  1.161
+++ extern.h28 Nov 2022 10:42:11 -
@@ -629,7 +629,7 @@ int  valid_filename(const char *, size_
 int valid_uri(const char *, size_t, const char *);
 int valid_origin(const char *, const char *);
 int valid_x509(char *, X509_STORE_CTX *, X509 *, struct auth *,
-   struct crl *, int);
+   struct crl *, int *);
 int valid_rsc(const char *, struct cert *, struct rsc *);
 int valid_econtent_version(const char *, const ASN1_INTEGER *);
 int valid_aspa(const char *, struct cert *, struct aspa *);
Index: filemode.c
===
RCS file: /cvs/src/usr.sbin/rpki-client/filemode.c,v
retrieving revision 1.17
diff -u -p -r1.17 filemode.c
--- filemode.c  26 Nov 2022 12:02:37 -  1.17
+++ filemode.c  28 Nov 2022 11:08:31 -
@@ -141,7 +141,7 @@ parse_load_certchain(char *uri)
struct cert *cert;
struct crl *crl;
struct auth *a;
-   int i;
+   int i, e;
 
for (i = 0; i < MAX_CERT_DEPTH; i++) {
filestack[i] = uri;
@@ -171,9 +171,13 @@ parse_load_certchain(char *uri)
uri = filestack[i];
 
crl = crl_get(, a);
-   if (!valid_x509(uri, ctx, cert->x509, a, crl, 0) ||
-   !valid_cert(uri, a, cert))
+   if (!valid_x509(uri, ctx, cert->x509, a, crl, ) ||
+   !valid_cert(uri, a, cert)) {
+   if (verbose > 1)
+   warnx("%s: %s", uri,
+   X509_verify_cert_error_string(e));
goto fail;
+   }
cert->talid = a->cert->talid;
a = auth_insert(, cert, a);
stack[i] = NULL;
@@ -275,7 +279,7 @@ proc_parser_file(char *file, unsigned ch
char filehash[SHA256_DIGEST_LENGTH];
char *hash;
enum rtype type;
-   int is_ta = 0;
+   int is_ta = 0, e;
 
if (num++ > 0) {
if ((outformats & FORMAT_JSON) == 0)
@@ -418,7 +422,7 @@ proc_parser_file(char *file, unsigned ch
a = auth_find(, aki);
c = crl_get(, a);
 
-   if ((status = valid_x509(file, ctx, x509, a, c, 0))) {
+   if ((status = valid_x509(file, ctx, x509, a, c, ))) {
switch (type) {
case RTYPE_ROA:
status = roa->valid;
@@ -438,8 +442,12 @@ proc_parser_file(char *file, unsigned ch
}
if (status)
printf("OK");
-   else
+   else {
+   if (verbose > 1)
+   warnx("%s: %s", file,
+   X509_verify_cert_error_string(e));
printf("Failed");
+   }
} else if (is_ta) {
if ((tal = find_tal(cert)) != NULL) {
cert = ta_parse(file, cert, tal->pkey, tal->pkeysz);
Index: parser.c
===
RCS file: /cvs/src/usr.sbin/rpki-client/parser.c,v
retrieving revision 1.78
diff -u -p -r1.78 parser.c
--- parser.c2 Nov 2022 12:43:02 -   1.78
+++ parser.c28 Nov 2022 14:39:37 -
@@ -132,6 +132,7 @@ proc_parser_roa(char *file, const unsign
struct auth *a;
struct crl  *crl;
X509*x509;
+   int  e;
 
if ((roa = roa_parse(, file, der, len)) == NULL)
return NULL;
@@ -139,7 +140,9 @@ proc_parser_roa(char *file, 

Re: Remove useless nd6_init_done from nd6_init()

2022-11-28 Thread Klemens Nanni
On Mon, Nov 28, 2022 at 02:54:31PM +0100, Alexander Bluhm wrote:
> > NB:  While here, nd6 and frag6 could statically initalise their lists
> > right away (they're both static/local to nd6.c and frag6.c anyway), but
> 
> I see no big adavantage of variable initializer over ..._init()
> function.  The latter is there anyway.
> 
> > that should probably be another diff, if at all, with more static added
> > to those files.
> 
> Why is static in the kernel a benefit?  There were times when static
> was no allowed to have more complete symbol list.

Seeing a static variable immediately tells me that it is not used
outside the function or compilation unit.

Imho, this makes it easier to work with the code, as you don't have to
cross-check and grep for variables, whether they're used somewhere else,
behind some language construct which made your grep not show it...

On the other hand, I do see how changing static around for existing code
is quite some churn, so I'll refrain from doing so here.



Re: Get rid of UVM_VNODE_CANPERSIST

2022-11-28 Thread Mark Kettenis
> Date: Wed, 23 Nov 2022 17:33:26 +0100
> From: Martin Pieuchot 
> 
> On 23/11/22(Wed) 16:34, Mark Kettenis wrote:
> > > Date: Wed, 23 Nov 2022 10:52:32 +0100
> > > From: Martin Pieuchot 
> > > 
> > > On 22/11/22(Tue) 23:40, Mark Kettenis wrote:
> > > > > Date: Tue, 22 Nov 2022 17:47:44 +
> > > > > From: Miod Vallat 
> > > > > 
> > > > > > Here is a diff.  Maybe bluhm@ can try this on the macppc machine 
> > > > > > that
> > > > > > triggered the original "vref used where vget required" problem?
> > > > > 
> > > > > On a similar machine it panics after a few hours with:
> > > > > 
> > > > > panic: uvn_flush: PGO_SYNCIO return 'try again' error (impossible)
> > > > > 
> > > > > The trace (transcribed by hand) is
> > > > > uvn_flush+0x820
> > > > > uvm_vnp_terminate+0x79
> > > > > vclean+0xdc
> > > > > vgonel+0x70
> > > > > getnewvnode+0x240
> > > > > ffs_vget+0xcc
> > > > > ffs_inode_alloc+0x13c
> > > > > ufs_makeinode+0x94
> > > > > ufs_create+0x58
> > > > > VOP_CREATE+0x48
> > > > > vn_open+0x188
> > > > > doopenat+0x1b4
> > > > 
> > > > Ah right, there is another path where we end up with a refcount of
> > > > zero.  Should be fixable, but I need to think about this for a bit.
> > > 
> > > Not sure to understand what you mean with refcount of 0.  Could you
> > > elaborate?
> > 
> > Sorry, I was thinking ahead a bit.  I'm pretty much convinced that the
> > issue we're dealing with is a race between a vnode being
> > recycled/cleaned and the pagedaemon paging out pages associated with
> > that same vnode.
> > 
> > The crashes we've seen before were all in the pagedaemon path where we
> > end up calling into the VFS layer with a vnode that has v_usecount ==
> > 0.  My "fix" avoids that, but hits the issue that when we are in the
> > codepath that is recycling/cleaning the vnode, we can't use vget() to
> > get a reference to the vnode since it checks that the vnode isn't in
> > the process of being cleaned.
> > 
> > But if we avoid that issue (by for example) skipping the vget() call
> > if the UVM_VNODE_DYING flag is set, we run into the same scenario
> > where we call into the VFS layer with v_usecount == 0.  Now that may
> > not actually be a problem, but I need to investigate this a bit more.
> 
> When the UVM_VNODE_DYING flag is set the caller always own a valid
> reference to the vnode.  Either because it is in the process of cleaning
> it via  uvm_vnp_terminate() or because it uvn_detach() has been called
> which means the reference to the vnode hasn't been dropped yet.  So I
> believe `v_usecount' for such vnode is positive.

I don't think so.  The vnode that can be recycled is sitting on the
freelist with v_usecount == 0.  When getnewvnode() decides to recycle
a vnode it takes it off the freelist and calls vgonel(), which i turn
calls vclean(), which only increases v_usecount if it is non-zero.  So
at the point where uvn_vnp_terminate() gets called v_usecount
definitely is 0.

That said, the vnode is no longer on the freelist at that point and
since UVM_VNODE_DYING is set, uvn_vnp_uncache() will return
immediately without calling vref() to get another reference.  So that
is fine.

> > Or maybe calling into the VFS layer with a vnode that has v_usecount
> > == 0 is perfectly fine and we should do the vget() dance I propose in
> > uvm_vnp_unache() instead of in uvn_put().
> 
> I'm not following.  uvm_vnp_uncache() is always called with a valid
> vnode, no?

Not sure what you mean with a "valid vnode"; uvm_vnp_uncache() checks
the UVM_VNODE_VALID flag at the start, which suggests that it can be
called in cases where that flag is not set.  But it will unlock and
return immediately in that case, so it should be safe.

Anyway, I think I have convinced myself that in the case where the
pagedaemon ends up calling uvn_put() for a persisting vnode vm object,
we do need to get a refence before calling uvn_io().  Otherwise we run
the risk of the vnode being recycled under our feet while we're doing
I/O.

So here is an updated diff that checks the UVM_VNODE_DYING flag and
skips the refcount manipulation if it is set.

What do you think?


Index: uvm/uvm_vnode.c
===
RCS file: /cvs/src/sys/uvm/uvm_vnode.c,v
retrieving revision 1.130
diff -u -p -r1.130 uvm_vnode.c
--- uvm/uvm_vnode.c 20 Oct 2022 13:31:52 -  1.130
+++ uvm/uvm_vnode.c 28 Nov 2022 14:01:20 -
@@ -899,11 +899,21 @@ uvn_cluster(struct uvm_object *uobj, vof
 int
 uvn_put(struct uvm_object *uobj, struct vm_page **pps, int npages, int flags)
 {
-   int retval;
+   struct uvm_vnode *uvn = (struct uvm_vnode *)uobj;
+   int dying, retval;
 
KASSERT(rw_write_held(uobj->vmobjlock));
 
+   dying = (uvn->u_flags & UVM_VNODE_DYING);
+   if (!dying) {
+   if (vget(uvn->u_vnode, LK_NOWAIT))
+   return VM_PAGER_AGAIN;
+   }
+
retval = uvn_io((struct uvm_vnode*)uobj, pps, npages, flags, UIO_WRITE);
+
+   if 

Re: Remove useless nd6_init_done from nd6_init()

2022-11-28 Thread Alexander Bluhm
On Sun, Nov 27, 2022 at 09:23:25PM +, Klemens Nanni wrote:
> Only ip6_init() calls nd6_init(), exactly once, just like it calls
> frag6_init() which on the other hand does not have some fra6_init_done
> to guard against itself.
> 
> Like all other domains, ip6_init() is called in domaininit(), early in
> the kernel's main().
> 
> This variable was probably never useful and dates back to nd6.c r1.1:
> bring in KAME IPv6 code, dated 19991208.
> 
> Feedback? OK?

OK bluhm@

> NB:  While here, nd6 and frag6 could statically initalise their lists
> right away (they're both static/local to nd6.c and frag6.c anyway), but

I see no big adavantage of variable initializer over ..._init()
function.  The latter is there anyway.

> that should probably be another diff, if at all, with more static added
> to those files.

Why is static in the kernel a benefit?  There were times when static
was no allowed to have more complete symbol list.

> diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c
> index 9fdaf8138d1..07ccf615746 100644
> --- a/sys/netinet6/nd6.c
> +++ b/sys/netinet6/nd6.c
> @@ -104,21 +104,12 @@ struct task nd6_expire_task;
>  void
>  nd6_init(void)
>  {
> - static int nd6_init_done = 0;
> -
> - if (nd6_init_done) {
> - log(LOG_NOTICE, "%s called more than once\n", __func__);
> - return;
> - }
> -
>   TAILQ_INIT(_list);
>   pool_init(_pool, sizeof(struct llinfo_nd6), 0,
>   IPL_SOFTNET, 0, "nd6", NULL);
>  
>   task_set(_expire_task, nd6_expire, NULL);
>  
> - nd6_init_done = 1;
> -
>   /* start timer */
>   timeout_set_proc(_timer_to, nd6_timer, NULL);
>   timeout_set_proc(_slowtimo_ch, nd6_slowtimo, NULL);



Re: nd6: DAD: Remove useless variable, simplify code

2022-11-28 Thread Alexander Bluhm
On Sun, Nov 27, 2022 at 06:42:48PM +, Klemens Nanni wrote:
> Using a local `duplicate' variable to defer the actual checks by a few
> lines, interleaved with comments (saying the same thing but negated),
> is harder to follow that neccessary.
> 
> Fold the logic and merge comments (remove the last obvious one missing
> a negation) to save 20 LOC.
> 
> Feedback? Objection? OK?

OK bluhm@

> -  * We have transmitted sufficient number of DAD packets.
> +  * We have transmitted enough DAD packets.

Could you leave this line as it is?  Not changing comment makes cvs
blame easier to use.  And "enough" is not better to understand than
"sufficient number of".