Refactor bgpd control code

2020-10-21 Thread Claudio Jeker
This refactors the control code a bit and removes the common var from the
session.h header. The session engine no longer walks the control
connection list. Additionally cleanup the control.c code around
control_dispatch_msg(). E.g. don't do double lookups of control sessions
by fd to close them.

OK?
-- 
:wq Claudio

Index: control.c
===
RCS file: /cvs/src/usr.sbin/bgpd/control.c,v
retrieving revision 1.100
diff -u -p -r1.100 control.c
--- control.c   10 May 2020 13:38:46 -  1.100
+++ control.c   21 Oct 2020 16:57:53 -
@@ -29,11 +29,13 @@
 #include "session.h"
 #include "log.h"
 
+TAILQ_HEAD(ctl_conns, ctl_conn) ctl_conns = TAILQ_HEAD_INITIALIZER(ctl_conns);
+
 #defineCONTROL_BACKLOG 5
 
 struct ctl_conn*control_connbyfd(int);
 struct ctl_conn*control_connbypid(pid_t);
-int control_close(int);
+int control_close(struct ctl_conn *);
 voidcontrol_result(struct ctl_conn *, u_int);
 ssize_t imsg_read_nofd(struct imsgbuf *);
 
@@ -136,6 +138,22 @@ control_shutdown(int fd)
close(fd);
 }
 
+size_t
+control_fill_pfds(struct pollfd *pfd, size_t size)
+{
+   struct ctl_conn *ctl_conn;
+   size_t i = 0;
+
+   TAILQ_FOREACH(ctl_conn, _conns, entry) {
+   pfd[i].fd = ctl_conn->ibuf.fd;
+   pfd[i].events = POLLIN;
+   if (ctl_conn->ibuf.w.queued > 0)
+   pfd[i].events |= POLLOUT;
+   i++;
+   }
+   return i;
+}
+
 unsigned int
 control_accept(int listenfd, int restricted)
 {
@@ -198,15 +216,8 @@ control_connbypid(pid_t pid)
 }
 
 int
-control_close(int fd)
+control_close(struct ctl_conn *c)
 {
-   struct ctl_conn *c;
-
-   if ((c = control_connbyfd(fd)) == NULL) {
-   log_warn("control_close: fd %d: not found", fd);
-   return (0);
-   }
-
if (c->terminate && c->ibuf.pid)
imsg_ctl_rde(IMSG_CTL_TERMINATE, c->ibuf.pid, NULL, 0);
 
@@ -220,8 +231,7 @@ control_close(int fd)
 }
 
 int
-control_dispatch_msg(struct pollfd *pfd, u_int *ctl_cnt,
-struct peer_head *peers)
+control_dispatch_msg(struct pollfd *pfd, struct peer_head *peers)
 {
struct imsg  imsg;
struct ctl_conn *c;
@@ -237,10 +247,8 @@ control_dispatch_msg(struct pollfd *pfd,
}
 
if (pfd->revents & POLLOUT) {
-   if (msgbuf_write(>ibuf.w) <= 0 && errno != EAGAIN) {
-   *ctl_cnt -= control_close(pfd->fd);
-   return (1);
-   }
+   if (msgbuf_write(>ibuf.w) <= 0 && errno != EAGAIN)
+   return control_close(c);
if (c->throttled && c->ibuf.w.queued < CTL_MSG_LOW_MARK) {
if (imsg_ctl_rde(IMSG_XON, c->ibuf.pid, NULL, 0) != -1)
c->throttled = 0;
@@ -251,16 +259,12 @@ control_dispatch_msg(struct pollfd *pfd,
return (0);
 
if (((n = imsg_read_nofd(>ibuf)) == -1 && errno != EAGAIN) ||
-   n == 0) {
-   *ctl_cnt -= control_close(pfd->fd);
-   return (1);
-   }
+   n == 0)
+   return control_close(c);
 
for (;;) {
-   if ((n = imsg_get(>ibuf, )) == -1) {
-   *ctl_cnt -= control_close(pfd->fd);
-   return (1);
-   }
+   if ((n = imsg_get(>ibuf, )) == -1)
+   return control_close(c);
 
if (n == 0)
break;
Index: session.c
===
RCS file: /cvs/src/usr.sbin/bgpd/session.c,v
retrieving revision 1.402
diff -u -p -r1.402 session.c
--- session.c   27 Jun 2020 07:24:42 -  1.402
+++ session.c   21 Oct 2020 16:49:10 -
@@ -196,7 +196,6 @@ session_main(int debug, int verbose)
struct peer *p, **peer_l = NULL, *next;
struct mrt  *m, *xm, **mrt_l = NULL;
struct pollfd   *pfd = NULL;
-   struct ctl_conn *ctl_conn;
struct listen_addr  *la;
void*newp;
time_t   now;
@@ -237,7 +236,6 @@ session_main(int debug, int verbose)
fatal(NULL);
imsg_init(ibuf_main, 3);
 
-   TAILQ_INIT(_conns);
LIST_INIT();
listener_cnt = 0;
peer_cnt = 0;
@@ -438,13 +436,10 @@ session_main(int debug, int verbose)
 
idx_mrts = i;
 
-   TAILQ_FOREACH(ctl_conn, _conns, entry) {
-   pfd[i].fd = ctl_conn->ibuf.fd;
-   pfd[i].events = POLLIN;
-   if (ctl_conn->ibuf.w.queued > 0)
-   pfd[i].events |= POLLOUT;
-   i++;
-   }
+   i += control_fill_pfds(pfd + i, pfd_elms -i);
+
+

cleanup bgpd commons first step

2020-10-21 Thread Claudio Jeker
Bgpd uses many common symbols and the latest compilers are being picky
about these common symbols.
This removes the global bgpd_process variable and cleans up the filter_set
code to not depend on process knowledge (instead use a new type and don't
overload another one).

-- 
:wq Claudio

Index: bgpd.c
===
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.c,v
retrieving revision 1.229
diff -u -p -r1.229 bgpd.c
--- bgpd.c  11 May 2020 16:59:19 -  1.229
+++ bgpd.c  21 Oct 2020 07:18:00 -
@@ -117,10 +117,9 @@ main(int argc, char *argv[])
int  pipe_m2r[2];
 
conffile = CONFFILE;
-   bgpd_process = PROC_MAIN;
 
log_init(1, LOG_DAEMON);/* log to stderr until daemonized */
-   log_procinit(log_procnames[bgpd_process]);
+   log_procinit(log_procnames[PROC_MAIN]);
log_setverbose(1);
 
saved_argv0 = argv[0];
Index: bgpd.h
===
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v
retrieving revision 1.403
diff -u -p -r1.403 bgpd.h
--- bgpd.h  10 May 2020 13:38:46 -  1.403
+++ bgpd.h  21 Oct 2020 07:29:53 -
@@ -120,7 +120,7 @@ enum bgpd_process {
PROC_MAIN,
PROC_SE,
PROC_RDE
-} bgpd_process;
+};
 
 enum reconf_action {
RECONF_NONE,
@@ -995,6 +995,7 @@ enum action_types {
ACTION_SET_PREPEND_PEER,
ACTION_SET_AS_OVERRIDE,
ACTION_SET_NEXTHOP,
+   ACTION_SET_NEXTHOP_REF,
ACTION_SET_NEXTHOP_REJECT,
ACTION_SET_NEXTHOP_BLACKHOLE,
ACTION_SET_NEXTHOP_NOMODIFY,
@@ -1017,7 +1018,7 @@ struct filter_set {
u_int32_tmetric;
int32_t  relative;
struct bgpd_addr nexthop;
-   struct nexthop  *nh;
+   struct nexthop  *nh_ref;
struct community community;
char pftable[PFTABLE_LEN];
char rtlabel[RTLABEL_LEN];
Index: printconf.c
===
RCS file: /cvs/src/usr.sbin/bgpd/printconf.c,v
retrieving revision 1.142
diff -u -p -r1.142 printconf.c
--- printconf.c 23 Apr 2020 16:13:11 -  1.142
+++ printconf.c 21 Oct 2020 07:32:06 -
@@ -356,6 +356,7 @@ print_set(struct filter_set_head *set)
break;
case ACTION_RTLABEL_ID:
case ACTION_PFTABLE_ID:
+   case ACTION_SET_NEXTHOP_REF:
/* not possible */
printf("king bula saiz: config broken");
break;
Index: rde.c
===
RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
retrieving revision 1.503
diff -u -p -r1.503 rde.c
--- rde.c   21 Oct 2020 06:56:32 -  1.503
+++ rde.c   21 Oct 2020 09:39:49 -
@@ -157,8 +157,7 @@ rde_main(int debug, int verbose)
log_init(debug, LOG_DAEMON);
log_setverbose(verbose);
 
-   bgpd_process = PROC_RDE;
-   log_procinit(log_procnames[bgpd_process]);
+   log_procinit(log_procnames[PROC_RDE]);
 
if ((pw = getpwnam(BGPD_USER)) == NULL)
fatal("getpwnam");
@@ -509,8 +508,11 @@ badnetdel:
if ((s = malloc(sizeof(struct filter_set))) == NULL)
fatal(NULL);
memcpy(s, imsg.data, sizeof(struct filter_set));
-   if (s->type == ACTION_SET_NEXTHOP)
-   s->action.nh = nexthop_get(>action.nexthop);
+   if (s->type == ACTION_SET_NEXTHOP) {
+   s->action.nh_ref =
+   nexthop_get(>action.nexthop);
+   s->type = ACTION_SET_NEXTHOP_REF;
+   }
TAILQ_INSERT_TAIL(_set, s, entry);
break;
case IMSG_CTL_SHOW_NETWORK:
@@ -922,8 +924,11 @@ rde_dispatch_imsg_parent(struct imsgbuf 
if ((s = malloc(sizeof(struct filter_set))) == NULL)
fatal(NULL);
memcpy(s, imsg.data, sizeof(struct filter_set));
-   if (s->type == ACTION_SET_NEXTHOP)
-   s->action.nh = nexthop_get(>action.nexthop);
+   if (s->type == ACTION_SET_NEXTHOP) {
+   s->action.nh_ref =
+   nexthop_get(>action.nexthop);
+   s->type = ACTION_SET_NEXTHOP_REF;
+   }
TAILQ_INSERT_TAIL(_set, s, entry);
break;
case 

OpenBGPD 6.8p0 released

2020-10-20 Thread Claudio Jeker
We have released OpenBGPD 6.8p0, which will be arriving in the
OpenBGPD directory of your local OpenBSD mirror soon.

This is the first stable release for the 6.8 version. It includes
the following changes:

 * In bgpctl(8), the "reload" command now takes a 'reason' argument
   to use as Administrative Shutdown Communication to its neighbors.

 * Added bgpctl(8) support for VPNv6 in the family option of the
   "show rib" command.

 * Added bgpctl(8) support for JSON formatted output in various
   "show" commands.

 * Support to build OpenBGPD on Alpine Linux added

OpenBGPD-portable is known to compile and run on FreeBSD, and
the Linux distributions Debian, Ubuntu and Alpine Linux. It is our
hope that packagers take interest and help adapt OpenBGPD-portable to
more distributions.

We welcome feedback and improvements from the broader community.
Thanks to all of the contributors who helped make this release
possible.



Re: ifconfig: consistent display of P2P link

2020-10-07 Thread Claudio Jeker
On Wed, Oct 07, 2020 at 12:27:04PM +0200, Denis Fondras wrote:
> All tunnels & point-to-point addresses are separated by "->" but inet.
> 
> Before :
> gre0: flags=8051 mtu 1476
> index 6 priority 0 llprio 6
>   encap: vnetid none txprio payload rxprio packet
>   groups: gre
>   tunnel: inet 192.0.2.1 -> 198.51.100.1 ttl 64 nodf ecn
>   inet 172.16.0.1 --> 172.16.0.2 netmask 0x
>   inet6 fe80::c23f:d5ff:fe63:ffe3%gre0 ->  prefixlen 64 scopeid 0x6
>   inet6 2001:db8::1 -> 2001:db8::2 prefixlen 128
> 
> After :
> gre0: flags=8051 mtu 1476
> index 6 priority 0 llprio 6
>   encap: vnetid none txprio payload rxprio packet
>   groups: gre
>   tunnel: inet 192.0.2.1 -> 198.51.100.1 ttl 64 nodf ecn
>   inet 172.16.0.1 -> 172.16.0.2 netmask 0x
>   inet6 fe80::c23f:d5ff:fe63:ffe3%gre0 ->  prefixlen 64 scopeid 0x6
>   inet6 2001:db8::1 -> 2001:db8::2 prefixlen 128
> 
> OK ?

Isn't it the other way around, that originally --> was used but then IPv6
came and introduced -> which was copied around?

I like --> a bit better since it stands a bit more out.

E.g.
gre0: flags=8051 mtu 1476
index 6 priority 0 llprio 6
encap: vnetid none txprio payload rxprio packet
groups: gre
tunnel: inet 192.0.2.1 --> 198.51.100.1 ttl 64 nodf ecn
inet 172.16.0.1 --> 172.16.0.2 netmask 0x
inet6 fe80::c23f:d5ff:fe63:ffe3%gre0 -->  prefixlen 64 scopeid 0x6
inet6 2001:db8::1 --> 2001:db8::2 prefixlen 128
 
> Denis
> 
> Index: ifconfig.c
> ===
> RCS file: /cvs/src/sbin/ifconfig/ifconfig.c,v
> retrieving revision 1.426
> diff -u -p -r1.426 ifconfig.c
> --- ifconfig.c15 Sep 2020 15:23:11 -  1.426
> +++ ifconfig.c17 Sep 2020 14:41:34 -
> @@ -3552,7 +3552,7 @@ in_status(int force)
>   }
>   (void) strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
>   sin = (struct sockaddr_in *)_dstaddr;
> - printf(" --> %s", inet_ntoa(sin->sin_addr));
> + printf(" -> %s", inet_ntoa(sin->sin_addr));
>   }
>   printf(" netmask 0x%x", ntohl(netmask.sin_addr.s_addr));
>   if (flags & IFF_BROADCAST) {
> 

-- 
:wq Claudio



Re: curproc vs MP vs locking

2020-09-15 Thread Claudio Jeker
On Tue, Sep 15, 2020 at 04:38:45PM +0200, Mark Kettenis wrote:
> > Date: Tue, 15 Sep 2020 12:34:07 +0200
> > From: Martin Pieuchot 
> > 
> > Many functions in the kernel take a "struct proc *" as argument.  When
> > reviewing diffs or reading the signature of such functions it is not
> > clear if this pointer can be any thread or if it is, like in many cases,
> > pointing to `curproc'.
> > 
> > This distinction matters when it comes to reading/writing members of
> > this "struct proc" and that's why a growing number of functions start
> > with the following idiom:
> > 
> > KASSERT(p == curproc);
> > 
> > This is verbose and redundant, so I suggested to always use `curproc'
> > and stop passing a "struct proc *" as argument when a function isn't
> > meant to modify any thread.  claudio@ raised a concern of performance
> > claiming that `curproc' isn't always cheap.  Is it still true?  Does
> > the KASSERT()s make us pay the cost anyhow?
> 
> Right, because our kernel has DIAGNOSTIC enabled.
> 
> > If that's the case can we adopt a convention to help review functions
> > that take a "struct proc *" but only mean `curproc'?  What about naming
> > this parameter `curp' instead of `p'?
> 
> That'll result in quite a bit of churn.  I'd really like to avoid
> doing that.

I think the conclusion between the people here at k2k20 is that we should
drop the argument from the function and use curproc in the functions
(assigning curproc = p early on). This way there will be no way of using
the wrong proc. 

-- 
:wq Claudio



Re: sigabort(), p_sigmask & p_siglist

2020-09-15 Thread Claudio Jeker
On Tue, Sep 15, 2020 at 12:52:40PM +0200, Martin Pieuchot wrote:
> Diff below introduces an helper for sending an uncatchable SIGABRT and
> annotate that `p_siglist' and `p_sigmask' are updated using atomic
> operations.
> 
> As a result setsigvec() becomes local to kern/kern_sig.c.
> 
> Note that other places in the kernel use sigexit(p, SIGABRT) for the
> same purpose and aren't converted by this change.
> 
> Ik?

OK claudio@ but I would split the proc.h into its own commit since it is
unrelated to the sigabort() introduction.
 
> Index: kern/kern_pledge.c
> ===
> RCS file: /cvs/src/sys/kern/kern_pledge.c,v
> retrieving revision 1.263
> diff -u -p -r1.263 kern_pledge.c
> --- kern/kern_pledge.c17 Jul 2020 16:28:19 -  1.263
> +++ kern/kern_pledge.c15 Sep 2020 08:30:19 -
> @@ -529,7 +529,6 @@ pledge_fail(struct proc *p, int error, u
>  {
>   const char *codes = "";
>   int i;
> - struct sigaction sa;
>  
>   /* Print first matching pledge */
>   for (i = 0; code && pledgenames[i].bits != 0; i++)
> @@ -550,11 +549,7 @@ pledge_fail(struct proc *p, int error, u
>   p->p_p->ps_acflag |= APLEDGE;
>  
>   /* Send uncatchable SIGABRT for coredump */
> - memset(, 0, sizeof sa);
> - sa.sa_handler = SIG_DFL;
> - setsigvec(p, SIGABRT, );
> - atomic_clearbits_int(>p_sigmask, sigmask(SIGABRT));
> - psignal(p, SIGABRT);
> + sigabort(p);
>  
>   p->p_p->ps_pledge = 0;  /* Disable all PLEDGE_ flags */
>   KERNEL_UNLOCK();
> Index: kern/kern_proc.c
> ===
> RCS file: /cvs/src/sys/kern/kern_proc.c,v
> retrieving revision 1.86
> diff -u -p -r1.86 kern_proc.c
> --- kern/kern_proc.c  30 Jan 2020 08:51:27 -  1.86
> +++ kern/kern_proc.c  15 Sep 2020 08:52:57 -
> @@ -494,7 +494,6 @@ void
>  db_kill_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
>  {
>   struct process *pr;
> - struct sigaction sa;
>   struct proc *p;
>  
>   pr = prfind(addr);
> @@ -506,11 +505,7 @@ db_kill_cmd(db_expr_t addr, int have_add
>   p = TAILQ_FIRST(>ps_threads);
>  
>   /* Send uncatchable SIGABRT for coredump */
> - memset(, 0, sizeof sa);
> - sa.sa_handler = SIG_DFL;
> - setsigvec(p, SIGABRT, );
> - atomic_clearbits_int(>p_sigmask, sigmask(SIGABRT));
> - psignal(p, SIGABRT);
> + sigabort(p);
>  }
>  
>  void
> Index: kern/kern_sig.c
> ===
> RCS file: /cvs/src/sys/kern/kern_sig.c,v
> retrieving revision 1.262
> diff -u -p -r1.262 kern_sig.c
> --- kern/kern_sig.c   13 Sep 2020 13:33:37 -  1.262
> +++ kern/kern_sig.c   15 Sep 2020 08:33:04 -
> @@ -122,6 +122,8 @@ const int sigprop[NSIG + 1] = {
>  #define  stopsigmask (sigmask(SIGSTOP) | sigmask(SIGTSTP) | \
>   sigmask(SIGTTIN) | sigmask(SIGTTOU))
>  
> +void setsigvec(struct proc *, int, struct sigaction *);
> +
>  void proc_stop(struct proc *p, int);
>  void proc_stop_sweep(void *);
>  void *proc_stop_si;
> @@ -1483,6 +1493,21 @@ sigexit(struct proc *p, int signum)
>   }
>   exit1(p, 0, signum, EXIT_NORMAL);
>   /* NOTREACHED */
> +}
> +
> +/*
> + * Send uncatchable SIGABRT for coredump.
> + */
> +void
> +sigabort(struct proc *p)
> +{
> + struct sigaction sa;
> +
> + memset(, 0, sizeof sa);
> + sa.sa_handler = SIG_DFL;
> + setsigvec(p, SIGABRT, );
> + atomic_clearbits_int(>p_sigmask, sigmask(SIGABRT));
> + psignal(p, SIGABRT);
>  }
>  
>  /*
> Index: sys/signalvar.h
> ===
> RCS file: /cvs/src/sys/sys/signalvar.h,v
> retrieving revision 1.43
> diff -u -p -r1.43 signalvar.h
> --- sys/signalvar.h   13 Sep 2020 13:33:37 -  1.43
> +++ sys/signalvar.h   15 Sep 2020 08:34:15 -
> @@ -126,9 +126,9 @@ void  siginit(struct sigacts *);
>  void trapsignal(struct proc *p, int sig, u_long code, int type,
>   union sigval val);
>  void sigexit(struct proc *, int);
> +void sigabort(struct proc *);
>  int  sigismasked(struct proc *, int);
>  int  sigonstack(size_t);
> -void setsigvec(struct proc *, int, struct sigaction *);
>  int  killpg1(struct proc *, int, int, int);
>  
>  void signal_init(void);
> Index: sys/proc.h
> ===
> RCS file: /cvs/src/sys/sys/proc.h,v
> retrieving revision 1.299
> diff -u -p -r1.299 proc.h
> --- sys/proc.h26 Aug 2020 03:19:09 -  1.299
> +++ sys/proc.h15 Sep 2020 10:15:36 -
> @@ -383,14 +383,14 @@ struct proc {
>   struct  kcov_dev *p_kd; /* kcov device handle */
>   struct  lock_list_entry *p_sleeplocks;  /* WITNESS lock tracking */ 
>  
> - int  p_siglist; /* Signals arrived but not delivered. */
> + int  p_siglist; /* 

Re: rtm_getifa: Never ignore RTA_IFP

2020-09-13 Thread Claudio Jeker
On Sun, Sep 13, 2020 at 11:28:11AM -0400, Demi M. Obenour wrote:
> Resending without quoted-printable encoding, in case that helps.
> ---
> If an RTM_ADD command on a routing socket includes an RTA_IFA sockaddr,
> and that sockaddr is an exact match for one of the interfaces in the
> relevant routing domain, any RTA_IFP sockaddr in the same message is
> ignored.  If there are multiple interfaces with the same IP address,
> this can cause packets to be sent out the wrong interface.  Fix this
> by skipping the exact-match check on RTA_IFA if an RTA_IFP sockaddr
> was sent.
> 
> The RTA_IFP sockaddr was also being ignored if there was no interface
> with the requested index.  Return ENXIO to userspace instead.
> 
> The bug can easily be seen by running the following commands as root
> on a machine where vether0 and vether1 do not exist, and on which
> the subnet 192.0.2.0/24 (reserved for documentation) is not in use:
> 
> # ifconfig vether0 destroy 2>/dev/null
> # ifconfig vether1 destroy 2>/dev/null
> # dummy_mac=fe:ff:ff:ff:ff:ff dummy_ip=192.0.2.5
> # ifconfig vether0 create lladdr "$dummy_mac"
> # ifconfig vether1 create lladdr "$dummy_mac"
> # ifconfig vether0 inet "$dummy_ip" prefixlen 32
> # route -n delete "$dummy_ip/32" "$dummy_ip"
> # ifconfig vether1 inet "$dummy_ip" prefixlen 32
> # route -n delete "$dummy_ip/32" "$dummy_ip"
> # route -n add -inet 192.0.2.6 -static -iface -llinfo -link \
> vether1 -ifp vether1 -inet -ifa "$dummy_ip"
> # route -n show -inet
> 
> On a system with an unpatched kernel, the final command will show
> that the route to 192.0.2.6 is via vether0.  If this patch has been
> applied, the route to 192.0.2.6 will be (correctly) via vether1.
> 

Can you please explain why you think this fix is needed. Looking at the
code above my first reaction is don't do that. The configuration with the
same IP on multiple interface you do is something I would generally not
recommend.
It seems like you try to do a poor mans link aggregation and should
instead use trunk(4) or aggr(4).

> ---
>  sys/net/rtsock.c | 26 --
>  1 file changed, 20 insertions(+), 6 deletions(-)
> 
> diff --git sys/net/rtsock.c sys/net/rtsock.c
> index fa84ddc25e5..dc8446bd78f 100644
> --- sys/net/rtsock.c
> +++ sys/net/rtsock.c
> @@ -1235,7 +1235,8 @@ rtm_getifa(struct rt_addrinfo *info, unsigned int rtid)
>   struct sockaddr_dl *sdl;
>  
>   sdl = satosdl(info->rti_info[RTAX_IFP]);
> - ifp = if_get(sdl->sdl_index);
> + if ((ifp = if_get(sdl->sdl_index)) == NULL)
> + return (ENXIO);
>   }
>  
>  #ifdef IPSEC
> @@ -1246,11 +1247,19 @@ rtm_getifa(struct rt_addrinfo *info, unsigned int 
> rtid)
>* enc0.
>*/
>   if (info->rti_info[RTAX_DST] &&
> - info->rti_info[RTAX_DST]->sa_family == PF_KEY)
> + info->rti_info[RTAX_DST]->sa_family == PF_KEY) {
>   info->rti_ifa = enc_getifa(rtid, 0);
> +
> + if (info->rti_ifa != NULL && ifp != NULL &&
> + ifp != info->rti_ifa->ifa_ifp) {
> + if_put(ifp);
> + return (EADDRNOTAVAIL);
> + }
> + }
>  #endif
>  
> - if (info->rti_ifa == NULL && info->rti_info[RTAX_IFA] != NULL)
> + if (info->rti_ifa == NULL && ifp == NULL &&
> + info->rti_info[RTAX_IFA] != NULL)
>   info->rti_ifa = ifa_ifwithaddr(info->rti_info[RTAX_IFA], rtid);
>  
>   if (info->rti_ifa == NULL) {
> @@ -1273,10 +1282,15 @@ rtm_getifa(struct rt_addrinfo *info, unsigned int 
> rtid)
>   sa, sa, rtid);
>   }
>  
> - if_put(ifp);
> -
> - if (info->rti_ifa == NULL)
> + if (info->rti_ifa == NULL) {
> + if_put(ifp);
>   return (ENETUNREACH);
> + }
> +
> + if (ifp != NULL && ifp != info->rti_ifa->ifa_ifp)
> + panic("rtm_getifa: returned route to wrong interface");
> +
> + if_put(ifp);
>  
>   return (0);
>  }
>  
> 
> 

-- 
:wq Claudio



rpki-client cleanup includes

2020-09-12 Thread Claudio Jeker
extern.h uses stuff from openssl/x509.h so put that include in there
and remove all the various other openssl includes in other files that
actually don't need x509 functions.

-- 
:wq Claudio

Index: as.c
===
RCS file: /cvs/src/usr.sbin/rpki-client/as.c,v
retrieving revision 1.5
diff -u -p -r1.5 as.c
--- as.c27 Nov 2019 17:18:24 -  1.5
+++ as.c12 Sep 2020 15:02:20 -
@@ -25,8 +25,6 @@
 #include 
 #include 
 
-#include 
-
 #include "extern.h"
 
 /*
Index: cert.c
===
RCS file: /cvs/src/usr.sbin/rpki-client/cert.c,v
retrieving revision 1.17
diff -u -p -r1.17 cert.c
--- cert.c  28 Jul 2020 07:35:04 -  1.17
+++ cert.c  12 Sep 2020 15:02:20 -
@@ -26,7 +26,6 @@
 #include 
 #include 
 
-#include 
 #include  /* DIST_POINT */
 
 #include "extern.h"
Index: crl.c
===
RCS file: /cvs/src/usr.sbin/rpki-client/crl.c,v
retrieving revision 1.8
diff -u -p -r1.8 crl.c
--- crl.c   2 Apr 2020 09:16:43 -   1.8
+++ crl.c   12 Sep 2020 15:02:20 -
@@ -26,8 +26,6 @@
 #include 
 #include 
 
-#include 
-
 #include "extern.h"
 
 X509_CRL *
Index: extern.h
===
RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v
retrieving revision 1.33
diff -u -p -r1.33 extern.h
--- extern.h12 Sep 2020 10:02:01 -  1.33
+++ extern.h12 Sep 2020 15:02:20 -
@@ -20,6 +20,8 @@
 #include 
 #include 
 
+#include 
+
 enum cert_as_type {
CERT_AS_ID, /* single identifier */
CERT_AS_INHERIT, /* inherit from parent */
Index: io.c
===
RCS file: /cvs/src/usr.sbin/rpki-client/io.c,v
retrieving revision 1.8
diff -u -p -r1.8 io.c
--- io.c29 Nov 2019 05:09:50 -  1.8
+++ io.c12 Sep 2020 15:02:20 -
@@ -25,8 +25,6 @@
 #include 
 #include 
 
-#include 
-
 #include "extern.h"
 
 void
Index: ip.c
===
RCS file: /cvs/src/usr.sbin/rpki-client/ip.c,v
retrieving revision 1.12
diff -u -p -r1.12 ip.c
--- ip.c16 Apr 2020 14:39:44 -  1.12
+++ ip.c12 Sep 2020 15:02:20 -
@@ -25,8 +25,6 @@
 #include 
 #include 
 
-#include 
-
 #include "extern.h"
 
 #define   PREFIX_SIZE(x)  (((x) + 7) / 8)
Index: log.c
===
RCS file: /cvs/src/usr.sbin/rpki-client/log.c,v
retrieving revision 1.5
diff -u -p -r1.5 log.c
--- log.c   29 Nov 2019 05:14:11 -  1.5
+++ log.c   12 Sep 2020 15:02:20 -
@@ -21,7 +21,6 @@
 #include 
 
 #include 
-#include 
 
 #include "extern.h"
 
Index: mft.c
===
RCS file: /cvs/src/usr.sbin/rpki-client/mft.c,v
retrieving revision 1.15
diff -u -p -r1.15 mft.c
--- mft.c   30 Jun 2020 12:52:44 -  1.15
+++ mft.c   12 Sep 2020 15:02:20 -
@@ -24,7 +24,6 @@
 #include 
 #include 
 
-#include 
 #include 
 
 #include "extern.h"
Index: output-bgpd.c
===
RCS file: /cvs/src/usr.sbin/rpki-client/output-bgpd.c,v
retrieving revision 1.17
diff -u -p -r1.17 output-bgpd.c
--- output-bgpd.c   28 Apr 2020 13:41:35 -  1.17
+++ output-bgpd.c   12 Sep 2020 15:02:20 -
@@ -16,7 +16,6 @@
  */
 
 #include 
-#include 
 
 #include "extern.h"
 
Index: output-bird.c
===
RCS file: /cvs/src/usr.sbin/rpki-client/output-bird.c,v
retrieving revision 1.9
diff -u -p -r1.9 output-bird.c
--- output-bird.c   28 Apr 2020 15:03:39 -  1.9
+++ output-bird.c   12 Sep 2020 15:02:20 -
@@ -17,7 +17,6 @@
  */
 
 #include 
-#include 
 
 #include "extern.h"
 
Index: output-csv.c
===
RCS file: /cvs/src/usr.sbin/rpki-client/output-csv.c,v
retrieving revision 1.7
diff -u -p -r1.7 output-csv.c
--- output-csv.c28 Apr 2020 13:41:35 -  1.7
+++ output-csv.c12 Sep 2020 15:02:20 -
@@ -16,7 +16,6 @@
  */
 
 #include 
-#include 
 
 #include "extern.h"
 
Index: output-json.c
===
RCS file: /cvs/src/usr.sbin/rpki-client/output-json.c,v
retrieving revision 1.12
diff -u -p -r1.12 output-json.c
--- output-json.c   3 May 2020 20:24:02 -   1.12
+++ output-json.c   12 Sep 2020 15:02:20 -
@@ -19,7 +19,6 @@
 #include 
 #include 
 #include 
-#include 
 
 #include "extern.h"
 
Index: output.c
===
RCS file: /cvs/src/usr.sbin/rpki-client/output.c,v
retrieving revision 1.16
diff -u -p -r1.16 output.c
--- output.c14 May 2020 20:49:04 -  1.16
+++ output.c

Re: issignal() w/o KERNEL_LOCK()

2020-09-09 Thread Claudio Jeker
On Wed, Sep 09, 2020 at 06:23:22PM +0200, Martin Pieuchot wrote:
> On 09/09/20(Wed) 10:02, Claudio Jeker wrote:
> > On Wed, Sep 09, 2020 at 08:33:30AM +0200, Martin Pieuchot wrote:
> > > Per-process data structures needed to suspend the execution of threads
> > > are since recently protected by the SCHED_LOCK().  So the KERNEL_LOCK()
> > > dance inside issignal() is no longer necessary and can be removed, ok?
> > 
> > This is not quite right. single_thread_set() still needs the
> > KERNEL_LOCK() to avoid racing against itself.
> 
> Which data structure still requires the KERNEL_LOCK()?  Are you talking
> about the per-process list of threads?
> 
> Isn't the SCHED_LOCK() enough to prevent racing against itself?

The main problem is a race for setting ps_single. It is possible that two
threads enter single_thread_set() both succeed on single_thread_check()
but now the first thread will get stomped over by the second thread.
The code is not quite right and it needs to be restructured to be safe.
It probably needs a similar setup finish dance like sleep.

-- 
:wq Claudio



Re: issignal() w/o KERNEL_LOCK()

2020-09-09 Thread Claudio Jeker
On Wed, Sep 09, 2020 at 08:33:30AM +0200, Martin Pieuchot wrote:
> Per-process data structures needed to suspend the execution of threads
> are since recently protected by the SCHED_LOCK().  So the KERNEL_LOCK()
> dance inside issignal() is no longer necessary and can be removed, ok?

This is not quite right. single_thread_set() still needs the
KERNEL_LOCK() to avoid racing against itself.
 
> Note that CURSIG() is currently always called with the KERNEL_LOCK()
> held so the code below is redundant.

This is a very weak argument. The goal is to call CURSIG() without the
KERNEL_LOCK() but it is currently obvious that single_thread_set() needs
the KERNEL_LOCK() and needs to be fixed first. Fixing single_thread_set
and single_thread_clear (which I think is actually fine) is still necessary.
 
While the diff is OK it is mainly so because of side-effects that will be
removed in the future.

> This is a step towards getting signal handling out of ze big lock.
> 
> Index: kern/kern_sig.c
> ===
> RCS file: /cvs/src/sys/kern/kern_sig.c,v
> retrieving revision 1.260
> diff -u -p -r1.260 kern_sig.c
> --- kern/kern_sig.c   26 Aug 2020 03:16:53 -  1.260
> +++ kern/kern_sig.c   8 Sep 2020 05:48:51 -
> @@ -1203,11 +1203,7 @@ issignal(struct proc *p)
>   signum != SIGKILL) {
>   pr->ps_xsig = signum;
>  
> - if (dolock)
> - KERNEL_LOCK();
>   single_thread_set(p, SINGLE_PTRACE, 0);
> - if (dolock)
> - KERNEL_UNLOCK();
>  
>   if (dolock)
>   SCHED_LOCK(s);
> @@ -1215,11 +1211,7 @@ issignal(struct proc *p)
>   if (dolock)
>   SCHED_UNLOCK(s);
>  
> - if (dolock)
> - KERNEL_LOCK();
>   single_thread_clear(p, 0);
> - if (dolock)
> - KERNEL_UNLOCK();
>  
>   /*
>* If we are no longer being traced, or the parent
> @@ -1484,6 +1476,22 @@ sigexit(struct proc *p, int signum)
>   }
>   exit1(p, 0, signum, EXIT_NORMAL);
>   /* NOTREACHED */
> +}
> +
> +/*
> + * Return 1 if `sig', a given signal, is ignored or masked for `p', a given
> + * thread, and 0 otherwise.
> + */
> +int
> +sigismasked(struct proc *p, int sig)
> +{
> + struct process *pr = p->p_p;
> +
> + if ((pr->ps_sigacts->ps_sigignore & sigmask(sig)) ||
> + (p->p_sigmask & sigmask(sig)))
> + return 1;
> +
> + return 0;
>  }
>  
>  int nosuidcoredump = 1;
> 

-- 
:wq Claudio



Re: m_defrag(9) leak

2020-09-02 Thread Claudio Jeker
On Thu, Sep 03, 2020 at 06:34:38AM +0200, Bjorn Ketelaars wrote:
> On Tue 25/08/2020 08:42, Martin Pieuchot wrote:
> > Maxime Villard mentioned a leak due to a missing m_freem() in wg(4):
> > https://marc.info/?l=netbsd-tech-net=159827988018641=2
> > 
> > It seems to be that such leak is present in other uses of m_defrag() in
> > the tree.  I won't take the time to go though all of them, but an audit
> > would be welcome.
> 
> Similar issue seems to exist in:
> 
> sys/arch/octeon/dev/if_cnmac.c
> sys/arch/octeon/dev/if_ogx.c
> sys/dev/fdt/if_dwge.c
> sys/dev/fdt/if_dwxe.c
> sys/dev/ic/bcmgenet.c
> sys/dev/ic/gem.c
> sys/dev/ic/re.c
> sys/dev/ic/rt2860.c
> sys/dev/pci/if_bge.c
> sys/dev/pci/if_bnx.c
> sys/dev/pci/if_bnxt.c
> sys/dev/pci/if_bwfm_pci.c
> sys/dev/pci/if_cas.c
> sys/dev/pci/if_em.c
> sys/dev/pci/if_iavf.c
> sys/dev/pci/if_ix.c
> sys/dev/pci/if_ixl.c
> sys/dev/pci/if_mcx.c
> sys/dev/pci/if_msk.c
> sys/dev/pci/if_myx.c
> sys/dev/pci/if_rge.c
> sys/dev/pci/if_se.c
> sys/dev/pci/if_sis.c
> sys/dev/pci/if_sk.c
> sys/dev/pci/if_vge.c
> sys/dev/pci/if_vic.c
> sys/dev/pci/if_vmx.c
> sys/dev/pci/if_vr.c
> sys/dev/pv/if_hvn.c
> sys/dev/pv/if_vio.c
> sys/dev/pv/if_xnf.c
> 
> The diff below should fix this. At least I'm able to build a kernel
> (amd64 only), which doesn't explode when actually using it.

This is probably not correct. m_defrag does not free the mbuf on failure
because in the drivers the mbuf is most probably still sitting on the
interace output queue and will be retried later on.
This is by design. wg(4) abused m_defrag for something else and its error
handling was just wrong.

 
> diff --git sys/arch/octeon/dev/if_cnmac.c sys/arch/octeon/dev/if_cnmac.c
> index c45503c3d7f..c6a12d20a9a 100644
> --- sys/arch/octeon/dev/if_cnmac.c
> +++ sys/arch/octeon/dev/if_cnmac.c
> @@ -755,8 +755,10 @@ cnmac_send_makecmd_gbuf(struct cnmac_softc *sc, struct 
> mbuf *m0,
>   return 0;
>  
>  defrag:
> - if (m_defrag(m0, M_DONTWAIT) != 0)
> + if (m_defrag(m0, M_DONTWAIT) != 0) {
> + m_freem(m0);
>   return 1;
> + }
>   gbuf[0] = cnmac_send_makecmd_w1(m0->m_len, KVTOPHYS(m0->m_data));
>   *rsegs = 1;
>   return 0;
> diff --git sys/arch/octeon/dev/if_ogx.c sys/arch/octeon/dev/if_ogx.c
> index 13a9cd32a7d..67695fabb23 100644
> --- sys/arch/octeon/dev/if_ogx.c
> +++ sys/arch/octeon/dev/if_ogx.c
> @@ -1243,8 +1243,10 @@ ogx_send_mbuf(struct ogx_softc *sc, struct mbuf *m0)
>   }
>  
>   if (m != NULL) {
> - if (m_defrag(m0, M_DONTWAIT) != 0)
> + if (m_defrag(m0, M_DONTWAIT) != 0) {
> + m_freem(m0);
>   return ENOMEM;
> + }
>  
>   /* Discard previously set fragments. */
>   scroff -= sizeof(word) * nfrags;
> diff --git sys/dev/fdt/if_dwge.c sys/dev/fdt/if_dwge.c
> index 58114bf3e38..e9bef31fcdc 100644
> --- sys/dev/fdt/if_dwge.c
> +++ sys/dev/fdt/if_dwge.c
> @@ -1136,8 +1136,10 @@ dwge_encap(struct dwge_softc *sc, struct mbuf *m, int 
> *idx)
>   map = sc->sc_txbuf[cur].tb_map;
>  
>   if (bus_dmamap_load_mbuf(sc->sc_dmat, map, m, BUS_DMA_NOWAIT)) {
> - if (m_defrag(m, M_DONTWAIT))
> + if (m_defrag(m, M_DONTWAIT)) {
> + m_freem(m);
>   return (EFBIG);
> + }
>   if (bus_dmamap_load_mbuf(sc->sc_dmat, map, m, BUS_DMA_NOWAIT))
>   return (EFBIG);
>   }
> diff --git sys/dev/fdt/if_dwxe.c sys/dev/fdt/if_dwxe.c
> index e4895a9a044..a3c6122840a 100644
> --- sys/dev/fdt/if_dwxe.c
> +++ sys/dev/fdt/if_dwxe.c
> @@ -1198,8 +1198,10 @@ dwxe_encap(struct dwxe_softc *sc, struct mbuf *m, int 
> *idx)
>   map = sc->sc_txbuf[cur].tb_map;
>  
>   if (bus_dmamap_load_mbuf(sc->sc_dmat, map, m, BUS_DMA_NOWAIT)) {
> - if (m_defrag(m, M_DONTWAIT))
> + if (m_defrag(m, M_DONTWAIT)) {
> + m_freem(m);
>   return (EFBIG);
> + }
>   if (bus_dmamap_load_mbuf(sc->sc_dmat, map, m, BUS_DMA_NOWAIT))
>   return (EFBIG);
>   }
> diff --git sys/dev/ic/bcmgenet.c sys/dev/ic/bcmgenet.c
> index c9b21f7768b..2444b71a68a 100644
> --- sys/dev/ic/bcmgenet.c
> +++ sys/dev/ic/bcmgenet.c
> @@ -215,15 +215,19 @@ genet_setup_txbuf(struct genet_softc *sc, int index, 
> struct mbuf *m)
>* than the minimum Ethernet packet size.
>*/
>   if (m->m_len < ETHER_MIN_LEN - ETHER_CRC_LEN) {
> - if (m_defrag(m, M_DONTWAIT))
> + if (m_defrag(m, M_DONTWAIT)) {
> + m_freem(m);
>   return 0;
> + }
>   }
>  
>   error = bus_dmamap_load_mbuf(sc->sc_tx.buf_tag,
>   sc->sc_tx.buf_map[index].map, m, BUS_DMA_WRITE | BUS_DMA_NOWAIT);
>   if (error == EFBIG) {
> - if (m_defrag(m, M_DONTWAIT))
> + if (m_defrag(m, M_DONTWAIT)) {
> + 

Re: m_defrag(9) leak

2020-08-25 Thread Claudio Jeker
On Tue, Aug 25, 2020 at 08:38:06PM +1000, Matt Dunwoodie wrote:
> On Tue, 25 Aug 2020 08:54:10 +0200
> Claudio Jeker  wrote:
> 
> > On Tue, Aug 25, 2020 at 08:42:47AM +0200, Martin Pieuchot wrote:
> > > Maxime Villard mentioned a leak due to a missing m_freem() in wg(4):
> > >   https://marc.info/?l=netbsd-tech-net=159827988018641=2
> > > 
> > > It seems to be that such leak is present in other uses of
> > > m_defrag() in the tree.  I won't take the time to go though all of
> > > them, but an audit would be welcome.  
> > 
> > Why does wg(4) needs m_defrag? and why is it used in this way? It
> > does not even check if m_defrag() is actually needed.
> >
> > m_defrag() should be used by HW drivers where DMA constraints require
> > the mbuf to be flattened. Software dirvers should use m_pullup /
> > m_pulldown etc instead.
> 
> wg(4) uses m_defrag to bring all mbuf fragments into one, so it can
> read handshake values, and decrypt data directly from the mbuf. In
> both cases it needs the full length of the packet.

For the handshake headers m_pullup() or m_pulldown() is normally the way
to go.  Doing a massive pullup to decrypt data is a poor design. You work
against the network stack here and this comes at a reasonably high price
(considering you need to allocate a new mbuf, mbuf cluster and copy all
data over).
 
> However you're right, it doesn't check if it needs defrag and yes
> m_pullup is preferable. I have a new patch for m_pullup and includes a
> comment on why it's done. Thoughts?
> 
> There is one other case of "m_pullup(m, m->m_pkthdr.len)" in sppp_input.

sppp(4) is not without its own flaws. That code was added because of
alignment issues. It may actually no longer be needed but I have not the
time right now to really think this through.

> (To avoid any confusion with the previous patch, there is no need to
> m_free(m) as m_pullup will do that for us.)

> diff --git if_wg.c if_wg.c
> index e5a1071ccf1..242bd105e72 100644
> --- if_wg.c
> +++ if_wg.c
> @@ -2022,7 +2022,13 @@ wg_input(void *_sc, struct mbuf *m, struct ip *ip, 
> struct ip6_hdr *ip6,
>   /* m has a IP/IPv6 header of hlen length, we don't need it anymore. */
>   m_adj(m, hlen);
>  
> - if (m_defrag(m, M_NOWAIT) != 0)
> + /*
> +  * Ensure mbuf is contiguous over full length of packet. This is done
> +  * so we can directly read the handshake values in wg_handshake, and so
> +  * we can decrypt a transport packet by passing a single buffer to
> +  * noise_remote_decrypt in wg_decap.
> +  */
> + if ((m = m_pullup(m, m->m_pkthdr.len)) == NULL)
>   return NULL;
>  
>   if ((m->m_pkthdr.len == sizeof(struct wg_pkt_initiation) &&

I'm fine with this or the m_defrag fix to go in now to fix the mbuf leak.

-- 
:wq Claudio



Re: m_defrag(9) leak

2020-08-25 Thread Claudio Jeker
On Tue, Aug 25, 2020 at 08:42:47AM +0200, Martin Pieuchot wrote:
> Maxime Villard mentioned a leak due to a missing m_freem() in wg(4):
>   https://marc.info/?l=netbsd-tech-net=159827988018641=2
> 
> It seems to be that such leak is present in other uses of m_defrag() in
> the tree.  I won't take the time to go though all of them, but an audit
> would be welcome.

Why does wg(4) needs m_defrag? and why is it used in this way? It does not
even check if m_defrag() is actually needed.

m_defrag() should be used by HW drivers where DMA constraints require
the mbuf to be flattened. Software dirvers should use m_pullup /
m_pulldown etc instead.
 
> Index: net//if_wg.c
> ===
> RCS file: /cvs/src/sys/net/if_wg.c,v
> retrieving revision 1.12
> diff -u -p -r1.12 if_wg.c
> --- net//if_wg.c  21 Aug 2020 22:59:27 -  1.12
> +++ net//if_wg.c  25 Aug 2020 06:34:32 -
> @@ -2022,8 +2022,10 @@ wg_input(void *_sc, struct mbuf *m, stru
>   /* m has a IP/IPv6 header of hlen length, we don't need it anymore. */
>   m_adj(m, hlen);
>  
> - if (m_defrag(m, M_NOWAIT) != 0)
> + if (m_defrag(m, M_NOWAIT) != 0) {
> + m_freem(m);
>   return NULL;
> + }
>  
>   if ((m->m_pkthdr.len == sizeof(struct wg_pkt_initiation) &&
>   *mtod(m, uint32_t *) == WG_PKT_INITIATION) ||
> 

-- 
:wq Claudio



Re: timekeep: fixing large skews on amd64 with RDTSCP

2020-08-23 Thread Claudio Jeker
On Sun, Aug 23, 2020 at 04:06:01PM +0200, Christian Weisgerber wrote:
> Scott Cheloha:
> 
> > This "it might slow down the network stack" thing keeps coming up, and
> > yet nobody can point to (a) who expressed this concern or (b) what the
> > penalty is in practice.
> 
> It was kettenis@ who simply raised the question and asked for
> comments from the network people.
> 
> I think we should just go ahead and use rdtsc_lfence() in
> tsc_get_timecount().  It is *correct*.

I agree. For the network stack there are bigger fishes to fry befor such a
micro optimisation would even matter.

-- 
:wq Claudio



Re: diff: simplify ospf6d code

2020-08-21 Thread Claudio Jeker
On Fri, Aug 21, 2020 at 10:17:16AM +0200, Theo Buehler wrote:
> On Fri, Aug 21, 2020 at 10:08:50AM +0200, Jan Klemkow wrote:
> > Hi,
> > 
> > The following diff simplifies a switch case statement with no functional
> > change.
> > 
> > In case of IMSG_CTL_SHOW_DATABASE duplicated code is removed.  This part
> > of the code is now the same as in ospfd.
> 
> This part looks fine.
> 
> > 
> > In case of IMSG_CTL_SHOW_DB_INTRA the code was also duplicated and due
> > to a missing continue the v->type variable was double check.
> 
> This doesn't look correct. v->type was checked against
> LSA_TYPE_INTRA_A_PREFIX which is not the same as
> LSA_TYPE_INTER_A_PREFIX
> 
> I can't tell if a continue; is missing (which looks likely) in the
> IMSG_CTL_SHOW_DB_INTRA case or if the check against both INTRA and INTER
> is deliberate.

Good catch. Yes the continue is missing in that case.
The IMSG_CTL_SHOW_DB_INTRA case should only send back LSA with type
LSA_TYPE_INTRA_A_PREFIX. LSA_TYPE_INTER_A_PREFIX should not be included
there. This is one of the extra LSA types ospfv3 added to the mix.
 
> > 
> > OK?
> > 
> > bye,
> > Jan
> > 
> > Index: rde_lsdb.c
> > ===
> > RCS file: /cvs/src/usr.sbin/ospf6d/rde_lsdb.c,v
> > retrieving revision 1.43
> > diff -u -p -r1.43 rde_lsdb.c
> > --- rde_lsdb.c  17 Feb 2020 08:12:22 -  1.43
> > +++ rde_lsdb.c  21 Aug 2020 07:52:15 -
> > @@ -763,9 +763,7 @@ lsa_dump(struct lsa_tree *tree, int imsg
> > lsa_age(v);
> > switch (imsg_type) {
> > case IMSG_CTL_SHOW_DATABASE:
> > -   rde_imsg_compose_ospfe(IMSG_CTL_SHOW_DATABASE, 0, pid,
> > -   >lsa->hdr, ntohs(v->lsa->hdr.len));
> > -   continue;
> > +   break;
> > case IMSG_CTL_SHOW_DB_SELF:
> > if (v->lsa->hdr.adv_rtr == rde_router_id())
> > break;
> > @@ -787,8 +785,6 @@ lsa_dump(struct lsa_tree *tree, int imsg
> > break;
> > continue;
> > case IMSG_CTL_SHOW_DB_INTRA:
> > -   if (v->type == LSA_TYPE_INTRA_A_PREFIX)
> > -   break;
> > case IMSG_CTL_SHOW_DB_SUM:
> > if (v->type == LSA_TYPE_INTER_A_PREFIX)
> > break;
> > 
> 

-- 
:wq Claudio



Re: diff: simplify ospf6d code

2020-08-21 Thread Claudio Jeker
On Fri, Aug 21, 2020 at 10:08:50AM +0200, Jan Klemkow wrote:
> Hi,
> 
> The following diff simplifies a switch case statement with no functional
> change.
> 
> In case of IMSG_CTL_SHOW_DATABASE duplicated code is removed.  This part
> of the code is now the same as in ospfd.
> 
> In case of IMSG_CTL_SHOW_DB_INTRA the code was also duplicated and due
> to a missing continue the v->type variable was double check.
> 
> OK?

OK claudio@


> Index: rde_lsdb.c
> ===
> RCS file: /cvs/src/usr.sbin/ospf6d/rde_lsdb.c,v
> retrieving revision 1.43
> diff -u -p -r1.43 rde_lsdb.c
> --- rde_lsdb.c17 Feb 2020 08:12:22 -  1.43
> +++ rde_lsdb.c21 Aug 2020 07:52:15 -
> @@ -763,9 +763,7 @@ lsa_dump(struct lsa_tree *tree, int imsg
>   lsa_age(v);
>   switch (imsg_type) {
>   case IMSG_CTL_SHOW_DATABASE:
> - rde_imsg_compose_ospfe(IMSG_CTL_SHOW_DATABASE, 0, pid,
> - >lsa->hdr, ntohs(v->lsa->hdr.len));
> - continue;
> + break;
>   case IMSG_CTL_SHOW_DB_SELF:
>   if (v->lsa->hdr.adv_rtr == rde_router_id())
>   break;
> @@ -787,8 +785,6 @@ lsa_dump(struct lsa_tree *tree, int imsg
>   break;
>   continue;
>   case IMSG_CTL_SHOW_DB_INTRA:
> - if (v->type == LSA_TYPE_INTRA_A_PREFIX)
> - break;
>   case IMSG_CTL_SHOW_DB_SUM:
>   if (v->type == LSA_TYPE_INTER_A_PREFIX)
>   break;
> 

-- 
:wq Claudio



Re: hostname.if '!' commands and rdomains

2020-07-29 Thread Claudio Jeker
On Wed, Jul 29, 2020 at 04:43:18PM +0200, Klemens Nanni wrote:
> On Wed, Jul 29, 2020 at 05:33:14PM +0300, Kapetanakis Giannis wrote:
> > Wouldn't this break those who already have
> > !route -T2 
> > 
> > in their hostname.if files?
> No,
> 
>   $ route -T1 exec id -R
>   1
>   $ route -T0 exec route -T1 exec id -R
>   1

But:
$ route -T2 exec id -R
2
$ route -T2 exec route -T0 exec id -R
route: setrtable: Operation not permitted

Only root can change the rdomain if it is currently != 0.

-- 
:wq Claudio



Re: pipex(4): kill unused declaration

2020-06-30 Thread Claudio Jeker
On Tue, Jun 30, 2020 at 04:30:24PM +0300, Vitaliy Makkoveev wrote:
> `udpcksum' declared but not used in net/pipex.c, so kill it

OK claudio@ 
> Index: sys/net/pipex.c
> ===
> RCS file: /cvs/src/sys/net/pipex.c,v
> retrieving revision 1.116
> diff -u -p -r1.116 pipex.c
> --- sys/net/pipex.c   22 Jun 2020 09:38:15 -  1.116
> +++ sys/net/pipex.c   30 Jun 2020 13:28:48 -
> @@ -104,9 +104,6 @@ struct mbuf_queue pipexoutq = MBUF_QUEUE
>  /* borrow an mbuf pkthdr field */
>  #define ph_ppp_proto ether_vtag
>  
> -/* from udp_usrreq.c */
> -extern int udpcksum;
> -
>  #ifdef PIPEX_DEBUG
>  int pipex_debug = 0; /* systcl net.inet.ip.pipex_debug */
>  #endif
> 

-- 
:wq Claudio



Re: [PATCH] usr.sbin/rpki-client: remove -f (force) option

2020-06-30 Thread Claudio Jeker
On Tue, Jun 30, 2020 at 10:33:21AM +, Job Snijders wrote:
> Remove rpki-client's -f command line option
> 
> I haven't come across a use case that requires tricking the software
> into accepting out-of-date manifests. Anyone using -f? I think this is a
> leftover from the initial debugging era.
> 
> OK?

Agreed. I think the last time I used this was in Elk Lakes during
development. I would not encurage anyone to use -f in production.
OK claudio@

 
> Index: extern.h
> ===
> RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v
> retrieving revision 1.30
> diff -u -p -r1.30 extern.h
> --- extern.h  24 Jun 2020 14:39:21 -  1.30
> +++ extern.h  30 Jun 2020 10:21:04 -
> @@ -289,7 +289,7 @@ struct cert   *cert_read(int);
>  
>  void  mft_buffer(char **, size_t *, size_t *, const struct mft *);
>  void  mft_free(struct mft *);
> -struct mft   *mft_parse(X509 **, const char *, int);
> +struct mft   *mft_parse(X509 **, const char *);
>  int   mft_check(const char *, struct mft *);
>  struct mft   *mft_read(int);
>  
> Index: main.c
> ===
> RCS file: /cvs/src/usr.sbin/rpki-client/main.c,v
> retrieving revision 1.71
> diff -u -p -r1.71 main.c
> --- main.c24 Jun 2020 14:39:21 -  1.71
> +++ main.c30 Jun 2020 10:21:05 -
> @@ -148,7 +148,7 @@ struct filepath_tree  fpt = RB_INITIALIZ
>  /*
>   * Mark that our subprocesses will never return.
>   */
> -static void  proc_parser(int, int) __attribute__((noreturn));
> +static void  proc_parser(int) __attribute__((noreturn));
>  static void  proc_rsync(char *, char *, int, int)
>   __attribute__((noreturn));
>  static void  build_chain(const struct auth *, STACK_OF(X509) **);
> @@ -892,8 +892,8 @@ proc_parser_roa(struct entity *entp,
>   * Return the mft on success or NULL on failure.
>   */
>  static struct mft *
> -proc_parser_mft(struct entity *entp, int force, X509_STORE *store,
> -X509_STORE_CTX *ctx, struct auth_tree *auths, struct crl_tree *crlt)
> +proc_parser_mft(struct entity *entp, X509_STORE *store, X509_STORE_CTX *ctx,
> + struct auth_tree *auths, struct crl_tree *crlt)
>  {
>   struct mft  *mft;
>   X509*x509;
> @@ -902,7 +902,7 @@ proc_parser_mft(struct entity *entp, int
>   STACK_OF(X509)  *chain;
>  
>   assert(!entp->has_dgst);
> - if ((mft = mft_parse(, entp->uri, force)) == NULL)
> + if ((mft = mft_parse(, entp->uri)) == NULL)
>   return NULL;
>  
>   a = valid_ski_aki(entp->uri, auths, mft->ski, mft->aki);
> @@ -1127,7 +1127,7 @@ build_crls(const struct auth *a, struct 
>   * The process will exit cleanly only when fd is closed.
>   */
>  static void
> -proc_parser(int fd, int force)
> +proc_parser(int fd)
>  {
>   struct tal  *tal;
>   struct cert *cert;
> @@ -1249,8 +1249,7 @@ proc_parser(int fd, int force)
>*/
>   break;
>   case RTYPE_MFT:
> - mft = proc_parser_mft(entp, force,
> - store, ctx, , );
> + mft = proc_parser_mft(entp, store, ctx, , );
>   c = (mft != NULL);
>   io_simple_buffer(, , , , sizeof(int));
>   if (mft != NULL)
> @@ -1500,8 +1499,7 @@ int
>  main(int argc, char *argv[])
>  {
>   int  rc = 1, c, proc, st, rsync,
> -  fl = SOCK_STREAM | SOCK_CLOEXEC, noop = 0,
> -  force = 0;
> +  fl = SOCK_STREAM | SOCK_CLOEXEC, noop = 0;
>   size_t   i, j, eid = 1, outsz = 0, talsz = 0;
>   pid_tprocpid, rsyncpid;
>   int  fd[2];
> @@ -1539,7 +1537,7 @@ main(int argc, char *argv[])
>   if (pledge("stdio rpath wpath cpath fattr proc exec unveil", NULL) == 
> -1)
>   err(1, "pledge");
>  
> - while ((c = getopt(argc, argv, "b:Bcd:e:fjnot:T:v")) != -1)
> + while ((c = getopt(argc, argv, "b:Bcd:e:jnot:T:v")) != -1)
>   switch (c) {
>   case 'b':
>   bind_addr = optarg;
> @@ -1556,9 +1554,6 @@ main(int argc, char *argv[])
>   case 'e':
>   rsync_prog = optarg;
>   break;
> - case 'f':
> - force = 1;
> - break;
>   case 'j':
>   outformats |= FORMAT_JSON;
>   break;
> @@ -1634,7 +1629,7 @@ main(int argc, char *argv[])
>   err(1, "%s: unveil", cachedir);
>   if (pledge("stdio rpath", NULL) == -1)
>   err(1, "pledge");
> - proc_parser(fd[0], force);
> + proc_parser(fd[0]);
>   /* NOTREACHED */
>   }
>  
> @@ -1826,7 +1821,7 @@ main(int argc, char 

Re: wg(4): encapsulated transport checksums

2020-06-30 Thread Claudio Jeker
On Tue, Jun 30, 2020 at 09:22:18AM +1200, richard.n.proc...@gmail.com wrote:
> Hi Jason,
> 
> On 27/06/2020, at 10:09 PM, Jason A. Donenfeld  wrote:
> > [...] I thought I'd lay out my understanding of the matter,
> > and you can let me know whether or not this corresponds with what you  
> > had in mind:
> > [...]
> 
> My main concern is the end-to-end TCP or UDP transport checksum of the
> tunneled (or inner, or encapsulated) packet. Your argument seems to
> concern instead the per-hop IPv4 header checksum (which is also
> interesting to look at, but first things first).
> 
> As I read it, wg_decap() tells the stack to ignore the transport checksum
> of the tunneled packet, and I think this is incorrect for the following
> reason: the packet may have been corrupted outside of the tunnel, because
> the tunnel needn't cover the entire path the packet took through the
> network.
> 
> So a tunneled packet may be corrupt, and one addressed to the tunnel
> endpoint will be delivered with its end-to-end transport checksum
> unverified. Higher layers may receive corrupt data as as result.[*]  
> 
> (Routers, as intermediate network elements, are under no obligation to
> check end-to-end transport checksums. It isn't their job.)
> 
> One might argue (I do not) that this isn't a concern, because encryption
> these days is ubiquitous and comes with far stronger integrity checks.
> Nonetheless, even here transport checksums remain relevant for two
> reasons. Firsly, because networks remain unreliable: I see non-zero
> numbers of failed checksums on my systems. And, secondly, because higher
> layers require a reliable transport: TLS for instance will drop the
> connection when the MAC check fails[1].
> 
> Let's turn to the per-hop IPv4 checksum, which wg_decap() also tells the 
> stack to ignore. I suspect the cost of verifying that checksum -- 20 bytes 
> on a hot cache line -- is negligible both absolutely and relative to the 
> cost of decrypting the packet. And as the optimisation appears nowhere 
> else in the tree that I can find, removing it would make wg(4) no worse 
> than the other tunnels. Do you have evidence that the cost is in fact 
> significant?
> 
> Further, as Theo pointed out, the link layer has in any case no business 
> with the IPv4 checksum, being part of the network layer. Layer violations 
> are problematic for at least two reasons. Firstly, they constrict the 
> design space. For instance, I suppose the IPv4 checksum needn't be 
> per-hop. It might be updated incrementally, increasing its scope. But this 
> would be nullified by any link layer that, acting on a false assumption 
> about the layer above it, told the stack to ignore that layer's checksum. 
> Secondly, layer violations, an optimisation, which almost by definition 
> rely on additional premises, burden the correctness obligation and so 
> trade less work for the computer in narrow circumstances for (often much) 
> more work for the fallible human to show that the process remains sound.
> 
> On that balance I now think that skipping the IPv4 check a false economy,
> too. Hopefully I have managed to make my reasons clearer this time around, 
> please let me know if not, or if you disagree. 
> 
> See updated patch below, looking for oks to commit that.
>  
> cheers,
> Richard.
> 
> [*] By way of background, I understand the transport checksum was added to
> the early ARPANET primarily to guard against corruption inside its
> routers[0], after a router fault which "[brought] the network to its
> knees". In other words, end-to-end checks are necessary to catch faults in
> the routers; link-level checks aren't enough.
> 
> More generally, transport checksums set a lower bound on the reliability
> of the end-to-end transport, which decouples it from the reliability of  
> the underlying network.
> 
> [0] Kleinrock "Queuing Systems, Volume 2: Computer Applications",
> John Wiley and Sons (1976), p441
> 
> [1] RFC5246 TLS v1.2 (2008), section 7.2.2.
> 
> TLS's requirement is reasonable: it would otherwise be obliged to
> reimplement for itself retransmission, which would drag with it other
> transport layer mechanisms like acknowledgements and (for performance)
> sequence numbers and sliding windows.

I agree with all of this and think that this is the right fix.
OK claudio@
 
> Index: net/if_wg.c
> ===
> RCS file: /cvs/src/sys/net/if_wg.c,v
> retrieving revision 1.7
> diff -u -p -u -p -r1.7 if_wg.c
> --- net/if_wg.c   23 Jun 2020 10:03:49 -  1.7
> +++ net/if_wg.c   28 Jun 2020 20:17:07 -
> @@ -1660,14 +1660,8 @@ wg_decap(struct wg_softc *sc, struct mbu
>   goto error;
>   }
>  
> - /*
> -  * We can mark incoming packet csum OK. We mark all flags OK
> -  * irrespective to the packet type.
> -  */
> - m->m_pkthdr.csum_flags |= (M_IPV4_CSUM_IN_OK | M_TCP_CSUM_IN_OK |
> - M_UDP_CSUM_IN_OK | 

Re: vlan and bridge panic with latest snapshot

2020-06-22 Thread Claudio Jeker
On Sun, Jun 21, 2020 at 08:51:53PM +0200, Hrvoje Popovski wrote:
> Hi all,
> 
> with today's snapshot from 21-Jun-2020 09:34
> OpenBSD 6.7-current (GENERIC.MP) #286: Sun Jun 21 08:51:29 MDT 2020
> dera...@amd64.openbsd.org:/usr/src/sys/arch/amd64/compile/GENERIC.MP
> 
> if i do "ifconfig vlan" i'm getting assert
> x3550m4# ifconfig vlan
> vlan100: flags=8splassert: vlan_ioctl: want 2 have 0
> Starting stack trace...
> vlan_ioctl(80bb4800,c02069d3,800021f6f5d0) at vlan_ioctl+0x65
> ifioctl(fd8785005668,c02069d3,800021f6f5d0,800021ffb130) at
> ifioctl+0x91c
> soo_ioctl(fd8784e6d630,c02069d3,800021f6f5d0,800021ffb130)
> at soo_ioctl+0x171
> sys_ioctl(800021ffb130,800021f6f6e0,800021f6f740) at
> sys_ioctl+0x2df
> syscall(800021f6f7b0) at syscall+0x389
> Xsyscall() at Xsyscall+0x128
> end of kernel
> end trace frame: 0x7f7e53d0, count: 251
> End of stack trace.
> 
> 
> with ifconfig bridge0 up everything seems fine but ifconfig bridge0
> destroy and ifconfig after that get me panic ..
> 
> x3550m4# ifconfig
> lo0: flags=8049 msplassert: vlan_ioctl:
> want 2 have 0
> Starting stack trace...
> vlan_ioctl(80bb4800,c02069d3,800021f6f510) at vlan_ioctl+0x65
> ifioctl(fd8785005668,c02069d3,800021f6f510,800021ffb130) at
> ifioctl+0x91c
> soo_ioctl(fd8784e6d630,c02069d3,800021f6f510,800021ffb130)
> at soo_ioctl+0x171
> sys_ioctl(800021ffb130,800021f6f620,800021f6f680) at
> sys_ioctl+0x2df
> syscall(800021f6f6f0) at syscall+0x389
> Xsyscall() at Xsyscall+0x128
> end of kernel
> end trace frame: 0x7f7ddd20, count: 251
> End of stack trace.
> tu 32768
> indexpanic: netlock: lock not held
> Stopped at  db_enter+0x10:  popq%rbp
> TIDPIDUID PRFLAGS PFLAGS  CPU  COMMAND
> *505095   3193  0 0x3  03K ifconfig
> db_enter() at db_enter+0x10
> panic(81dbfaab) at panic+0x128
> rw_exit_write(820e6138) at rw_exit_write+0xb5
> bridge_ioctl(81754000,c02069d3,800021f6f510) at
> bridge_ioctl+0x42
> ifioctl(fd8785005668,c02069d3,800021f6f510,800021ffb130) at
> ifioctl+0x91c
> soo_ioctl(fd8784e6d630,c02069d3,800021f6f510,800021ffb130)
> at soo_ioctl+0x171
> sys_ioctl(800021ffb130,800021f6f620,800021f6f680) at
> sys_ioctl+0x2df
> syscall(800021f6f6f0) at syscall+0x389
> Xsyscall() at Xsyscall+0x128
> end of kernel
> end trace frame: 0x7f7ddd20, count: 6
> https://www.openbsd.org/ddb.html describes the minimum info required in
> bugreports.  Insufficient info makes it difficult to find and fix bugs.
> 

This crashes are because of wg(4) calling the interface ioctl handler
without holding the netlock() this is not allowed.

As a quick fix this diff may work.
-- 
:wq Claudio

Index: net/if.c
===
RCS file: /cvs/src/sys/net/if.c,v
retrieving revision 1.609
diff -u -p -r1.609 if.c
--- net/if.c22 Jun 2020 03:07:57 -  1.609
+++ net/if.c22 Jun 2020 09:06:42 -
@@ -2220,13 +2221,6 @@ ifioctl(struct socket *so, u_long cmd, c
break;
 
/* don't take NET_LOCK because i2c reads take a long time */
-   error = ((*ifp->if_ioctl)(ifp, cmd, data));
-   break;
-   case SIOCSWG:
-   case SIOCGWG:
-   /* Don't take NET_LOCK to allow wg(4) to continue to send and
-* receive packets while we're loading a large number of
-* peers. wg(4) uses its own lock to serialise access. */
error = ((*ifp->if_ioctl)(ifp, cmd, data));
break;
 
Index: net/if_wg.c
===
RCS file: /cvs/src/sys/net/if_wg.c,v
retrieving revision 1.3
diff -u -p -r1.3 if_wg.c
--- net/if_wg.c 21 Jun 2020 12:11:26 -  1.3
+++ net/if_wg.c 22 Jun 2020 09:06:37 -
@@ -2450,10 +2450,14 @@ wg_ioctl(struct ifnet *ifp, u_long cmd, 
 
switch (cmd) {
case SIOCSWG:
+   NET_UNLOCK();
ret = wg_ioctl_set(sc, (struct wg_data_io *) data);
+   NET_LOCK();
break;
case SIOCGWG:
+   NET_UNLOCK();
ret = wg_ioctl_get(sc, (struct wg_data_io *) data);
+   NET_LOCK();
break;
/* Interface IOCTLs */
case SIOCSIFADDR:



Re: ddb(4): tr /t 0t

2020-06-17 Thread Claudio Jeker
On Wed, Jun 17, 2020 at 10:34:58AM +0100, Stuart Henderson wrote:
> Every time I want to use this I spend several minutes figuring out rhe
> correct prefix, it would help to add a note.  Ok?

Since I hit the same issue I'm OK with this :)
 
> Index: man4/ddb.4
> ===
> RCS file: /cvs/src/share/man/man4/ddb.4,v
> retrieving revision 1.97
> diff -u -p -r1.97 ddb.4
> --- man4/ddb.417 May 2020 14:34:35 -  1.97
> +++ man4/ddb.417 Jun 2020 09:31:49 -
> @@ -557,6 +557,8 @@ modifier interprets the
>  .Ar frameaddr
>  argument as the TID of a process and shows the stack trace of
>  that process.
> +.Ar frameaddr
> +is subject to the radix; use the 0t prefix to enter a decimal TID.
>  The
>  .Cm /t
>  modifier is not supported on all platforms.
> 

-- 
:wq Claudio



Re: netstat -R: list rdomains with associated ifs and tables

2020-06-09 Thread Claudio Jeker
On Tue, Jun 09, 2020 at 08:44:42AM +0200, Remi Locherer wrote:
> On Mon, Jun 08, 2020 at 10:10:17PM +0200, Remi Locherer wrote:
> > Hi,
> > 
> > to my knowledge there is no easy way to list all active rdomains or
> > routing tables. Other platforms have "show vrf" or similar commands
> > for an overview.
> > 
> > Here is my attempt at such a view for OpenBSD:
> 
> Updated diff with small changes:
> - Print inet instead of Internet (input deraadt)
> - Removed padding before rdomain id.
> - Changed man page wording.
> 
> twister ..in/netstat$ obj/netstat -R
> Rdomain 0
>   Interfaces: lo0 iwm0 re0 enc0 pflog0 mpe0
>   Routing tables:
>   0: inet   8, inet6  45, mpls   1
>   3: inet   1, inet6   0, mpls   0
>   7: inet  130309, inet6   1, mpls   0
> 
> Rdomain 77
>   Interfaces: vether77 lo77
>   Routing tables:
>  77: inet   0, inet6   0, mpls   0
> 
> Rdomain 122
>   Interfaces: vether122 lo122 pair122 vether1122 vether1123 vether1124 
> vether1125 vether1126 vether1127
>   Routing tables:
> 122: inet  24, inet6   0, mpls   0
> 
> Rdomain 255
>   Interfaces: vether255 lo255
>   Routing tables:
> 255: inet   3, inet6   0, mpls   0
> 
> twister ..in/netstat$
> 
> OK?

Why do you think the route counts are needed? You fetch all routing tables
to count them in userland. The sysctl for doing that is expensive and
especially on systems with full tables will make this command slow.
If this is something we really want then the kernel should track and
provide the count.

Apart from that I think this is a good addition.
 
> Index: main.c
> ===
> RCS file: /cvs/src/usr.bin/netstat/main.c,v
> retrieving revision 1.116
> diff -u -p -r1.116 main.c
> --- main.c28 Apr 2019 17:59:51 -  1.116
> +++ main.c30 May 2020 17:59:33 -
> @@ -127,7 +127,7 @@ main(int argc, char *argv[])
>   tableid = getrtable();
>  
>   while ((ch = getopt(argc, argv,
> - "AaBbc:deFf:ghI:iLlM:mN:np:P:qrsT:tuvW:w:")) != -1)
> + "AaBbc:deFf:ghI:iLlM:mN:np:P:qRrsT:tuvW:w:")) != -1)
>   switch (ch) {
>   case 'A':
>   Aflag = 1;
> @@ -225,6 +225,9 @@ main(int argc, char *argv[])
>   case 'q':
>   qflag = 1;
>   break;
> + case 'R':
> + Rflag = 1;
> + break;
>   case 'r':
>   rflag = 1;
>   break;
> @@ -318,6 +321,11 @@ main(int argc, char *argv[])
>   mroutepr();
>   if (af == AF_INET6 || af == AF_UNSPEC)
>   mroute6pr();
> + exit(0);
> + }
> +
> + if (Rflag) {
> + rdomainpr();
>   exit(0);
>   }
>  
> Index: netstat.1
> ===
> RCS file: /cvs/src/usr.bin/netstat/netstat.1,v
> retrieving revision 1.86
> diff -u -p -r1.86 netstat.1
> --- netstat.1 17 Apr 2019 20:34:21 -  1.86
> +++ netstat.1 8 Jun 2020 20:42:46 -
> @@ -74,6 +74,8 @@
>  .Op Fl i | I Ar interface
>  .Nm
>  .Op Fl W Ar interface
> +.Nm
> +.Op Fl R
>  .Sh DESCRIPTION
>  The
>  .Nm
> @@ -267,6 +269,8 @@ Otherwise the states of the matching soc
>  Only show interfaces that have seen packets (or bytes if
>  .Fl b
>  is specified).
> +.It Fl R
> +List all rdomains with associated interfaces and routing tables.
>  .It Fl r
>  Show the routing tables.
>  The output is explained in more detail below.
> Index: netstat.h
> ===
> RCS file: /cvs/src/usr.bin/netstat/netstat.h,v
> retrieving revision 1.74
> diff -u -p -r1.74 netstat.h
> --- netstat.h 28 Apr 2019 17:59:51 -  1.74
> +++ netstat.h 7 Jun 2020 22:03:10 -
> @@ -57,6 +57,7 @@ int pflag;  /* show given protocol */
>  int  Pflag;  /* show given PCB */
>  int  qflag;  /* only display non-zero values for output */
>  int  rflag;  /* show routing tables (or routing stats) */
> +int  Rflag;  /* show rdomain and rtable summary */
>  int  sflag;  /* show protocol statistics */
>  int  tflag;  /* show i/f watchdog timers */
>  int  vflag;  /* be verbose */
> @@ -112,6 +113,9 @@ void  rt_stats(void);
>  void pr_rthdr(int, int);
>  void pr_encaphdr(void);
>  void pr_family(int);
> +
> +void rdomainpr(void);
> +void rttsummarypr(int);
>  
>  void ip6_stats(char *);
>  void icmp6_stats(char *);
> Index: route.c
> ===
> RCS file: /cvs/src/usr.bin/netstat/route.c,v
> retrieving revision 1.104
> diff -u -p -r1.104 route.c
> --- route.c   28 Jun 2019 13:35:02 -  1.104
> +++ route.c   9 Jun 2020 06:36:29 -
> @@ -51,6 +51,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  

Re: userland clock_gettime proof of concept

2020-05-29 Thread Claudio Jeker
On Fri, May 29, 2020 at 01:45:37PM +0100, Stuart Henderson wrote:
> On 2020/05/29 13:50, Paul Irofti wrote:
> > +struct __timekeep {
> > +   uint32_t major; /* version major number */
> > +   uint32_t minor; /* version minor number */
> > +
> > +   u_int64_t   th_scale;
> > +   unsigned intth_offset_count;
> > +   struct bintime  th_offset;
> > +   struct bintime  th_naptime;
> > +   struct bintime  th_boottime;
> > +   volatile unsigned int   th_generation;
> > +
> > +   unsigned inttc_user;
> > +   unsigned inttc_counter_mask;
> > +};
> 
> Ah good, you got rid of u_int, that was causing problems with port builds.

Probably the u_int64_t should also be changed to uint64_t. At least I
think code should not mix u_intXY_t and uintXY_t.

-- 
:wq Claudio



Re: WireGuard patchset for OpenBSD, rev. 2

2020-05-28 Thread Claudio Jeker
On Thu, May 28, 2020 at 01:07:40PM +0200, Martin Pieuchot wrote:
> On 27/05/20(Wed) 20:18, Matt Dunwoodie wrote:
> > On Wed, 27 May 2020 09:34:53 +0200
> > Martin Pieuchot  wrote:
> > > Regarding the kernel, I'd suggest you use "#if NWG > 0" like it is
> > > done for other pseudo-drives with 'needs-flag'.  
> > 
> > For the most part there is no significant changes to other parts of the
> > network stack, so I don't believe this should be necessary. If there is
> > anything in particular that you think should be flagged like that then
> > please do say.
> 
> I'm thinking of the `inp_upcall' abstraction and the in6_ifattach()
> chunk.  Is it possible to do without adding a function pointer to
> "struct inpcb" and guard the logic with #if NWG > 0" instead?  I'm not
> saying that such abstraction is not wanted, but I would prefer we think
> it through rather than add it for one particular driver/subsystem.
> 
> Have you seen the "#if NVXLAN" chunk in udp_input()?  Maybe this hook
> could also be considered for the abstraction you're suggesting.

Why is this code not just using the existing kernel socket API?
Why is there a need for yet another upcall interface?

I would not like to have more #if XYZ in udp_input() I already feel that
other codepaths in there should be reworked because this spaghetti coding
in the input path needs to stop.
 
-- 
:wq Claudio



Re: [RFC] pppd: add pipex(4) L2TP control support

2020-05-26 Thread Claudio Jeker
On Tue, May 26, 2020 at 09:22:28AM +0200, Martin Pieuchot wrote:
> On 25/05/20(Mon) 21:42, Sergey Ryazanov wrote:
> > Add dedicated option to activate kernel L2TP acceleration via
> > the pipex(4). The options should be passed by a L2TP tunnel
> > management daemon (e.g. xl2tpd).
> 
> What is the difference between npppd(8) and pppd(8)?   Aren't those two
> redundant?  Why did you choose to modify pppd(8) and not npppd(8)?

npppd(8) is server only it can not establish a connection. pppd(8) on the
other hand is more client side (but I think it can do both).

I think the split in userland makes sense (using npppd as LNS/LAC and pppd
to connect to a ISP via PPP (even though we also use sppp/pppoe(4) for
that). Now for the kernel side it would be great if the interface used
would be the same for all ppp users. In this regard this is a step in the
right direction.

 
> > This diff is complete, but kernel support in ppp(4) is not ready.
> > ---
> >  usr.sbin/pppd/ipcp.c|  5 +++
> >  usr.sbin/pppd/options.c | 82 +
> >  usr.sbin/pppd/pppd.8| 18 +
> >  usr.sbin/pppd/pppd.h|  7 
> >  usr.sbin/pppd/sys-bsd.c | 56 
> >  5 files changed, 168 insertions(+)
> > 
> > diff --git usr.sbin/pppd/ipcp.c usr.sbin/pppd/ipcp.c
> > index 1296d897b14..e7a6dbd6ee7 100644
> > --- usr.sbin/pppd/ipcp.c
> > +++ usr.sbin/pppd/ipcp.c
> > @@ -1251,6 +1251,10 @@ ipcp_up(f)
> > return;
> > }
> >  
> > +   /* enable pipex(4), keep working if failed */
> > +   if (pipex_conf.pr_protocol && !apipex(go->ouraddr, ho->hisaddr, mask))
> > +   IPCPDEBUG((LOG_WARNING, "apipex failed"));
> > +
> >  #if (defined(SVR4) && (defined(SNI) || defined(__USLC__)))
> > if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) {
> > IPCPDEBUG((LOG_WARNING, "sifaddr failed"));
> > @@ -1304,6 +1308,7 @@ ipcp_down(f)
> >  if (demand) {
> > sifnpmode(f->unit, PPP_IP, NPMODE_QUEUE);
> >  } else {
> > +   dpipex();
> > sifdown(f->unit);
> > ipcp_clear_addrs(f->unit);
> >  }
> > diff --git usr.sbin/pppd/options.c usr.sbin/pppd/options.c
> > index 828f7cdce65..fe0e2e6b54b 100644
> > --- usr.sbin/pppd/options.c
> > +++ usr.sbin/pppd/options.c
> > @@ -144,6 +144,9 @@ struct  bpf_program pass_filter;/* Filter program for 
> > packets to pass */
> >  struct bpf_program active_filter; /* Filter program for link-active 
> > pkts */
> >  pcap_t  pc;/* Fake struct pcap so we can compile 
> > expr */
> >  #endif
> > +struct pipex_session_req pipex_conf = {/* pipex(4) session 
> > configuration */
> > +  .pr_protocol = 0,
> > +};
> >  
> >  /*
> >   * Prototypes
> > @@ -253,6 +256,8 @@ static int setactivefilter(char **);
> >  static int setmslanman(char **);
> >  #endif
> >  
> > +static int setpipexl2tp(char **);
> > +
> >  static int number_option(char *, u_int32_t *, int);
> >  static int int_option(char *, int *);
> >  static int readable(int fd);
> > @@ -391,6 +396,8 @@ static struct cmd {
> >  {"ms-lanman", 0, setmslanman}, /* Use LanMan psswd when using MS-CHAP 
> > */
> >  #endif
> >  
> > +{"pipex-l2tp", 6, setpipexl2tp},   /* set pipex(4) L2TP parameters 
> > */
> > +
> >  {NULL, 0, NULL}
> >  };
> >  
> > @@ -2283,3 +2290,78 @@ setmslanman(argv)
> >  return (1);
> >  }
> >  #endif
> > +
> > +static int
> > +inet_atoss(cp, ss)
> > +char *cp;
> > +struct sockaddr_storage *ss;
> > +{
> > +struct sockaddr_in *sin = (struct sockaddr_in *)ss;
> > +char *c, *p;
> > +unsigned port;
> > +
> > +if ((c = strchr(cp, ':')) == NULL)
> > +   return 0;
> > +*c = '\0';
> > +if (!inet_aton(cp, >sin_addr))
> > +   return 0;
> > +if (!(port = strtoul(c + 1, , 10)) || *p != '\0')
> > +   return 0;
> > +sin->sin_port = htons(port);
> > +sin->sin_family = AF_INET;
> > +ss->ss_len = sizeof(*sin);
> > +
> > +return 1;
> > +}
> > +
> > +static int
> > +strtou16(str, valp)
> > +char *str;
> > +uint16_t *valp;
> > +{
> > +char *ptr;
> > +
> > +*valp = strtoul(str, , 0);
> > +
> > +return *ptr == '\0' ? 1 : 0;
> > +}
> > +
> > +static int
> > +setpipexl2tp(argv)
> > +char **argv;
> > +{
> > +BZERO((char *)_conf, sizeof(pipex_conf));
> > +
> > +if (!inet_atoss(argv[0], _conf.pr_local_address)) {
> > +   option_error("pipex-l2tp: invalid local address of tunnel: %s", 
> > argv[0]);
> > +   return 0;
> > +}
> > +if (!inet_atoss(argv[1], _conf.pr_peer_address)) {
> > +   option_error("pipex-l2tp: invalid peer address of tunnel: %s", argv[1]);
> > +   return 0;
> > +}
> > +if (!strtou16(argv[2], _conf.pr_proto.l2tp.tunnel_id)) {
> > +   option_error("pipex-l2tp: invalid local tunnel id: %s", argv[2]);
> > +   return 0;
> > +}
> > +if (!strtou16(argv[3], _conf.pr_proto.l2tp.peer_tunnel_id)) {
> > +   option_error("pipex-l2tp: invalid peer tunnel id: %s", argv[3]);
> > +   return 0;
> > +}
> > +if 

Re: vmd(8) and thread safety: a quick proof of concept using libevent 2.1 from ports

2020-05-25 Thread Claudio Jeker
On Mon, May 25, 2020 at 02:14:18AM -0700, Pratik Vyas wrote:
> * Claudio Jeker  [2020-05-25 10:14:11 +0200]:
> 
> > The problem is that the vm exit is handled by a different thread then the
> > event loop. So some event_add/evtimer_add calls are done from a different
> > thread then the main event loop (mainly interrupt processing).
> > 
> > One approach to fix this is to ensure that the event functions are
> > exclusivly used in the main event thread but as usual it is easy to
> > introduce bugs again. 
> 
> Hi Claudio,
> 
> I think it is possible to do this without too much complexity till we
> have one only one cpu.  Bascially, we have two threads right now that do
> event_add/evtimer_add, 
> 1) vmm_pipe / imsg comm channel between vmm and vm process
> 2) vcpu0 loop
> 
> I think it's possible to make the vmm_pipe be not its own thread and
> just be an event based implementation.
> 
> Dave actually discovered that if you disable vmm_pipe, this libevent
> state corruption does not occour.
> 
> I will take a stab at this.

Sure, this is a simple fix.
In the long run I guess we need to fix this better (also the way devices
are implemented could benefit from this, since they are currently too
synchronous to get a lot of performance out of them).

-- 
:wq Claudio



Re: vmd(8) and thread safety: a quick proof of concept using libevent 2.1 from ports

2020-05-25 Thread Claudio Jeker
On Mon, May 25, 2020 at 10:02:27AM +0200, Martin Pieuchot wrote:
> On 24/05/20(Sun) 07:56, Dave Voutila wrote:
> > On Sat, May 23, 2020 at 9:38 PM Dave Voutila  wrote:
> > >
> > > Hello tech@,
> > >
> > > Attached is a diff that patches vmd(8) to utilize libevent 2.1 (from
> > > ports) in an attempt to test the hypothesis that thread safety will
> > > help stabilize Linux guest support. There's some longer detail below
> > > about this hypothesis, but let me cut to the chase:
> > 
> > I failed to pose the hypothesis more concretely.
> > 
> > If I understand vmd(8) correctly, the process created by the 'vmm'
> > process (after privsep) forks to create a 'vm' process representing
> > the guest. After this fork, there's a call to vmm.c::vmm_pipe(), which
> > adds an event to the event_base to deal with imsg's. Once in
> > vm.c::run_vm(), a pthread is created (the 'event_thread') that
> > initiates the event pump/loop. My speculation is this design is
> > leading to spurious issues with the libevent state in the event_base.
> >[...]
> > >
> > > - Rework the vm.c event handling to not be multi-threaded?
> 
> I'd say that or fix base's libevent.  Both imply understanding precisely
> what the race/corruption is.
> 
> Do all the threads need to modify libevent's states?  What for?

The problem is that the vm exit is handled by a different thread then the
event loop. So some event_add/evtimer_add calls are done from a different
thread then the main event loop (mainly interrupt processing).

One approach to fix this is to ensure that the event functions are
exclusivly used in the main event thread but as usual it is easy to
introduce bugs again. I don't think there is a way to fix/change our
libevent code without major drawbacks for all other libevent users.

-- 
:wq Claudio



include interface name in rad error message

2020-05-20 Thread Claudio Jeker
In my syslog I have this:
rad[83563]: RA from non link local address ::
now it would be splendid to know on which of the 4 interfaces rad is
operating on this happened. So here is a diff doing that.

-- 
:wq Claudio

Index: engine.c
===
RCS file: /cvs/src/usr.sbin/rad/engine.c,v
retrieving revision 1.15
diff -u -p -r1.15 engine.c
--- engine.c15 Mar 2019 16:47:19 -  1.15
+++ engine.c20 May 2020 07:09:32 -
@@ -482,7 +482,8 @@ parse_rs(struct imsg_ra_rs *rs)
len = rs->len;
 
if (!IN6_IS_ADDR_LINKLOCAL(>from.sin6_addr)) {
-   log_warnx("RA from non link local address %s", hbuf);
+   log_warnx("RA from non link local address %s on %s", hbuf,
+   if_indextoname(rs->if_index, ifnamebuf));
return;
}
 



OpenBGPD 6.7p0 released

2020-05-19 Thread Claudio Jeker


We have released OpenBGPD 6.7p0, which will be arriving in the
OpenBGPD directory of your local OpenBSD mirror soon.

This is the first stable release for the 6.7 version. It includes
the following changes:

  * Add initial support for JSON output in bgpctl(8).

  * Allow setting both IPv4 and IPv6 local-addresses at the same
time in bgpd.conf group blocks.  Introduced 'no local-address'
to reset a previously set local address.

  * Properly aggregate duplicate bgpd(8) roa table prefix/source-as
combinations into a single entry with the longest maxlen length.

  * Implemented bgpd.conf(5) max-prefix NUM out to limit the number
of announced prefixes, avoiding leaks of full tables to upstreams
and peers.

  * Extended bgpctl(8) 'show neighbor' to include the received and set
prefix count, as well as the max-prefix out limit if set.

  * Improved reporting of notifications to include the suberror cause.

  * Also report the last received error cause in bgpctl(8) show neighbor
output.

  * Fix softreconfig out handling to also work for neighbors using
'export default-route'.

  * Mark stale prefixes in the Adj-RIB-Out so that graceful reload
operates properly.

  * Made it possible to build OpenBGPD-portable with bison. There is
no longer the need to use byacc on Linux distributions.

  * Support for --runstatedir to specify the location of the bgpctl.sock.

  * Cleaned up configure script for better protability.

OpenBGPD-portable is known to compile and run on FreeBSD 12.x, and
the Linux distributions Debian 9 and Ubuntu 14.04 or later. It is our
hope that packagers take interest and help adapt OpenBGPD-portable to
more distributions.

We welcome feedback and improvements from the broader community.
Thanks to all of the contributors who helped make this release
possible.



Re: [PATCH] ppp(4): use common bpf filter hook

2020-05-19 Thread Claudio Jeker
On Tue, May 19, 2020 at 12:19:12PM +0300, Vitaliy Makkoveev wrote:
> I am OK with this diff. Also all pseudo interfaces except switch(4) do
> the same.

Agreed. There is no need to be special here. This is OK claudio and I will
commit it later unless someone else wants to jump in first.
 
> On Mon, May 04, 2020 at 10:02:53PM +0300, Sergey Ryazanov wrote:
> > Use bpf filter hook from the common interface structure. This simplifies
> > the code by unifying it and prepare ppp(4) for pipex(4) support.
> > 
> > Ok?
> > 
> > ---
> >  sys/net/if_ppp.c| 16 
> >  sys/net/if_pppvar.h |  1 -
> >  2 files changed, 8 insertions(+), 9 deletions(-)
> > 
> > diff --git sys/net/if_ppp.c sys/net/if_ppp.c
> > index 192ec7c91e0..4cba9a8778c 100644
> > --- sys/net/if_ppp.c
> > +++ sys/net/if_ppp.c
> > @@ -204,9 +204,11 @@ int
> >  ppp_clone_create(struct if_clone *ifc, int unit)
> >  {
> > struct ppp_softc *sc;
> > +   struct ifnet *ifp;
> >  
> > sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_ZERO);
> > sc->sc_unit = unit;
> > +   ifp = >sc_if;
> > snprintf(sc->sc_if.if_xname, sizeof sc->sc_if.if_xname, "%s%d",
> > ifc->ifc_name, unit);
> > sc->sc_if.if_softc = sc;
> > @@ -224,7 +226,7 @@ ppp_clone_create(struct if_clone *ifc, int unit)
> > if_attach(>sc_if);
> > if_alloc_sadl(>sc_if);
> >  #if NBPFILTER > 0
> > -   bpfattach(>sc_bpf, >sc_if, DLT_PPP, PPP_HDRLEN);
> > +   bpfattach(>if_bpf, ifp, DLT_PPP, PPP_HDRLEN);
> >  #endif
> > NET_LOCK();
> > LIST_INSERT_HEAD(_softc_list, sc, sc_list);
> > @@ -754,11 +756,9 @@ pppoutput(struct ifnet *ifp, struct mbuf *m0, struct 
> > sockaddr *dst,
> > }
> >  
> >  #if NBPFILTER > 0
> > -   /*
> > -* See if bpf wants to look at the packet.
> > -*/
> > -   if (sc->sc_bpf)
> > -   bpf_mtap(sc->sc_bpf, m0, BPF_DIRECTION_OUT);
> > +   /* See if bpf wants to look at the packet. */
> > +   if (ifp->if_bpf)
> > +   bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
> >  #endif
> >  
> > /*
> > @@ -1369,8 +1369,8 @@ ppp_inproc(struct ppp_softc *sc, struct mbuf *m)
> >  
> >  #if NBPFILTER > 0
> > /* See if bpf wants to look at the packet. */
> > -   if (sc->sc_bpf)
> > -   bpf_mtap(sc->sc_bpf, m, BPF_DIRECTION_IN);
> > +   if (ifp->if_bpf)
> > +   bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
> >  #endif
> >  
> > rv = 0;
> > diff --git sys/net/if_pppvar.h sys/net/if_pppvar.h
> > index 87f7d1798bb..9dc774a0515 100644
> > --- sys/net/if_pppvar.h
> > +++ sys/net/if_pppvar.h
> > @@ -113,7 +113,6 @@ struct ppp_softc {
> > struct  mbuf *sc_togo;  /* output packet ready to go */
> > struct  mbuf_list sc_npqueue;   /* output packets not to be sent yet */
> > struct  pppstat sc_stats;   /* count of bytes/pkts sent/rcvd */
> > -   caddr_t sc_bpf; /* hook for BPF */
> > enumNPmode sc_npmode[NUM_NP]; /* what to do with each NP */
> > struct  compressor *sc_xcomp;   /* transmit compressor */
> > void*sc_xc_state;   /* transmit compressor state */
> > -- 
> > 2.26.0
> > 
> 

-- 
:wq Claudio



Re: libsa's in_cksum() cannot handle payload of odd-length?

2020-05-18 Thread Claudio Jeker
On Mon, May 18, 2020 at 03:50:05PM +0200, Patrick Wildt wrote:
> Hi,
> 
> I was trying to tftpboot and had an issue with files of odd-length.
> As it turns out, I think the in_cksum() that's called for UDP payload
> cannot handle a payload length that's not aligned to 16 bytes.
> 
> I don't know how in_cksum() is supposed to work exactly, but it looks
> like the first step is summing up all bytes.  The code is using 16-
> byte blocks, apart from some oddbyte magic.
> 
> First of all, why is there a while loop around code that already
> consumes the whole length?  That can be done in a single step
> without the loop.  Why does it continue of there's an "oddbyte"?
> 
> If I simplify that whole construct, consuming in 16-bytes step
> until there's only one left, then summing that one, in_cksum()
> works for me.
> 
> Can someone please help me have a look?

There are other versions of in_cksum in our tree.
Like: ./usr.sbin/ospfd/in_cksum.c

I'm surprised that the libsa code does no htons / ntohs conversions.
Also after looking at the ospfd/in_cksum.c code I wonder if the htons /
ntohs are actually reversed in that that code...
 
> Patrick
> 
> diff --git a/sys/lib/libsa/in_cksum.c b/sys/lib/libsa/in_cksum.c
> index d3f2e6ac978..57ded38a7b7 100644
> --- a/sys/lib/libsa/in_cksum.c
> +++ b/sys/lib/libsa/in_cksum.c
> @@ -59,31 +59,24 @@
>  int
>  in_cksum(const void *p, int len)
>  {
> - int sum = 0, oddbyte = 0, v = 0;
>   const u_char *cp = p;
> + int sum = 0;
>  
>   /* we assume < 2^16 bytes being summed */
> - while (len > 0) {
> - if (oddbyte) {
> - sum += v + *cp++;
> - len--;
> - }
> + while (len > 1) {
>   if (((long)cp & 1) == 0) {
> - while ((len -= 2) >= 0) {
> - sum += *(const u_short *)cp;
> - cp += 2;
> - }
> + sum += *(const u_short *)cp;
> + cp += 2;
>   } else {
> - while ((len -= 2) >= 0) {
> - sum += *cp++ << 8;
> - sum += *cp++;
> - }
> + sum += *cp++ << 8;
> + sum += *cp++;
>   }
> - if ((oddbyte = len & 1) != 0)
> - v = *cp << 8;
> + len -= 2;
> + }
> + if (len > 0) {
> + sum += *cp++;
> + len--;
>   }
> - if (oddbyte)
> - sum += v;
>   sum = (sum >> 16) + (sum & 0x); /* add in accumulated carries */
>   sum += sum >> 16;   /* add potential last carry */
>   return (0x & ~sum);
> 

-- 
:wq Claudio



Re: Prometheus core metrics for bgpd and ospfd approach ideas

2020-05-18 Thread Claudio Jeker
On Mon, May 18, 2020 at 04:16:05PM +0100, Stuart Henderson wrote:
> On 2020/05/18 15:31, Richard Chivers wrote:
> > Hi,
> > 
> > We could do with exposing certain metrics from bgpd, ospfd and pf.
> > 
> > I was considering a couple of approaches and really was just
> > interested in what would make most sense in general.
> > 
> > Has anyone else considered this at all?
> > 
> > Would this be useful to anyone else?
> 
> It would be useful.
> 
> I think the method which fits best with the rest of the system would
> be to export these via agentx -> snmpd, where possible using standard
> MIBs e.g. for BGP that would be BGP4-MIB/CISCO-BGP4-MIB.
> 
> IIRC it has been looked at a bit, but I'm not sure of the current state
> of any of it.
> 
> Data can be picked up from SNMP directly by some existing tools,
> for Prometheus it could be sent via snmp_exporter.

I'm totally torn by this. agentx support sounds great but then you realize
how complex and cumbersome it is to implement those mibs inside the
daemons (even if abstracted away there are various snmp specific getters
to be implemented which looks like a lot of code).

bgpctl show terse and show neighbor  terse was created to do simple
monitoring scripts. Also part of the reason for JSON support was to
provide a machine readable output for monitoring systems. I would not mind
to actually add special commands similar to terse for this.

Prometheus is a bit of a special snow-flake since it formats the metric
pages in its own special format. So you would need to write a translation
wrapper.

Last note, please do not try to directly talk to the daemons always pass
via the *ctl program. The API used between for example bgpd and bgpctl
is not public and also not stable. It requires that both tools are in
sync.

-- 
:wq Claudio



Re: ospfctl json support

2020-05-18 Thread Claudio Jeker
On Mon, May 18, 2020 at 02:46:52PM +0100, Richard Chivers wrote:
> Hi,
> 
> Thanks for the feedback, I wasn't happy with the detail flag either, I
> just missed coming back to rethink / change it.
> 
> There was a lot of duplicate code i seem to remember, as much of the
> output is sent regardless.
> 
> I will take a look over the next couple of days when I get a few
> minutes to retest etc.
> 
> I will also check the style(9) I imagine I have the wrong line length
> configured

Most issues I have seen are missing spaces around if() and }else{.

> In terms of process, shall I do that first before anything else happens?
> Sorry not familiar with the review process etc.

Do it in that order you think works best. Keep the diffs small to help to
move them quickly.
 
> On Mon, May 18, 2020 at 11:00 AM Claudio Jeker  
> wrote:
> >
> > On Mon, May 18, 2020 at 09:49:24AM +0200, Denis Fondras wrote:
> > > On Mon, May 18, 2020 at 09:04:06AM +0200, Claudio Jeker wrote:
> > > > There is a file missing in the diff.
> > > >
> > > > One thing I have seen in the original diff from Richard was that the
> > > > copyright in the new file should be copied from ospfctl.c since this is
> > > > mostly a copy paste action and not new work.
> > > >
> > >
> > > Stupid me... Here is an update.
> > > Thank you Claudio.
> >
> > Not sure about the detail switches. Like this one:
> >
> > > + case IMSG_CTL_SHOW_INTERFACE:
> > > + ctliface = imsg->data;
> > > + if(res->action == SHOW_IFACE_DTAIL)
> > > + output->interface(ctliface, 1);
> > > + else
> > > + output->interface(ctliface, 0);
> > > + break;
> >
> > I pushed those down into the show functions so that the show() function in
> > bgpctl does not do any kind of decision on the output.
> >
> > I looked over the code. There is more KNF fixes needed and maybe some
> > additional changes (like return a response object for all calls) that can
> > happen in tree.
> >
> > OK claudio@
> >
> > > Index: Makefile
> > > ===
> > > RCS file: /cvs/src/usr.sbin/ospfctl/Makefile,v
> > > retrieving revision 1.5
> > > diff -u -p -r1.5 Makefile
> > > --- Makefile  2 Sep 2016 14:02:48 -   1.5
> > > +++ Makefile  17 May 2020 10:51:28 -
> > > @@ -3,7 +3,7 @@
> > >  .PATH:   ${.CURDIR}/../ospfd
> > >
> > >  PROG=ospfctl
> > > -SRCS=logmsg.c ospfctl.c parser.c
> > > +SRCS=logmsg.c ospfctl.c output.c parser.c
> > >  CFLAGS+= -Wall
> > >  CFLAGS+= -Wstrict-prototypes -Wmissing-prototypes
> > >  CFLAGS+= -Wshadow -Wpointer-arith -Wcast-qual
> > > Index: ospfctl.c
> > > ===
> > > RCS file: /cvs/src/usr.sbin/ospfctl/ospfctl.c,v
> > > retrieving revision 1.66
> > > diff -u -p -r1.66 ospfctl.c
> > > --- ospfctl.c 1 Nov 2019 18:15:28 -   1.66
> > > +++ ospfctl.c 17 May 2020 11:11:50 -
> > > @@ -35,42 +35,16 @@
> > >
> > >  #include "ospf.h"
> > >  #include "ospfd.h"
> > > +#include "ospfctl.h"
> > >  #include "ospfe.h"
> > >  #include "parser.h"
> > >
> > >  __dead void   usage(void);
> > > -int   show_summary_msg(struct imsg *);
> > > -uint64_t  get_ifms_type(uint8_t);
> > > -int   show_interface_msg(struct imsg *);
> > > -int   show_interface_detail_msg(struct imsg *);
> > > -const char   *print_link(int);
> > > -const char   *fmt_timeframe(time_t t);
> > > -const char   *fmt_timeframe_core(time_t t);
> > > -const char   *log_id(u_int32_t );
> > > -const char   *log_adv_rtr(u_int32_t);
> > > -void  show_database_head(struct in_addr, char *, u_int8_t);
> > > -int   show_database_msg(struct imsg *);
> > > -char *print_ls_type(u_int8_t);
> > > -void  show_db_hdr_msg_detail(struct lsa_hdr *);
> > > -char *print_rtr_link_type(u_int8_t);
> > > -const char   *print_ospf_flags(u_int8_t);
> > > -int   show_db_msg_detail(struct imsg *imsg);
> > > -int   show_nbr_msg(struct imsg *);
> > > -const char   *print_ospf_options(u_int8_t);
>

Re: ospfctl json support

2020-05-18 Thread Claudio Jeker
On Mon, May 18, 2020 at 09:49:24AM +0200, Denis Fondras wrote:
> On Mon, May 18, 2020 at 09:04:06AM +0200, Claudio Jeker wrote:
> > There is a file missing in the diff.
> > 
> > One thing I have seen in the original diff from Richard was that the
> > copyright in the new file should be copied from ospfctl.c since this is
> > mostly a copy paste action and not new work.
> > 
> 
> Stupid me... Here is an update.
> Thank you Claudio.

Not sure about the detail switches. Like this one:

> + case IMSG_CTL_SHOW_INTERFACE:
> + ctliface = imsg->data;
> + if(res->action == SHOW_IFACE_DTAIL)
> + output->interface(ctliface, 1);
> + else
> + output->interface(ctliface, 0);
> + break;

I pushed those down into the show functions so that the show() function in
bgpctl does not do any kind of decision on the output.

I looked over the code. There is more KNF fixes needed and maybe some
additional changes (like return a response object for all calls) that can
happen in tree.

OK claudio@
 
> Index: Makefile
> ===
> RCS file: /cvs/src/usr.sbin/ospfctl/Makefile,v
> retrieving revision 1.5
> diff -u -p -r1.5 Makefile
> --- Makefile  2 Sep 2016 14:02:48 -   1.5
> +++ Makefile  17 May 2020 10:51:28 -
> @@ -3,7 +3,7 @@
>  .PATH:   ${.CURDIR}/../ospfd
>  
>  PROG=ospfctl
> -SRCS=logmsg.c ospfctl.c parser.c
> +SRCS=logmsg.c ospfctl.c output.c parser.c
>  CFLAGS+= -Wall
>  CFLAGS+= -Wstrict-prototypes -Wmissing-prototypes
>  CFLAGS+= -Wshadow -Wpointer-arith -Wcast-qual
> Index: ospfctl.c
> ===
> RCS file: /cvs/src/usr.sbin/ospfctl/ospfctl.c,v
> retrieving revision 1.66
> diff -u -p -r1.66 ospfctl.c
> --- ospfctl.c 1 Nov 2019 18:15:28 -   1.66
> +++ ospfctl.c 17 May 2020 11:11:50 -
> @@ -35,42 +35,16 @@
>  
>  #include "ospf.h"
>  #include "ospfd.h"
> +#include "ospfctl.h"
>  #include "ospfe.h"
>  #include "parser.h"
>  
>  __dead void   usage(void);
> -int   show_summary_msg(struct imsg *);
> -uint64_t  get_ifms_type(uint8_t);
> -int   show_interface_msg(struct imsg *);
> -int   show_interface_detail_msg(struct imsg *);
> -const char   *print_link(int);
> -const char   *fmt_timeframe(time_t t);
> -const char   *fmt_timeframe_core(time_t t);
> -const char   *log_id(u_int32_t );
> -const char   *log_adv_rtr(u_int32_t);
> -void  show_database_head(struct in_addr, char *, u_int8_t);
> -int   show_database_msg(struct imsg *);
> -char *print_ls_type(u_int8_t);
> -void  show_db_hdr_msg_detail(struct lsa_hdr *);
> -char *print_rtr_link_type(u_int8_t);
> -const char   *print_ospf_flags(u_int8_t);
> -int   show_db_msg_detail(struct imsg *imsg);
> -int   show_nbr_msg(struct imsg *);
> -const char   *print_ospf_options(u_int8_t);
> -int   show_nbr_detail_msg(struct imsg *);
> -int   show_rib_msg(struct imsg *);
> -void  show_rib_head(struct in_addr, u_int8_t, u_int8_t);
> -const char   *print_ospf_rtr_flags(u_int8_t);
> -int   show_rib_detail_msg(struct imsg *);
> -void  show_fib_head(void);
> -int   show_fib_msg(struct imsg *);
> -void  show_interface_head(void);
> -const char *  get_media_descr(uint64_t);
> -const char *  get_linkstate(uint8_t, int);
> -void  print_baudrate(u_int64_t);
> -int   show_fib_interface_msg(struct imsg *);
> +
> +int show(struct imsg *, struct parse_result *);
>  
>  struct imsgbuf   *ibuf;
> +const struct output  *output = _output;
>  
>  __dead void
>  usage(void)
> @@ -145,10 +119,6 @@ main(int argc, char *argv[])
>   imsg_compose(ibuf, IMSG_CTL_SHOW_SUM, 0, 0, -1, NULL, 0);
>   break;
>   case SHOW_IFACE:
> - printf("%-11s %-18s %-6s %-10s %-10s %-8s %3s %3s\n",
> - "Interface", "Address", "State", "HelloTimer", "Linkstate",
> - "Uptime", "nc", "ac");
> - /*FALLTHROUGH*/
>   case SHOW_IFACE_DTAIL:
>   if (*res->ifname) {
>   ifidx = if_nametoindex(res->ifname);
> @@ -159,9 +129,6 @@ main(int argc, char *argv[])
>   , sizeof(ifidx));
>   break;
>   case SHOW_NBR:
> - printf("%-15s %-3s %-12s %-8s %-15s %-9s %s\n&qu

Re: ospfctl json support

2020-05-18 Thread Claudio Jeker
On Sun, May 17, 2020 at 04:32:33PM +0200, Denis Fondras wrote:
> On Fri, May 15, 2020 at 11:34:58AM +0100, Richard Chivers wrote:
> > Hi,
> > 
> > I have now resolved the spacing/tabbing issues I think correctly
> > following style(9), along with a couple of other indent issues.
> > 
> > Would appreciate a cursory look at this stage to spot any further common 
> > issues.
> > 
> 
> I fixed some indent and break long lines.
> 
> It reads OK for me. A quick test shows it works for basic commands.
> 
> OK denis@
> 
> Anyone else for a OK ?

There is a file missing in the diff.

One thing I have seen in the original diff from Richard was that the
copyright in the new file should be copied from ospfctl.c since this is
mostly a copy paste action and not new work.

 
> Index: Makefile
> ===
> RCS file: /cvs/src/usr.sbin/ospfctl/Makefile,v
> retrieving revision 1.5
> diff -u -p -r1.5 Makefile
> --- Makefile  2 Sep 2016 14:02:48 -   1.5
> +++ Makefile  17 May 2020 10:51:28 -
> @@ -3,7 +3,7 @@
>  .PATH:   ${.CURDIR}/../ospfd
>  
>  PROG=ospfctl
> -SRCS=logmsg.c ospfctl.c parser.c
> +SRCS=logmsg.c ospfctl.c output.c parser.c
>  CFLAGS+= -Wall
>  CFLAGS+= -Wstrict-prototypes -Wmissing-prototypes
>  CFLAGS+= -Wshadow -Wpointer-arith -Wcast-qual
> Index: ospfctl.c
> ===
> RCS file: /cvs/src/usr.sbin/ospfctl/ospfctl.c,v
> retrieving revision 1.66
> diff -u -p -r1.66 ospfctl.c
> --- ospfctl.c 1 Nov 2019 18:15:28 -   1.66
> +++ ospfctl.c 17 May 2020 11:11:50 -
> @@ -35,42 +35,16 @@
>  
>  #include "ospf.h"
>  #include "ospfd.h"
> +#include "ospfctl.h"
>  #include "ospfe.h"
>  #include "parser.h"
>  
>  __dead void   usage(void);
> -int   show_summary_msg(struct imsg *);
> -uint64_t  get_ifms_type(uint8_t);
> -int   show_interface_msg(struct imsg *);
> -int   show_interface_detail_msg(struct imsg *);
> -const char   *print_link(int);
> -const char   *fmt_timeframe(time_t t);
> -const char   *fmt_timeframe_core(time_t t);
> -const char   *log_id(u_int32_t );
> -const char   *log_adv_rtr(u_int32_t);
> -void  show_database_head(struct in_addr, char *, u_int8_t);
> -int   show_database_msg(struct imsg *);
> -char *print_ls_type(u_int8_t);
> -void  show_db_hdr_msg_detail(struct lsa_hdr *);
> -char *print_rtr_link_type(u_int8_t);
> -const char   *print_ospf_flags(u_int8_t);
> -int   show_db_msg_detail(struct imsg *imsg);
> -int   show_nbr_msg(struct imsg *);
> -const char   *print_ospf_options(u_int8_t);
> -int   show_nbr_detail_msg(struct imsg *);
> -int   show_rib_msg(struct imsg *);
> -void  show_rib_head(struct in_addr, u_int8_t, u_int8_t);
> -const char   *print_ospf_rtr_flags(u_int8_t);
> -int   show_rib_detail_msg(struct imsg *);
> -void  show_fib_head(void);
> -int   show_fib_msg(struct imsg *);
> -void  show_interface_head(void);
> -const char *  get_media_descr(uint64_t);
> -const char *  get_linkstate(uint8_t, int);
> -void  print_baudrate(u_int64_t);
> -int   show_fib_interface_msg(struct imsg *);
> +
> +int show(struct imsg *, struct parse_result *);
>  
>  struct imsgbuf   *ibuf;
> +const struct output  *output = _output;
>  
>  __dead void
>  usage(void)
> @@ -145,10 +119,6 @@ main(int argc, char *argv[])
>   imsg_compose(ibuf, IMSG_CTL_SHOW_SUM, 0, 0, -1, NULL, 0);
>   break;
>   case SHOW_IFACE:
> - printf("%-11s %-18s %-6s %-10s %-10s %-8s %3s %3s\n",
> - "Interface", "Address", "State", "HelloTimer", "Linkstate",
> - "Uptime", "nc", "ac");
> - /*FALLTHROUGH*/
>   case SHOW_IFACE_DTAIL:
>   if (*res->ifname) {
>   ifidx = if_nametoindex(res->ifname);
> @@ -159,9 +129,6 @@ main(int argc, char *argv[])
>   , sizeof(ifidx));
>   break;
>   case SHOW_NBR:
> - printf("%-15s %-3s %-12s %-8s %-15s %-9s %s\n", "ID", "Pri",
> - "State", "DeadTime", "Address", "Iface","Uptime");
> - /*FALLTHROUGH*/
>   case SHOW_NBR_DTAIL:
>   imsg_compose(ibuf, IMSG_CTL_SHOW_NBR, 0, 0, -1, NULL, 0);
>   break;
> @@ -194,9 +161,6 @@ main(int argc, char *argv[])
>   imsg_compose(ibuf, IMSG_CTL_SHOW_DB_OPAQ, 0, 0, -1, NULL, 0);
>   break;
>   case SHOW_RIB:
> - printf("%-20s %-17s %-12s %-9s %-7s %-8s\n", "Destination",
> - "Nexthop", "Path Type", "Type", "Cost", "Uptime");
> - /*FALLTHROUGH*/
>   case SHOW_RIB_DTAIL:
>   imsg_compose(ibuf, IMSG_CTL_SHOW_RIB, 0, 0, -1, NULL, 0);
>   break;
> @@ -207,7 +171,6 @@ main(int argc, char *argv[])
>   else
>   

Re: bgpctl paged output for show rib

2020-05-17 Thread Claudio Jeker
On Sun, May 17, 2020 at 11:51:33AM +0200, Denis Fondras wrote:
> > This implements a way to add a limit for bgpctl show rib output.
> > When a limit is set then the output will include a token (at the end)
> > that can be used to get the next batch of output. These two things allow
> > to build a frontend that puts the output onto multiple pages.
> > Both regular output and JSON output include the token.
> >
> 
> I am not comfortable with this. It seems out of the scope of bgpctl.
> I would prefer to keep it simple / follow the unix way, aka pipe the output to
> another tool to paginate the output.
> In your example you use a temp file, why not work on this file to manage the
> limit / page display ?

The idea is to use this for looking glass software. Currently bgplg will
a) load the bgpd excessivly when 'bgpctl show rib' is requested
b) the output is too long for the user
c) if used with JSON the array will blow up some systems because there are
just too many objects in the output.

This is a place where unix tools don't work well. You also don't want to
use head and tail to build a poor man paging system since it will not do a
fast lookup of the offset but instead walk over the table over and over
again. Also most of this is for a webservice using the JSON export.

-- 
:wq Claudio



bgpctl paged output for show rib

2020-05-14 Thread Claudio Jeker
This implements a way to add a limit for bgpctl show rib output.
When a limit is set then the output will include a token (at the end)
that can be used to get the next batch of output. These two things allow
to build a frontend that puts the output onto multiple pages.
Both regular output and JSON output include the token.

A simple but dumb example of this:
set -e
TMP=$(mktemp)
while true; do
bgpctl show rib limit 100 $token | tee "$TMP"
token=$(grep ^token "$TMP")
done

This can be used for looking glass software to limit output and offer
people a way to page through the output.
-- 
:wq Claudio

Index: bgpctl/bgpctl.c
===
RCS file: /cvs/src/usr.sbin/bgpctl/bgpctl.c,v
retrieving revision 1.263
diff -u -p -r1.263 bgpctl.c
--- bgpctl/bgpctl.c 10 May 2020 13:38:46 -  1.263
+++ bgpctl/bgpctl.c 13 May 2020 14:41:24 -
@@ -240,6 +240,8 @@ main(int argc, char *argv[])
strlcpy(ribreq.rib, res->rib, sizeof(ribreq.rib));
ribreq.aid = res->aid;
ribreq.flags = res->flags;
+   ribreq.limit = res->limit;
+   ribreq.token = res->token;
imsg_compose(ibuf, type, 0, 0, -1, , sizeof(ribreq));
break;
case SHOW_RIB_MEM:
@@ -391,11 +393,12 @@ show(struct imsg *imsg, struct parse_res
 {
struct peer *p;
struct ctl_timer*t;
-   struct ctl_show_interface   *iface;
struct ctl_show_nexthop *nh;
struct kroute_full  *kf;
struct ktable   *kt;
struct ctl_show_rib  rib;
+   struct ctl_show_rib_tokentoken;
+   struct ctl_show_interface   *iface;
u_char  *asdata;
struct rde_memstats stats;
struct rde_hashstatshash;
@@ -466,6 +469,14 @@ show(struct imsg *imsg, struct parse_res
memcpy(, imsg->data, sizeof(hash));
output->rib_hash();
break;
+   case IMSG_CTL_TOKEN:
+   if (imsg->hdr.len != IMSG_HEADER_SIZE + sizeof(token)) {
+   warnx("got IMSG_CTL_TOKEN with wrong len");
+   break;
+   }
+   memcpy(, imsg->data, sizeof(token));
+   output->token();
+   break;
case IMSG_CTL_RESULT:
if (imsg->hdr.len != IMSG_HEADER_SIZE + sizeof(rescode)) {
warnx("got IMSG_CTL_RESULT with wrong len");
@@ -975,6 +986,20 @@ fmt_ext_community(u_int8_t *data)
(unsigned long long)be64toh(ext));
return buf;
}
+}
+
+const char *
+fmt_token(struct ctl_show_rib_token *t)
+{
+   static char buf[128];
+
+   snprintf(buf, sizeof(buf), "%d:%d:%u:%x:%x:%x:%x:%x:%x:%x:%x:%d",
+   t->peerid, t->prefix.aid, t->prefix.scope_id,
+   t->prefix.addr32[0], t->prefix.addr32[1], t->prefix.addr32[2],
+   t->prefix.addr32[3], t->prefix.addr32[4], t->prefix.addr32[5],
+   t->prefix.addr32[6], t->prefix.addr32[7], t->prefixlen);
+
+   return buf;
 }
 
 void
Index: bgpctl/bgpctl.h
===
RCS file: /cvs/src/usr.sbin/bgpctl/bgpctl.h,v
retrieving revision 1.7
diff -u -p -r1.7 bgpctl.h
--- bgpctl/bgpctl.h 2 May 2020 14:33:33 -   1.7
+++ bgpctl/bgpctl.h 13 May 2020 10:00:49 -
@@ -30,6 +30,7 @@ struct output {
struct parse_result *);
void(*rib_hash)(struct rde_hashstats *);
void(*rib_mem)(struct rde_memstats *);
+   void(*token)(struct ctl_show_rib_token *);
void(*result)(u_int);
void(*tail)(void);
 };
@@ -53,3 +54,4 @@ const char*fmt_attr(u_int8_t, int);
 const char *fmt_community(u_int16_t, u_int16_t);
 const char *fmt_large_community(u_int32_t, u_int32_t, u_int32_t);
 const char *fmt_ext_community(u_int8_t *);
+const char *fmt_token(struct ctl_show_rib_token *);
Index: bgpctl/json.c
===
RCS file: /cvs/src/usr.sbin/bgpctl/json.c,v
retrieving revision 1.2
diff -u -p -r1.2 json.c
--- bgpctl/json.c   4 May 2020 16:00:13 -   1.2
+++ bgpctl/json.c   14 May 2020 14:57:32 -
@@ -117,6 +117,20 @@ json_do_array(const char *name)
 }
 
 void
+json_do_end_array(const char *name)
+{
+   int l;
+
+   l = do_find(ARRAY, name);
+   if (l == -1)
+   errx(1, "json array %s not found", name);
+
+   /* array already in use, close element and move on */
+   while (level >= l)
+   json_do_end();
+}
+
+void
 json_do_object(const char *name)
 {
int i, l;
Index: bgpctl/json.h
===
RCS file: /cvs/src/usr.sbin/bgpctl/json.h,v
retrieving revision 1.2
diff -u -p -r1.2 json.h
--- 

Re: Minor change in rpki-client.8

2020-05-14 Thread Claudio Jeker
On Thu, May 14, 2020 at 01:48:05AM +0200, Robert Scheck wrote:
> Following claudio@'s recent change from "-rlt" to "-rt" in rpki-client [1],
> I would like to propose this minor change to rpki-client.8 hereby:
> 
> diff --git a/src/usr.sbin/rpki-client/rpki-client.8 
> b/src/usr.sbin/rpki-client/rpki-client.8
> index 06d3490..ec1e4ae 100644
> --- a/src/usr.sbin/rpki-client/rpki-client.8
> +++ b/src/usr.sbin/rpki-client/rpki-client.8
> @@ -76,7 +76,7 @@ instead of
>  .Xr openrsync 1
>  to fetch repositories.
>  It must accept the
> -.Fl rlt ,
> +.Fl rt ,
>  .Fl -address
>  and
>  .Fl -delete
> 
> 
> Regards,
>   Robert
> 
> [1] 
> https://github.com/rpki-client/rpki-client-openbsd/commit/dfb8acbffdb9e9874b4707a05f1a99149b305cf8.patch
> 

Committed, thanks for the report

-- 
:wq Claudio



bgpctl parser cleanup

2020-05-12 Thread Claudio Jeker
Minimal cleanup of things not used in the bgpctl parser.
Bulk is not used and the ADDRESS / PREFIX tokens no longer overwrite the
action since a while.

-- 
:wq Claudio

Index: parser.c
===
RCS file: /cvs/src/usr.sbin/bgpctl/parser.c,v
retrieving revision 1.103
diff -u -p -r1.103 parser.c
--- parser.c11 May 2020 07:55:18 -  1.103
+++ parser.c12 May 2020 10:25:37 -
@@ -61,8 +61,7 @@ enum token_type {
RD,
FAMILY,
RTABLE,
-   FILENAME,
-   BULK
+   FILENAME
 };
 
 struct token {
@@ -592,24 +591,18 @@ match_token(int *argc, char **argv[], co
if (parse_addr(word, )) {
match++;
t = [i];
-   if (t->value)
-   res.action = t->value;
}
break;
case PEERADDRESS:
if (parse_addr(word, )) {
match++;
t = [i];
-   if (t->value)
-   res.action = t->value;
}
break;
case PREFIX:
if (parse_prefix(word, wordlen, , 
)) {
match++;
t = [i];
-   if (t->value)
-   res.action = t->value;
}
break;
case ASTYPE:
@@ -797,10 +790,6 @@ match_token(int *argc, char **argv[], co
t = [i];
}
break;
-   case BULK:
-   match++;
-   t = [i];
-   break;
case ENDTOKEN:
break;
}
@@ -890,7 +879,6 @@ show_valid_args(const struct token table
case FILENAME:
fprintf(stderr, "  \n");
break;
-   case BULK:
case ENDTOKEN:
break;
}



Re: ospfctl json support

2020-05-11 Thread Claudio Jeker
On Mon, May 11, 2020 at 12:38:38PM +0100, Richard Chivers wrote:
> Hi,
> 
> I have done some work over the last few days to implement json support
> into ospfctl following the work done recently in bgpctl.
> 
> I have some queries, hoping to get some help with.
> 
> The change involves a refactor of ospfctl, but reuses the recent
> json.c written by Claudio, that is in the
> usr.sbin/bgpctl directory. At present no changes have been required at all.
> What is the best approach here, should/could this be centralised somewhere?

At the moment just copy the files into ospfctl. We did the same thing with
other bits in the tree. My json API is super minimal and is for sure not
something that should be put into a common framework right now. The way
objects and arrays are opened and closed is a bit rough and does not
always work well.
 
> In some cases there is room for change, for example ospfctl sh rib &
> ospfctl sh rib detail.
> 
> In my view here, it makes sense to have a full list returned rather
> than splitting json into multiple lists of Router, Network and
> External.
> I looked for inspiration in the bgpctl, but couldn't find a similar
> pattern. The reason for a single list is that if consuming the json,
> I expect you will not want code that has to iterate over three
> separate arrays. Just looking for some feedback really. The original
> split
> made sense for screen use, just not so sure about machine readability.
> This issue also applies to ospfctl sh data, which returns 3 lists.

A lot of this is depending on the imsgs used between ospfctl and ospfd.
IIRC ospfd sends all data in one batch so the multiple lists just happen
by ospfctl and indeed for json output it would be best to display the rib
as a single array of entries (which have a similar structure but probably
per LSA specific attributes).

> When I am finished, should I just post the diff on here? Just
> conscious it is quite a big refactor, albeit much of the code is
> reused just moved into output.c as
> was done for bgpctl.

Please split it up like I did it for bgpctl. I first did a lot of the
moving and cleanup and only later added the new input mode. This makes the
individual steps smaller to review.

> I am testing each call individually against a set of openbsd 6.6 boxes
> we have running, which is great for ospfd. What is the normal
> practise for ospf6, is there a script run to replicate code changes or
> is it just a case of making very similar changes line by line?

There is no script, you do it by hand it is quicker.

> Just looking for the general thinking and approach I guess. I don't
> currently have ospf6 set-up so that would be some overhead.
> Happy to configure it though if needed/expected.

Get ospfctl first, after that ospf6ctl can be done (and maybe somebody
else will take care of that).
 
> Finally what was the driver under bgpctl for the json output, ours is
> for reading metrics to populate telemetry, just interested as the
> purpose other
> people have. Having this context will help in micro decisions when
> implementing the json structure.

I'm doing this work to provide JSON payloads to external looking glasses.
I would not put the RIB into telemetry (that is just useless churn and
load on the telemetry system). In bgpctl the terse outputs are simple
space separated outputs for telemetry scripting but I guess people will
also use the JSON output for this.

> As a final thought is this something that is actually wanted
> generally, I assumed it was as bgpctl has gone/is going in that
> direction, but just don't want to assume.

I see no reason why not. At least I wont veto it.

-- 
:wq Claudio



minor bgpd cleanup

2020-05-11 Thread Claudio Jeker
There is no need to limit the number of chars printed by log_reason().
log_reason() returns a strnvis cleaned buffer and so %s is good enough.
While there wrap a long line.

-- 
:wq Claudio

Index: bgpd.c
===
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.c,v
retrieving revision 1.228
diff -u -p -r1.228 bgpd.c
--- bgpd.c  10 May 2020 13:38:46 -  1.228
+++ bgpd.c  11 May 2020 07:58:02 -
@@ -829,10 +829,10 @@ dispatch_imsg(struct imsgbuf *ibuf, int 
else {
reconfig = 1;
reconfpid = imsg.hdr.pid;
-   if (imsg.hdr.len == IMSG_HEADER_SIZE + 
REASON_LEN &&
-   ((char *)imsg.data)[0])
-   log_info("reload due to: %.*s",
-   REASON_LEN, log_reason(imsg.data));
+   if (imsg.hdr.len == IMSG_HEADER_SIZE +
+   REASON_LEN && ((char *)imsg.data)[0])
+   log_info("reload due to: %s",
+   log_reason(imsg.data));
}
break;
case IMSG_CTL_FIB_COUPLE:



teach bgpctl about IPv6 MPLS VPN

2020-05-08 Thread Claudio Jeker
Bgpctl has a way to specify the address family to show in 'show rib'
commands. Teach it to also support IPv6 MPLS VPNs (aka VPNv6).

OK?
-- 
:wq Claudio

Index: parser.c
===
RCS file: /cvs/src/usr.sbin/bgpctl/parser.c,v
retrieving revision 1.101
diff -u -p -r1.101 parser.c
--- parser.c22 Jan 2020 07:52:38 -  1.101
+++ parser.c7 May 2020 17:11:38 -
@@ -581,6 +581,11 @@ match_token(int *argc, char **argv[], co
t = [i];
res.aid = AID_VPN_IPv4;
}
+   if (!strcasecmp(word, "VPNv6")) {
+   match++;
+   t = [i];
+   res.aid = AID_VPN_IPv6;
+   }
break;
case ADDRESS:
if (parse_addr(word, )) {
@@ -878,7 +883,8 @@ show_valid_args(const struct token table
fprintf(stderr, "  \n");
break;
case FAMILY:
-   fprintf(stderr, "  [ inet | inet6 | IPv4 | IPv6 | VPNv4 
]\n");
+   fprintf(stderr, "  [ inet | inet6 | IPv4 | IPv6 | "
+   "VPNv4 | VPNv6 ]\n");
break;
case FILENAME:
fprintf(stderr, "  \n");



that ospfd fix for ospf6d

2020-05-06 Thread Claudio Jeker
Can someone give this diff for ospf6d a try?
This fixes the same issue that I just committed for ospfd:

revision 1.48
date: 2020/05/06 14:40:54;  author: claudio;  state: Exp;  lines: +5 -5;
commitid: 1nh8JCAv0Kmqd1jV;
Do not use the pointer returned by ibuf_reserve() after calling another
ibuf function. After the call the internal buffer may have moved by
realloc()
and so the pointer is invalid. Instead use ibuf_size() to get the current
offset in the buffer and use ibuf_seek() later on to write back the
updated
lsa age into the buffer at the right spot.
This fixes an issue seen by Richard Chivers on routers with many passive
interfaces.
OK stsp@ deraadt@


Thanks
-- 
:wq Claudio

Index: lsupdate.c
===
RCS file: /cvs/src/usr.sbin/ospf6d/lsupdate.c,v
retrieving revision 1.16
diff -u -p -r1.16 lsupdate.c
--- lsupdate.c  4 May 2020 14:36:51 -   1.16
+++ lsupdate.c  6 May 2020 14:33:40 -
@@ -194,13 +194,13 @@ int
 add_ls_update(struct ibuf *buf, struct iface *iface, void *data, u_int16_t len,
 u_int16_t older)
 {
-   void*lsage;
-   u_int16_tage;
+   size_t  ageoff;
+   u_int16_t   age;
 
if (buf->wpos + len >= buf->max)
return (0);
 
-   lsage = ibuf_reserve(buf, 0);
+   ageoff = ibuf_size(buf);
if (ibuf_add(buf, data, len)) {
log_warn("add_ls_update");
return (0);
@@ -212,7 +212,7 @@ add_ls_update(struct ibuf *buf, struct i
if ((age += older + iface->transmit_delay) >= MAX_AGE)
age = MAX_AGE;
age = htons(age);
-   memcpy(lsage, , sizeof(age));
+   memcpy(ibuf_seek(buf, ageoff, sizeof(age)), , sizeof(age));
 
return (1);
 }



JSON support for bgpctl(8)

2020-05-01 Thread Claudio Jeker
  (*timer)(struct ctl_timer *);
+   void(*fib)(struct kroute_full *);
+   void(*fib_table)(struct ktable *);
+   void(*nexthop)(struct ctl_show_nexthop *);
+   void(*interface)(struct ctl_show_interface *);
+   void(*attr)(u_char *, size_t, struct parse_result *);
+   void(*communities)(u_char *, size_t, struct parse_result *);
+   void(*rib)(struct ctl_show_rib *, u_char *, size_t,
+   struct parse_result *);
+   void(*rib_hash)(struct rde_hashstats *);
+   void(*rib_mem)(struct rde_memstats *);
+   void(*result)(u_int);
+   void(*tail)(void);
+};
+
+extern const struct output show_output, json_output;
+extern const size_t pt_sizes[];
 
 #define EOL0(flag) ((flag & F_CTL_SSV) ? ';' : '\n')
 
@@ -43,8 +49,7 @@ const char*fmt_ovs(u_int8_t, int);
 const char *fmt_auth_method(enum auth_method);
 const char *fmt_mem(long long);
 const char *fmt_errstr(u_int8_t, u_int8_t);
-const char *fmt_attr(u_int8_t, u_int8_t);
+const char *fmt_attr(u_int8_t, int);
 const char *fmt_community(u_int16_t, u_int16_t);
 const char *fmt_large_community(u_int32_t, u_int32_t, u_int32_t);
 const char *fmt_ext_community(u_int8_t *);
-
Index: json.c
===
RCS file: json.c
diff -N json.c
--- /dev/null   1 Jan 1970 00:00:00 -
+++ json.c  30 Apr 2020 16:43:41 -
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2020 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 "json.h"
+
+#define JSON_MAX_STACK 16
+
+enum json_type {
+   NONE,
+   START,
+   ARRAY,
+   OBJECT
+};
+
+struct json_stack {
+   const char  *name;
+   unsigned intcount;
+   enum json_type  type;
+} stack[JSON_MAX_STACK];
+
+char indent[JSON_MAX_STACK + 1];
+int level;
+
+static void
+do_coma_indent(void)
+{
+   if (stack[level].count++ > 0)
+   printf(",\n");
+   printf("\t%.*s", level, indent);
+}
+
+static void
+do_name(const char *name)
+{
+   if (stack[level].type == ARRAY)
+   return;
+   printf("\"%s\": ", name);
+}
+
+static int
+do_find(enum json_type type, const char *name)
+{
+   int i;
+
+   for (i = level; i > 0; i--)
+   if (type == stack[i].type &&
+   strcmp(name, stack[i].name) == 0)
+   return i;
+
+   /* not found */
+   return -1;
+}
+
+void
+json_do_start(void)
+{
+   memset(indent, '\t', JSON_MAX_STACK);
+   memset(stack, 0, sizeof(stack));
+   level = 0;
+   stack[level].type = START;
+
+   printf("{\n");
+}
+
+void
+json_do_finish(void)
+{
+   while (level > 0)
+   json_do_end();
+   printf("\n}\n");
+}
+
+void
+json_do_array(const char *name)
+{
+   int i, l;
+
+   if ((l = do_find(ARRAY, name)) > 0) {
+   /* array already in use, close element and move on */
+   for (i = level - l; i > 0; i--)
+   json_do_end();
+   return;
+   }
+   /* Do not stack arrays, while allowed this is not needed */
+   if (stack[level].type == ARRAY)
+   json_do_end();
+
+   do_coma_indent();
+   do_name(name);
+   printf("[\n");
+
+   if (++level >= JSON_MAX_STACK)
+   errx(1, "json stack too deep");
+   
+   stack[level].name = name;
+   stack[level].type = ARRAY;
+   stack[level].count = 0;
+}
+
+void
+json_do_object(const char *name)
+{
+   int i, l;
+
+   if ((l = do_find(OBJECT, name)) > 0) {
+   /* roll back to that object and close it */
+   for (i = level - l; i >= 0; i--)
+   json_do_end();
+   }
+
+   do_coma_indent();
+   do_name(name);
+   printf("{\n");
+
+   if (++level >= JSON_MAX_STACK)
+   errx(1, "json stack too deep");
+   
+   stack[level].name = name;
+   stack[level].type = OBJECT;
+   stack[level].count = 0;
+}
+
+void
+json_do_

Re: IPv6 Support for umb(4)

2020-04-27 Thread Claudio Jeker
On Mon, Apr 27, 2020 at 10:26:01AM +0200, Gerhard Roth wrote:
> Should we change umb(4) so that it only grabs an IPv6 address
> in case somebody does a "ifconfig umb0 inet6 eui64" first?
> 
> Anyone willing to ok the patch below?

see below
 
> On 2/19/20 9:19 AM, Gerhard Roth wrote:
> > On Wed, 19 Feb 2020 08:45:39 +0100 Claudio Jeker  
> > wrote:
> > > On Tue, Feb 18, 2020 at 11:16:54PM +, Stuart Henderson wrote:
> > > > On 2020/02/18 13:40, Gerhard Roth wrote:
> > > > > > > Yes, I tried MBIM_CONTEXT_IPTYPE_IPV4ANDV6 myself first but to no
> > > > > > > avail. The switched to MBIM_CONTEXT_IPTYPE_IPV4V6 and everything
> > > > > > > was fine.
> > > > > > 
> > > > > > Obviously it needs to switch based on INET6, but with the current
> > > > > > mechanism used for handling v6 in OpenBSD, shouldn't it disable v6
> > > > > > unless the interface has a link-local configured? (So the usual 
> > > > > > method
> > > > > > to enable v6 and bring an interface up would be "inet6 eui64" and 
> > > > > > "up").
> > > > > > That is how pppoe works.
> > > > > 
> > > > > 
> > > > > Hi Stuart,
> > > > > 
> > > > > you mean like that?
> > > > 
> > > > Yes, that looks right - sorry I don't have a working umb to test though!
> > > 
> > > I guess we should then also adjust the manpage to make sure people know
> > > how to enable IPv6 in hostname.umb0
> > 
> > 
> > Took a look at pppoe.4 and tried to extract what is needed for umb.4.
> > Updated diff below.
> > 
> > Gerhard
> > 
> > 
> > Index: share/man/man4/umb.4
> > ===
> > RCS file: /cvs/src/share/man/man4/umb.4,v
> > retrieving revision 1.10
> > diff -u -p -u -p -r1.10 umb.4
> > --- share/man/man4/umb.418 Feb 2020 08:09:37 -  1.10
> > +++ share/man/man4/umb.419 Feb 2020 08:14:01 -
> > @@ -40,6 +40,19 @@ will remain in this state until the MBIM
> >   In case the device is connected to an "always-on" USB port,
> >   it may be possible to connect to a provider without entering the
> >   PIN again even if the system was rebooted.
> > +.Pp
> > +To use IPv6, configure a link-local address before bringing
> > +the interface up.
> > +Some devices require the
> > +.Sy AUTOCONF6
> > +flag on the interface.

I think I asked this already, how does one know if autoconf is needed or
not. Is that only device specific or also provider dependent?
Adding autoconf will enable slaacd(8) on the device. What kind of troubles
could result from this on a device that do not need it?
In general this paragraph does not really help me to understand the
situation better.

> > +.Pp
> > +A typical
> > +.Pa /etc/hostname.umb0
> > +looks like this:
> > +.Bd -literal -offset indent
> > +pin 1234 apn ISP-APN-Name inet6 eui64 autoconf -roaming up
> > +.Ed

In my opinion this is a bad example, it mixes a lot of different options
which are not explained to the user in that man page. Also I think it is
bad practice to put everything on one line. ifconfig(8) is rather
sensitive when it comes to multiple commands in a single invocation.
If I look at this and compare it with my hostname.umb0 file
pin 
up
I have more questions, what is apn and why would I need, where do I find
what I need to put there. ifconfig umb0 does not show anything named apn.
Also why is -roaming after inet6 eui64 autoconf? Isn't -roaming default?

Ideally the first paragraph explains the IPv6 setup well enough that no
example config is needed here.

> >   .Sh HARDWARE
> >   The following devices should work:
> >   .Pp
> > Index: sys/dev/usb/if_umb.c
> > ===
> > RCS file: /cvs/src/sys/dev/usb/if_umb.c,v
> > retrieving revision 1.32
> > diff -u -p -u -p -r1.32 if_umb.c
> > --- sys/dev/usb/if_umb.c18 Feb 2020 08:09:37 -  1.32
> > +++ sys/dev/usb/if_umb.c18 Feb 2020 12:35:45 -
> > @@ -2583,7 +2583,8 @@ umb_send_connect(struct umb_softc *sc, i
> > c->iptype = htole32(MBIM_CONTEXT_IPTYPE_IPV4);
> >   #ifdef INET6
> > /* XXX FIXME: support IPv6-only mode, too */
> > -   if ((sc->sc_flags & UMBFLG_NO_INET6) == 0)
> > +   if ((sc->sc_flags & UMBFLG_NO_INET6) == 0 &&
> > +   in6ifa_ifpforlinklocal(GET_IFP(sc), 0) != NULL)
> > c->iptype = htole32(MBIM_CONTEXT_IPTYPE_IPV4V6);
> >   #endif
> > memcpy(c->context, umb_uuid_context_internet, sizeof (c->context));
> > 

The code diff is fine by me.

-- 
:wq Claudio



Re: bgpd local-address improvement

2020-04-23 Thread Claudio Jeker
On Thu, Apr 23, 2020 at 06:08:02PM +0100, Stuart Henderson wrote:
> We could use it in the sample config too. OK?

OK. Lets burn down the bad v4 vs v6 groups :)
 
> Index: bgpd.conf
> ===
> RCS file: /cvs/src/etc/examples/bgpd.conf,v
> retrieving revision 1.18
> diff -u -p -r1.18 bgpd.conf
> --- bgpd.conf 16 Feb 2020 20:02:21 -  1.18
> +++ bgpd.conf 23 Apr 2020 17:07:12 -
> @@ -51,18 +51,15 @@ prefix-set bogons {
>  network prefix-set mynetworks set large-community $ASN:1:1
>  
>  # assume simple network with 3 routers in IBGP full mesh
> -group "ibgp mesh v4" {
> +group "ibgp mesh" {
>   remote-as $ASN
> - # use loopback for IBGP sessions, assume its distributed in OSPF
> + # use loopback for IBGP sessions, assume it's distributed in OSPF
>   local-address 192.0.2.1
> - neighbor 192.0.2.2  # router 2 ipv4
> - neighbor 192.0.2.3  # router 3 ipv4
> -}
> -# define the IPv6 IBGP sessions
> -group "ibgp mesh v6" {
> - remote-as $ASN
>   local-address 2001:db8:abcd::1
> +
> + neighbor 192.0.2.2  # router 2 ipv4
>   neighbor 2001:db8:abcd::2   # router 2 ipv6
> + neighbor 192.0.2.3  # router 3 ipv4
>   neighbor 2001:db8:abcd::3   # router 3 ipv6
>  }
>  
> 

-- 
:wq Claudio



Re: resolv.conf(5) says options inet6 does nothing

2020-04-23 Thread Claudio Jeker
On Thu, Apr 23, 2020 at 06:31:12PM +0200, Jeremie Courreges-Anglas wrote:
> On Thu, Apr 23 2020, Jason McIntyre  wrote:
> > On Thu, Apr 23, 2020 at 05:17:08PM +0200, Solene Rapenne wrote:
> >> Is there a reason to keep this part in resolv.conf(5) about an option
> >> doing nothing?
> >> 
> >> > options inet6
> >> > Enables support for IPv6-only applications, by setting RES_USE_INET6
> >> > in _res.options (see res_init(3)). On OpenBSD this option does
> >> > nothing.
> >> 
> >> If we can remove it, here is the diff.
> >> 
> >
> > hi.
> >
> > i guess if you did this, you'd need to look at res_init.3 too.
> 
> "options inet6" in resolv.conf(5) does bothing, it doesn't "set
> RES_USE_INET6 in _res.options".  I think we can just delete any mention
> of "options inet6" in resolv.conf(5).
> 
> RES_USE_INET6 as documented in res_init(3) should be investigated some
> more.  It actually does *something* in the current code, but it
> doesn't enable the IPv4-mapped IPv6 addresses which we don't support.
> 
> Maybe this option should just be deleted (probably safer to wait after
> 6.7 is released).  People should use getaddrinfo(3) instead.
> 

resolv.conf and res_init is used on many other operating systems. It is
defacto a standard file and so it makes sense to document options that may
exist on other system.

-- 
:wq Claudio



bgpd local-address improvement

2020-04-23 Thread Claudio Jeker
local-address is one of those values that need to be set in some cases but
is not very flexible to use. This diff tries to change this a bit.

It allows to set the local-address for both IPv4 and IPv6 at the same time
and also allows to unset a previously set local-address. For example:

group IBGP {
local-address 192.0.2.1
local-address 2001:db8:abcd::1

neighbor 192.0.2.2 { remote-as $AS }
neighbor 2001:db8:abcd::2 { remote-as $AS }

# reset the local-address for whatever reason
neighbor 192.0.2.3 {
no local-address
remote-as $AS
}
}

As usual setting a local-address on the neighbor will override the group
config. I think for IBGP and multihop sessions this can simplify the
config a fair bit. In my case this will collaps IPv4 and IPv6 specific
groups back together since the only reason they are split is because of
local-address.

What do other bgpd user think?
-- 
:wq Claudio

Index: bgpd.h
===
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v
retrieving revision 1.401
diff -u -p -r1.401 bgpd.h
--- bgpd.h  14 Feb 2020 13:54:31 -  1.401
+++ bgpd.h  22 Apr 2020 15:50:46 -
@@ -365,7 +365,8 @@ struct capabilities {
 
 struct peer_config {
struct bgpd_addr remote_addr;
-   struct bgpd_addr local_addr;
+   struct bgpd_addr local_addr_v4;
+   struct bgpd_addr local_addr_v6;
struct peer_auth auth;
struct capabilities  capabilities;
char group[PEER_DESCR_LEN];
Index: parse.y
===
RCS file: /cvs/src/usr.sbin/bgpd/parse.y,v
retrieving revision 1.405
diff -u -p -r1.405 parse.y
--- parse.y 16 Mar 2020 14:47:30 -  1.405
+++ parse.y 23 Apr 2020 07:51:25 -
@@ -1260,8 +1260,27 @@ peeropts : REMOTEAS as4number{
free($2);
}
| LOCALADDR address {
-   memcpy(>conf.local_addr, &$2,
-   sizeof(curpeer->conf.local_addr));
+   if ($2.aid == AID_INET)
+   memcpy(>conf.local_addr_v4, &$2,
+   sizeof(curpeer->conf.local_addr_v4));
+   else if ($2.aid == AID_INET6)
+   memcpy(>conf.local_addr_v6, &$2,
+   sizeof(curpeer->conf.local_addr_v6));
+   else {
+   yyerror("Unsupported address family %s for "
+   "local-addr", aid2str($2.aid));
+   YYERROR;
+   }
+   }
+   | yesno LOCALADDR   {
+   if ($1) {
+   yyerror("bad local-address definition");
+   YYERROR;
+   }
+   memset(>conf.local_addr_v4, 0,
+   sizeof(curpeer->conf.local_addr_v4));
+   memset(>conf.local_addr_v6, 0,
+   sizeof(curpeer->conf.local_addr_v6));
}
| MULTIHOP NUMBER   {
if ($2 < 2 || $2 > 255) {
@@ -4176,11 +4195,17 @@ str2key(char *s, char *dest, size_t max_
 int
 neighbor_consistent(struct peer *p)
 {
-   /* local-address and peer's address: same address family */
-   if (p->conf.local_addr.aid &&
-   p->conf.local_addr.aid != p->conf.remote_addr.aid) {
-   yyerror("local-address and neighbor address "
-   "must be of the same address family");
+   struct bgpd_addr *local_addr;
+
+   switch (p->conf.remote_addr.aid) {
+   case AID_INET:
+   local_addr = >conf.local_addr_v4;
+   break;
+   case AID_INET6:
+   local_addr = >conf.local_addr_v6;
+   break;
+   default:
+   yyerror("Bad address family for remote-addr");
return (-1);
}
 
@@ -4189,7 +4214,7 @@ neighbor_consistent(struct peer *p)
p->conf.auth.method == AUTH_IPSEC_IKE_AH ||
p->conf.auth.method == AUTH_IPSEC_MANUAL_ESP ||
p->conf.auth.method == AUTH_IPSEC_MANUAL_AH) &&
-   !p->conf.local_addr.aid) {
+   local_addr->aid == AID_UNSPEC) {
yyerror("neighbors with any form of IPsec configured "
"need local-address to be specified");
return (-1);
Index: pfkey.c
===
RCS file: /cvs/src/usr.sbin/bgpd/pfkey.c,v
retrieving revision 1.60
diff -u -p -r1.60 pfkey.c
--- pfkey.c 1 Oct 2019 11:05:30 -   1.60
+++ pfkey.c 22 Apr 2020 16:08:33 -
@@ -55,6 +55,18 @@ int  pfkey_send(int, 

Re: rpki-client(8), fix default cachedir

2020-04-18 Thread Claudio Jeker
On Sat, Apr 18, 2020 at 01:41:15PM +0100, Stuart Henderson wrote:
> Spotted while trying to figure out what "rpki-client: cache directory 
> required"
> meant.
> 
> ok?

Indeed. OK
 
> Index: rpki-client.8
> ===
> RCS file: /cvs/src/usr.sbin/rpki-client/rpki-client.8,v
> retrieving revision 1.22
> diff -u -p -r1.22 rpki-client.8
> --- rpki-client.8 6 Mar 2020 22:22:31 -   1.22
> +++ rpki-client.8 18 Apr 2020 12:37:18 -
> @@ -68,7 +68,7 @@ The directory where
>  .Nm
>  will store the cached repository data.
>  Defaults to
> -.Pa /var/db/rpki-client/ .
> +.Pa /var/cache/rpki-client .
>  .It Fl e Ar rsync_prog
>  Use
>  .Ar rsync_prog
> 

-- 
:wq Claudio



Re: rpki-client: replace deprecated ERR_remove_state

2020-04-16 Thread Claudio Jeker
On Thu, Apr 16, 2020 at 09:45:45AM -0600, Theo de Raadt wrote:
> I don't understand the point of any of this cleanup.  The process
> is dying and none of these things maintain external state.
> 
> I'm going to call it what it is: stylistically stupid and rigid.
> 
> Why?  Because it would mean every call to errx() in the program is
> wrong because they don't attempt this, and only this one exit() call
> needs this kind of cleanup.  That is simply not plausible.

Indeed, also I noticed that ERR_remove_thread_state() was deprecated in
OpenSSL 1.1 and so I'm kind of back to square 1 again regarding the use of
deprecated functions.

All this cleanup before exit(3) is done mostly to please runtime memory
leak checkers.

Also EVP_cleanup() and ERR_free_strings() are deprecated according to
their man page. There is no documentation for CRYPTO_cleanup_all_ex_data()
but looking at the code it seems to be not important.

Removing all of them seems to be the best move forward.

> Claudio Jeker  wrote:
> 
> > ERR_remove_state(0) is deprecated use the new api
> > ERR_remove_thread_state(NULL) instead.
> > 
> > -- 
> > :wq Claudio
> > 
> > Index: main.c
> > ===
> > RCS file: /cvs/src/usr.sbin/rpki-client/main.c,v
> > retrieving revision 1.61
> > diff -u -p -r1.61 main.c
> > --- main.c  1 Apr 2020 14:15:49 -   1.61
> > +++ main.c  16 Apr 2020 10:01:56 -
> > @@ -1250,7 +1250,7 @@ out:
> >  
> > EVP_cleanup();
> > CRYPTO_cleanup_all_ex_data();
> > -   ERR_remove_state(0);
> > +   ERR_remove_thread_state(NULL);
> > ERR_free_strings();
> >  
> > exit(rc);
> > 
> 

-- 
:wq Claudio



rpki-client: replace deprecated ERR_remove_state

2020-04-16 Thread Claudio Jeker
ERR_remove_state(0) is deprecated use the new api
ERR_remove_thread_state(NULL) instead.

-- 
:wq Claudio

Index: main.c
===
RCS file: /cvs/src/usr.sbin/rpki-client/main.c,v
retrieving revision 1.61
diff -u -p -r1.61 main.c
--- main.c  1 Apr 2020 14:15:49 -   1.61
+++ main.c  16 Apr 2020 10:01:56 -
@@ -1250,7 +1250,7 @@ out:
 
EVP_cleanup();
CRYPTO_cleanup_all_ex_data();
-   ERR_remove_state(0);
+   ERR_remove_thread_state(NULL);
ERR_free_strings();
 
exit(rc);



cleanup an bad and unneeded typecast in rpki-client

2020-04-16 Thread Claudio Jeker
There is a bit of strange code in the ip parser of rpki-client to parse
the AFI. This is a 2byte network byte order value. Instead of using a a
char buf and a short just do everything with a one uint16_t. The current
code does *(uint16_t)buf which is not save since buf is a char array.
Lucky us that the stack ends up enough aligned that this code does not
blow up on strict align archs. Still fix is simple and makes the code much
cleaner.

-- 
:wq Claudio

Index: ip.c
===
RCS file: /cvs/src/usr.sbin/rpki-client/ip.c,v
retrieving revision 1.9
diff -u -p -r1.9 ip.c
--- ip.c27 Nov 2019 17:18:24 -  1.9
+++ ip.c16 Apr 2020 09:48:02 -
@@ -41,8 +41,7 @@
 int
 ip_addr_afi_parse(const char *fn, const ASN1_OCTET_STRING *p, enum afi *afi)
 {
-   char buf[2];
-   shortv;
+   uint16_t v;
 
if (p->length == 0 || p->length > 3) {
warnx("%s: invalid field length, want 1--3, have %d",
@@ -50,8 +49,8 @@ ip_addr_afi_parse(const char *fn, const 
return 0;
}
 
-   memcpy(buf, p->data, sizeof(uint16_t));
-   v = ntohs(*(uint16_t *)buf);
+   memcpy(, p->data, sizeof(v));
+   v = ntohs(v);
 
/* Only accept IPv4 and IPv6 AFIs. */
 



update strstr.c and memmem.c to latest musl

2020-04-15 Thread Claudio Jeker
Our strstr.c is based on musl but since the import a few minor tweaks
happened and this brings us back in sync. For memmem.c our libc has a very
simple implementation. This switches the code to the memmem.c from musl
which is O(n) like strstr.c. For memmem() similar configure checks are
done as for strstr to verify the runtime so it makes sense to provide a
good version in libc.

-- 
:wq Claudio

Index: string/memmem.c
===
RCS file: /cvs/src/lib/libc/string/memmem.c,v
retrieving revision 1.4
diff -u -p -r1.4 memmem.c
--- string/memmem.c 31 Aug 2015 02:53:57 -  1.4
+++ string/memmem.c 15 Apr 2020 07:38:09 -
@@ -1,64 +1,184 @@
-/* $OpenBSD: memmem.c,v 1.4 2015/08/31 02:53:57 guenther Exp $ */
-/*-
- * Copyright (c) 2005 Pascal Gloor 
+/* $OpenBSD$ */
+
+/*
+ * Copyright (c) 2005-2020 Rich Felker, et al.
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *notice, this list of conditions and the following disclaimer in the
- *documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *products derived from this software without specific prior written
- *permission.
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include 
+#include 
+
+static char *
+twobyte_memmem(const unsigned char *h, size_t k, const unsigned char *n)
+{
+   uint16_t nw = n[0]<<8 | n[1], hw = h[0]<<8 | h[1];
+   for (h+=2, k-=2; k; k--, hw = hw<<8 | *h++)
+   if (hw == nw) return (char *)h-2;
+   return hw == nw ? (char *)h-2 : 0;
+}
+
+static char *
+threebyte_memmem(const unsigned char *h, size_t k, const unsigned char *n)
+{
+   uint32_t nw = n[0]<<24 | n[1]<<16 | n[2]<<8;
+   uint32_t hw = h[0]<<24 | h[1]<<16 | h[2]<<8;
+   for (h+=3, k-=3; k; k--, hw = (hw|*h++)<<8)
+   if (hw == nw) return (char *)h-3;
+   return hw == nw ? (char *)h-3 : 0;
+}
+
+static char *
+fourbyte_memmem(const unsigned char *h, size_t k, const unsigned char *n)
+{
+   uint32_t nw = n[0]<<24 | n[1]<<16 | n[2]<<8 | n[3];
+   uint32_t hw = h[0]<<24 | h[1]<<16 | h[2]<<8 | h[3];
+   for (h+=4, k-=4; k; k--, hw = hw<<8 | *h++)
+   if (hw == nw) return (char *)h-4;
+   return hw == nw ? (char *)h-4 : 0;
+}
+
+#define MAX(a,b) ((a)>(b)?(a):(b))
+#define MIN(a,b) ((a)<(b)?(a):(b))
+
+#define BITOP(a,b,op) \
+ ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a
 
 /*
- * Find the first occurrence of the byte string s in byte string l.
+ * Maxime Crochemore and Dominique Perrin, Two-way string-matching,
+ * Journal of the ACM, 38(3):651-675, July 1991.
  */
+static char *
+twoway_memmem(const unsigned char *h, const unsigned char *z,
+const unsigned char *n, 

Re: Simplify NET_LOCK() variations

2020-04-14 Thread Claudio Jeker
On Tue, Apr 14, 2020 at 10:08:54AM +0200, Martin Pieuchot wrote:
> Thanks for all the inputs, updated diff below.
> 
> On 13/04/20(Mon) 03:20, Alexandr Nedvedicky wrote:
> > On Sun, Apr 12, 2020 at 07:02:43PM +0200, Mark Kettenis wrote:
> > > > From: "Theo de Raadt" 
> > > > Date: Sun, 12 Apr 2020 10:28:59 -0600
> > > > 
> > > > > + if ((p->p_flag & P_SYSTEM) &&
> > > > > + (strncmp(p->p_p->ps_comm, "softnet", 7) == 0))
> > > > 
> > > > Wow that is ugly.  
> > > 
> > > A better approach might be to store a pointer to the softnet task's
> > > struct proc in a global variable and check that.  That is what we do
> > > for the pagedaemon for example.
> 
> Diff below implements that by introducing the in_taskq() function, any
> comment on that approach?
> 
> > I'm not sure same thing would work for network task. Currently
> > there is a single instance of pagedaemon, however we hope to
> > have more network tasks running in parallel.
> 
> Let's concentrate on the present.  More work is required to have
> multiple network tasks running in parallel anyway ;)
> 
> Diff below uses NET_RLOCK_IN_SOFTNET() with a corresponding KASSERT()
> and converts all the places where tasks are enqueued on the "softnet"
> taskq.
> 
> Any other comment or concern?

I'm very concerned about this. I think this is a complicated workaround
that will haunt us later on. I don't really understand what goes on there
and the names don't help me that much. It just makes this even more
confusing.

Shouldn't we fix the network stack so that it actually can use read locks
and with that multiple concurrent threads instead? Here the main problem
seems to be that solock needs to finally grow up to a real individual lock.
Are there other issues with multiple softnet task that we know off?
 
> Index: kern/kern_task.c
> ===
> RCS file: /cvs/src/sys/kern/kern_task.c,v
> retrieving revision 1.27
> diff -u -p -r1.27 kern_task.c
> --- kern/kern_task.c  19 Dec 2019 17:40:11 -  1.27
> +++ kern/kern_task.c  14 Apr 2020 07:49:38 -
> @@ -47,6 +47,7 @@ struct taskq {
>   unsigned int tq_nthreads;
>   unsigned int tq_flags;
>   const char  *tq_name;
> + struct proc **tq_threads;
>  
>   struct mutex tq_mtx;
>   struct task_list tq_worklist;
> @@ -55,6 +56,7 @@ struct taskq {
>  #endif
>  };
>  
> +struct proc *systqproc;
>  static const char taskq_sys_name[] = "systq";
>  
>  struct taskq taskq_sys = {
> @@ -64,6 +66,7 @@ struct taskq taskq_sys = {
>   1,
>   0,
>   taskq_sys_name,
> + ,
>   MUTEX_INITIALIZER(IPL_HIGH),
>   TAILQ_HEAD_INITIALIZER(taskq_sys.tq_worklist),
>  #ifdef WITNESS
> @@ -74,6 +77,7 @@ struct taskq taskq_sys = {
>  #endif
>  };
>  
> +struct proc *systqmpproc;
>  static const char taskq_sys_mp_name[] = "systqmp";
>  
>  struct taskq taskq_sys_mp = {
> @@ -83,6 +87,7 @@ struct taskq taskq_sys_mp = {
>   1,
>   TASKQ_MPSAFE,
>   taskq_sys_mp_name,
> + ,
>   MUTEX_INITIALIZER(IPL_HIGH),
>   TAILQ_HEAD_INITIALIZER(taskq_sys_mp.tq_worklist),
>  #ifdef WITNESS
> @@ -129,6 +134,8 @@ taskq_create(const char *name, unsigned 
>   tq->tq_nthreads = nthreads;
>   tq->tq_name = name;
>   tq->tq_flags = flags;
> + tq->tq_threads = mallocarray(nthreads, sizeof(*tq->tq_threads),
> + M_DEVBUF, M_WAITOK|M_ZERO);
>  
>   mtx_init_flags(>tq_mtx, ipl, name, 0);
>   TAILQ_INIT(>tq_worklist);
> @@ -172,6 +179,8 @@ taskq_destroy(struct taskq *tq)
>   }
>   mtx_leave(>tq_mtx);
>  
> + free(tq->tq_threads, M_DEVBUF,
> + tq->tq_nthreads * sizeof(*tq->tq_threads));
>   free(tq, M_DEVBUF, sizeof(*tq));
>  }
>  
> @@ -186,6 +195,8 @@ taskq_create_thread(void *arg)
>   switch (tq->tq_state) {
>   case TQ_S_DESTROYED:
>   mtx_leave(>tq_mtx);
> + free(tq->tq_threads, M_DEVBUF,
> + tq->tq_nthreads * sizeof(*tq->tq_threads));
>   free(tq, M_DEVBUF, sizeof(*tq));
>   return;
>  
> @@ -356,7 +367,17 @@ taskq_thread(void *xtq)
>  {
>   struct taskq *tq = xtq;
>   struct task work;
> - int last;
> + int last, i;
> +
> + mtx_enter(>tq_mtx);
> + for (i = 0; i < tq->tq_nthreads; i++) {
> + if (tq->tq_threads[i] == NULL) {
> + tq->tq_threads[i] = curproc;
> + break;
> + }
> + }
> + KASSERT(i < tq->tq_nthreads);
> + mtx_leave(>tq_mtx);
>  
>   if (ISSET(tq->tq_flags, TASKQ_MPSAFE))
>   KERNEL_UNLOCK();
> @@ -381,4 +402,17 @@ taskq_thread(void *xtq)
>   wakeup_one(>tq_running);
>  
>   kthread_exit(0);
> +}
> +
> +int
> +in_taskq(struct taskq *tq)
> +{
> + int i;
> +
> + for (i = 0; i < tq->tq_nthreads; i++) {
> + if (curproc == tq->tq_threads[i])
> + 

Re: suggest to run rpki-client hourly

2020-04-13 Thread Claudio Jeker
On Mon, Apr 13, 2020 at 02:43:27PM +, Job Snijders wrote:
> Hi,
> 
> I'm reviewing some of the timers associated with the workings of the
> end-to-end propagation from ROA to VRP. I think suggesting to run
> rpki-client only once a day can make for needless brittleness.
> 
> Running rpki-client just once a day also results in only making a rsync
> fetch attempt once a day. If the connection can't be established because
> of a transient network issue, the RP can easily end up going without
> contact with the CA Publication Point for close to 48 hours. A lot of
> CRLs appear to have expiration dates in the range of '24 hours'.
> 
> I think attempting to contact a CA PP at least once an hour is more
> appropriate for the various 24-48h sliding windows that are in play.
> 
> Thoughts? OK?
> 
> Kind regards,
> 
> Job
> 
> Index: crontab
> ===
> RCS file: /cvs/src/etc/crontab,v
> retrieving revision 1.25
> diff -u -p -r1.25 crontab
> --- crontab   4 Dec 2019 15:07:51 -   1.25
> +++ crontab   13 Apr 2020 14:34:45 -
> @@ -19,4 +19,4 @@ HOME=/var/log
>  30   5   1   *   *   /bin/sh /etc/monthly
>  #0   *   *   *   *   sleep $((RANDOM \% 2048)) && 
> /usr/libexec/spamd-setup
>  
> -#0   9   *   *   *   -n sleep $((RANDOM \% 4096)) && 
> rpki-client -v && bgpctl reload
> +#0   *   *   *   *   -n sleep $((RANDOM \% 4096)) && 
> rpki-client -v && bgpctl reload
> 

I personally run rpki-client every hour and that works very well for me.
I do not use the sleep RANDOM thing because I prefer to have rpki-client
run always at the same interval (1h) and I just selected a random minute
in the hour.

-- 
:wq Claudio



Re: pppx(4): kill forgotten splx(9) stuff

2020-04-07 Thread Claudio Jeker
On Tue, Apr 07, 2020 at 12:36:29PM +0300, Vitaliy Makkoveev wrote:
> pppx_if containing tree and per pppx_dev list are protected by rwlock so
> these splx(9) related dances and commentaries are not actual.
> Also pxd_svcq protected by NET_LOCK().
> 
> Index: sys/net/if_pppx.c
> ===
> RCS file: /cvs/src/sys/net/if_pppx.c,v
> retrieving revision 1.81
> diff -u -p -r1.81 if_pppx.c
> --- sys/net/if_pppx.c 7 Apr 2020 07:11:22 -   1.81
> +++ sys/net/if_pppx.c 7 Apr 2020 09:06:35 -
> @@ -126,7 +126,7 @@ struct pppx_dev {
>   struct selinfo  pxd_wsel;
>   struct mutexpxd_wsel_mtx;
>  
> - /* queue of packets for userland to service - protected by splnet */
> + /* queue of packets for userland to service - protected by NET_LOCK() */
>   struct mbuf_queue   pxd_svcq;
>   int pxd_waiting;
>   LIST_HEAD(,pppx_if) pxd_pxis;
> @@ -622,7 +622,6 @@ pppx_if_next_unit(void)
>  
>   rw_assert_wrlock(_ifs_lk);
>  
> - /* this is safe without splnet since we're not modifying it */
>   do {
>   int found = 0;
>   RBT_FOREACH(pxi, pppx_ifs, _ifs) {
> @@ -842,7 +841,6 @@ pppx_add_session(struct pppx_dev *pxd, s
>   pxi->pxi_key.pxik_protocol = req->pr_protocol;
>   pxi->pxi_dev = pxd;
>  
> - /* this is safe without splnet since we're not modifying it */
>   if (RBT_FIND(pppx_ifs, _ifs, pxi) != NULL) {
>   pool_put(pppx_if_pl, pxi);
>   error = EADDRINUSE;
> @@ -850,8 +848,7 @@ pppx_add_session(struct pppx_dev *pxd, s
>   goto out;
>   }
>  
> - if (RBT_INSERT(pppx_ifs, _ifs, pxi) != NULL)
> - panic("%s: pppx_ifs modified while lock was held", __func__);
> + RBT_INSERT(pppx_ifs, _ifs, pxi);

I would merge this into the RBT_FIND() above like this:

if (RBT_INSERT(pppx_ifs, _ifs, pxi) != NULL) {
pool_put(pppx_if_pl, pxi);
error = EADDRINUSE;
rw_exit_write(_ifs_lk);
goto out;
}

This does the same thing but without two lookups.


>   LIST_INSERT_HEAD(>pxd_pxis, pxi, pxi_list);
>   rw_exit_write(_ifs_lk);
>  
> @@ -1039,8 +1036,7 @@ pppx_if_destroy(struct pppx_dev *pxd, st
>   NET_LOCK();
>  
>   rw_enter_write(_ifs_lk);
> - if (RBT_REMOVE(pppx_ifs, _ifs, pxi) == NULL)
> - panic("%s: pppx_ifs modified while lock was held", __func__);
> + RBT_REMOVE(pppx_ifs, _ifs, pxi);
>   LIST_REMOVE(pxi, pxi_list);
>   rw_exit_write(_ifs_lk);
>  

Unsure about this one here. I would prefer if the panic remained for now
(mainly because of the XXXSMP NET_UNLOCK() dance just above). I wonder if the
order of this could not be modified so that the NET_LOCK is released after
the RBT_REMOVE.

-- 
:wq Claudio



Re: pipex(4) fix: check session existence before creation

2020-04-06 Thread Claudio Jeker
On Mon, Apr 06, 2020 at 06:32:01PM +0300, Vitaliy Makkoveev wrote:
> 
> 
> > On 6 Apr 2020, at 17:37, Claudio Jeker  wrote:
> > 
> > On Mon, Apr 06, 2020 at 07:54:20PM +0300, Vitaliy Makkoveev wrote:
> >> Deny to create pipex_session which is already exist. Newly created
> >> session will be placed to list head so the caller of
> >> pipex_*_lookup_session() will receive wrong session.
> > 
> > I think in the pppx(4) case the code is already doing this check in the
> > RBT_FIND() on line 835. Still I think this is a good thing to add.
> > OK claudio@
> > 
> 
> In pppx(4) layer not in pipex(4). Without this check pppx(4) can
> override pppac(4) owned session.

Yes, the pppac(4) version does not do the check. I'm not sure sure if it is
valid to use both pppx and pppac at the same time. In the end doing the
check feels right.
 
> > 
> >> Index: sys/net/if_pppx.c
> >> ===
> >> RCS file: /cvs/src/sys/net/if_pppx.c,v
> >> retrieving revision 1.79
> >> diff -u -p -r1.79 if_pppx.c
> >> --- sys/net/if_pppx.c  6 Apr 2020 12:31:30 -   1.79
> >> +++ sys/net/if_pppx.c  6 Apr 2020 13:47:26 -
> >> @@ -719,6 +719,11 @@ pppx_add_session(struct pppx_dev *pxd, s
> >>return (EPROTONOSUPPORT);
> >>}
> >> 
> >> +  session = pipex_lookup_by_session_id(req->pr_protocol,
> >> +  req->pr_session_id);
> >> +  if (session)
> >> +  return (EEXIST);
> >> +
> >>pxi = pool_get(pppx_if_pl, PR_WAITOK | PR_ZERO);
> >>if (pxi == NULL)
> >>return (ENOMEM);
> >> Index: sys/net/pipex.c
> >> ===
> >> RCS file: /cvs/src/sys/net/pipex.c,v
> >> retrieving revision 1.112
> >> diff -u -p -r1.112 pipex.c
> >> --- sys/net/pipex.c6 Apr 2020 13:14:04 -   1.112
> >> +++ sys/net/pipex.c6 Apr 2020 13:47:33 -
> >> @@ -312,6 +312,11 @@ pipex_add_session(struct pipex_session_r
> >>return (EPROTONOSUPPORT);
> >>}
> >> 
> >> +  session = pipex_lookup_by_session_id(req->pr_protocol,
> >> +  req->pr_session_id);
> >> +  if (session)
> >> +  return (EEXIST);
> >> +
> >>/* prepare a new session */
> >>session = pool_get(_session_pool, PR_WAITOK | PR_ZERO);
> >>session->state = PIPEX_STATE_OPENED;
> >> 
> > 
> > -- 
> > :wq Claudio
> 

-- 
:wq Claudio



Re: pipex(4) fix: check session existence before creation

2020-04-06 Thread Claudio Jeker
On Mon, Apr 06, 2020 at 07:54:20PM +0300, Vitaliy Makkoveev wrote:
> Deny to create pipex_session which is already exist. Newly created
> session will be placed to list head so the caller of
> pipex_*_lookup_session() will receive wrong session.

I think in the pppx(4) case the code is already doing this check in the
RBT_FIND() on line 835. Still I think this is a good thing to add.
OK claudio@

 
> Index: sys/net/if_pppx.c
> ===
> RCS file: /cvs/src/sys/net/if_pppx.c,v
> retrieving revision 1.79
> diff -u -p -r1.79 if_pppx.c
> --- sys/net/if_pppx.c 6 Apr 2020 12:31:30 -   1.79
> +++ sys/net/if_pppx.c 6 Apr 2020 13:47:26 -
> @@ -719,6 +719,11 @@ pppx_add_session(struct pppx_dev *pxd, s
>   return (EPROTONOSUPPORT);
>   }
>  
> + session = pipex_lookup_by_session_id(req->pr_protocol,
> + req->pr_session_id);
> + if (session)
> + return (EEXIST);
> +
>   pxi = pool_get(pppx_if_pl, PR_WAITOK | PR_ZERO);
>   if (pxi == NULL)
>   return (ENOMEM);
> Index: sys/net/pipex.c
> ===
> RCS file: /cvs/src/sys/net/pipex.c,v
> retrieving revision 1.112
> diff -u -p -r1.112 pipex.c
> --- sys/net/pipex.c   6 Apr 2020 13:14:04 -   1.112
> +++ sys/net/pipex.c   6 Apr 2020 13:47:33 -
> @@ -312,6 +312,11 @@ pipex_add_session(struct pipex_session_r
>   return (EPROTONOSUPPORT);
>   }
>  
> + session = pipex_lookup_by_session_id(req->pr_protocol,
> + req->pr_session_id);
> + if (session)
> + return (EEXIST);
> +
>   /* prepare a new session */
>   session = pool_get(_session_pool, PR_WAITOK | PR_ZERO);
>   session->state = PIPEX_STATE_OPENED;
> 

-- 
:wq Claudio



Re: Fix pipex(4) pipex_ioctl() access to not owned sessions (kernel crash too)

2020-04-06 Thread Claudio Jeker
On Thu, Apr 02, 2020 at 01:44:50PM +0300, Vitaliy Makkoveev wrote:
> pipex(4) has pipex_ioctl() interface for pipex_session related routines.
> pipex_ioctl() calls should be done with pipex_iface_contex, so any
> operations should be done with pipex_sessions owned by passed
> pipex_iface_contex. pipex_session check ownership is missing within
> pipex_ioctl() so anybody can do pipex_ioctl() commands PIPEXDSESSION,
> PIPEXCSESSION, PIPEXGSTAT and PIPEXGCLOSED on any pipex_session.
> PIPEXDSESSION on foreign pppx(4) owned pipex_session will crash kernel.
> Code to reproduce and screenshot attached below. Diffs below add
> pipes_session ownrship check to pipex_ioctl() internals.
> 

...

> This diff add ownership checks to the rest pipex_ioctl() commands. A few
> words about pppx_get_closed(): since in-kernel timeout feature was
> disabled for pppx(4) related pipex_sessions, closed pipex_sessions can't
> exist in system, so this function is dummy. I have an idea how to
> reenable this disabled timeout, but some reafactoring requited, and fair
> pipex_ioctl(PIPEXGCLOSED) call will be restored.

One minor comment below:
 
>  cut begin
> diff --git sys/net/if_pppx.c sys/net/if_pppx.c
> index 37a6af0..6c4977d 100644
> --- sys/net/if_pppx.c
> +++ sys/net/if_pppx.c
> @@ -175,6 +175,12 @@ int  pppx_add_session(struct pppx_dev *,
>   struct pipex_session_req *);
>  int  pppx_del_session(struct pppx_dev *,
>   struct pipex_session_close_req *);
> +int  pppx_config_session(struct pppx_dev *,
> + struct pipex_session_config_req *);
> +int  pppx_get_stat(struct pppx_dev *,
> + struct pipex_session_stat_req *);
> +int  pppx_get_closed(struct pppx_dev *,
> + struct pipex_session_list_req *);
>  int  pppx_set_session_descr(struct pppx_dev *,
>   struct pipex_session_descr_req *);
>  
> @@ -451,16 +457,18 @@ pppxioctl(dev_t dev, u_long cmd, caddr_t addr, int 
> flags, struct proc *p)
>   break;
>  
>   case PIPEXCSESSION:
> - error = pipex_config_session(
> + error = pppx_config_session(pxd,
>   (struct pipex_session_config_req *)addr);
>   break;
>  
>   case PIPEXGSTAT:
> - error = pipex_get_stat((struct pipex_session_stat_req *)addr);
> + error = pppx_get_stat(pxd,
> + (struct pipex_session_stat_req *)addr);
>   break;
>  
>   case PIPEXGCLOSED:
> - error = pipex_get_closed((struct pipex_session_list_req *)addr);
> + error = pppx_get_closed(pxd,
> + (struct pipex_session_list_req *)addr);
>   break;
>  
>   case PIPEXSIFDESCR:
> @@ -947,6 +955,40 @@ pppx_del_session(struct pppx_dev *pxd, struct 
> pipex_session_close_req *req)
>   return (0);
>  }
>  
> +int
> +pppx_config_session(struct pppx_dev *pxd,
> +struct pipex_session_config_req *req)
> +{
> + struct pppx_if *pxi;
> +
> + pxi = pppx_if_find(pxd, req->pcr_session_id, req->pcr_protocol);
> + if (pxi == NULL)
> + return (EINVAL);
> +
> + return pipex_config_session(req, >pxi_ifcontext);
> +}
> +
> +int
> +pppx_get_stat(struct pppx_dev *pxd, struct pipex_session_stat_req *req)
> +{
> + struct pppx_if *pxi;
> +
> + pxi = pppx_if_find(pxd, req->psr_session_id, req->psr_protocol);
> + if (pxi == NULL)
> + return (EINVAL);
> +
> + return pipex_get_stat(req, >pxi_ifcontext);
> +}
> +
> +int
> +pppx_get_closed(struct pppx_dev *pxd, struct pipex_session_list_req *req)
> +{
> + /* XXX: Only opened sessions exist for pppx(4) */
> + memset(req, 0, sizeof(*req));
> +
> + return 0;
> +}
> +
>  int
>  pppx_set_session_descr(struct pppx_dev *pxd,
>  struct pipex_session_descr_req *req)
> diff --git sys/net/pipex.c sys/net/pipex.c
> index 22edce3..219e18d 100644
> --- sys/net/pipex.c
> +++ sys/net/pipex.c
> @@ -235,15 +235,17 @@ pipex_ioctl(struct pipex_iface_context *pipex_iface, 
> u_long cmd, caddr_t data)
>  
>   case PIPEXCSESSION:
>   ret = pipex_config_session(
> - (struct pipex_session_config_req *)data);
> + (struct pipex_session_config_req *)data, pipex_iface);
>   break;
>  
>   case PIPEXGSTAT:
> - ret = pipex_get_stat((struct pipex_session_stat_req *)data);
> + ret = pipex_get_stat((struct pipex_session_stat_req *)data,
> + pipex_iface);
>   break;
>  
>   case PIPEXGCLOSED:
> - ret = pipex_get_closed((struct pipex_session_list_req *)data);
> + ret = pipex_get_closed((struct pipex_session_list_req *)data,
> + pipex_iface);
>   break;
>  
>   default:
> @@ -514,7 +516,8 @@ pipex_close_session(struct pipex_session_close_req *req,
>  }
>  
>  Static int
> -pipex_config_session(struct 

SMR_TAILQ implementation

2020-04-06 Thread Claudio Jeker
To make signal delivery not require the kernel lock I need a basic TAILQ
implementation that is SMR safe. This diff implements this TAILQ.
Without the write lock only SMR_TAILQ_FOREACH() (including SMR_TAIL_FIRST and
SMR_TAILQ_NEXT) can be used. No other traversals are supported.
For the locked version the one function I need is
SMR_TAILQ_INSERT_TAIL_LOCKED() the other functions are more or less
adapted copies of the SMR_LIST version (with the usual TAILQ extra
checks).

Please review. I tried to ensure that smr_tqh_first and smr_tqe_next are
updates last after the membar to ensure that the list can always be
traversed.
-- 
:wq Claudio

Index: sys/smr.h
===
RCS file: /cvs/src/sys/sys/smr.h,v
retrieving revision 1.4
diff -u -p -r1.4 smr.h
--- sys/smr.h   3 Apr 2020 03:36:57 -   1.4
+++ sys/smr.h   6 Apr 2020 10:25:04 -
@@ -318,6 +318,115 @@ struct {  
\
 * any concurrent readers to proceed iteration. */  \
 } while (0)
 
+/*
+ * Tail queue definitions.
+ */
+#defineSMR_TAILQ_HEAD(name, type)  
\
+struct name {  \
+   struct type *smr_tqh_first; /* first element, SMR-protected */\
+   struct type **smr_tqh_last; /* last element, SMR-protected */\
+}
+
+#defineSMR_TAILQ_HEAD_INITIALIZER(head)
\
+   { .smr_tqh_first = NULL, .smr_tqh_last = &(head).smr_tqh_first }
+
+#defineSMR_TAILQ_ENTRY(type)   
\
+struct {   \
+   struct type *smr_tqe_next;  /* next element, SMR-protected */\
+   struct type **smr_tqe_prev; /* address of previous next element */\
+}
+
+/*
+ * Tail queue access methods.
+ */
+#defineSMR_TAILQ_END(head) NULL
+
+#defineSMR_TAILQ_FIRST(head) \
+   SMR_PTR_GET(&(head)->smr_tqh_first)
+#defineSMR_TAILQ_NEXT(elm, field) \
+   SMR_PTR_GET(&(elm)->field.smr_tqe_next)
+
+#defineSMR_TAILQ_FIRST_LOCKED(head)((head)->smr_tqh_first)
+#defineSMR_TAILQ_NEXT_LOCKED(elm, field)   
((elm)->field.smr_tqe_next)
+#defineSMR_TAILQ_LAST_LOCKED(head, headname) \
+   (*(((struct headname *)((head)->smr_tqh_last))->smr_tqh_last))
+#defineSMR_TAILQ_EMPTY_LOCKED(head) \
+   (SMR_TAILQ_FIRST_LOCKED(head) == SMR_TAILQ_END(head))
+
+#defineSMR_TAILQ_FOREACH(var, head, field) 
\
+   for((var) = SMR_TAILQ_FIRST(head);  \
+   (var)!= SMR_TAILQ_END(head);\
+   (var) = SMR_TAILQ_NEXT(var, field))
+
+#defineSMR_TAILQ_FOREACH_LOCKED(var, head, field)  
\
+   for((var) = SMR_TAILQ_FIRST_LOCKED(head);   \
+   (var)!= SMR_TAILQ_END(head);\
+   (var) = SMR_TAILQ_NEXT_LOCKED(var, field))
+
+#defineSMR_TAILQ_FOREACH_SAFE_LOCKED(var, head, field, tvar)   
\
+   for ((var) = SMR_TAILQ_FIRST_LOCKED(head);  \
+   (var) && ((tvar) = SMR_TAILQ_NEXT_LOCKED(var, field), 1);   \
+   (var) = (tvar))
+
+/*
+ * Tail queue functions.
+ */
+#defineSMR_TAILQ_INIT(head) do {   
\
+   (head)->smr_tqh_first = TAILQ_END(head);\
+   (head)->smr_tqh_last = &(head)->smr_tqh_first;  \
+} while (0)
+
+#defineSMR_TAILQ_INSERT_AFTER_LOCKED(head, listelm, elm, field) do {   
\
+   (elm)->field.smr_tqe_next = (listelm)->field.smr_tqe_next;  \
+   if ((listelm)->field.smr_tqe_next != NULL)  \
+   (listelm)->field.smr_tqe_next->field.smr_tqe_prev = \
+   &(elm)->field.smr_tqe_next; \
+   else\
+   (head)->smr_tqh_last = &(elm)->field.smr_tqe_next;  \
+   (elm)->field.smr_tqe_prev = &(listelm)->field.smr_tqe_next; \
+   membar_producer();  \
+   (listelm)->field.smr_tqe_next = (elm);  \
+} while (0)
+
+#defineSMR_TAILQ_INSERT_BEFORE_LOCKED(listelm, elm, field) do {
\
+   (elm)->field.smr_tqe_prev = (listelm)->field.smr_tqe_prev;  \
+   (elm)->field.smr_tqe_next = (listelm);  \
+   membar_producer();  \
+   *(listelm)->field.smr_tqe_prev = (elm); \
+   (listelm)->field.smr_tqe_prev = &(elm)->field.smr_tqe_next; \
+} while (0)
+
+#defineSMR_TAILQ_INSERT_HEAD_LOCKED(head, elm, field) do { 

Re: rpki-client and non-existing files

2020-04-01 Thread Claudio Jeker
On Wed, Apr 01, 2020 at 09:42:42PM +0200, Sebastian Benoit wrote:
> ok
> 
> you remove the "if (verbose > 0)" in the cms_parse_validate() case on
> purpose?

Yes, since we use rpki-client in cron with the magic -n prefix it would be
nice to have enough verbosity to know why the process failed without
having to run rpki-client -v. So I kind of walked back from the
rpki-client must be silent by default unless a bad error happens case.
 
> Claudio Jeker(cje...@diehard.n-r-g.com) on 2020.04.01 16:33:44 +0200:
> > On Wed, Apr 01, 2020 at 01:06:21PM +0200, Claudio Jeker wrote:
> > > Currently rpki-client logs missing files like this:
> > > 
> > > rpki-client:  ...trace: error:02FFF002:system library:func(4095):No such 
> > > file or directory
> > > rpki-client:  ...trace: error:20FFF080:BIO routines:CRYPTO_internal:no 
> > > such file
> > > rpki-client: 
> > > rpki.cnnic.cn/rpki/A9162E3D/515/FE-4PMY9qqTI2aJ0xLDm7cD-fvw.mft: 
> > > BIO_new_file
> > > 
> > > Yes, you need to read the errors in reverse and even then the errors are
> > > just hard to read.
> > > 
> > > This ugly format is mostly to blame on the error stack of OpenSSL.
> > > As a workaround I switched to using fopen() and then BIO_new_fd()
> > > which does the same thing but allows me to get a nice error from fopen():
> > > 
> > > rpki-client: 
> > > rpki.cnnic.cn/rpki/A9162E3D/515/FE-4PMY9qqTI2aJ0xLDm7cD-fvw.mft: 
> > > fopen: No such file or directory
> > > 
> > > Any opinions?
> > 
> > This diff removes the fopen: from the warn string:
> > 
> > rpki-client: 
> > rpki.cnnic.cn/rpki/A9162E3D/515/FE-4PMY9qqTI2aJ0xLDm7cD-fvw.mft: No 
> > such file or directory
> > 
> > This is more in form with e.g.
> > 
> > rpki-client: 
> > rpki-repo.registro.br/repo/D81aiXpDAv5WBmgE8oEpfordjGP62otn2fHrhaL4cgby/0/3137372e3133302e302e302f32302d3234203d3e203238323630.roa:
> >  CRL has expired
> > 
> > -- 
> > :wq Claudio
> > 
> > Index: cert.c
> > ===
> > RCS file: /cvs/src/usr.sbin/rpki-client/cert.c,v
> > retrieving revision 1.14
> > diff -u -p -r1.14 cert.c
> > --- cert.c  26 Feb 2020 02:35:08 -  1.14
> > +++ cert.c  1 Apr 2020 14:28:29 -
> > @@ -930,12 +930,18 @@ cert_parse_inner(X509 **xp, const char *
> > ASN1_OBJECT *obj;
> > struct parse p;
> > BIO *bio = NULL, *shamd;
> > +   FILE*f;
> > EVP_MD  *md;
> > char mdbuf[EVP_MAX_MD_SIZE];
> >  
> > *xp = NULL;
> >  
> > -   if ((bio = BIO_new_file(fn, "rb")) == NULL) {
> > +   if ((f = fopen(fn, "rb")) == NULL) {
> > +   warn("%s", fn);
> > +   return NULL;
> > +   }
> > +
> > +   if ((bio = BIO_new_fp(f, BIO_CLOSE)) == NULL) {
> > if (verbose > 0)
> > cryptowarnx("%s: BIO_new_file", fn);
> > return NULL;
> > Index: cms.c
> > ===
> > RCS file: /cvs/src/usr.sbin/rpki-client/cms.c,v
> > retrieving revision 1.6
> > diff -u -p -r1.6 cms.c
> > --- cms.c   29 Nov 2019 05:14:11 -  1.6
> > +++ cms.c   1 Apr 2020 14:28:34 -
> > @@ -42,6 +42,7 @@ cms_parse_validate(X509 **xp, const char
> > ASN1_OCTET_STRING   **os = NULL;
> > BIO *bio = NULL, *shamd;
> > CMS_ContentInfo *cms;
> > +   FILE*f;
> > char buf[128], mdbuf[EVP_MAX_MD_SIZE];
> > int  rc = 0, sz;
> > STACK_OF(X509)  *certs = NULL;
> > @@ -55,10 +56,13 @@ cms_parse_validate(X509 **xp, const char
> >  * This is usually fopen() failure, so let it pass through to
> >  * the handler, which will in turn ignore the entity.
> >  */
> > +   if ((f = fopen(fn, "rb")) == NULL) {
> > +   warn("%s", fn);
> > +   return NULL;
> > +   }
> >  
> > -   if ((bio = BIO_new_file(fn, "rb")) == NULL) {
> > -   if (verbose > 0)
> > -   cryptowarnx("%s: BIO_new_file", fn);
> > +   if ((bio = BIO_new_fp(f, BIO_CLOSE)) == NULL) {
> > +   cryptowarnx("%s: BIO_new_fp", fn);
> > return NULL;
> > }
> >  
> > Index: crl.c
> > =

Re: rpki-client and non-existing files

2020-04-01 Thread Claudio Jeker
On Wed, Apr 01, 2020 at 01:06:21PM +0200, Claudio Jeker wrote:
> Currently rpki-client logs missing files like this:
> 
> rpki-client:  ...trace: error:02FFF002:system library:func(4095):No such file 
> or directory
> rpki-client:  ...trace: error:20FFF080:BIO routines:CRYPTO_internal:no such 
> file
> rpki-client: 
> rpki.cnnic.cn/rpki/A9162E3D/515/FE-4PMY9qqTI2aJ0xLDm7cD-fvw.mft: 
> BIO_new_file
> 
> Yes, you need to read the errors in reverse and even then the errors are
> just hard to read.
> 
> This ugly format is mostly to blame on the error stack of OpenSSL.
> As a workaround I switched to using fopen() and then BIO_new_fd()
> which does the same thing but allows me to get a nice error from fopen():
> 
> rpki-client: 
> rpki.cnnic.cn/rpki/A9162E3D/515/FE-4PMY9qqTI2aJ0xLDm7cD-fvw.mft: fopen: 
> No such file or directory
> 
> Any opinions?

This diff removes the fopen: from the warn string:

rpki-client: 
rpki.cnnic.cn/rpki/A9162E3D/515/FE-4PMY9qqTI2aJ0xLDm7cD-fvw.mft: No such 
file or directory

This is more in form with e.g.

rpki-client: 
rpki-repo.registro.br/repo/D81aiXpDAv5WBmgE8oEpfordjGP62otn2fHrhaL4cgby/0/3137372e3133302e302e302f32302d3234203d3e203238323630.roa:
 CRL has expired

-- 
:wq Claudio

Index: cert.c
===
RCS file: /cvs/src/usr.sbin/rpki-client/cert.c,v
retrieving revision 1.14
diff -u -p -r1.14 cert.c
--- cert.c  26 Feb 2020 02:35:08 -  1.14
+++ cert.c  1 Apr 2020 14:28:29 -
@@ -930,12 +930,18 @@ cert_parse_inner(X509 **xp, const char *
ASN1_OBJECT *obj;
struct parse p;
BIO *bio = NULL, *shamd;
+   FILE*f;
EVP_MD  *md;
char mdbuf[EVP_MAX_MD_SIZE];
 
*xp = NULL;
 
-   if ((bio = BIO_new_file(fn, "rb")) == NULL) {
+   if ((f = fopen(fn, "rb")) == NULL) {
+   warn("%s", fn);
+   return NULL;
+   }
+
+   if ((bio = BIO_new_fp(f, BIO_CLOSE)) == NULL) {
if (verbose > 0)
cryptowarnx("%s: BIO_new_file", fn);
return NULL;
Index: cms.c
===
RCS file: /cvs/src/usr.sbin/rpki-client/cms.c,v
retrieving revision 1.6
diff -u -p -r1.6 cms.c
--- cms.c   29 Nov 2019 05:14:11 -  1.6
+++ cms.c   1 Apr 2020 14:28:34 -
@@ -42,6 +42,7 @@ cms_parse_validate(X509 **xp, const char
ASN1_OCTET_STRING   **os = NULL;
BIO *bio = NULL, *shamd;
CMS_ContentInfo *cms;
+   FILE*f;
char buf[128], mdbuf[EVP_MAX_MD_SIZE];
int  rc = 0, sz;
STACK_OF(X509)  *certs = NULL;
@@ -55,10 +56,13 @@ cms_parse_validate(X509 **xp, const char
 * This is usually fopen() failure, so let it pass through to
 * the handler, which will in turn ignore the entity.
 */
+   if ((f = fopen(fn, "rb")) == NULL) {
+   warn("%s", fn);
+   return NULL;
+   }
 
-   if ((bio = BIO_new_file(fn, "rb")) == NULL) {
-   if (verbose > 0)
-   cryptowarnx("%s: BIO_new_file", fn);
+   if ((bio = BIO_new_fp(f, BIO_CLOSE)) == NULL) {
+   cryptowarnx("%s: BIO_new_fp", fn);
return NULL;
}
 
Index: crl.c
===
RCS file: /cvs/src/usr.sbin/rpki-client/crl.c,v
retrieving revision 1.7
diff -u -p -r1.7 crl.c
--- crl.c   29 Nov 2019 04:40:04 -  1.7
+++ crl.c   1 Apr 2020 14:28:41 -
@@ -36,10 +36,16 @@ crl_parse(const char *fn, const unsigned
int  rc = 0, sz;
X509_CRL*x = NULL;
BIO *bio = NULL, *shamd;
+   FILE*f;
EVP_MD  *md;
char mdbuf[EVP_MAX_MD_SIZE];
 
-   if ((bio = BIO_new_file(fn, "rb")) == NULL) {
+   if ((f = fopen(fn, "rb")) == NULL) {
+   warn("%s", fn);
+   return NULL;
+   }
+
+   if ((bio = BIO_new_fp(f, BIO_CLOSE)) == NULL) {
if (verbose > 0)
cryptowarnx("%s: BIO_new_file", fn);
return NULL;



Re: pselect(2) bug or feature?

2020-04-01 Thread Claudio Jeker
On Wed, Apr 01, 2020 at 01:08:10PM +0200, Martin Pieuchot wrote:
> While working on moving pselect(2) outside of the KERNEL_LOCK() I found
> this surprising {p,}select(2) behavior exposed by the libc/sys/t_select.c
> regression test.  Should it be considered as a bug or feature?

I think this is actually a feature. The standard does not mention that you
have to listen on something and it would allow to use select() as a
sleep() replacement. I would expect that pselect() should behave the same
way.

poll() does the same thing (you are allowed to pass a 0 poll fds).

> The above mentioned test does the following (simplified):
> 
>   fd = open("/dev/null", O_RDONLY);
>   FD_ZERO();
>   FD_SET(fd, );
>   pselect(1, , NULL, NULL, NULL, );
> 
> Note that in most environments, open(2) will return a value higher than
> 1 which means the value written by FD_SET() will never be checked by the
> current implementation of {p,}select(2).  In this case, even if it isn't
> waiting for any condition, the current implementation will block.
> 
> To put it differently, the code above is an obfuscated way to write:
> 
>   sigsuspend();
> 
> If we agree that this is not what the user wants to do, I'm suggesting
> the diff below which makes {p,}select(2) return EINVAL if no bit has
> been found in the given set up to `nfds'.
> 
> Independently from our decision, I'd suggest to rename the variable
> name `nfds' in the syscall documentation because it can lead to this
> kind of confusion.
> 
> Finally if we accept this change the regression test will have to be
> adapted because polling "/dev/null" for reading always return true so
> pselect(2) wont block waiting for a signal.  Any suggestion?
> 
> Index: sys/kern/sys_generic.c
> ===
> RCS file: /cvs/src/sys/kern/sys_generic.c,v
> retrieving revision 1.131
> diff -u -p -r1.131 sys_generic.c
> --- sys/kern/sys_generic.c20 Mar 2020 04:11:05 -  1.131
> +++ sys/kern/sys_generic.c1 Apr 2020 10:27:51 -
> @@ -703,7 +703,7 @@ selscan(struct proc *p, fd_set *ibits, f
>  {
>   caddr_t cibits = (caddr_t)ibits, cobits = (caddr_t)obits;
>   struct filedesc *fdp = p->p_fd;
> - int msk, i, j, fd;
> + int msk, i, j, fd, foundfds = 0;
>   fd_mask bits;
>   struct file *fp;
>   int n = 0;
> @@ -719,6 +719,7 @@ selscan(struct proc *p, fd_set *ibits, f
>   bits &= ~(1 << j);
>   if ((fp = fd_getfile(fdp, fd)) == NULL)
>   return (EBADF);
> + foundfds++;
>   if ((*fp->f_ops->fo_poll)(fp, flag[msk], p)) {
>   FD_SET(fd, pobits);
>   n++;
> @@ -727,6 +728,8 @@ selscan(struct proc *p, fd_set *ibits, f
>   }
>   }
>   }
> + if (foundfds == 0)
> + return (EINVAL);
>   *retval = n;
>   return (0);
>  }
> Index: lib/libc/sys/select.2
> ===
> RCS file: /cvs/src/lib/libc/sys/select.2,v
> retrieving revision 1.42
> diff -u -p -r1.42 select.2
> --- lib/libc/sys/select.2 17 Sep 2016 01:01:42 -  1.42
> +++ lib/libc/sys/select.2 1 Apr 2020 10:35:29 -
> @@ -188,7 +188,7 @@ The specified time limit is invalid.
>  One of its components is negative or too large.
>  .It Bq Er EINVAL
>  .Fa nfds
> -was less than 0.
> +was smaller than the smallest descriptor specified in the sets.
>  .El
>  .Sh SEE ALSO
>  .Xr accept 2 ,
> 

-- 
:wq Claudio



rpki-client and non-existing files

2020-04-01 Thread Claudio Jeker
Currently rpki-client logs missing files like this:

rpki-client:  ...trace: error:02FFF002:system library:func(4095):No such file 
or directory
rpki-client:  ...trace: error:20FFF080:BIO routines:CRYPTO_internal:no such file
rpki-client: 
rpki.cnnic.cn/rpki/A9162E3D/515/FE-4PMY9qqTI2aJ0xLDm7cD-fvw.mft: 
BIO_new_file

Yes, you need to read the errors in reverse and even then the errors are
just hard to read.

This ugly format is mostly to blame on the error stack of OpenSSL.
As a workaround I switched to using fopen() and then BIO_new_fd()
which does the same thing but allows me to get a nice error from fopen():

rpki-client: 
rpki.cnnic.cn/rpki/A9162E3D/515/FE-4PMY9qqTI2aJ0xLDm7cD-fvw.mft: fopen: No 
such file or directory

Any opinions?
-- 
:wq Claudio

Index: cert.c
===
RCS file: /cvs/src/usr.sbin/rpki-client/cert.c,v
retrieving revision 1.14
diff -u -p -r1.14 cert.c
--- cert.c  26 Feb 2020 02:35:08 -  1.14
+++ cert.c  30 Mar 2020 11:40:28 -
@@ -930,12 +930,18 @@ cert_parse_inner(X509 **xp, const char *
ASN1_OBJECT *obj;
struct parse p;
BIO *bio = NULL, *shamd;
+   FILE*f;
EVP_MD  *md;
char mdbuf[EVP_MAX_MD_SIZE];
 
*xp = NULL;
 
-   if ((bio = BIO_new_file(fn, "rb")) == NULL) {
+   if ((f = fopen(fn, "rb")) == NULL) {
+   warn("%s: fopen", fn);
+   return NULL;
+   }
+
+   if ((bio = BIO_new_fp(f, BIO_CLOSE)) == NULL) {
if (verbose > 0)
cryptowarnx("%s: BIO_new_file", fn);
return NULL;
Index: cms.c
===
RCS file: /cvs/src/usr.sbin/rpki-client/cms.c,v
retrieving revision 1.6
diff -u -p -r1.6 cms.c
--- cms.c   29 Nov 2019 05:14:11 -  1.6
+++ cms.c   30 Mar 2020 11:40:23 -
@@ -42,6 +42,7 @@ cms_parse_validate(X509 **xp, const char
ASN1_OCTET_STRING   **os = NULL;
BIO *bio = NULL, *shamd;
CMS_ContentInfo *cms;
+   FILE*f;
char buf[128], mdbuf[EVP_MAX_MD_SIZE];
int  rc = 0, sz;
STACK_OF(X509)  *certs = NULL;
@@ -55,10 +56,13 @@ cms_parse_validate(X509 **xp, const char
 * This is usually fopen() failure, so let it pass through to
 * the handler, which will in turn ignore the entity.
 */
+   if ((f = fopen(fn, "rb")) == NULL) {
+   warn("%s: fopen", fn);
+   return NULL;
+   }
 
-   if ((bio = BIO_new_file(fn, "rb")) == NULL) {
-   if (verbose > 0)
-   cryptowarnx("%s: BIO_new_file", fn);
+   if ((bio = BIO_new_fp(f, BIO_CLOSE)) == NULL) {
+   cryptowarnx("%s: BIO_new_fp", fn);
return NULL;
}
 
Index: crl.c
===
RCS file: /cvs/src/usr.sbin/rpki-client/crl.c,v
retrieving revision 1.7
diff -u -p -r1.7 crl.c
--- crl.c   29 Nov 2019 04:40:04 -  1.7
+++ crl.c   30 Mar 2020 11:40:32 -
@@ -36,10 +36,16 @@ crl_parse(const char *fn, const unsigned
int  rc = 0, sz;
X509_CRL*x = NULL;
BIO *bio = NULL, *shamd;
+   FILE*f;
EVP_MD  *md;
char mdbuf[EVP_MAX_MD_SIZE];
 
-   if ((bio = BIO_new_file(fn, "rb")) == NULL) {
+   if ((f = fopen(fn, "rb")) == NULL) {
+   warn("%s: fopen", fn);
+   return NULL;
+   }
+
+   if ((bio = BIO_new_fp(f, BIO_CLOSE)) == NULL) {
if (verbose > 0)
cryptowarnx("%s: BIO_new_file", fn);
return NULL;



Re: rtsock: redundant NULL pointer check

2020-03-24 Thread Claudio Jeker
On Mon, Mar 23, 2020 at 10:36:20PM +0100, Tobias Heider wrote:
> It seems that there is no way 'rtm' could actually be NULL here, which
> means we can get rid of the check.
> 
> ok?

OK claudio@
 
> Index: net/rtsock.c
> ===
> RCS file: /mount/openbsd/cvs/src/sys/net/rtsock.c,v
> retrieving revision 1.297
> diff -u -p -r1.297 rtsock.c
> --- net/rtsock.c  24 Nov 2019 07:56:03 -  1.297
> +++ net/rtsock.c  23 Mar 2020 21:15:51 -
> @@ -858,14 +858,12 @@ fail:
>   return (error);
>   }
>   }
> - if (rtm) {
> - if (m_copyback(m, 0, len, rtm, M_NOWAIT)) {
> - m_freem(m);
> - m = NULL;
> - } else if (m->m_pkthdr.len > len)
> - m_adj(m, len - m->m_pkthdr.len);
> - free(rtm, M_RTABLE, len);
> - }
> + if (m_copyback(m, 0, len, rtm, M_NOWAIT)) {
> + m_freem(m);
> + m = NULL;
> + } else if (m->m_pkthdr.len > len)
> + m_adj(m, len - m->m_pkthdr.len);
> + free(rtm, M_RTABLE, len);
>   if (m)
>   route_input(m, so, info.rti_info[RTAX_DST] ?
>   info.rti_info[RTAX_DST]->sa_family : AF_UNSPEC);
> 

-- 
:wq Claudio



Re: Fix tsleep(9) during execve(2)

2020-03-22 Thread Claudio Jeker
On Sun, Mar 22, 2020 at 04:58:47AM +, Visa Hankala wrote:
> The recent change of initializing sls_sig = 0 in sleep_setup()
> (r1.164 of kern_synch.c) has introduced a regression with execve(2).
> execve(2) sets the current process in single thread mode for replacing
> the program image. In this mode, sleep_setup_signal() cancels a sleep,
> making tsleep(9) with PCATCH return immediately. Previously, when
> sls_sig was initialized with value 1, tsleep() with PCATCH returned
> EINTR during exec. Now it returns zero.
> 
> The previous behaviour was not exactly right but did not seem to cause
> apparent harm. The current situation is different. For example, the
> call chain shown below can hang. The sleep does not actually happen so
> vwaitforio() can spin because the pending I/O does not get finished.
> 
> tsleep
> vwaitforio
> nfs_flush
> nfs_close
> VOP_CLOSE
> vn_closefile
> fdrop
> closef
> fdcloseexec
> sys_execve
> 
> The hang was reported and offending commit located by Pavel Korovin.
> 
> I think the proper way to fix the problem is to tighten the conditions
> when sleep_setup_signal() cancels the sleep. Instead of checking
> p->p_p->ps_single != NULL, which affects the whole process, the thread
> should determine if P_SUSPSINGLE is set in p->p_flag. This limits the
> cancelling to the threads that have been suspended for single thread
> mode. The thread that runs execve(2) does not have the flag set.
> 
> OK?

OK claudio@. The P_SUSPSINGLE check is also used in userret to enter
single_thread_check() so this makes this code behave the same way.
 
> Index: kern/kern_synch.c
> ===
> RCS file: src/sys/kern/kern_synch.c,v
> retrieving revision 1.166
> diff -u -p -r1.166 kern_synch.c
> --- kern/kern_synch.c 20 Mar 2020 17:13:51 -  1.166
> +++ kern/kern_synch.c 22 Mar 2020 04:25:32 -
> @@ -480,7 +480,7 @@ sleep_setup_signal(struct sleep_state *s
>* stopped, p->p_wchan will be 0 upon return from CURSIG.
>*/
>   atomic_setbits_int(>p_flag, P_SINTR);
> - if (p->p_p->ps_single != NULL || (sls->sls_sig = CURSIG(p)) != 0) {
> + if ((p->p_flag & P_SUSPSINGLE) || (sls->sls_sig = CURSIG(p)) != 0) {
>   unsleep(p);
>   p->p_stat = SONPROC;
>   sls->sls_do_sleep = 0;
> 

-- 
:wq Claudio



bgpctl code reshuffle

2020-03-19 Thread Claudio Jeker
Move some more output functions to output.c and convert some other
functions to a fmt_xyz() function that returns a string with the value
instead of doing a printf(). This is mostly mechanical but please test.

-- 
:wq Claudio

Index: bgpctl.c
===
RCS file: /cvs/src/usr.sbin/bgpctl/bgpctl.c,v
retrieving revision 1.258
diff -u -p -r1.258 bgpctl.c
--- bgpctl.c24 Jan 2020 05:46:00 -  1.258
+++ bgpctl.c19 Mar 2020 17:36:18 -
@@ -46,11 +46,6 @@
 
 int main(int, char *[]);
 int show(struct imsg *, struct parse_result *);
-voidshow_attr(void *, u_int16_t, int);
-voidshow_communities(u_char *, size_t, int);
-voidshow_community(u_char *, u_int16_t);
-voidshow_large_community(u_char *, u_int16_t);
-voidshow_ext_community(u_char *, u_int16_t);
 voidsend_filterset(struct imsgbuf *, struct filter_set_head *);
 voidshow_mrt_dump_neighbors(struct mrt_rib *, struct mrt_peer *,
void *);
@@ -425,7 +420,6 @@ show(struct imsg *imsg, struct parse_res
if (imsg->hdr.len < IMSG_HEADER_SIZE + sizeof(*kt))
errx(1, "wrong imsg len");
kt = imsg->data;
-
show_fib_table(kt);
break;
case IMSG_CTL_SHOW_RIB:
@@ -443,7 +437,7 @@ show(struct imsg *imsg, struct parse_res
warnx("bad IMSG_CTL_SHOW_RIB_COMMUNITIES received");
break;
}
-   show_communities(imsg->data, ilen, res->flags);
+   show_communities(imsg->data, ilen, res);
break;
case IMSG_CTL_SHOW_RIB_ATTR:
ilen = imsg->hdr.len - IMSG_HEADER_SIZE;
@@ -451,7 +445,7 @@ show(struct imsg *imsg, struct parse_res
warnx("bad IMSG_CTL_SHOW_RIB_ATTR received");
break;
}
-   show_attr(imsg->data, ilen, res->flags);
+   show_attr(imsg->data, ilen, res);
break;
case IMSG_CTL_SHOW_RIB_MEM:
memcpy(, imsg->data, sizeof(stats));
@@ -506,7 +500,7 @@ fmt_peer(const char *descr, const struct
 }
 
 const char *
-print_auth_method(enum auth_method method)
+fmt_auth_method(enum auth_method method)
 {
switch (method) {
case AUTH_MD5SIG:
@@ -525,75 +519,6 @@ print_auth_method(enum auth_method metho
}
 }
 
-void
-print_neighbor_capa_mp(struct peer *p)
-{
-   int comma;
-   u_int8_ti;
-
-   for (i = 0, comma = 0; i < AID_MAX; i++)
-   if (p->capa.peer.mp[i]) {
-   printf("%s%s", comma ? ", " : "", aid2str(i));
-   comma = 1;
-   }
-}
-
-void
-print_neighbor_capa_restart(struct peer *p)
-{
-   int comma;
-   u_int8_ti;
-
-   if (p->capa.peer.grestart.timeout)
-   printf(": Timeout: %d, ", p->capa.peer.grestart.timeout);
-   for (i = 0, comma = 0; i < AID_MAX; i++)
-   if (p->capa.peer.grestart.flags[i] & CAPA_GR_PRESENT) {
-   if (!comma &&
-   p->capa.peer.grestart.flags[i] & CAPA_GR_RESTART)
-   printf("restarted, ");
-   if (comma)
-   printf(", ");
-   printf("%s", aid2str(i));
-   if (p->capa.peer.grestart.flags[i] & CAPA_GR_FORWARD)
-   printf(" (preserved)");
-   comma = 1;
-   }
-}
-
-void
-print_neighbor_msgstats(struct peer *p)
-{
-   printf("  Message statistics:\n");
-   printf("  %-15s %-10s %-10s\n", "", "Sent", "Received");
-   printf("  %-15s %10llu %10llu\n", "Opens",
-   p->stats.msg_sent_open, p->stats.msg_rcvd_open);
-   printf("  %-15s %10llu %10llu\n", "Notifications",
-   p->stats.msg_sent_notification, p->stats.msg_rcvd_notification);
-   printf("  %-15s %10llu %10llu\n", "Updates",
-   p->stats.msg_sent_update, p->stats.msg_rcvd_update);
-   printf("  %-15s %10llu %10llu\n", "Keepalives",
-   p->stats.msg_sent_keepalive, p->stats.msg_rcvd_keepalive);
-   printf("  %-15s %10llu %10llu\n", "Route Refresh",
-   p->stats.msg_sent_rrefresh, p->stats.msg_rcvd_rrefresh);
-   printf("  %-15s %10llu %10llu\n\n", "Total",
-   p->stats.msg_sent_open + p->stats.msg_sent_notification +
-   p->stats.msg_sent_update + p->stats.msg_sent_keepalive +
-   p->stats.msg_sent_rrefresh,
-   p->stats.msg_rcvd_open + p->stats.msg_rcvd_notification +
-   p->stats.msg_rcvd_update + p->stats.msg_rcvd_keepalive +
-   p->stats.msg_rcvd_rrefresh);
-   printf("  Update statistics:\n");
-   printf("  %-15s %-10s %-10s\n", "", "Sent", "Received");
-  

Re: Patch: Sending credentials over Unix datagram sockets

2020-03-18 Thread Claudio Jeker
On Wed, Mar 18, 2020 at 02:53:14AM -, David Mackay wrote:
> Dear openbsd-tech,
> 
> On GNU HURD and FreeBSD, the control message SCM_CREDS may be allocated by a
> client of a Unix datagram socket. When the kernel encounters this, it fills
> out
> a struct cmsgcred containing PID, UID, GID, effective UID, and effective
> GIDs of
> the sender.
> 
> This patch implements this for OpenBSD.
> 
> Kind regards,
> David
> 
> 
> diff --git sys/kern/uipc_usrreq.c sys/kern/uipc_usrreq.c
> index 8a735f3..7df3846 100644
> --- sys/kern/uipc_usrreq.c
> +++ sys/kern/uipc_usrreq.c
> @@ -688,9 +688,10 @@ unp_externalize(struct mbuf *rights, socklen_t
> controllen, int flags)
>   /*
>* This code only works because SCM_RIGHTS is the only supported
>* control message type on unix sockets. Enforce this here.
> +  * If it isn't, then return.
>*/
>   if (cm->cmsg_type != SCM_RIGHTS || cm->cmsg_level != SOL_SOCKET)
> - return EINVAL;
> + return (0);

I highly suspect that this is not correct without further changes.
There is a reason why the comment is explicit about the fact that it only
works if SCM_RIGHTS is the only control message type. Just ignoring this
fact is probably a security risk.

-- 
:wq Claudio



Re: acpitoshiba: remove dead code

2020-03-16 Thread Claudio Jeker
On Mon, Mar 16, 2020 at 09:29:43AM +0100, Jasper Lievisse Adriaanse wrote:
> Hi,
> 
> The type of brightness and video_output is uint32_t; therefore it
> can never be less than 0 (which is what HCI_LCD_BRIGHTNESS_MIN and
> HCI_VIDEO_OUTPUT_CYCLE_MIN are defined to). So trim the checks by
> removig the impossible cases.
> 
> Coverity CID 1453109, 1453169
> 
> OK?

I find such changes actually bad.  Currently the code is clear doing a
real range check, After the change you will wonder why
HCI_LCD_BRIGHTNESS_MIN is not in that check and need to start digging.
Now I do understand that the code right now is not correct since this is a
signed vs unsigned comparison but please look at more then just that bit.

e.g.
int
toshiba_find_brightness(struct acpitoshiba_softc *sc, int *new_blevel)
{
int ret, current_blevel;

...
ret = toshiba_set_brightness(sc, _blevel);
}

So this function is passing a signed int to a function expecting unsinged
int

int
toshiba_fn_key_brightness_down(struct acpitoshiba_softc *sc)
{
uint32_t brightness_level;

...
if (brightness_level-- == HCI_LCD_BRIGHTNESS_MIN)
brightness_level = HCI_LCD_BRIGHTNESS_MIN;
else
ret = toshiba_set_brightness(sc, _level);
}

This code is also strange, especially since brightness_level is set but
not used again. I think this driver needs a bit more cleanup.
 
> Index: acpi/acpitoshiba.c
> ===
> RCS file: /cvs/src/sys/dev/acpi/acpitoshiba.c,v
> retrieving revision 1.12
> diff -u -p -r1.12 acpitoshiba.c
> --- acpi/acpitoshiba.c13 Oct 2019 10:56:31 -  1.12
> +++ acpi/acpitoshiba.c11 Mar 2020 11:35:23 -
> @@ -438,9 +438,8 @@ toshiba_set_brightness(struct acpitoshib
>   for (i = 0; i < HCI_WORDS; ++i)
>   args[i].type = AML_OBJTYPE_INTEGER;
>  
> - if ((*brightness < HCI_LCD_BRIGHTNESS_MIN) ||
> - (*brightness > HCI_LCD_BRIGHTNESS_MAX))
> -return (HCI_FAILURE);
> + if (*brightness > HCI_LCD_BRIGHTNESS_MAX)
> + return (HCI_FAILURE);
>  
>   *brightness <<= HCI_LCD_BRIGHTNESS_SHIFT;
>  
> @@ -534,8 +533,7 @@ toshiba_set_video_output(struct acpitosh
>  
>   bzero(args, sizeof(args));
>  
> - if ((*video_output < HCI_VIDEO_OUTPUT_CYCLE_MIN) ||
> - (*video_output > HCI_VIDEO_OUTPUT_CYCLE_MAX))
> + if (*video_output > HCI_VIDEO_OUTPUT_CYCLE_MAX)
>   return (HCI_FAILURE);
>  
>   *video_output |= HCI_VIDEO_OUTPUT_FLAG;
> -- 
> jasper
> 

-- 
:wq Claudio



Re: Rename ps_flags -> ps_sigflags in struct sigacts

2020-03-12 Thread Claudio Jeker
On Thu, Mar 12, 2020 at 08:15:00AM -0500, Amit Kulkarni wrote:
> Hi,
> 
> In grepping for ps_flags in /sys, it is confusing to see that ps_flags is 
> associated with
> 
> 1) PWM_POLARITY (power regulation?).
>   Proposed to rename to ps_pwmflags?
> 2) process signals: struct sigacts in /sys/sys/signalvar.h
> 3) its rightful usage as ps_flags for struct process in /sys/sys/proc.h
> 
> 
> So, to reduce confusion while grepping, the below diff simply renames usages 
> of ps_flags in relation to struct sigacts (#2 above) to ps_sigflags.
> 

I have the same issue with ps_flags vs ps_flags and I think it resulted in
some major confusion for others as well. See inline.

> Index: kern/init_main.c
> ===
> RCS file: /cvs/src/sys/kern/init_main.c,v
> retrieving revision 1.296
> diff -u -p -u -p -r1.296 init_main.c
> --- kern/init_main.c  25 Feb 2020 16:55:33 -  1.296
> +++ kern/init_main.c  12 Mar 2020 12:58:41 -
> @@ -639,7 +639,7 @@ start_init(void *arg)
>   check_console(p);
>  
>   /* process 0 ignores SIGCHLD, but we can't */
> - p->p_p->ps_sigacts->ps_flags = 0;
> + p->p_p->ps_sigacts->ps_sigflags = 0;
>  
>   /*
>* Need just enough stack to hold the faked-up "execve()" arguments.
> Index: kern/kern_exit.c
> ===
> RCS file: /cvs/src/sys/kern/kern_exit.c,v
> retrieving revision 1.185
> diff -u -p -u -p -r1.185 kern_exit.c
> --- kern/kern_exit.c  1 Mar 2020 18:50:52 -   1.185
> +++ kern/kern_exit.c  12 Mar 2020 12:58:42 -
> @@ -215,7 +215,7 @@ exit1(struct proc *p, int xexit, int xsi
>* If parent has the SAS_NOCLDWAIT flag set, we're not
>* going to become a zombie.
>*/
> - if (pr->ps_pptr->ps_sigacts->ps_flags & SAS_NOCLDWAIT)
> + if (pr->ps_pptr->ps_sigacts->ps_sigflags & SAS_NOCLDWAIT)
>   atomic_setbits_int(>ps_flags, PS_NOZOMBIE);
>   }
>  
> Index: kern/kern_sig.c
> ===
> RCS file: /cvs/src/sys/kern/kern_sig.c,v
> retrieving revision 1.252
> diff -u -p -u -p -r1.252 kern_sig.c
> --- kern/kern_sig.c   11 Mar 2020 15:45:03 -  1.252
> +++ kern/kern_sig.c   12 Mar 2020 12:58:42 -
> @@ -285,9 +285,9 @@ sys_sigaction(struct proc *p, void *v, r
>   if ((ps->ps_siginfo & bit) != 0)
>   sa->sa_flags |= SA_SIGINFO;
>   if (signum == SIGCHLD) {
> - if ((ps->ps_flags & SAS_NOCLDSTOP) != 0)
> + if ((ps->ps_sigflags & SAS_NOCLDSTOP) != 0)
>   sa->sa_flags |= SA_NOCLDSTOP;
> - if ((ps->ps_flags & SAS_NOCLDWAIT) != 0)
> + if ((ps->ps_sigflags & SAS_NOCLDWAIT) != 0)
>   sa->sa_flags |= SA_NOCLDWAIT;
>   }
>   if ((sa->sa_mask & bit) == 0)
> @@ -336,9 +336,9 @@ setsigvec(struct proc *p, int signum, st
>   ps->ps_catchmask[signum] = sa->sa_mask &~ sigcantmask;
>   if (signum == SIGCHLD) {
>   if (sa->sa_flags & SA_NOCLDSTOP)
> - atomic_setbits_int(>ps_flags, SAS_NOCLDSTOP);
> + atomic_setbits_int(>ps_sigflags, SAS_NOCLDSTOP);
>   else
> - atomic_clearbits_int(>ps_flags, SAS_NOCLDSTOP);
> + atomic_clearbits_int(>ps_sigflags, SAS_NOCLDSTOP);

I doubt these should be atomic functions here. The sigacts ps_flags are
don't need atomic updates (especially since most other calls are not
atomic.

>   /*
>* If the SA_NOCLDWAIT flag is set or the handler
>* is SIG_IGN we reparent the dying child to PID 1
> @@ -350,9 +350,9 @@ setsigvec(struct proc *p, int signum, st
>   if (initprocess->ps_sigacts != ps &&
>   ((sa->sa_flags & SA_NOCLDWAIT) ||
>   sa->sa_handler == SIG_IGN))
> - atomic_setbits_int(>ps_flags, SAS_NOCLDWAIT);
> + atomic_setbits_int(>ps_sigflags, SAS_NOCLDWAIT);
>   else
> - atomic_clearbits_int(>ps_flags, SAS_NOCLDWAIT);
> + atomic_clearbits_int(>ps_sigflags, SAS_NOCLDWAIT);

And again.

>   }
>   if ((sa->sa_flags & SA_RESETHAND) != 0)
>   ps->ps_sigreset |= bit;
> @@ -406,7 +406,7 @@ siginit(struct process *pr)
>   for (i = 0; i < NSIG; i++)
>   if (sigprop[i] & SA_IGNORE && i != SIGCONT)
>   ps->ps_sigignore |= sigmask(i);
> - ps->ps_flags = SAS_NOCLDWAIT | SAS_NOCLDSTOP;
> + ps->ps_sigflags = SAS_NOCLDWAIT | SAS_NOCLDSTOP;
>  }
>  
>  /*
> @@ -442,7 +442,7 @@ execsigs(struct proc *p)
>* Clear set of signals caught on the signal stack.
>*/
>   sigstkinit(>p_sigstk);
> - 

Re: rpki-client: output.c static/const tweaks

2020-03-10 Thread Claudio Jeker
On Tue, Mar 10, 2020 at 01:10:58AM +0100, Jeremie Courreges-Anglas wrote:
> 
> Claudio suggested[0] to restrict the visibility of three helper
> functions in this file.  The diff below goes a bit further, sprinkling
> some static and const magic to help the compiler generate better code.
> 
> ok?

OK claudio@
 
> [0] https://marc.info/?l=openbsd-tech=158375920102498=2
> 
> 
> Index: extern.h
> ===
> RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v
> retrieving revision 1.25
> diff -u -p -r1.25 extern.h
> --- extern.h  9 Mar 2020 23:50:01 -   1.25
> +++ extern.h  10 Mar 2020 00:09:25 -
> @@ -370,9 +370,6 @@ extern int outformats;
>  extern char*  outputdir;
>  
>  int   outputfiles(struct vrp_tree *v);
> -FILE *output_createtmp(char *);
> -void  output_cleantmp(void);
> -int   output_finish(FILE *);
>  int   output_bgpd(FILE *, struct vrp_tree *);
>  int   output_bird1v4(FILE *, struct vrp_tree *);
>  int   output_bird1v6(FILE *, struct vrp_tree *);
> Index: output.c
> ===
> RCS file: /cvs/src/usr.sbin/rpki-client/output.c,v
> retrieving revision 1.8
> diff -u -p -r1.8 output.c
> --- output.c  9 Mar 2020 23:50:01 -   1.8
> +++ output.c  10 Mar 2020 00:09:25 -
> @@ -29,12 +29,12 @@
>  #include "extern.h"
>  
>  char *outputdir;
> -char  output_tmpname[PATH_MAX];
> -char  output_name[PATH_MAX];
> -
>  int   outformats;
>  
> -struct outputs {
> +static char   output_tmpname[PATH_MAX];
> +static char   output_name[PATH_MAX];
> +
> +static const struct outputs {
>   int  format;
>   char*name;
>   int (*fn)(FILE *, struct vrp_tree *);
> @@ -48,8 +48,11 @@ struct outputs {
>   { 0, NULL }
>  };
>  
> -void  sig_handler(int);
> -void  set_signal_handler(void);
> +static FILE  *output_createtmp(char *);
> +static void   output_cleantmp(void);
> +static intoutput_finish(FILE *);
> +static void   sig_handler(int);
> +static void   set_signal_handler(void);
>  
>  int
>  outputfiles(struct vrp_tree *v)
> @@ -89,7 +92,7 @@ outputfiles(struct vrp_tree *v)
>   return rc;
>  }
>  
> -FILE *
> +static FILE *
>  output_createtmp(char *name)
>  {
>   FILE *f;
> @@ -113,7 +116,7 @@ output_createtmp(char *name)
>   return f;
>  }
>  
> -int
> +static int
>  output_finish(FILE *out)
>  {
>   if (fclose(out) != 0)
> @@ -124,7 +127,7 @@ output_finish(FILE *out)
>   return 0;
>  }
>  
> -void
> +static void
>  output_cleantmp(void)
>  {
>   if (*output_tmpname)
> @@ -135,7 +138,7 @@ output_cleantmp(void)
>  /*
>   * Signal handler that clears the temporary files.
>   */
> -void
> +static void
>  sig_handler(int sig __unused)
>  {
>   output_cleantmp();
> @@ -145,7 +148,7 @@ sig_handler(int sig __unused)
>  /*
>   * Set signal handler on panic signals.
>   */
> -void
> +static void
>  set_signal_handler(void)
>  {
>   struct sigaction sa;
> 
> 
> -- 
> jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE

-- 
:wq Claudio



Re: rpki-client: check fflush on output files

2020-03-09 Thread Claudio Jeker
On Mon, Mar 09, 2020 at 09:41:37AM +0100, Jeremie Courreges-Anglas wrote:
> On Sat, Mar 07 2020, Claudio Jeker  wrote:
> > On Sat, Mar 07, 2020 at 08:35:39AM +0100, Jeremie Courreges-Anglas wrote:
> >> On Fri, Mar 06 2020, "Theo de Raadt"  wrote:
> >> >> Jeremie Courreges-Anglas  wrote:
> >> >> > 
> >> >> > 
> >> >> > Checking the return value of fprintf is good but not enough to ensure
> >> >> > that data has properly been written to the file without an error.  To 
> >> >> > do
> >> >> > that we can use fflush(3) in a single place.
> >> [redacted]
> >> >> How about checking the return value of fclose() in output_finish() 
> >> >> instead?
> >> > Oh you want to reach the error-reporting code...
> >> 
> >> And the cleanup-on-error code.  Doing it here looks more appealing than
> >> adding
> >>if (fflush(out) != 0)
> >>return -1;
> >> 
> >> at the end of all the output_* functions.
> >> 
> >> If you're careful about write errors you can avoid feeding an
> >> incomplete/garbage file to your BGP daemon.  The code was already
> >> careful, but did not account for buffering.  This is what this patch
> >> tries to address.
> >> 
> >> >> > Build-tested only.  ok?
> >> >> > 
> >> >> > Bonus: in output_finish(), "out = NULL;" is pointless, so zap it.
> >> >> > I suspect it's a remnant from a time where the output FILE * was
> >> >> > a global.  That would be a separate commit.
> >> 
> >> Diff below again for convenience,
> >> 
> >> 
> >> Index: output.c
> >> ===
> >> RCS file: /d/cvs/src/usr.sbin/rpki-client/output.c,v
> >> retrieving revision 1.6
> >> diff -u -p -p -u -r1.6 output.c
> >> --- output.c   6 Mar 2020 17:36:42 -   1.6
> >> +++ output.c   6 Mar 2020 23:04:18 -
> >> @@ -71,7 +71,7 @@ outputfiles(struct vrp_tree *v)
> >>rc = 1;
> >>continue;
> >>}
> >> -  if ((*outputs[i].fn)(fout, v) != 0) {
> >> +  if ((*outputs[i].fn)(fout, v) != 0 || fflush(fout) != 0) {
> >>logx("output for %s format failed", outputs[i].name);
> >>fclose(fout);
> >>output_cleantmp();
> >> @@ -112,8 +112,6 @@ void
> >>  output_finish(FILE *out)
> >>  {
> >>fclose(out);
> >> -  out = NULL;
> >> -
> >>rename(output_tmpname, output_name);
> >>output_tmpname[0] = '\0';
> >>  }
> >> 
> >
> > I think it would be better to pick up the fclose error in output_finish()
> > and while doing that also check for rename() errors. At least those errors
> > should be logged.
> 
> Agreed.  Here's an updated diff that tests the return value of
> output_finish().  Suggestions welcome for the error message in this
> case.
> 
> It also drops the extra "out = NULL;", and replaces logx() calls with
> warn(3) in this file.  I see no reason to drop those messages and errno
> information.  logx() seems used mostly for statistics.
> 
> Thoughts, tests / oks?

Works for me. Ok claudio@

PS: I think some of the output_* prototypes could be moved to output.c
since those functions are only used internally.
 
> Index: extern.h
> ===
> RCS file: /d/cvs/src/usr.sbin/rpki-client/extern.h,v
> retrieving revision 1.24
> diff -u -p -r1.24 extern.h
> --- extern.h  6 Mar 2020 17:36:42 -   1.24
> +++ extern.h  9 Mar 2020 08:19:20 -
> @@ -372,7 +372,7 @@ extern char*   outputdir;
>  int   outputfiles(struct vrp_tree *v);
>  FILE *output_createtmp(char *);
>  void  output_cleantmp(void);
> -void  output_finish(FILE *);
> +int   output_finish(FILE *);
>  int   output_bgpd(FILE *, struct vrp_tree *);
>  int   output_bird1v4(FILE *, struct vrp_tree *);
>  int   output_bird1v6(FILE *, struct vrp_tree *);
> Index: output.c
> ===
> RCS file: /d/cvs/src/usr.sbin/rpki-client/output.c,v
> retrieving revision 1.6
> diff -u -p -r1.6 output.c
> --- output.c  6 Mar 2020 17:36:42 -   1.6
> +++ output.c  9 Mar 2020 08:20:39 

Re: rpki-client: check fflush on output files

2020-03-07 Thread Claudio Jeker
On Sat, Mar 07, 2020 at 08:35:39AM +0100, Jeremie Courreges-Anglas wrote:
> On Fri, Mar 06 2020, "Theo de Raadt"  wrote:
> >> Jeremie Courreges-Anglas  wrote:
> >> > 
> >> > 
> >> > Checking the return value of fprintf is good but not enough to ensure
> >> > that data has properly been written to the file without an error.  To do
> >> > that we can use fflush(3) in a single place.
> [redacted]
> >> How about checking the return value of fclose() in output_finish() instead?
> > Oh you want to reach the error-reporting code...
> 
> And the cleanup-on-error code.  Doing it here looks more appealing than
> adding
>   if (fflush(out) != 0)
>   return -1;
> 
> at the end of all the output_* functions.
> 
> If you're careful about write errors you can avoid feeding an
> incomplete/garbage file to your BGP daemon.  The code was already
> careful, but did not account for buffering.  This is what this patch
> tries to address.
> 
> >> > Build-tested only.  ok?
> >> > 
> >> > Bonus: in output_finish(), "out = NULL;" is pointless, so zap it.
> >> > I suspect it's a remnant from a time where the output FILE * was
> >> > a global.  That would be a separate commit.
> 
> Diff below again for convenience,
> 
> 
> Index: output.c
> ===
> RCS file: /d/cvs/src/usr.sbin/rpki-client/output.c,v
> retrieving revision 1.6
> diff -u -p -p -u -r1.6 output.c
> --- output.c  6 Mar 2020 17:36:42 -   1.6
> +++ output.c  6 Mar 2020 23:04:18 -
> @@ -71,7 +71,7 @@ outputfiles(struct vrp_tree *v)
>   rc = 1;
>   continue;
>   }
> - if ((*outputs[i].fn)(fout, v) != 0) {
> + if ((*outputs[i].fn)(fout, v) != 0 || fflush(fout) != 0) {
>   logx("output for %s format failed", outputs[i].name);
>   fclose(fout);
>   output_cleantmp();
> @@ -112,8 +112,6 @@ void
>  output_finish(FILE *out)
>  {
>   fclose(out);
> - out = NULL;
> -
>   rename(output_tmpname, output_name);
>   output_tmpname[0] = '\0';
>  }
> 

I think it would be better to pick up the fclose error in output_finish()
and while doing that also check for rename() errors. At least those errors
should be logged.

-- 
:wq Claudio



Re: regress: bgpd: config: Fix attribute ordering

2020-03-06 Thread Claudio Jeker
On Fri, Mar 06, 2020 at 06:51:16PM +0100, Sebastian Benoit wrote:
> I dont see that here.
> Sure that you have an up-to-date tree?
> And no diff in there?
 
I think the problem is big-endian vs little-endian.
I need to think about how and if this should be fixed.
 
> Klemens Nanni(k...@openbsd.org) on 2020.03.05 23:39:20 +0100:
> > 
> > I ran bgpd to test diffs and stumbled across what looks like simple
> > disorder in the config checks.
> > 
> > bgpd must have changed in how it orders attributes within `set { ... }'
> > blocks;  breaking the sets into multiple lines and diffing line-wise
> > instead of word-wise shows that the printed config indeed only differs
> > in the way set attributes from the config appear in bgpd output.
> > 
> > Still, I'd like any of the bgpd hackers to verify before I "fix" regress.
> > 
> > OK?
> > 
> > 
> > Index: regress/usr.sbin/bgpd/config/bgpd.conf.10.ok
> > ===
> > RCS file: /cvs/src/regress/usr.sbin/bgpd/config/bgpd.conf.10.ok,v
> > retrieving revision 1.6
> > diff -u -p -r1.6 bgpd.conf.10.ok
> > --- regress/usr.sbin/bgpd/config/bgpd.conf.10.ok17 Jul 2019 10:27:50 
> > -  1.6
> > +++ regress/usr.sbin/bgpd/config/bgpd.conf.10.ok5 Mar 2020 22:32:53 
> > -
> > @@ -40,4 +40,4 @@ match from any large-community 1234:5678
> >  match from any large-community 1234:5678:1 large-community 1234:5678:2 
> > large-community 1234:5678:3 
> >  match from any community 1234:1 large-community 1234:5678:1 
> >  match from any large-community 1234:5678:1 community 1234:1 
> > -match from any set { community delete 1234:5678 community delete 1234:* 
> > community delete *:5678 community delete local-as:5678 community delete 
> > local-as:neighbor-as large-community delete 1234:15:5678 large-community 
> > delete *:15:5678 large-community delete local-as:15:5678 large-community 
> > delete local-as:15:* large-community delete local-as:15:neighbor-as 
> > large-community delete local-as:*:* community 1234:5678 community 
> > local-as:5678 community local-as:neighbor-as large-community 1234:15:5678 
> > large-community local-as:15:5678 large-community local-as:15:neighbor-as }
> > +match from any set { community delete 1234:5678 large-community delete 
> > 1234:15:5678 community delete *:5678 large-community delete *:15:5678 
> > community delete local-as:5678 large-community delete local-as:15:5678 
> > community delete 1234:* community delete local-as:neighbor-as 
> > large-community delete local-as:15:* large-community delete local-as:*:* 
> > large-community delete local-as:15:neighbor-as community 1234:5678 
> > large-community 1234:15:5678 community local-as:5678 large-community 
> > local-as:15:5678 community local-as:neighbor-as large-community 
> > local-as:15:neighbor-as }
> > Index: regress/usr.sbin/bgpd/config/bgpd.conf.11.ok
> > ===
> > RCS file: /cvs/src/regress/usr.sbin/bgpd/config/bgpd.conf.11.ok,v
> > retrieving revision 1.5
> > diff -u -p -r1.5 bgpd.conf.11.ok
> > --- regress/usr.sbin/bgpd/config/bgpd.conf.11.ok17 Jul 2019 10:27:50 
> > -  1.5
> > +++ regress/usr.sbin/bgpd/config/bgpd.conf.11.ok5 Mar 2020 22:35:04 
> > -
> > @@ -33,7 +33,7 @@ match from any ext-community ovs invalid
> >  match from any ext-community ovs not-found 
> >  match from any ext-community rt 64496:201 ext-community soo 64496:202 
> >  match from any ext-community rt 64496:301 ext-community soo 420001:302 
> > ext-community odi 127.0.0.1:303 
> > -match from any set { ext-community delete ovs valid ext-community delete 
> > odi 127.0.0.1:6003 ext-community delete soo 420001:6002 ext-community 
> > delete ort 0x123456789abf ext-community delete rt 64496:6001 ext-community 
> > ovs valid ext-community odi 127.0.0.1:5003 ext-community soo 
> > 420001:5002 ext-community ort 0x123456789abc ext-community rt 
> > 64496:5001 }
> > +match from any set { ext-community delete ovs valid ext-community delete 
> > ort 0x123456789abf ext-community delete rt 64496:6001 ext-community delete 
> > odi 127.0.0.1:6003 ext-community delete soo 420001:6002 ext-community 
> > ovs valid ext-community ort 0x123456789abc ext-community rt 64496:5001 
> > ext-community odi 127.0.0.1:5003 ext-community soo 420001:5002 }
> >  match from any ext-community * * 
> >  match from any ext-community rt * 
> >  match from any ext-community soo * 
> > @@ -47,7 +47,7 @@ match from any ext-community rt 127.0.0.
> >  match from any ext-community soo 64496:* 
> >  match from any ext-community soo 420001:* 
> >  match from any ext-community soo 127.0.0.1:* 
> > -match from any set { ext-community delete odi 127.0.0.1:* ext-community 
> > delete soo 420001:* ext-community delete rt 64496:* ext-community 
> > delete mac-mob * ext-community delete ovs * ext-community delete rt * 
> > ext-community delete soo * ext-community delete odi * ext-community 

Re: BIRD 1.x/2.x support at rpki-client

2020-03-06 Thread Claudio Jeker
On Fri, Mar 06, 2020 at 05:53:59PM +0100, Sebastian Benoit wrote:
> Hi,
> 
> generate 3 different outputs for BIRD:
> - bird v1 with IPv4 routes
> - bird v1 with IPv6 routes
> - bird v2
> when using command line option -B.
> BIRD v2 output from Robert Scheck, robert AT fedoraproject DOT org
> 
> 
> Note that I haven't tried this with bird 1 or 2 yet ;)
> comments, oks?
> 
> 
> (benno_rpki_bird.diff)
> 
> diff --git usr.sbin/rpki-client/extern.h usr.sbin/rpki-client/extern.h
> index 127db60fa37..6592ea83b5e 100644
> --- usr.sbin/rpki-client/extern.h
> +++ usr.sbin/rpki-client/extern.h
> @@ -374,7 +374,9 @@ FILE  *output_createtmp(char *);
>  void  output_cleantmp(void);
>  void  output_finish(FILE *);
>  int   output_bgpd(FILE *, struct vrp_tree *);
> -int   output_bird(FILE *, struct vrp_tree *);
> +int   output_bird1v4(FILE *, struct vrp_tree *);
> +int   output_bird1v6(FILE *, struct vrp_tree *);
> +int   output_bird2(FILE *, struct vrp_tree *);
>  int   output_csv(FILE *, struct vrp_tree *);
>  int   output_json(FILE *, struct vrp_tree *);
>  
> diff --git usr.sbin/rpki-client/output-bird.c 
> usr.sbin/rpki-client/output-bird.c
> index a15faa69164..0299018f8af 100644
> --- usr.sbin/rpki-client/output-bird.c
> +++ usr.sbin/rpki-client/output-bird.c
> @@ -1,6 +1,7 @@
>  /*   $OpenBSD: output-bird.c,v 1.6 2019/12/04 23:03:05 benno Exp $ */
>  /*
>   * Copyright (c) 2019 Claudio Jeker 
> + * Copyright (c) 2020 Robert Scheck 
>   *
>   * Permission to use, copy, modify, and distribute this software for any
>   * purpose with or without fee is hereby granted, provided that the above
> @@ -21,7 +22,7 @@
>  #include "extern.h"
>  
>  int
> -output_bird(FILE *out, struct vrp_tree *vrps)
> +output_bird1v4(FILE *out, struct vrp_tree *vrps)
>  {
>   extern  const char *bird_tablename;
>   char buf[64];
> @@ -31,10 +32,78 @@ output_bird(FILE *out, struct vrp_tree *vrps)
>   return -1;
>  
>   RB_FOREACH(v, vrp_tree, vrps) {
> - ip_addr_print(>addr, v->afi, buf, sizeof(buf));
> - if (fprintf(out, "\troa %s max %u as %u;\n", buf, v->maxlength,
> - v->asid) < 0)
> + if (v->afi == AFI_IPV4) {
> + ip_addr_print(>addr, v->afi, buf, sizeof(buf));
> + if (fprintf(out, "\troa %s max %u as %u;\n", buf,
> + v->maxlength, v->asid) < 0)
> + return -1;
> + }
> + }
> +
> + if (fprintf(out, "}\n") < 0)
>   return -1;
> + return 0;
> +}
> +
> +int
> +output_bird1v6(FILE *out, struct vrp_tree *vrps)
> +{
> + extern  const char *bird_tablename;
> + char buf[64];
> + struct vrp  *v;
> +
> + if (fprintf(out, "roa table %s {\n", bird_tablename) < 0)
> + return -1;
> +
> + RB_FOREACH(v, vrp_tree, vrps) {
> + if (v->afi == AFI_IPV6) {
> + ip_addr_print(>addr, v->afi, buf, sizeof(buf));
> + if (fprintf(out, "\troa %s max %u as %u;\n", buf,
> + v->maxlength, v->asid) < 0)
> + return -1;
> + }
> + }
> +
> + if (fprintf(out, "}\n") < 0)
> + return -1;
> + return 0;
> +}
> +
> +int
> +output_bird2(FILE *out, struct vrp_tree *vrps)
> +{
> + extern  const char *bird_tablename;
> + char buf[64];
> + struct vrp  *v;
> + time_t   now = time(NULL);
> +
> + if (fprintf(out, "define force_roa_table_update = %lld;\n\n"
> + "roa4 table %s4;\nroa6 table %s6;\n\n"
> + "protocol static {\n\troa4 { table %s4; };\n\n",
> + (long long) now, bird_tablename, bird_tablename,
> + bird_tablename) < 0)
> + return -1;
> +
> + RB_FOREACH(v, vrp_tree, vrps) {
> + if (v->afi == AFI_IPV4) {
> + ip_addr_print(>addr, v->afi, buf, sizeof(buf));
> + if (fprintf(out, "\troute %s max %u as %u;\n", buf,
> + v->maxlength, v->asid) < 0)
> + return -1;
> + }
> + }
> +
> + if (fprintf(out, "}\n\nprotocol static {\n\troa6 { table %s6; };\n\n",
> + bird_tablename) < 0)
> + retur

Re: BIRD 1.x/2.x support at rpki-client

2020-03-04 Thread Claudio Jeker
On Wed, Mar 04, 2020 at 07:48:28AM -0700, Theo de Raadt wrote:
> Job Snijders  wrote:
> 
> > I think we still need to support BIRD 1 for the foreseeable future, NIC.CZ 
> > hasn’t communicated plans to deprecate BIRD1 and still supports it; and 
> > BIRD1 still is widely deployed.
> > 
> > I’m somewhat preferential to just generate all 3 BIRD flavors if -B is 
> > given as command line option.
> 
> output.c does the mkstemp dance above the output function, and it is
> table driven to generate one file with a function, per option.
> 
> But imagine if the table was changed to do this:
> 
> } outputs[] = {
> { FORMAT_OPENBGPD, "openbgpd", output_bgpd },
> { FORMAT_BIRD, "bird1v4", output_bird1v4 },
> { FORMAT_BIRD, "bird1v6", output_bird1v6 }
> { FORMAT_BIRD, "bird", output_bird2 }
> { FORMAT_CSV, "csv", output_csv },
> { FORMAT_JSON, "json", output_json },
> ...
> 
> I'd like if someone wrote output_bird1v4, output_bird1v6, and output_bird2
> functions (or whatever the case may be), is that the way to do it?

I think that is a good way to solve this issue. 

-- 
:wq Claudio



Re: IPv6 Support for umb(4)

2020-02-18 Thread Claudio Jeker
On Tue, Feb 18, 2020 at 11:16:54PM +, Stuart Henderson wrote:
> On 2020/02/18 13:40, Gerhard Roth wrote:
> > > > Yes, I tried MBIM_CONTEXT_IPTYPE_IPV4ANDV6 myself first but to no
> > > > avail. The switched to MBIM_CONTEXT_IPTYPE_IPV4V6 and everything
> > > > was fine.  
> > > 
> > > Obviously it needs to switch based on INET6, but with the current
> > > mechanism used for handling v6 in OpenBSD, shouldn't it disable v6
> > > unless the interface has a link-local configured? (So the usual method
> > > to enable v6 and bring an interface up would be "inet6 eui64" and "up").
> > > That is how pppoe works.
> > 
> > 
> > Hi Stuart,
> > 
> > you mean like that?
> 
> Yes, that looks right - sorry I don't have a working umb to test though!

I guess we should then also adjust the manpage to make sure people know
how to enable IPv6 in hostname.umb0
 
> > Index: sys/dev/usb/if_umb.c
> > ===
> > RCS file: /cvs/src/sys/dev/usb/if_umb.c,v
> > retrieving revision 1.32
> > diff -u -p -u -p -r1.32 if_umb.c
> > --- sys/dev/usb/if_umb.c18 Feb 2020 08:09:37 -  1.32
> > +++ sys/dev/usb/if_umb.c18 Feb 2020 12:35:45 -
> > @@ -2583,7 +2583,8 @@ umb_send_connect(struct umb_softc *sc, i
> > c->iptype = htole32(MBIM_CONTEXT_IPTYPE_IPV4);
> >  #ifdef INET6
> > /* XXX FIXME: support IPv6-only mode, too */
> > -   if ((sc->sc_flags & UMBFLG_NO_INET6) == 0)
> > +   if ((sc->sc_flags & UMBFLG_NO_INET6) == 0 &&
> > +   in6ifa_ifpforlinklocal(GET_IFP(sc), 0) != NULL)
> > c->iptype = htole32(MBIM_CONTEXT_IPTYPE_IPV4V6);
> >  #endif
> > memcpy(c->context, umb_uuid_context_internet, sizeof (c->context));
> 

-- 
:wq Claudio



Re: IPv6 Support for umb(4)

2020-02-17 Thread Claudio Jeker
On Tue, Feb 18, 2020 at 08:25:48AM +0100, Gerhard Roth wrote:
> Hi Claudio,
> 
> thanks for looking at it.
> 
> For your questions find my replies below.
> 

Thanks. Bummer about not knowing what the cause of no IPv6 config is.
I guess it is time to get this in an have people play with it.

> 
> On Mon, 17 Feb 2020 17:30:03 +0100 Claudio Jeker  
> wrote:
> > On Tue, Feb 04, 2020 at 09:16:34AM +0100, Gerhard Roth wrote:
> > > Hi Alex,
> > > 
> > > thanks for looking into it.
> > > 
> > > 
> > > On Tue, 4 Feb 2020 00:20:42 +0100 Alexander Bluhm 
> > >  wrote:  
> > > > On Tue, Jan 28, 2020 at 03:03:47PM +0100, Gerhard Roth wrote:  
> > > > > this patch adds IPv6 support to umb(4).
> > > > 
> > > > It breaks my IPv4 setup.
> > > > 
> > > > umb0 at uhub0 port 4 configuration 1 interface 6 "Lenovo H5321 gw" rev 
> > > > 2.00/0.00 addr 2
> > > > provider Vodafone.de
> > > > firmware CXP 901 8700/1 - R3C18
> > > > 
> > > > When I apply the diff, my umb device does not get an IPv4 address.
> > > > 
> > > > umb0: state going up from 'open' to 'radio on'
> > > > umb0: none state unlocked (-1 attempts left)
> > > > umb0: set/qry MBIM_CID_SUBSCRIBER_READY_STATUS failed: BUSY
> > > > umb0: packet service changed from detached to attaching, class none, 
> > > > speed: 0 up / 0 down
> > > > umb0: SIM initialized
> > > > umb0: state going up from 'radio on' to 'SIM is ready'
> > > > umb0: packet service changed from attaching to attached, class HSPA, 
> > > > speed: 576 up / 1440 down
> > > > umb0: state going up from 'SIM is ready' to 'attached'
> > > > umb0: connecting ...
> > > > umb0: set/qry MBIM_CID_CONNECT failed: NO_DEVICE_SUPPORT  
> > > 
> > > That looks like the firmware of this Lenovo H5321 doesn't support IPv6.
> > > Well at least it gives a decent error code.
> > > 
> > >   
> > > > umb0: state change timeout
> > > > umb0: connecting ...
> > > > umb0: set/qry MBIM_CID_CONNECT failed: NO_DEVICE_SUPPORT
> > > > umb0: state change timeout
> > > > umb0: connecting ...
> > > > umb0: set/qry MBIM_CID_CONNECT failed: NO_DEVICE_SUPPORT
> > > > umb0: state change timeout
> > > > ...
> > > > 
> > > > A few comments inline.
> > > >   
> > > > > +#ifdef INET6
> > > > > +int   umb_add_inet6_config(struct umb_softc *, struct 
> > > > > in6_addr *,
> > > > > + u_int, struct in6_addr *);
> > > > > +#endif
> > > > 
> > > > Usually I avoid #ifdef for prototypes.  It does not matter whether
> > > > the compiler reads them and without #ifdef the code is nicer.  
> > > 
> > > Removed it.
> > > 
> > >   
> > > >   
> > > > > +tryv6:;
> > > > 
> > > > The ; is wrong.  
> > > 
> > > Not really, because the label 'tryv6' is immediately followed by
> > > an "#ifdef INET6". So looking just at this label I cannot directly tell
> > > whether there is code that follows or not. And a label with no code
> > > following is a syntax error in C.
> > > 
> > > I just followed a old "C Style and Coding Standards for SunOS" paper
> > > by Bill Shannon from 1993 that says:
> > > 
> > >   If a label is not followed by a program statement (e.g.
> > >   if the next token is a closing brace( } )) a NULL
> > >   statement ( ; ) must follow the label.
> > > 
> > >   
> > > >   
> > > > > + if (n == 0 || off + sizeof (ipv6elem) > len)
> > > > > + goto done;
> > > > > + if (n != 1 && ifp->if_flags & IFF_DEBUG)
> > > > > + log(LOG_INFO, "%s: more than one IPv6 addr: 
> > > > > %d\n",
> > > > > + DEVNAM(ifp->if_softc), n);
> > > > > +
> > > > > + /* Only pick the first one */
> > > > > + memcpy(, data + off, sizeof (ipv6elem));
> > > > > + memcpy(, ipv6elem.addr, sizeof (addr6));
> > > > > +
> > > > > + off = letoh32(ic->ipv6_gwoffs);
> > > > 

Re: pppx(4): rwsleep(9) -> rwsleep_nsec(9)

2020-02-17 Thread Claudio Jeker
On Mon, Feb 17, 2020 at 06:35:38PM -0600, Scott Cheloha wrote:
> Infinite sleep, trivial.
> 
> ok?

OK claudio@
 
> Index: net/if_pppx.c
> ===
> RCS file: /cvs/src/sys/net/if_pppx.c,v
> retrieving revision 1.74
> diff -u -p -r1.74 if_pppx.c
> --- net/if_pppx.c 28 Jan 2020 16:26:09 -  1.74
> +++ net/if_pppx.c 18 Feb 2020 00:35:08 -
> @@ -295,8 +295,8 @@ pppxread(dev_t dev, struct uio *uio, int
>  
>   NET_LOCK();
>   pxd->pxd_waiting = 1;
> - error = rwsleep(pxd, ,
> - (PZERO + 1)|PCATCH, "pppxread", 0);
> + error = rwsleep_nsec(pxd, ,
> + (PZERO + 1)|PCATCH, "pppxread", INFSLP);
>   NET_UNLOCK();
>   if (error != 0) {
>   return (error);
> 

-- 
:wq Claudio



Re: IPv6 Support for umb(4)

2020-02-17 Thread Claudio Jeker
On Tue, Feb 04, 2020 at 09:16:34AM +0100, Gerhard Roth wrote:
> Hi Alex,
> 
> thanks for looking into it.
> 
> 
> On Tue, 4 Feb 2020 00:20:42 +0100 Alexander Bluhm  
> wrote:
> > On Tue, Jan 28, 2020 at 03:03:47PM +0100, Gerhard Roth wrote:
> > > this patch adds IPv6 support to umb(4).  
> > 
> > It breaks my IPv4 setup.
> > 
> > umb0 at uhub0 port 4 configuration 1 interface 6 "Lenovo H5321 gw" rev 
> > 2.00/0.00 addr 2
> > provider Vodafone.de
> > firmware CXP 901 8700/1 - R3C18
> > 
> > When I apply the diff, my umb device does not get an IPv4 address.
> > 
> > umb0: state going up from 'open' to 'radio on'
> > umb0: none state unlocked (-1 attempts left)
> > umb0: set/qry MBIM_CID_SUBSCRIBER_READY_STATUS failed: BUSY
> > umb0: packet service changed from detached to attaching, class none, speed: 
> > 0 up / 0 down
> > umb0: SIM initialized
> > umb0: state going up from 'radio on' to 'SIM is ready'
> > umb0: packet service changed from attaching to attached, class HSPA, speed: 
> > 576 up / 1440 down
> > umb0: state going up from 'SIM is ready' to 'attached'
> > umb0: connecting ...
> > umb0: set/qry MBIM_CID_CONNECT failed: NO_DEVICE_SUPPORT
> 
> That looks like the firmware of this Lenovo H5321 doesn't support IPv6.
> Well at least it gives a decent error code.
> 
> 
> > umb0: state change timeout
> > umb0: connecting ...
> > umb0: set/qry MBIM_CID_CONNECT failed: NO_DEVICE_SUPPORT
> > umb0: state change timeout
> > umb0: connecting ...
> > umb0: set/qry MBIM_CID_CONNECT failed: NO_DEVICE_SUPPORT
> > umb0: state change timeout
> > ...
> > 
> > A few comments inline.
> > 
> > > +#ifdef INET6
> > > +int   umb_add_inet6_config(struct umb_softc *, struct 
> > > in6_addr *,
> > > + u_int, struct in6_addr *);
> > > +#endif  
> > 
> > Usually I avoid #ifdef for prototypes.  It does not matter whether
> > the compiler reads them and without #ifdef the code is nicer.
> 
> Removed it.
> 
> 
> > 
> > > +tryv6:;  
> > 
> > The ; is wrong.
> 
> Not really, because the label 'tryv6' is immediately followed by
> an "#ifdef INET6". So looking just at this label I cannot directly tell
> whether there is code that follows or not. And a label with no code
> following is a syntax error in C.
> 
> I just followed a old "C Style and Coding Standards for SunOS" paper
> by Bill Shannon from 1993 that says:
> 
>   If a label is not followed by a program statement (e.g.
>   if the next token is a closing brace( } )) a NULL
>   statement ( ; ) must follow the label.
> 
> 
> > 
> > > + if (n == 0 || off + sizeof (ipv6elem) > len)
> > > + goto done;
> > > + if (n != 1 && ifp->if_flags & IFF_DEBUG)
> > > + log(LOG_INFO, "%s: more than one IPv6 addr: %d\n",
> > > + DEVNAM(ifp->if_softc), n);
> > > +
> > > + /* Only pick the first one */
> > > + memcpy(, data + off, sizeof (ipv6elem));
> > > + memcpy(, ipv6elem.addr, sizeof (addr6));
> > > +
> > > + off = letoh32(ic->ipv6_gwoffs);
> > > + memcpy(, data + off, sizeof (gw6));  
> > 
> > I think we should check the data length like above.
> > 
> > if (off + sizeof (gw6) > len)
> > goto done;
> > 
> > And IPv4 should get the same check.
> 
> Thanks for spotting that. Added check to both cases.
> 
> 
> > 
> > > @@ -380,6 +381,6 @@ struct umb_softc {
> > >
> > >  #define sc_state sc_info.state
> > >  #define sc_roaming   sc_info.enable_roaming
> > > - struct umb_info sc_info;
> > > + struct umb_info  sc_info;
> > >  };
> > >  #endif /* _KERNEL */  
> > 
> > This whitespace chunk is wrong.
> 
> I think it was wrong before. It's common idiom to add an extra space
> to non-pointer members to keep the member names aligned, e.g.
> 
>   struct foo {
>   int *abc;
>   int  def;
>   int *bar;
>   };
> 
> Please correct me if I'm wrong.
> 
> > 
> > bluhm
> 
> 
> The updated patch below introduces a UMBFLG_NO_INET6 which is set on
> receipt of a MBIM_STATUS_NO_DEVICE_SUPPORT in response to a
> MBIM_CID_CONNECT. The code will then retry the connect operation in
> IPv4-only mode.
> 
> That won't give you any IPv6 support, but at least it won't break
> your setup.
> 

A few whitespace fixes and some comments inline but apart from that
OK claudio@

> Index: sbin/ifconfig/ifconfig.c
> ===
> RCS file: /cvs/src/sbin/ifconfig/ifconfig.c,v
> retrieving revision 1.417
> diff -u -p -u -p -r1.417 ifconfig.c
> --- sbin/ifconfig/ifconfig.c  27 Dec 2019 14:34:46 -  1.417
> +++ sbin/ifconfig/ifconfig.c  28 Jan 2020 12:16:23 -
> @@ -5666,6 +5666,7 @@ umb_status(void)
>   char apn[UMB_APN_MAXLEN+1];
>   char pn[UMB_PHONENR_MAXLEN+1];
>   int  i, n;
> + char astr[INET6_ADDRSTRLEN];
>  
>   memset((char *), 0, sizeof(mi));
>   

Adjust some DLT_IEEE802_11_RADIO bpf taps

2020-02-17 Thread Claudio Jeker
As already done on iwm(4) and one of the athn(4), there is no need to pass
the radio tap structure to bpf_mtap by faking up an mbuf. The code can
just use bpf_mtap_hdr() (which does a similar dance but with far less
memory on the stack).

There are many other wifi driver that do the same thing so I would be
happy if somebody else would apply the same logic there too :)

I could only compile test this diff.
-- 
:wq Claudio

Index: ar9003.c
===
RCS file: /cvs/src/sys/dev/ic/ar9003.c,v
retrieving revision 1.49
diff -u -p -r1.49 ar9003.c
--- ar9003.c12 Sep 2019 12:55:06 -  1.49
+++ ar9003.c17 Feb 2020 15:51:19 -
@@ -856,7 +856,6 @@ ar9003_rx_radiotap(struct athn_softc *sc
 
struct athn_rx_radiotap_header *tap = >sc_rxtap;
struct ieee80211com *ic = >sc_ic;
-   struct mbuf mb;
uint64_t tsf;
uint32_t tstamp;
uint8_t rate;
@@ -905,13 +904,7 @@ ar9003_rx_radiotap(struct athn_softc *sc
case 0xc: tap->wr_rate = 108; break;
}
}
-   mb.m_data = (caddr_t)tap;
-   mb.m_len = sc->sc_rxtap_len;
-   mb.m_next = m;
-   mb.m_nextpkt = NULL;
-   mb.m_type = 0;
-   mb.m_flags = 0;
-   bpf_mtap(sc->sc_drvbpf, , BPF_DIRECTION_IN);
+   bpf_mtap_hdr(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m, BPF_DIRECTION_IN);
 }
 #endif
 
@@ -1484,7 +1477,6 @@ ar9003_tx(struct athn_softc *sc, struct 
 #if NBPFILTER > 0
if (__predict_false(sc->sc_drvbpf != NULL)) {
struct athn_tx_radiotap_header *tap = >sc_txtap;
-   struct mbuf mb;
 
tap->wt_flags = 0;
/* Use initial transmit rate. */
@@ -1496,13 +1488,8 @@ ar9003_tx(struct athn_softc *sc, struct 
ridx[0] != ATHN_RIDX_CCK1 &&
(ic->ic_flags & IEEE80211_F_SHPREAMBLE))
tap->wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
-   mb.m_data = (caddr_t)tap;
-   mb.m_len = sc->sc_txtap_len;
-   mb.m_next = m;
-   mb.m_nextpkt = NULL;
-   mb.m_type = 0;
-   mb.m_flags = 0;
-   bpf_mtap(sc->sc_drvbpf, , BPF_DIRECTION_OUT);
+   bpf_mtap_hdr(sc->sc_drvbpf, tap, sc->sc_txtap_len, m,
+   BPF_DIRECTION_OUT);
}
 #endif
 
Index: ath.c
===
RCS file: /cvs/src/sys/dev/ic/ath.c,v
retrieving revision 1.117
diff -u -p -r1.117 ath.c
--- ath.c   12 Sep 2019 12:55:06 -  1.117
+++ ath.c   17 Feb 2020 15:50:05 -
@@ -1922,8 +1922,6 @@ ath_rx_proc(void *arg, int npending)
 
 #if NBPFILTER > 0
if (sc->sc_drvbpf) {
-   struct mbuf mb;
-
sc->sc_rxtap.wr_flags = IEEE80211_RADIOTAP_F_FCS;
sc->sc_rxtap.wr_rate =
sc->sc_hwmap[ds->ds_rxstat.rs_rate] &
@@ -1932,13 +1930,8 @@ ath_rx_proc(void *arg, int npending)
sc->sc_rxtap.wr_rssi = ds->ds_rxstat.rs_rssi;
sc->sc_rxtap.wr_max_rssi = ic->ic_max_rssi;
 
-   mb.m_data = (caddr_t)>sc_rxtap;
-   mb.m_len = sc->sc_rxtap_len;
-   mb.m_next = m;
-   mb.m_nextpkt = NULL;
-   mb.m_type = 0;
-   mb.m_flags = 0;
-   bpf_mtap(sc->sc_drvbpf, , BPF_DIRECTION_IN);
+   bpf_mtap_hdr(sc->sc_drvbpf, >sc_rxtap,
+   sc->sc_rxtap_len, m, BPF_DIRECTION_IN);
}
 #endif
m_adj(m, -IEEE80211_CRC_LEN);
@@ -2307,8 +2300,6 @@ ath_tx_start(struct ath_softc *sc, struc
bpf_mtap(ic->ic_rawbpf, m0, BPF_DIRECTION_OUT);
 
if (sc->sc_drvbpf) {
-   struct mbuf mb;
-
sc->sc_txtap.wt_flags = 0;
if (shortPreamble)
sc->sc_txtap.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
@@ -2320,13 +2311,8 @@ ath_tx_start(struct ath_softc *sc, struc
sc->sc_txtap.wt_antenna = antenna;
sc->sc_txtap.wt_hwqueue = hwqueue;
 
-   mb.m_data = (caddr_t)>sc_txtap;
-   mb.m_len = sc->sc_txtap_len;
-   mb.m_next = m0;
-   mb.m_nextpkt = NULL;
-   mb.m_type = 0;
-   mb.m_flags = 0;
-   bpf_mtap(sc->sc_drvbpf, , BPF_DIRECTION_OUT);
+   bpf_mtap_hdr(sc->sc_drvbpf, >sc_txtap, sc->sc_txtap_len,
+   m0, BPF_DIRECTION_OUT);
}
 #endif
 
Index: rt2560.c
===
RCS file: /cvs/src/sys/dev/ic/rt2560.c,v
retrieving revision 1.85
diff -u -p -r1.85 rt2560.c
--- rt2560.c12 Sep 2019 12:55:07 -  1.85
+++ rt2560.c17 Feb 2020 16:00:23 -
@@ -1171,7 +1171,6 @@ 

minor bgpd cleanup

2020-02-14 Thread Claudio Jeker
Move and rename copy_filterset to rde_filter.c as filterset_copy.
This way it matches the other filterset_* functions.

OK?
-- 
:wq Claudio

Index: bgpd.h
===
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v
retrieving revision 1.400
diff -u -p -r1.400 bgpd.h
--- bgpd.h  12 Feb 2020 10:33:56 -  1.400
+++ bgpd.h  14 Feb 2020 12:16:43 -
@@ -1182,8 +1182,6 @@ void  free_prefixtree(struct prefixset_t
 void   filterlist_free(struct filter_head *);
 inthost(const char *, struct bgpd_addr *, u_int8_t *);
 u_int32_t  get_bgpid(void);
-void   copy_filterset(struct filter_set_head *,
-   struct filter_set_head *);
 void   expand_networks(struct bgpd_config *);
 intprefixset_cmp(struct prefixset_item *, struct prefixset_item *);
 RB_PROTOTYPE(prefixset_tree, prefixset_item, entry, prefixset_cmp);
@@ -1261,10 +1259,10 @@ int pftable_addr_remove(struct pftable_m
 intpftable_commit(void);
 
 /* rde_filter.c */
-voidfilterset_free(struct filter_set_head *);
-int filterset_cmp(struct filter_set *, struct filter_set *);
-voidfilterset_move(struct filter_set_head *,
-   struct filter_set_head *);
+void   filterset_free(struct filter_set_head *);
+intfilterset_cmp(struct filter_set *, struct filter_set *);
+void   filterset_move(struct filter_set_head *, struct filter_set_head *);
+void   filterset_copy(struct filter_set_head *, struct filter_set_head *);
 const char *filterset_name(enum action_types);
 
 /* rde_sets.c */
Index: config.c
===
RCS file: /cvs/src/usr.sbin/bgpd/config.c,v
retrieving revision 1.94
diff -u -p -r1.94 config.c
--- config.c28 Jan 2020 15:45:46 -  1.94
+++ config.c14 Feb 2020 12:21:44 -
@@ -496,22 +496,6 @@ prepare_listeners(struct bgpd_config *co
 }
 
 void
-copy_filterset(struct filter_set_head *source, struct filter_set_head *dest)
-{
-   struct filter_set   *s, *t;
-
-   if (source == NULL)
-   return;
-
-   TAILQ_FOREACH(s, source, entry) {
-   if ((t = malloc(sizeof(struct filter_set))) == NULL)
-   fatal(NULL);
-   memcpy(t, s, sizeof(struct filter_set));
-   TAILQ_INSERT_TAIL(dest, t, entry);
-   }
-}
-
-void
 expand_networks(struct bgpd_config *c)
 {
struct network  *n, *m, *tmp;
@@ -533,8 +517,7 @@ expand_networks(struct bgpd_config *c)
memcpy(>net.prefix, >p.addr,
sizeof(m->net.prefix));
m->net.prefixlen = psi->p.len;
-   TAILQ_INIT(>net.attrset);
-   copy_filterset(>net.attrset,
+   filterset_copy(>net.attrset,
>net.attrset);
TAILQ_INSERT_TAIL(nw, m, entry);
}
Index: parse.y
===
RCS file: /cvs/src/usr.sbin/bgpd/parse.y,v
retrieving revision 1.403
diff -u -p -r1.403 parse.y
--- parse.y 24 Jan 2020 05:44:05 -  1.403
+++ parse.y 14 Feb 2020 12:21:59 -
@@ -4076,8 +4076,7 @@ expand_rule(struct filter_rule *rule, st
memcpy(r, rule, sizeof(struct 
filter_rule));
memcpy(>match, match,
sizeof(struct filter_match));
-   TAILQ_INIT(>set);
-   copy_filterset(set, >set);
+   filterset_copy(set, >set);
 
if (rb != NULL)
strlcpy(r->rib, rb->name,
Index: rde_filter.c
===
RCS file: /cvs/src/usr.sbin/bgpd/rde_filter.c,v
retrieving revision 1.122
diff -u -p -r1.122 rde_filter.c
--- rde_filter.c13 Aug 2019 12:16:20 -  1.122
+++ rde_filter.c14 Feb 2020 12:21:28 -
@@ -502,6 +502,10 @@ filterset_cmp(struct filter_set *a, stru
return (0);
 }
 
+/*
+ * move filterset from source to dest. dest will be initialized first.
+ * After the move source is an empty list.
+ */
 void
 filterset_move(struct filter_set_head *source, struct filter_set_head *dest)
 {
@@ -509,6 +513,26 @@ filterset_move(struct filter_set_head *s
if (source == NULL)
return;
TAILQ_CONCAT(dest, source, entry);
+}
+
+/*
+ * copy filterset from source to dest. dest will be initialized first.
+ */
+void
+filterset_copy(struct filter_set_head *source, struct filter_set_head *dest)
+{
+   struct filter_set   *s, *t;
+
+   TAILQ_INIT(dest);

Re: remove needless #ifdef

2020-02-13 Thread Claudio Jeker
On Thu, Feb 13, 2020 at 11:50:46PM +0100, Jan Stary wrote:
> On Feb 10 09:28:38, yasu...@openbsd.org wrote:
> > Hi,
> > 
> > On Sun, 09 Feb 2020 19:28:50 +0100
> > Jeremie Courreges-Anglas  wrote:
> > > On Sun, Feb 09 2020, Jan Stary  wrote:
> > >> Currently, sys/net/pipex_local.h asks #ifdef __OpenBSD__
> > >> and if so, defines "Static" to be nothing, to use it later.
> > >> That can go away, right?
> > > 
> > > I believe that's something the IIJ folks want to keep, cc'ing Yasuoka.
> > 
> > I once thought keeping "static" is better for maintaining the code,
> > but now I don't think it's necessary.  So it's ok to remove them.
> 
> So can we remove the please?

Yes. OK claudio

>   Jan
> 
> > >>
> > >> Index: sys/net/pipex_local.h
> > >> ===
> > >> RCS file: /cvs/src/sys/net/pipex_local.h,v
> > >> retrieving revision 1.30
> > >> diff -u -p -r1.30 pipex_local.h
> > >> --- sys/net/pipex_local.h31 Jan 2019 18:01:14 -  1.30
> > >> +++ sys/net/pipex_local.h9 Feb 2020 15:26:51 -
> > >> @@ -26,12 +26,6 @@
> > >>   * SUCH DAMAGE.
> > >>   */
> > >>  
> > >> -#ifdef __OpenBSD__
> > >> -#define Static
> > >> -#else
> > >> -#define Static static
> > >> -#endif
> > >> -
> > >>  #define PIPEX_PPTP  1
> > >>  #define PIPEX_L2TP  1
> > >>  #define PIPEX_PPPOE 1
> > >> @@ -372,59 +366,56 @@ extern struct pipex_hash_head  pipex_id_h
> > >>  #define PIPEX_TCP_OPTLEN 40
> > >>  #define PIPEX_L2TP_MINLEN   8
> > >>  
> > >> -/*
> > >> - * static function prototypes
> > >> - */
> > >> -Static void  pipex_iface_start (struct 
> > >> pipex_iface_context *);
> > >> -Static void  pipex_iface_stop (struct 
> > >> pipex_iface_context *);
> > >> -Static int   pipex_add_session (struct 
> > >> pipex_session_req *, struct pipex_iface_context *);
> > >> -Static int   pipex_close_session (struct 
> > >> pipex_session_close_req *);
> > >> -Static int   pipex_config_session (struct 
> > >> pipex_session_config_req *);
> > >> -Static int   pipex_get_stat (struct 
> > >> pipex_session_stat_req *);
> > >> -Static int   pipex_get_closed (struct 
> > >> pipex_session_list_req *);
> > >> -Static int   pipex_destroy_session (struct 
> > >> pipex_session *);
> > >> -Static struct pipex_session  *pipex_lookup_by_ip_address (struct 
> > >> in_addr);
> > >> -Static struct pipex_session  *pipex_lookup_by_session_id (int, int);
> > >> -Static void  pipex_ip_output (struct mbuf *, struct 
> > >> pipex_session *);
> > >> -Static void  pipex_ppp_output (struct mbuf *, struct 
> > >> pipex_session *, int);
> > >> -Static int   pipex_ppp_proto (struct mbuf *, struct 
> > >> pipex_session *, int, int *);
> > >> -Static void  pipex_ppp_input (struct mbuf *, struct 
> > >> pipex_session *, int);
> > >> -Static void  pipex_ip_input (struct mbuf *, struct 
> > >> pipex_session *);
> > >> +void  pipex_iface_start (struct pipex_iface_context *);
> > >> +void  pipex_iface_stop (struct pipex_iface_context *);
> > >> +int   pipex_add_session (struct pipex_session_req *, 
> > >> struct pipex_iface_context *);
> > >> +int   pipex_close_session (struct 
> > >> pipex_session_close_req *);
> > >> +int   pipex_config_session (struct 
> > >> pipex_session_config_req *);
> > >> +int   pipex_get_stat (struct pipex_session_stat_req *);
> > >> +int   pipex_get_closed (struct pipex_session_list_req 
> > >> *);
> > >> +int   pipex_destroy_session (struct pipex_session *);
> > >> +struct pipex_session  *pipex_lookup_by_ip_address (struct in_addr);
> > >> +struct pipex_session  *pipex_lookup_by_session_id (int, int);
> > >> +void  pipex_ip_output (struct mbuf *, struct 
> > >> pipex_session *);
> > >> +void  pipex_ppp_output (struct mbuf *, struct 
> > >> pipex_session *, int);
> > >> +int   pipex_ppp_proto (struct mbuf *, struct 
> > >> pipex_session *, int, int *);
> > >> +void  pipex_ppp_input (struct mbuf *, struct 
> > >> pipex_session *, int);
> > >> +void  pipex_ip_input (struct mbuf *, struct 
> > >> pipex_session *);
> > >>  #ifdef INET6
> > >> -Static void  pipex_ip6_input (struct mbuf *, struct 
> > >> pipex_session *);
> > >> +void  pipex_ip6_input (struct mbuf *, struct 
> > >> pipex_session *);
> > >>  #endif
> > >> -Static struct mbuf   *pipex_common_input(struct pipex_session 
> > >> *, struct mbuf *, int, int, int);
> > >> +struct mbuf   *pipex_common_input(struct pipex_session *, 
> > >> struct mbuf *, int, int, int);
> > >>  
> > >>  #ifdef PIPEX_PPPOE
> > >> -Static void  

Re: em(4) reset I210 wake status

2020-02-11 Thread Claudio Jeker
On Wed, Feb 05, 2020 at 10:32:09PM +0800, Nathanael Rensen wrote:
> When I boot an APU2 using wake-on-lan and then attempt to power off with
> shutdown -hp it wakes itself up again. To prevent this it is necessary to
> clear the I210 PME_STATUS flag. This is described in section 5.6.2 of the
> I210 datasheet:
> 
>   The PE_WAKE_N remains asserted until the operating system either writes
>   a 1b to the PMCSR.PME_Status bit or writes a 0b to the PMCSR.PME_En bit. 
> 
> In addition the WUS (wake up status) register is not automatically cleared,
> as described in section 8.2.13 of the i210 datasheet:
> 
>   This register is not cleared when PE_RST_N is asserted. It is only
>   cleared when LAN_PWR_GOOD is deasserted or when cleared by the software
>   device driver.
> 
> Nathanael
> 
> Index: sys/dev/pci/if_em.c
> ===
> RCS file: /cvs/src/sys/dev/pci/if_em.c,v
> retrieving revision 1.344
> diff -u -p -r1.344 if_em.c
> --- sys/dev/pci/if_em.c   4 Feb 2020 10:59:23 -   1.344
> +++ sys/dev/pci/if_em.c   5 Feb 2020 14:01:34 -
> @@ -561,6 +561,9 @@ em_attach(struct device *parent, struct 
>  #endif
>   printf(", address %s\n", ether_sprintf(sc->sc_ac.ac_enaddr));
>  
> + if (sc->hw.wus)
> + printf("%s wakeup: %d\n", sc->sc_dev.dv_xname, sc->hw.wus);
> +

Why do you need that? Is there a point to know which device got the
wakeup? In any case this should be folded into the regular device dmesg
line and not be a new line. e.g
em0 at pci1 dev 0 function 0 "Intel I210" rev 0x03: msi, address XX:YY, wakeup

Not sure if any other driver prints a message for a wakeup event.
So maybe hw.wus is not needed and then only the if_em_hw.c part of the
diff is needed.

>   /* Indicate SOL/IDER usage */
>   if (em_check_phy_reset_block(>hw))
>   printf("%s: PHY reset is blocked due to SOL/IDER session.\n",
> Index: sys/dev/pci/if_em_hw.c
> ===
> RCS file: /cvs/src/sys/dev/pci/if_em_hw.c,v
> retrieving revision 1.106
> diff -u -p -r1.106 if_em_hw.c
> --- sys/dev/pci/if_em_hw.c4 Feb 2020 10:59:23 -   1.106
> +++ sys/dev/pci/if_em_hw.c5 Feb 2020 14:01:34 -
> @@ -1678,6 +1678,12 @@ em_init_hw(struct em_hw *hw)
>   ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | 
>   E1000_TXDCTL_FULL_TX_DESC_WB;
>   E1000_WRITE_REG(hw, TXDCTL(1), ctrl);
> + hw->wus = E1000_READ_REG(hw, WUS);
> + if (hw->wus)
> + E1000_WRITE_REG(hw, WUS, reg_data);

What is reg_data? Guess you want to write back hw->wus or 0 to clear it.

> + reg_data = E1000_READ_REG(hw, WUC);
> + if (reg_data & E1000_WUC_PME_STATUS)
> + E1000_WRITE_REG(hw, WUC, reg_data);
>   break;
>   }
>  
> Index: sys/dev/pci/if_em_hw.h
> ===
> RCS file: /cvs/src/sys/dev/pci/if_em_hw.h,v
> retrieving revision 1.80
> diff -u -p -r1.80 if_em_hw.h
> --- sys/dev/pci/if_em_hw.h4 Feb 2020 10:59:23 -   1.80
> +++ sys/dev/pci/if_em_hw.h5 Feb 2020 14:01:34 -
> @@ -1482,6 +1482,7 @@ struct em_hw {
>  uint16_t swfw;
>  boolean_t eee_enable;
>  int sw_flag;
> +int wus;
>  };
>  
>  #define E1000_EEPROM_SWDPIN0   0x0001   /* SWDPIN 0 EEPROM Value */
> 

-- 
:wq Claudio



Re: [PATCH] pledge: allow kern.somaxconn sysctl for inet

2020-02-11 Thread Claudio Jeker
On Mon, Feb 03, 2020 at 12:52:05AM +, Jimmy Brush wrote:
> No golang tcp server can be pledged without this change because it
> queries kern.somaxconn before it listens on a tcp socket[1][2][3].
> 
> I cannot think of any advantage this change would give an attacker
> who has compromised a pledged process.
> 
> [1] https://golang.org/src/net/sock_posix.go#L57
> [2] https://golang.org/src/net/net.go#L373
> [3] https://golang.org/src/net/sock_bsd.go#L27
> 
> ---
>  sys/kern/kern_pledge.c | 6 ++
>  1 file changed, 6 insertions(+)
> 
> diff --git sys/kern/kern_pledge.c sys/kern/kern_pledge.c
> index 9f436df4893..8d1203198ed 100644
> --- sys/kern/kern_pledge.c
> +++ sys/kern/kern_pledge.c
> @@ -904,6 +904,12 @@ pledge_sysctl(struct proc *p, int miblen, int *mib, void 
> *new)
>   return (0);
>   }
>  
> + if ((p->p_p->ps_pledge & PLEDGE_INET)) {
> + if (miblen == 2 &&  /* kern.somaxconn */
> + mib[0] == CTL_KERN && mib[1] == KERN_SOMAXCONN)
> + return (0);
> + }
> +
>   if ((p->p_p->ps_pledge & (PLEDGE_ROUTE | PLEDGE_INET | PLEDGE_DNS))) {
>   if (miblen == 6 &&  /* getifaddrs() */
>   mib[0] == CTL_NET && mib[1] == PF_ROUTE &&
> 

I think go should not query the sysctl and instead just use a reasonably
high default (or let users choose). The kernel will then use the minimum
of the two values. At least this is what all other daemons do.
Guess that option will not happen...

-- 
:wq Claudio



Re: piixpm(4) support for AMD FCH watchdog

2020-02-11 Thread Claudio Jeker
On Sat, Feb 08, 2020 at 01:07:01PM +0800, Nathanael Rensen wrote:
> The diff below adds support for the watchdog as found in the embedded
> AMD FCH (fusion controller hub) as found on APU2.
> 
> Index: sys/dev/pci/piixpm.c
> ===
> RCS file: /cvs/src/sys/dev/pci/piixpm.c,v
> retrieving revision 1.42
> diff -u -p -r1.42 piixpm.c
> --- sys/dev/pci/piixpm.c  21 Jan 2020 06:37:24 -  1.42
> +++ sys/dev/pci/piixpm.c  8 Feb 2020 04:44:42 -
> @@ -54,8 +54,10 @@ struct piixpm_softc {
>   struct device   sc_dev;
>  
>   bus_space_tag_t sc_iot;
> + bus_space_tag_t sc_memt;
>   bus_space_handle_t  sc_ioh;
>   bus_space_handle_t  sc_sb800_ioh;
> + bus_space_handle_t  sc_wdt_mh;
>   void *  sc_ih;
>   int sc_poll;
>   int sc_is_sb800;
> @@ -83,6 +85,8 @@ int piixpm_i2c_exec(void *, i2c_op_t, i2
>  
>  int  piixpm_intr(void *);
>  
> +int  piixpm_wdt_cb(void *arg, int period);
> +
>  struct cfattach piixpm_ca = {
>   sizeof(struct piixpm_softc),
>   piixpm_match,
> @@ -127,7 +131,7 @@ piixpm_attach(struct device *parent, str
>   struct piixpm_softc *sc = (struct piixpm_softc *)self;
>   struct pci_attach_args *pa = aux;
>   bus_space_handle_t ioh;
> - u_int16_t val, smb0en;
> + u_int16_t val, smb0en, wdten = 0;
>   bus_addr_t base;
>   pcireg_t conf;
>   pci_intr_handle_t ih;
> @@ -136,6 +140,7 @@ piixpm_attach(struct device *parent, str
>   int numbusses, i;
>  
>   sc->sc_iot = pa->pa_iot;
> + sc->sc_memt = pa->pa_memt;
>   numbusses = 1;
>  
>   if ((PCI_VENDOR(pa->pa_id) == PCI_VENDOR_AMD &&
> @@ -160,7 +165,7 @@ piixpm_attach(struct device *parent, str
>  
>   /*
>* AMD Bolton matches PCI_PRODUCT_AMD_HUDSON2_SMB but
> -  * uses old register layout. Therefor check PCI_REVISION.
> +  * uses old register layout. Therefore check PCI_REVISION.
>*/
>   if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_AMD &&
>   ((PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_AMD_HUDSON2_SMB &&
> @@ -170,6 +175,7 @@ piixpm_attach(struct device *parent, str
>   AMDFCH41_PM_DECODE_EN);
>   val = bus_space_read_1(sc->sc_iot, ioh, 1);
>   smb0en = val & AMDFCH41_SMBUS_EN;
> + wdten = val & AMDFCH41_WDT_EN;
>  
>   bus_space_write_1(sc->sc_iot, ioh, 0,
>   AMDFCH41_PM_DECODE_EN + 1);
> @@ -282,7 +288,59 @@ piixpm_attach(struct device *parent, str
>   config_found(self, , iicbus_print);
>   }
>  

Why are you registering the watchdog late and not in the FCH specific
block above? Do other AMD SBx00 or KERNCZ chips support the watchdog in
the same way?

> + /* Register watchdog */
> + if (wdten && bus_space_map(sc->sc_memt, AMDFCH41_WDTREG_BASE,
> + AMDFCH41_WDTREG_SIZE, 0, >sc_wdt_mh) == 0) {
> + val = bus_space_read_1(sc->sc_memt, sc->sc_wdt_mh,
> + AMDFCH41_WDTREG_CTL);
> + if (val & AMDFCH41_WDTREG_CTL_FIRED) {
> + printf("%s watchdog caused previous restart\n",
> + sc->sc_dev.dv_xname);
> + bus_space_write_1(sc->sc_memt, sc->sc_wdt_mh,
> + AMDFCH41_WDTREG_CTL,
> + val | AMDFCH41_WDTREG_CTL_FIRED);
> + }
> +
> + if (val & AMDFCH41_WDTREG_CTL_DISABLED)
> + printf("%s watchdog disabled\n", sc->sc_dev.dv_xname);
> + else {
> + printf("%s watchdog found\n", sc->sc_dev.dv_xname);

The printf used here are non standard. Ideally this printing is folded
into the attach line of piixpm(4), e.g:
piixpm0 at pci0 dev 20 function 0 "AMD Hudson-2 SMBus" rev 0x42: SMI, watchdog
Same for the 'watchdog caused previous restart'. I think the common idiom
is to print ', watchdog' and ', reboot on timeout' for the two cases.

Also move the if (val & AMDFCH41_WDTREG_CTL_FIRED) check after
if (val & AMDFCH41_WDTREG_CTL_DISABLED)

> +
> + /* Set 1 second counter period */
> + bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, 0,
> + AMDFCH41_PM_DECODE_EN + 3);
> + val = bus_space_read_1(sc->sc_iot, sc->sc_sb800_ioh, 1);
> + val = (val & ~AMDFCH41_WDT_MASK) | AMDFCH41_WDT_1S;
> + bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, 1, val);
> +
> + wdog_register(piixpm_wdt_cb, sc);
> + }
> + }
> +
>   return;
> +}
> +
> +int
> +piixpm_wdt_cb(void *arg, int period)
> +{
> + struct piixpm_softc *sc = (struct piixpm_softc *)arg;
> + u_int16_t val;
> +
> + val = 

Re: PT_ATTACH wait(2) and reparent

2020-02-11 Thread Claudio Jeker
On Tue, Feb 11, 2020 at 02:03:40PM +0100, Martin Pieuchot wrote:
> On 06/02/20(Thu) 12:08, Martin Pieuchot wrote:
> > As exposed recently via the t_ptrace regression and some make changes an
> > exit status might reported twice to its parent via wait(2).
> > 
> > The diff below fixes that by making sure we do not re-parent a child to
> > the same parent.
> > 
> > With it the above mentioned regression as well as the ptrace one that
> > I'm porting from FreeBSD pass.
> > 
> > ok?
> 
> Anyone?
> 
> This fix is straightforward: there's no need to give the child back to
> the old parent if we *are* the old parent 8)
> 
> > Index: kern/kern_exit.c
> > ===
> > RCS file: /cvs/src/sys/kern/kern_exit.c,v
> > retrieving revision 1.182
> > diff -u -p -r1.182 kern_exit.c
> > --- kern/kern_exit.c19 Dec 2019 17:40:10 -  1.182
> > +++ kern/kern_exit.c6 Feb 2020 11:02:01 -
> > @@ -584,7 +584,8 @@ proc_finish_wait(struct proc *waiter, st
> >  * we need to give it back to the old parent.
> >  */
> > pr = p->p_p;
> > -   if (pr->ps_oppid && (tr = prfind(pr->ps_oppid))) {
> > +   if (pr->ps_oppid != 0 && (pr->ps_oppid != pr->ps_pptr->ps_pid) &&
> > +  (tr = prfind(tr->ps_oppid))) {
> > atomic_clearbits_int(>ps_flags, PS_TRACED);
> > pr->ps_oppid = 0;
> > proc_reparent(pr, tr);
> > 
> 

OK claudio@

-- 
:wq Claudio



fix possible nexthop list corruption in bgpd

2020-01-24 Thread Claudio Jeker
Adam Thompson reported a bgpd crash he sees in 6.6. Using
kern.nosuidcoredump=3 he was able to get me a back trace of the crash.
The RDE chokes on the TAILQ_REMOVE in nexthop_runner() which indicates
that the nexthop_runners list gets corrupted.
After staring at the code for a while I realized that it is possible that
a nexthop is put on the runner list even though there are no objects to
process. In this case if nexthop_unref() is called before the
nexthop_runner() had a chance to run and remove that nexthop the queue
will be corrupt because of a use-after-free of that element.
Fix is simple, check before enqueuing a nexthop on the nexthop_runners
queue that next_prefix is not NULL.

The 2nd hunk just adds a debug log in the case where a prefix removal
actually completes the nexthop run.

OK?
-- 
:wq Claudio

Index: rde_rib.c
===
RCS file: /cvs/src/usr.sbin/bgpd/rde_rib.c,v
retrieving revision 1.214
diff -u -p -r1.214 rde_rib.c
--- rde_rib.c   10 Jan 2020 14:52:57 -  1.214
+++ rde_rib.c   23 Jan 2020 03:59:09 -
@@ -1800,8 +1800,11 @@ nexthop_update(struct kroute_nexthop *ms
nh->nexthop_netlen = msg->netlen;
 
nh->next_prefix = LIST_FIRST(>prefix_h);
-   TAILQ_INSERT_HEAD(_runners, nh, runner_l);
-   log_debug("nexthop %s update starting", log_addr(>exit_nexthop));
+   if (nh->next_prefix != NULL) {
+   TAILQ_INSERT_HEAD(_runners, nh, runner_l);
+   log_debug("nexthop %s update starting",
+   log_addr(>exit_nexthop));
+   }
 }
 
 void
@@ -1860,8 +1863,11 @@ nexthop_unlink(struct prefix *p)
if (p == p->nexthop->next_prefix) {
p->nexthop->next_prefix = LIST_NEXT(p, entry.list.nexthop);
/* remove nexthop from list if no prefixes left to update */
-   if (p->nexthop->next_prefix == NULL)
+   if (p->nexthop->next_prefix == NULL) {
TAILQ_REMOVE(_runners, p->nexthop, runner_l);
+   log_debug("nexthop %s update finished",
+   log_addr(>nexthop->exit_nexthop));
+   }
}
 
p->flags &= ~PREFIX_NEXTHOP_LINKED;



Re: umb(4) WIP diff and questions

2020-01-22 Thread Claudio Jeker
On Thu, Jan 23, 2020 at 10:48:06AM +0900, Lee B wrote:
> On Tue Jan 14, 2020 at 5:59 PM, Claudio Jeker wrote:
> > 
> > Since the credentials should not be passed back to userland I would not
> > add them to struct umb_parameter but instead to struct umb_softc.
> > Then you don't need to use struct umb_parameter for the ioctl and
> > instead
> > could just pass the (utf16) string to the kernel.
> > Apart form that it looks good.
> >
> > 
> 
> OK, the umb_softc part was straightforward enough, thanks. I'd like
> some advice on how to handle the ifconfig(8) changes to accomodate
> this though. I see the wifi code appears to use a separate ioctl pair
> to handle the authentication credentials (WPA/PSK). Is this the right 
> way to go, or have I missed an easier solution?
> 

No that is the best way. Create a new ioctl to set the data. You can
decide if you want to pass the data together ot split in two commands. I
think a single ioctl has benefits for the driver but is more annoying to
handle in ifconfig.

-- 
:wq Claudio



Re: semicolon reduction

2020-01-21 Thread Claudio Jeker
On Wed, Jan 22, 2020 at 01:05:31AM -0500, Ted Unangst wrote:
> don't need semicolon after } in statements.

OK claudio@

> 
> Index: ifconfig/brconfig.c
> ===
> RCS file: /home/cvs/src/sbin/ifconfig/brconfig.c,v
> retrieving revision 1.24
> diff -u -p -r1.24 brconfig.c
> --- ifconfig/brconfig.c   24 Oct 2019 18:54:10 -  1.24
> +++ ifconfig/brconfig.c   22 Jan 2020 06:02:20 -
> @@ -353,7 +353,7 @@ bridge_list(char *delim)
>   if ((1 << (v - 1)) & reqp->ifbr_protected)
>   printf(",%u", v);
>   }
> - };
> + }
>   if (reqp->ifbr_ifsflags & IFBIF_STP)
>   printf(" %s role %s",
>   stpstates[reqp->ifbr_state],
> Index: kbd/kbd_wscons.c
> ===
> RCS file: /home/cvs/src/sbin/kbd/kbd_wscons.c,v
> retrieving revision 1.33
> diff -u -p -r1.33 kbd_wscons.c
> --- kbd/kbd_wscons.c  28 Jun 2019 13:32:44 -  1.33
> +++ kbd/kbd_wscons.c  22 Jan 2020 06:01:26 -
> @@ -198,7 +198,7 @@ kbd_list(void)
>   default:
>   t = SA_MAX;
>   break;
> - };
> + }
>  
>   if (t != SA_MAX) {
>   kbds[t]++;
> Index: mount_nfs/mount_nfs.c
> ===
> RCS file: /home/cvs/src/sbin/mount_nfs/mount_nfs.c,v
> retrieving revision 1.54
> diff -u -p -r1.54 mount_nfs.c
> --- mount_nfs/mount_nfs.c 5 Jan 2018 08:13:31 -   1.54
> +++ mount_nfs/mount_nfs.c 22 Jan 2020 06:02:49 -
> @@ -563,7 +563,7 @@ xdr_fh(XDR *xdrsp, struct nfhret *np)
>   if (!authfnd && (authcnt > 0 || np->auth != RPCAUTH_UNIX))
>   np->stat = EAUTH;
>   return (1);
> - };
> + }
>   return (0);
>  }
>  
> Index: nfsd/nfsd.c
> ===
> RCS file: /home/cvs/src/sbin/nfsd/nfsd.c,v
> retrieving revision 1.39
> diff -u -p -r1.39 nfsd.c
> --- nfsd/nfsd.c   28 Jun 2019 13:32:45 -  1.39
> +++ nfsd/nfsd.c   22 Jan 2020 05:59:42 -
> @@ -135,7 +135,7 @@ main(int argc, char *argv[])
>   break;
>   default:
>   usage();
> - };
> + }
>   argv += optind;
>   argc -= optind;
>  
> 

-- 
:wq Claudio



bgpd max-prefix out limit

2020-01-21 Thread Claudio Jeker
This diff implements 'max-prefix NUM out' which is a simple way to avoid
leaking full tables to upstream or peers. If the limit is triggered the
session will be closed with a NOTIFICATION (kind of suicide for the good
of the Internet).

In bgpctl the counters are visible in the 'bgpctl show nei' output.

Works for me (adopting the maxprefix regress test to test for 'max-prefix
NUM out'.

OK?
-- 
:wq Claudio

Index: bgpctl/bgpctl.c
===
RCS file: /cvs/src/usr.sbin/bgpctl/bgpctl.c,v
retrieving revision 1.257
diff -u -p -r1.257 bgpctl.c
--- bgpctl/bgpctl.c 21 Jan 2020 11:14:26 -  1.257
+++ bgpctl/bgpctl.c 21 Jan 2020 11:17:47 -
@@ -584,6 +584,8 @@ print_neighbor_msgstats(struct peer *p)
p->stats.msg_rcvd_rrefresh);
printf("  Update statistics:\n");
printf("  %-15s %-10s %-10s\n", "", "Sent", "Received");
+   printf("  %-15s %10u %10u\n", "Prefixes",
+   p->stats.prefix_out_cnt, p->stats.prefix_cnt);
printf("  %-15s %10llu %10llu\n", "Updates",
p->stats.prefix_sent_update, p->stats.prefix_rcvd_update);
printf("  %-15s %10llu %10llu\n", "Withdraws",
Index: bgpctl/output.c
===
RCS file: /cvs/src/usr.sbin/bgpctl/output.c,v
retrieving revision 1.4
diff -u -p -r1.4 output.c
--- bgpctl/output.c 21 Jan 2020 11:16:35 -  1.4
+++ bgpctl/output.c 21 Jan 2020 11:56:11 -
@@ -166,8 +166,16 @@ show_neighbor_full(struct peer *p, struc
if (p->conf.max_prefix_restart)
printf(" (restart %u)",
p->conf.max_prefix_restart);
-   printf("\n");
}
+   if (p->conf.max_out_prefix) {
+   printf(" Max-prefix out: %u", p->conf.max_out_prefix);
+   if (p->conf.max_out_prefix_restart)
+   printf(" (restart %u)",
+   p->conf.max_out_prefix_restart);
+   }
+   if (p->conf.max_prefix || p->conf.max_out_prefix)
+   printf("\n");
+
printf("  BGP version 4, remote router-id %s",
inet_ntoa(ina));
printf("%s\n", print_auth_method(p->auth.method));
Index: bgpd/bgpd.conf.5
===
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.conf.5,v
retrieving revision 1.197
diff -u -p -r1.197 bgpd.conf.5
--- bgpd/bgpd.conf.531 Oct 2019 09:09:04 -  1.197
+++ bgpd/bgpd.conf.525 Nov 2019 23:36:08 -
@@ -1057,6 +1057,21 @@ is specified, the session will be restar
 .Ar number
 minutes.
 .Pp
+.Pp
+.It Xo
+.Ic max-prefix Ar number Ic out
+.Op Ic restart Ar number
+.Xc
+Terminate the session when the maximum
+.Ar number
+of prefixes sent is exceeded
+(no such limit is imposed by default).
+If
+.Ic restart
+is specified, the session will be restarted after
+.Ar number
+minutes.
+.Pp
 .It Ic multihop Ar hops
 Neighbors not in the same AS as the local
 .Xr bgpd 8
Index: bgpd/bgpd.h
===
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v
retrieving revision 1.398
diff -u -p -r1.398 bgpd.h
--- bgpd/bgpd.h 21 Jan 2020 11:10:24 -  1.398
+++ bgpd/bgpd.h 21 Jan 2020 11:19:28 -
@@ -379,10 +379,12 @@ struct peer_config {
u_int32_tremote_as;
u_int32_tlocal_as;
u_int32_tmax_prefix;
+   u_int32_tmax_out_prefix;
enum export_type export_type;
enum enforce_as  enforce_as;
enum enforce_as  enforce_local_as;
u_int16_tmax_prefix_restart;
+   u_int16_tmax_out_prefix_restart;
u_int16_tholdtime;
u_int16_tmin_holdtime;
u_int16_tlocal_short_as;
Index: bgpd/parse.y
===
RCS file: /cvs/src/usr.sbin/bgpd/parse.y,v
retrieving revision 1.402
diff -u -p -r1.402 parse.y
--- bgpd/parse.y27 Sep 2019 10:26:32 -  1.402
+++ bgpd/parse.y30 Sep 2019 11:59:44 -
@@ -1391,6 +1391,14 @@ peeropts : REMOTEAS as4number{
curpeer->conf.max_prefix = $2;
curpeer->conf.max_prefix_restart = $3;
}
+   | MAXPREFIX NUMBER OUT restart {
+   if ($2 < 0 || $2 > UINT_MAX) {
+   yyerror("bad maximum number of prefixes");
+   YYERROR;
+   }
+   curpeer->conf.max_out_prefix = $2;
+   curpeer->conf.max_out_prefix_restart = $4;
+   }
| TCP MD5SIG PASSWORD string {
if (curpeer->conf.auth.method) {
yyerror("auth method cannot be 

Re: ospf6d: simplify lsa_snap()

2020-01-21 Thread Claudio Jeker
On Tue, Jan 21, 2020 at 03:58:58PM +0100, Remi Locherer wrote:
> On Tue, Jan 21, 2020 at 01:09:30PM +0100, Denis Fondras wrote:
> > On Tue, Jan 21, 2020 at 09:35:06AM +0100, Remi Locherer wrote:
> > > > @@ -235,6 +233,7 @@ lsa_check(struct rde_nbr *nbr, struct ls
> > > > case LSA_TYPE_NETWORK:
> > > > if ((len % sizeof(u_int32_t)) ||
> > > > len < sizeof(lsa->hdr) + sizeof(u_int32_t)) {
> > > > +   log_warnx("lsa_check: bad LSA network packet");
> > > 
> > > please use __func__
> > > 
> > 
> > None use __func__ currently.
> > 
> 
> Right, it's not often used in ospf6d.
> 
> I think we should use it more in such cases.
> 
> But you have my OK with or without that.
> 

I think the log_warnx should use __func__ less and instead use better
messages that an operator can understand without having to check the code.
As a developer 'lsa_check: bad LSA network packet' sounds great since I
can find the code but as an operator 'dropped LSA network packet with bad
size from neighbor XY' would be more effective. I'm probably the source of
most of those messages that's why I think they could be better :)
But changing those can happen some other time.

-- 
:wq Claudio



bgpctl show neighbor errors better

2020-01-21 Thread Claudio Jeker
So the 'Last error:' message for sessions that failed do often not include
the suberror and also it is only shown for NOTIFICATIONS we sent but not
for received notifications. The following diff fixes this.

So instead of:
  Last error: Cease
or
  Last error: unknown error code

I now get:
  Last error sent: Cease, recieved max-prefix exceeded
or
  Last error received: Cease, recieved max-prefix exceeded

-- 
:wq Claudio

Index: bgpctl/bgpctl.c
===
RCS file: /cvs/src/usr.sbin/bgpctl/bgpctl.c,v
retrieving revision 1.256
diff -u -p -r1.256 bgpctl.c
--- bgpctl/bgpctl.c 9 Jan 2020 11:57:04 -   1.256
+++ bgpctl/bgpctl.c 21 Jan 2020 08:18:59 -
@@ -1300,36 +1300,68 @@ send_filterset(struct imsgbuf *i, struct
 const char *
 get_errstr(u_int8_t errcode, u_int8_t subcode)
 {
-   static const char   *errstr = NULL;
+   static char  errbuf[256];
+   const char  *errstr = NULL;
+   const char  *suberr = NULL;
+   int  uk = 0;
 
-   if (errcode && errcode < sizeof(errnames)/sizeof(char *))
+   if (errcode == 0)   /* no error */
+   return NULL;
+
+   if (errcode < sizeof(errnames)/sizeof(char *))
errstr = errnames[errcode];
 
switch (errcode) {
case ERR_HEADER:
-   if (subcode &&
-   subcode < sizeof(suberr_header_names)/sizeof(char *))
-   errstr = suberr_header_names[subcode];
+   if (subcode < sizeof(suberr_header_names)/sizeof(char *))
+   suberr = suberr_header_names[subcode];
+   else
+   uk = 1;
break;
case ERR_OPEN:
-   if (subcode &&
-   subcode < sizeof(suberr_open_names)/sizeof(char *))
-   errstr = suberr_open_names[subcode];
+   if (subcode < sizeof(suberr_open_names)/sizeof(char *))
+   suberr = suberr_open_names[subcode];
+   else
+   uk = 1;
break;
case ERR_UPDATE:
-   if (subcode &&
-   subcode < sizeof(suberr_update_names)/sizeof(char *))
-   errstr = suberr_update_names[subcode];
+   if (subcode < sizeof(suberr_update_names)/sizeof(char *))
+   suberr = suberr_update_names[subcode];
+   else
+   uk = 1;
break;
case ERR_HOLDTIMEREXPIRED:
+   if (subcode != 0)
+   uk = 1;
+   break;
case ERR_FSM:
+   if (subcode < sizeof(suberr_fsm_names)/sizeof(char *))
+   suberr = suberr_fsm_names[subcode];
+   else
+   uk = 1;
+   break;
case ERR_CEASE:
+   if (subcode < sizeof(suberr_cease_names)/sizeof(char *))
+   suberr = suberr_cease_names[subcode];
+   else
+   uk = 1;
break;
default:
-   return ("unknown error code");
+   snprintf(errbuf, sizeof(errbuf),
+   "unknown error code %u subcode %u", errcode, subcode);
+   return (errbuf);
}
 
-   return (errstr);
+   if (uk)
+   snprintf(errbuf, sizeof(errbuf),
+   "%s, unknown subcode %u", errstr, subcode);
+   else if (suberr == NULL)
+   return (errstr);
+   else
+   snprintf(errbuf, sizeof(errbuf),
+   "%s, %s", errstr, suberr);
+
+   return (errbuf);
 }
 
 void
Index: bgpctl/output.c
===
RCS file: /cvs/src/usr.sbin/bgpctl/output.c,v
retrieving revision 1.3
diff -u -p -r1.3 output.c
--- bgpctl/output.c 9 Jan 2020 11:57:04 -   1.3
+++ bgpctl/output.c 21 Jan 2020 08:18:59 -
@@ -221,12 +221,16 @@ show_neighbor_full(struct peer *p, struc
log_shutcomm(p->stats.last_shutcomm));
}
if (p->state == STATE_IDLE) {
-   static const char   *errstr;
+   const char *errstr;
 
errstr = get_errstr(p->stats.last_sent_errcode,
p->stats.last_sent_suberr);
if (errstr)
-   printf("  Last error: %s\n\n", errstr);
+   printf("  Last error sent: %s\n\n", errstr);
+   errstr = get_errstr(p->stats.last_rcvd_errcode,
+   p->stats.last_rcvd_suberr);
+   if (errstr)
+   printf("  Last error received: %s\n\n", errstr);
} else {
printf("  Local host:  %20s, Local port:  %5u\n",
log_addr(>local), p->local_port);
Index: bgpd/bgpd.h
===
RCS 

Re: bgpd, remove getifaddrs call in RDE

2020-01-20 Thread Claudio Jeker
On Thu, Jan 09, 2020 at 02:45:46PM +0100, Claudio Jeker wrote:
> The RDE needs to know the local v4 and v6 address of a session so that
> nexthop self works. Until now the lookup for the other AF address was done
> in the RDE when the session got established. This diff moves this code
> over to the SE where it fits better. Especially this allows to remove the
> route pledge from the RDE.
> 
> This diff works for me but I would like more tests especially on link
> local IPv6 sessions (the KAME embedded scope curse haunts me again).

ping...

-- 
:wq Claudio

? obj
Index: bgpd.h
===
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v
retrieving revision 1.397
diff -u -p -r1.397 bgpd.h
--- bgpd.h  9 Jan 2020 11:55:25 -   1.397
+++ bgpd.h  9 Jan 2020 13:37:19 -
@@ -656,7 +656,8 @@ struct kif {
 };
 
 struct session_up {
-   struct bgpd_addrlocal_addr;
+   struct bgpd_addrlocal_v4_addr;
+   struct bgpd_addrlocal_v6_addr;
struct bgpd_addrremote_addr;
struct capabilities capa;
u_int32_t   remote_bgpid;
Index: rde.c
===
RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
retrieving revision 1.498
diff -u -p -r1.498 rde.c
--- rde.c   9 Jan 2020 13:31:52 -   1.498
+++ rde.c   9 Jan 2020 13:37:19 -
@@ -177,7 +177,7 @@ rde_main(int debug, int verbose)
setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
fatal("can't drop privileges");
 
-   if (pledge("stdio route recvfd", NULL) == -1)
+   if (pledge("stdio recvfd", NULL) == -1)
fatal("pledge");
 
signal(SIGTERM, rde_sighdlr);
Index: rde_peer.c
===
RCS file: /cvs/src/usr.sbin/bgpd/rde_peer.c,v
retrieving revision 1.2
diff -u -p -r1.2 rde_peer.c
--- rde_peer.c  9 Jan 2020 13:31:52 -   1.2
+++ rde_peer.c  9 Jan 2020 13:37:19 -
@@ -17,9 +17,7 @@
  */
 #include 
 #include 
-#include 
 
-#include 
 #include 
 #include 
 #include 
@@ -306,102 +304,6 @@ rde_up_dump_done(void *ptr, u_int8_t aid
fatal("%s: prefix_dump_new", __func__);
 }
 
-static int
-sa_cmp(struct bgpd_addr *a, struct sockaddr *b)
-{
-   struct sockaddr_in  *in_b;
-   struct sockaddr_in6 *in6_b;
-
-   if (aid2af(a->aid) != b->sa_family)
-   return (1);
-
-   switch (b->sa_family) {
-   case AF_INET:
-   in_b = (struct sockaddr_in *)b;
-   if (a->v4.s_addr != in_b->sin_addr.s_addr)
-   return (1);
-   break;
-   case AF_INET6:
-   in6_b = (struct sockaddr_in6 *)b;
-#ifdef __KAME__
-   /* directly stolen from sbin/ifconfig/ifconfig.c */
-   if (IN6_IS_ADDR_LINKLOCAL(_b->sin6_addr)) {
-   in6_b->sin6_scope_id =
-   ntohs(*(u_int16_t *)_b->sin6_addr.s6_addr[2]);
-   in6_b->sin6_addr.s6_addr[2] =
-   in6_b->sin6_addr.s6_addr[3] = 0;
-   }
-#endif
-   if (bcmp(>v6, _b->sin6_addr,
-   sizeof(struct in6_addr)))
-   return (1);
-   break;
-   default:
-   fatal("king bula sez: unknown address family");
-   /* NOTREACHED */
-   }
-
-   return (0);
-}
-
-/*
- * Figure out the local IP addresses most suitable for this session.
- * This looks up the local address of other address family based on
- * the address of the TCP session.
- */
-static int
-peer_localaddrs(struct rde_peer *peer, struct bgpd_addr *laddr)
-{
-   struct ifaddrs  *ifap, *ifa, *match;
-
-   if (getifaddrs() == -1)
-   fatal("getifaddrs");
-
-   for (match = ifap; match != NULL; match = match->ifa_next)
-   if (sa_cmp(laddr, match->ifa_addr) == 0)
-   break;
-
-   if (match == NULL) {
-   log_warnx("peer_localaddrs: local address not found");
-   return (-1);
-   }
-
-   for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
-   if (ifa->ifa_addr->sa_family == AF_INET &&
-   strcmp(ifa->ifa_name, match->ifa_name) == 0) {
-   if (ifa->ifa_addr->sa_family ==
-   match->ifa_addr->sa_family)
-   ifa = match;
-   sa2addr(ifa->ifa_addr, >local_v4_addr, NULL);
-   break;
-   }
-   }
-   for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
-   if (ifa->ifa_addr->sa_family == AF_INET6 &&am

Re: piixpm(4) on ATI SBx00

2020-01-20 Thread Claudio Jeker
On Tue, Jan 07, 2020 at 12:44:59PM +0100, Claudio Jeker wrote:
> On Tue, Jan 07, 2020 at 09:27:50AM +0100, Claudio Jeker wrote:
> > In -current I added support for the additional I2C busses on piixpm(4)
> > now I noticed that on my old AMD system the I2C bus seems to either
> > connect all those 4 busses together (or there is a bug in the driver).
> 
> Looks like this is indeed a problem with the driver.
> 
> With the following diff I now get:
> piixpm0 at pci0 dev 20 function 0 "ATI SBx00 SMBus" rev 0x41: polling
> iic0 at piixpm0
> sdtemp0 at iic0 addr 0x18: stts2002
> sdtemp1 at iic0 addr 0x19: stts2002
> sdtemp2 at iic0 addr 0x1a: stts2002
> sdtemp3 at iic0 addr 0x1b: stts2002
> spdmem0 at iic0 addr 0x50: 4GB DDR3 SDRAM ECC PC3-10600 with thermal sensor
> spdmem1 at iic0 addr 0x51: 4GB DDR3 SDRAM ECC PC3-10600 with thermal sensor
> spdmem2 at iic0 addr 0x52: 4GB DDR3 SDRAM ECC PC3-10600 with thermal sensor
> spdmem3 at iic0 addr 0x53: 4GB DDR3 SDRAM ECC PC3-10600 with thermal sensor
> iic1 at piixpm0   
>   piixpm0: exec: op 1, addr 0x18, cmdlen 1, len 0, flags 0x08: timeout, 
> status 0x1
> 
> iic2 at piixpm0
> iic3 at piixpm0
> 
> Not sure what is up with the timeout on iic @ addr 0x18. If that is seen
> on more systems it may be better to only use the primary bus on SB800
> devices that don't support SB800_PMREG_SMB0SEL.
> 
> Please test and report back.

Picking this up again. Since the second bus causes read timeouts and the
docu mentions that this bus is used for fan and temp control I think it is
better to just not attach the extra busses on these old AMD chipsets.
The additional SB800 busses will only be used if SB800_PMREG_SMB0SELEN
tells us that SMB0SELEN is enabled.

While looking at this I also investigated a bit more into the
PCI_PRODUCT_AMD_HUDSON2_SMB issues. So PCI ID 1022:780b are used by AMD
Bolton and Family 16h model 30h-3fh. AMD Bolton still needs the old layout
while the family 16h chips use the FCH register layout. So merge the if
statements a bit so that AMD Bolton uses the old code path and Family 16h
uses the new. 

Last but not least I was informed that we reversed the meaning of
SB800_SMB_HOSTC_SMI (if SB800_SMB_HOSTC bit 1 is set then use IRQ else
SMI). This is visible in the dmesg line of piixpm.

Please test this since I can't test this properly at the moment.
Works for me on
piixpm0 at pci0 dev 20 function 0 "AMD FCH SMBus" rev 0x61: SMI 

-- 
:wq Claudio

Index: piixpm.c
===
RCS file: /cvs/src/sys/dev/pci/piixpm.c,v
retrieving revision 1.41
diff -u -p -r1.41 piixpm.c
--- piixpm.c9 Jan 2020 14:35:19 -   1.41
+++ piixpm.c21 Jan 2020 01:23:21 -
@@ -158,8 +158,13 @@ piixpm_attach(struct device *parent, str
return;
}
 
+   /*
+* AMD Bolton matches PCI_PRODUCT_AMD_HUDSON2_SMB but
+* uses old register layout. Therefor check PCI_REVISION.
+*/
if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_AMD &&
-   (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_AMD_HUDSON2_SMB ||
+   ((PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_AMD_HUDSON2_SMB &&
+   PCI_REVISION(pa->pa_class) >= 0x1f) ||
PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_AMD_KERNCZ_SMB)) {
bus_space_write_1(sc->sc_iot, ioh, 0,
AMDFCH41_PM_DECODE_EN);
@@ -170,6 +175,9 @@ piixpm_attach(struct device *parent, str
AMDFCH41_PM_DECODE_EN + 1);
val = bus_space_read_1(sc->sc_iot, ioh, 1) << 8;
base = val;
+
+   sc->sc_is_fch = 1;
+   numbusses = 2;
} else {
/* Read "SmBus0En" */
bus_space_write_1(sc->sc_iot, ioh, 0,
@@ -181,6 +189,14 @@ piixpm_attach(struct device *parent, str
val |= (bus_space_read_1(sc->sc_iot, ioh, 1) << 8);
smb0en = val & SB800_SMB0EN_EN;
base = val & SB800_SMB0EN_BASE_MASK;
+
+   bus_space_write_1(sc->sc_iot, ioh, 0,
+   SB800_PMREG_SMB0SELEN);
+   val = bus_space_read_1(sc->sc_iot, ioh, 1);
+   if (val & SB800_SMB0SELEN_EN) {
+   sc->sc_is_sb800 = 1;
+   numbusses = 4;
+   }
}
 
if (smb0en == 0) {
@@ -190,17 +206,6 @@ piixpm_attach(struct device *parent, str
}
 
sc->sc_sb80

Re: carp: send only IPv4 carp packets on dual stack interface

2020-01-18 Thread Claudio Jeker
On Sat, Jan 18, 2020 at 01:45:18PM +, Stuart Henderson wrote:
> On 2020/01/18 06:18, chr...@openbsd.org wrote:
> > Anyway, my main concern indeed is the broadcast noise generated by carp and
> > I would be equally happy if we had a ``carppeer6`` option. Would that be
> > considered?
> 
> Adding carppeer6 seems a better/safer approach.
> 

Is there a need to add a new command for this or could carppeer be exended
to support AF_INET6? In general it is better if there are less IPv6
specific commands.

-- 
:wq Claudio



Re: umb(4) WIP diff and questions

2020-01-14 Thread Claudio Jeker
On Tue, Jan 14, 2020 at 02:40:45PM +0100, Stefan Sperling wrote:
> On Tue, Jan 14, 2020 at 09:51:05PM +0900, leeb wrote:
> > Hello again tech@
> > 
> > I've included diffs of what I've got so far at the bottom 
> > of this mail, but first a couple of questions:
> > 
> > - Using the full 510-character limits for username and
> > passphrase specified in the MBIM spec, kernel compilation 
> > fails due to tripping the 2047-byte stack frame warning
> > when compiling the driver. That's the reason for the '100'
> > magic numbers that I put in there temporarily.
> > 
> > Any hints on the best way to handle this would be appreciated. 
> 
> I would allocate mp dynamically instead of storing it on the stack.
> 
> In umb_ioctl(), you could change mp to a pointer type:
> 
>   struct umb_parameter *mp;
> 
> The ioctl is allowed to sleep until memory is available (M_WAITOK), so
> this allocation cannot fail and you don't need to check for NULL:
> 
>   mp = malloc(sizeof(*mp), M_DEVBUF, M_ZERO | M_WAITOK);
> 
> free mp before umb_ioctl returns:
> 
>   free(mp, M_DEVBUF, sizeof(*mp));
> 
> See 'man 9 malloc' for details.
> 
> > - I included the username/passphrase fields in the ifconfig
> > output, as it seems to me that APN settings are generally
> > made public so end-users can configure their own devices
> > If needed I'll take it out, or perhaps change it to display 
> > '*set*' (or similar) if you think it should be hidden?
> 
> Genrally, the kernel should not return credentials to userland.
> So these shouldn't just be hidden or obscured in ifconfig. Rather,
> umb_ioctl should not copy such data out to any userland program.
> 
> This rule also applies to wifi and carp interfaces, for instance.
>  
> > A couple of other points:
> > 
> > - Wireless providers where I am all seem to require a
> > username/password with the APN. So I'm unable to confirm
> > whether or not this breaks non-authenticated connections.
> > 
> > - I've been building my kernel using the documented 
> > procedure, and have no problems there. I ran through a
> > base system build and that (eventually) completed OK too.
> > When compiling ifconfig(8), I've been doing 'make includes'
> > in /usr/src (after installing and booting my new kernel), 
> > and using 'make ifconfig' and 'make install' in 
> > /usr/src/sbin/ifconfig. Is this OK? or should I be doing 
> > something else instead?
> 
> You should verify that 'make release' works after having completed a full
> system build. The ramdisks use a special build of ifconfig so a check that
> this still compiles is required. See 'man release' for details.
> 

Since the credentials should not be passed back to userland I would not
add them to struct umb_parameter but instead to struct umb_softc.
Then you don't need to use struct umb_parameter for the ioctl and instead
could just pass the (utf16) string to the kernel.
Apart form that it looks good.

-- 
:wq Claudio



Re: ospf(6)d.conf: define interface parameters per area or globally

2020-01-12 Thread Claudio Jeker
On Sun, Jan 12, 2020 at 03:46:15PM +0100, Remi Locherer wrote:
> On Wed, Jan 08, 2020 at 01:13:45PM +0100, Denis Fondras wrote:
> > On Wed, Jan 08, 2020 at 09:14:48AM +0100, Remi Locherer wrote:
> > > > I have a diff to allow parameters after interface or area definition.
> > > > Not sure if we want to do that though.
> > > 
> > > I would appreciate that! ;-)
> > > 
> > 
> > The ospfd diff needs some more work. Crypt authentication handling is not
> > perfect.
> 
> This works fine for me and the diff reads good. I tested ospfd and ospf6d.
> Also the crypt options for ospfd worked fine.
> 
> ok remi@

Currently all daemons behave the same way and inherit at the moment of
creation. Having this behave different between daemons is confusing.
At least ospfd and bgpd should behave the same. Not saying that the
current behaviour is great.
I think in the case of ospfd the way auth-md is handled by this diff is
not comparable with the behaviour of the other settings.

area 0.0.0.0 {
hello-interval 10
auth-md 1 foo

interface em0

hello-interval 20
auth-md 1 bar
auth-md 2 foofoo

interface em1 {
auth-md 3 barbar
}

hello-interval 30
auth-md 1 bay
auth-md 2 foobar
}

What values for hello-interval and auth-md should be set on em0 and em1?
 
> > 
> > Index: ospf6d/ospf6d.h
> > ===
> > RCS file: /cvs/src/usr.sbin/ospf6d/ospf6d.h,v
> > retrieving revision 1.44
> > diff -u -p -r1.44 ospf6d.h
> > --- ospf6d/ospf6d.h 3 Jan 2020 17:45:02 -   1.44
> > +++ ospf6d/ospf6d.h 8 Jan 2020 12:11:20 -
> > @@ -328,7 +328,7 @@ struct iface {
> > enum iface_type  type;
> > u_int8_t if_type;
> > u_int8_t linkstate;
> > -   u_int8_t priority;
> > +   int16_t  priority;
> > u_int8_t p2p;
> > u_int8_t cflags;
> >  #define F_IFACE_PASSIVE0x01
> > Index: ospf6d/parse.y
> > ===
> > RCS file: /cvs/src/usr.sbin/ospf6d/parse.y,v
> > retrieving revision 1.48
> > diff -u -p -r1.48 parse.y
> > --- ospf6d/parse.y  26 Dec 2019 10:24:18 -  1.48
> > +++ ospf6d/parse.y  8 Jan 2020 12:11:20 -
> > @@ -101,7 +101,7 @@ struct config_defaults {
> > u_int16_t   hello_interval;
> > u_int16_t   rxmt_interval;
> > u_int16_t   metric;
> > -   u_int8_tpriority;
> > +   int16_t priority;
> >  };
> >  
> >  struct config_defaults  globaldefs;
> > @@ -111,6 +111,7 @@ struct config_defaults  *defs;
> >  
> >  struct area*conf_get_area(struct in_addr);
> >  int conf_check_rdomain(u_int);
> > +voidiface_settings(struct iface *, struct config_defaults 
> > *);
> >  
> >  typedef struct {
> > union {
> > @@ -465,9 +466,14 @@ comma  : ','
> >  area   : AREA areaid {
> > area = conf_get_area($2);
> >  
> > -   memcpy(, defs, sizeof(areadefs));
> > +   memset(, 0, sizeof(areadefs));
> > +   areadefs.priority = -1;
> > defs = 
> > } '{' optnl areaopts_l '}' {
> > +   struct iface*i;
> > +   LIST_FOREACH(i, >iface_list, entry) {
> > +   iface_settings(i, );
> > +   }
> > area = NULL;
> > defs = 
> > }
> > @@ -540,15 +546,12 @@ interface : INTERFACE STRING  {
> > iface->area = area;
> > LIST_INSERT_HEAD(>iface_list, iface, entry);
> >  
> > -   memcpy(, defs, sizeof(ifacedefs));
> > +   memset(, 0, sizeof(ifacedefs));
> > +   ifacedefs.priority = -1;
> > defs = 
> > } interface_block {
> > -   iface->dead_interval = defs->dead_interval;
> > -   iface->transmit_delay = defs->transmit_delay;
> > -   iface->hello_interval = defs->hello_interval;
> > -   iface->rxmt_interval = defs->rxmt_interval;
> > -   iface->metric = defs->metric;
> > -   iface->priority = defs->priority;
> > +   iface->priority = -1;
> > +   iface_settings(iface, defs);
> > iface->cflags |= F_IFACE_CONFIGURED;
> > iface = NULL;
> > /* interface is always part of an area */
> > @@ -1018,6 +1021,8 @@ popfile(void)
> >  struct ospfd_conf *
> >  parse_config(char *filename, int opts)
> >  {
> > +   struct area *a;
> > +   struct iface*i;
> > struct sym  *sym, *next;
> >  
> > if ((conf = calloc(1, sizeof(struct ospfd_conf))) == NULL)
> > @@ -1068,6 +1073,10 @@ 

Re: dwiic(4) improvements

2020-01-11 Thread Claudio Jeker
On Sat, Jan 11, 2020 at 12:46:17PM +0100, Mark Kettenis wrote:
> > Date: Fri, 10 Jan 2020 12:07:51 +0100
> > From: Claudio Jeker 
> > 
> > On Sun, Dec 22, 2019 at 04:55:59PM +0100, Mark Kettenis wrote:
> > > The diff below contains a couple of improvements to dwiic(4).  They're
> > > mostly for making ipmi(4) on the Ampere/Lenovo arm64 boxes work
> > > better.  But they need testing on x86 machines with
> > > keyboards.touchpads/touchscreens connected over i2c.
> > > 
> > > Most of the diff is there to properly implement SMBus block write/read
> > > transactions.  Defines for these are taken from NetBSD (even though
> > > NetBSD doesn't actually implement these).  Nothing special needs to
> > > been done for block writes, but for block reads the slave device sends
> > > us byte count before sending us the data bytes.  So the code is
> > > changed such that we read the byte count first and then adjust the
> > > length of the transaction accordingly.
> > > 
> > > The diff then uses this support for block reads in the ipmi(4) SSIF
> > > interface code and adds support for multi-part read transactions on
> > > top of that.  That makes ipmi(4) fully functional on the arm64 machine
> > > mentioned above.
> > > 
> > > Well, almost.  I found that dwiic(4) still craps out every now and
> > > then on this machine.  Limiting the number of commands we send to the
> > > controller to the size of the Tx FIFO minus one seems to help.
> > > 
> > > Will probably split up the diff before committing.
> > > 
> > > ok?
> > > 
> > > 
> > > Index: dev/ic/dwiic.c
> > > ===
> > > RCS file: /cvs/src/sys/dev/ic/dwiic.c,v
> > > retrieving revision 1.8
> > > diff -u -p -r1.8 dwiic.c
> > > --- dev/ic/dwiic.c18 Aug 2019 15:52:45 -  1.8
> > > +++ dev/ic/dwiic.c22 Dec 2019 15:40:28 -
> > > @@ -338,6 +338,13 @@ dwiic_i2c_exec(void *cookie, i2c_op_t op
> > >  
> > >   dwiic_write(sc, DW_IC_DATA_CMD, cmd);
> > >  
> > > + /*
> > > +  * For a block read, get the byte count before
> > > +  * continuing to read the data bytes.
> > > +  */
> > > + if (I2C_OP_READ_P(op) && I2C_OP_BLKMODE_P(op) && readpos == 0)
> > > + tx_limit = 1;
> > > +
> > >   tx_limit--;
> > >   x++;
> > >  
> > > @@ -345,7 +352,7 @@ dwiic_i2c_exec(void *cookie, i2c_op_t op
> > >* As TXFLR fills up, we need to clear it out by reading all
> > >* available data.
> > >*/
> > > - while (I2C_OP_READ_P(op) && (tx_limit == 0 || x == len)) {
> > > + while (I2C_OP_READ_P(op) && (tx_limit <= 1 || x == len)) {
> > >   DPRINTF(("%s: %s: tx_limit %d, sent %d read reqs\n",
> > >   sc->sc_dev.dv_xname, __func__, tx_limit, x));
> > >  
> > 
> > I'm a bit confused with the previous two hunks. Why change the tx_limit
> > check? Also you set tx_limit to 1 and then immediatly a tx_limit-- follows
> > so that the limit is actually 0 which is what you want but then the change
> > of the check in the while loop seems wrong.
> 
> Ok, let's separate things out a bit more.  Here is the diff that just
> implements block mode.  There the limit is initially set to 1 to make
> sure we have a chance to look at the first byte to determine the total
> length of the transfer.
> 
> ok?
> 

Sure, that is OK claudio@

> 
> Index: dev/ic/dwiic.c
> ===
> RCS file: /cvs/src/sys/dev/ic/dwiic.c,v
> retrieving revision 1.8
> diff -u -p -r1.8 dwiic.c
> --- dev/ic/dwiic.c18 Aug 2019 15:52:45 -  1.8
> +++ dev/ic/dwiic.c11 Jan 2020 11:37:53 -
> @@ -338,6 +338,13 @@ dwiic_i2c_exec(void *cookie, i2c_op_t op
>  
>   dwiic_write(sc, DW_IC_DATA_CMD, cmd);
>  
> + /*
> +  * For a block read, get the byte count before
> +  * continuing to read the data bytes.
> +  */
> + if (I2C_OP_READ_P(op) && I2C_OP_BLKMODE_P(op) && readpos == 0)
> + tx_limit = 1;
> +
>   tx_limit--;
>   x++;
>  
> @@ -374,8 +381,7 @@ dwiic_i2c_exec(void *cookie, i2c_op_t op
>  
>

  1   2   3   4   5   6   7   8   9   10   >