Re: make art independent of struct sockaddr

2017-01-19 Thread Claudio Jeker
On Fri, Jan 20, 2017 at 01:26:11PM +1000, Martin Pieuchot wrote:
> On 20/01/17(Fri) 03:04, Claudio Jeker wrote:
> > I want to use art routing tables with pf addrs and not sockaddrs.
> > Art itself does not care but the API requires sockaddr pointers in some
> > places. This changes those to void *.
> > 
> > OK? This is step 2 to a new pf_table backend.
> 
> What's the problem with uint8_t?  If possible I'd prefer keeping that
> type since it's clear that we're dealing with bytes.

IIRC I did it to reduce the amount of casts needed. You can pass the
address of a struct in_addr or similar this way without having to cast.
 
> I also think that ``an_dst'' is no longer used and can die.  The value
> attached to an art_node is now ``an_rtlist''.  This might be renamed and
> we could use a "void *" since you're not going to use list for pf.
> 
> That means we could fold ``an_rtlist'' in the union and reduce the size
> of 'struct art_node'.
> 
art_get() still sets it unconditionally. I have nothing against olding
an_rtlist in but think we should make sure that you can use art without
multipath...

-- 
:wq Claudio



unify log.c in daemons [ypldap]

2017-01-19 Thread Sebastian Benoit
work on making log.c similar in all daemons:

reduce the (mostly whitespace) differences so that log.c's can be
diffed easily. disclaimer change ok henning@.


diff --git usr.sbin/ypldap/ldapclient.c usr.sbin/ypldap/ldapclient.c
index 02cd4616acf..3a8fb90d33e 100644
--- usr.sbin/ypldap/ldapclient.c
+++ usr.sbin/ypldap/ldapclient.c
@@ -39,6 +39,7 @@
 #include 
 
 #include "aldap.h"
+#include "log.h"
 #include "ypldap.h"
 
 voidclient_sig_handler(int, short, void *);
@@ -383,6 +384,7 @@ ldapclient(int pipe_main2client[2])
 #endif
setproctitle("ldap client");
ypldap_process = PROC_CLIENT;
+   log_procname = log_procnames[ypldap_process];
 
 #ifndef DEBUG
if (setgroups(1, >pw_gid) ||
diff --git usr.sbin/ypldap/log.c usr.sbin/ypldap/log.c
index ce60ae1f8ec..d3a5ba20727 100644
--- usr.sbin/ypldap/log.c
+++ usr.sbin/ypldap/log.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: log.c,v 1.2 2015/11/17 02:16:52 deraadt Exp $ */
+/* $OpenBSD: log.c,v 1.9 2016/09/02 14:02:48 benno Exp $ */
 
 /*
  * Copyright (c) 2003, 2004 Henning Brauer 
@@ -11,13 +11,11 @@
  * 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 MIND, 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.
+ * 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 
@@ -25,19 +23,13 @@
 #include 
 #include 
 #include 
+#include 
 
-voidlog_init(int);
-voidlog_warn(const char *, ...);
-voidlog_warnx(const char *, ...);
-voidlog_info(const char *, ...);
-voidlog_debug(const char *, ...);
-__dead void fatal(const char *);
-__dead void fatalx(const char *);
-
-int debug;
+#include "log.h"
 
-voidvlog(int, const char *, va_list);
-voidlogit(int, const char *, ...);
+int debug;
+int verbose;
+const char *log_procname;
 
 void
 log_init(int n_debug)
@@ -53,6 +45,12 @@ log_init(int n_debug)
 }
 
 void
+log_verbose(int v)
+{
+   verbose = v;
+}
+
+void
 logit(int pri, const char *fmt, ...)
 {
va_list ap;
@@ -81,7 +79,6 @@ vlog(int pri, const char *fmt, va_list ap)
vsyslog(pri, fmt, ap);
 }
 
-
 void
 log_warn(const char *emsg, ...)
 {
@@ -131,7 +128,7 @@ log_debug(const char *emsg, ...)
 {
va_list  ap;
 
-   if (debug > 1) {
+   if (verbose) {
va_start(ap, emsg);
vlog(LOG_DEBUG, emsg, ap);
va_end(ap);
@@ -142,13 +139,15 @@ void
 fatal(const char *emsg)
 {
if (emsg == NULL)
-   logit(LOG_CRIT, "fatal: %s", strerror(errno));
+   logit(LOG_CRIT, "fatal in %s: %s", log_procname,
+   strerror(errno));
else
if (errno)
-   logit(LOG_CRIT, "fatal: %s: %s",
-   emsg, strerror(errno));
+   logit(LOG_CRIT, "fatal in %s: %s: %s",
+   log_procname, emsg, strerror(errno));
else
-   logit(LOG_CRIT, "fatal: %s", emsg);
+   logit(LOG_CRIT, "fatal in %s: %s",
+   log_procname, emsg);
 
exit(1);
 }
diff --git usr.sbin/ypldap/log.h usr.sbin/ypldap/log.h
new file mode 100644
index 000..56f7b9246ac
--- /dev/null
+++ usr.sbin/ypldap/log.h
@@ -0,0 +1,45 @@
+/* $OpenBSD: log.h,v 1.8 2016/09/02 14:02:48 benno Exp $ */
+
+/*
+ * Copyright (c) 2003, 2004 Henning Brauer 
+ *
+ * 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.
+ */
+
+#ifndef LOG_H
+#define LOG_H
+
+#include 
+
+extern const char  *log_procname;
+
+voidlog_init(int);
+voidlog_verbose(int);
+voidlogit(int, const char *, ...)
+   __attribute__((__format__ (printf, 2, 3)));
+void

unify log.c in daemons [ldpd]

2017-01-19 Thread Sebastian Benoit
work on making log.c similar in all daemons:

move daemon-local functions into new logmsg.c, and reduce
the (mostly whitespace) differences so that log.c's can be diffed easily.

removal of log_rtmsg() approved by claudio@

diff --git usr.sbin/ldpctl/Makefile usr.sbin/ldpctl/Makefile
index 9e915a9bef1..b205e20d329 100644
--- usr.sbin/ldpctl/Makefile
+++ usr.sbin/ldpctl/Makefile
@@ -3,7 +3,7 @@
 .PATH: ${.CURDIR}/../ldpd
 
 PROG=  ldpctl
-SRCS=  util.c log.c ldpctl.c parser.c
+SRCS=  util.c log.c logmsg.c ldpctl.c parser.c
 CFLAGS+= -Wall
 CFLAGS+= -Wstrict-prototypes -Wmissing-prototypes
 CFLAGS+= -Wmissing-declarations
diff --git usr.sbin/ldpd/Makefile usr.sbin/ldpd/Makefile
index 2e0c948de3e..6cc3674c5ce 100644
--- usr.sbin/ldpd/Makefile
+++ usr.sbin/ldpd/Makefile
@@ -3,8 +3,8 @@
 PROG=  ldpd
 SRCS=  accept.c address.c adjacency.c control.c hello.c init.c interface.c \
keepalive.c kroute.c l2vpn.c labelmapping.c lde.c lde_lib.c ldpd.c \
-   ldpe.c log.c neighbor.c notification.c packet.c parse.y pfkey.c \
-   printconf.c socket.c util.c
+   ldpe.c log.c logmsg.c neighbor.c notification.c packet.c parse.y \
+   pfkey.c printconf.c socket.c util.c
 
 MAN=   ldpd.8 ldpd.conf.5
 
diff --git usr.sbin/ldpd/kroute.c usr.sbin/ldpd/kroute.c
index 260eddc651b..f9cee6548a0 100644
--- usr.sbin/ldpd/kroute.c
+++ usr.sbin/ldpd/kroute.c
@@ -1414,7 +1414,6 @@ rtmsg_process(char *buf, size_t len)
fatalx("rtmsg_process: partial rtm in buffer");
if (rtm->rtm_version != RTM_VERSION)
continue;
-   log_rtmsg(rtm->rtm_type);
 
sa = (struct sockaddr *)(next + rtm->rtm_hdrlen);
get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
diff --git usr.sbin/ldpd/lde.c usr.sbin/ldpd/lde.c
index b5186a8d816..0d57fc23dc2 100644
--- usr.sbin/ldpd/lde.c
+++ usr.sbin/ldpd/lde.c
@@ -98,6 +98,7 @@ lde(int debug, int verbose)
 
setproctitle("label decision engine");
ldpd_process = PROC_LDE_ENGINE;
+   log_procname = log_procnames[PROC_LDE_ENGINE];
 
if ((pw = getpwnam(LDPD_USER)) == NULL)
fatal("getpwnam");
diff --git usr.sbin/ldpd/ldpd.c usr.sbin/ldpd/ldpd.c
index 718702c9371..259efca73d1 100644
--- usr.sbin/ldpd/ldpd.c
+++ usr.sbin/ldpd/ldpd.c
@@ -113,6 +113,7 @@ main(int argc, char *argv[])
 
conffile = CONF_FILE;
ldpd_process = PROC_MAIN;
+   log_procname = log_procnames[ldpd_process];
 
log_init(1);/* log to stderr until daemonized */
log_verbose(1);
diff --git usr.sbin/ldpd/ldpd.h usr.sbin/ldpd/ldpd.h
index 8a5f6292fff..018d4741faf 100644
--- usr.sbin/ldpd/ldpd.h
+++ usr.sbin/ldpd/ldpd.h
@@ -357,6 +357,12 @@ enum ldpd_process {
PROC_LDE_ENGINE
 } ldpd_process;
 
+static const char * const log_procnames[] = {
+   "parent",
+   "ldpe",
+   "lde"
+};
+
 enum socket_type {
LDP_SOCKET_DISC,
LDP_SOCKET_EDISC,
@@ -603,4 +609,27 @@ int sock_set_ipv6_mcast_loop(int);
 /* printconf.c */
 void   print_config(struct ldpd_conf *);
 
+/* logmsg.h */
+struct in6_addr;
+union ldpd_addr;
+struct hello_source;
+struct fec;
+
+const char *log_sockaddr(void *);
+const char *log_in6addr(const struct in6_addr *);
+const char *log_in6addr_scope(const struct in6_addr *, unsigned int);
+const char *log_addr(int, const union ldpd_addr *);
+char   *log_label(uint32_t);
+char   *log_hello_src(const struct hello_source *);
+const char *log_map(const struct map *);
+const char *log_fec(const struct fec *);
+const char *af_name(int);
+const char *socket_name(int);
+const char *nbr_state_name(int);
+const char *if_state_name(int);
+const char *if_type_name(enum iface_type);
+const char *msg_name(uint16_t);
+const char *status_code_name(uint32_t);
+const char *pw_type_name(uint16_t);
+
 #endif /* _LDPD_H_ */
diff --git usr.sbin/ldpd/ldpe.c usr.sbin/ldpd/ldpe.c
index 218e431fbf7..8ee5f60aab0 100644
--- usr.sbin/ldpd/ldpe.c
+++ usr.sbin/ldpd/ldpe.c
@@ -78,6 +78,7 @@ ldpe(int debug, int verbose)
 
setproctitle("ldp engine");
ldpd_process = PROC_LDP_ENGINE;
+   log_procname = log_procnames[ldpd_process];
 
/* create ldpd control socket outside chroot */
if (control_init() == -1)
diff --git usr.sbin/ldpd/log.c usr.sbin/ldpd/log.c
index bfce33f804a..ca76f227f35 100644
--- usr.sbin/ldpd/log.c
+++ usr.sbin/ldpd/log.c
@@ -16,10 +16,6 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include 
-#include 
-#include 
-#include 
 #include 
 #include 
 #include 
@@ -29,21 +25,12 @@
 #include 
 #include 
 
-#include "ldpd.h"
-#include "ldpe.h"
-#include "lde.h"
 #include "log.h"
+#include "ldpd.h"
 
-static const char * const procnames[] = {
-   "parent",
-   "ldpe",
-   "lde"
-};
-
-static void vlog(int, const char *, va_list);
-
-static int  debug;
-static 

unify log.c in daemons [ldapd]

2017-01-19 Thread Sebastian Benoit
work on making log.c similar in all daemons:

move daemon-local functions into new logmsg.c, and reduce
the (mostly whitespace) differences so that log.c's can be diffed easily.


diff --git usr.sbin/ldapctl/Makefile usr.sbin/ldapctl/Makefile
index 50befd7..682b791 100644
--- usr.sbin/ldapctl/Makefile
+++ usr.sbin/ldapctl/Makefile
@@ -4,7 +4,7 @@
 
 PROG=  ldapctl
 MAN=   ldapctl.8
-SRCS=  ldapctl.c parse.y btree.c log.c ber.c util.c \
+SRCS=  ldapctl.c parse.y btree.c log.c logmsg.c ber.c util.c \
index.c attributes.c schema.c syntax.c matching.c
 
 LDADD= -ltls -levent -lz -lutil
diff --git usr.sbin/ldapctl/ldapctl.c usr.sbin/ldapctl/ldapctl.c
index 42b57c4..7e2178a 100644
--- usr.sbin/ldapctl/ldapctl.c
+++ usr.sbin/ldapctl/ldapctl.c
@@ -42,6 +42,7 @@
 #include 
 
 #include "ldapd.h"
+#include "log.h"
 
 enum action {
NONE,
@@ -61,6 +62,7 @@ intcompact_namespace(struct namespace *ns, const 
char *datadir);
 int compact_namespaces(const char *datadir);
 int index_namespace(struct namespace *ns, const char *datadir);
 int index_namespaces(const char *datadir);
+int ssl_load_certfile(struct ldapd_config *, const char *, 
u_int8_t);
 
 __dead void
 usage(void)
diff --git usr.sbin/ldapd/Makefile usr.sbin/ldapd/Makefile
index 5d2aea0..6a277c0 100644
--- usr.sbin/ldapd/Makefile
+++ usr.sbin/ldapd/Makefile
@@ -2,7 +2,7 @@
 
 PROG=  ldapd
 MAN=   ldapd.8 ldapd.conf.5
-SRCS=  ber.c log.c control.c \
+SRCS=  ber.c log.c logmsg.c control.c \
util.c ldapd.c ldape.c conn.c attributes.c namespace.c \
btree.c filter.c search.c parse.y \
auth.c modify.c index.c evbuffer_tls.c \
diff --git usr.sbin/ldapd/attributes.c usr.sbin/ldapd/attributes.c
index b89c75f..de04447 100644
--- usr.sbin/ldapd/attributes.c
+++ usr.sbin/ldapd/attributes.c
@@ -24,6 +24,7 @@
 #include 
 
 #include "ldapd.h"
+#include "log.h"
 
 struct ber_element *
 ldap_get_attribute(struct ber_element *entry, const char *attr)
diff --git usr.sbin/ldapd/auth.c usr.sbin/ldapd/auth.c
index dfbdfe1..35f2de2 100644
--- usr.sbin/ldapd/auth.c
+++ usr.sbin/ldapd/auth.c
@@ -29,6 +29,7 @@
 #include 
 
 #include "ldapd.h"
+#include "log.h"
 
 static int
 aci_matches(struct aci *aci, struct conn *conn, struct namespace *ns,
diff --git usr.sbin/ldapd/conn.c usr.sbin/ldapd/conn.c
index 728c75d..2ed77c7 100644
--- usr.sbin/ldapd/conn.c
+++ usr.sbin/ldapd/conn.c
@@ -24,6 +24,7 @@
 #include 
 
 #include "ldapd.h"
+#include "log.h"
 
 int conn_dispatch(struct conn *conn);
 int conn_tls_init(struct conn *);
diff --git usr.sbin/ldapd/control.c usr.sbin/ldapd/control.c
index ce25b20..477acdb 100644
--- usr.sbin/ldapd/control.c
+++ usr.sbin/ldapd/control.c
@@ -35,6 +35,7 @@
 #include 
 
 #include "ldapd.h"
+#include "log.h"
 
 #defineCONTROL_BACKLOG 5
 
diff --git usr.sbin/ldapd/filter.c usr.sbin/ldapd/filter.c
index 3e7954f..0371ed2 100644
--- usr.sbin/ldapd/filter.c
+++ usr.sbin/ldapd/filter.c
@@ -23,6 +23,7 @@
 #include 
 
 #include "ldapd.h"
+#include "log.h"
 
 static int  ldap_filt_eq(struct ber_element *root, struct plan *plan);
 static int  ldap_filt_subs(struct ber_element *root, struct plan *plan);
diff --git usr.sbin/ldapd/index.c usr.sbin/ldapd/index.c
index 8e35261..d91d645 100644
--- usr.sbin/ldapd/index.c
+++ usr.sbin/ldapd/index.c
@@ -79,6 +79,7 @@
 #include 
 
 #include "ldapd.h"
+#include "log.h"
 
 static int
 index_attribute(struct namespace *ns, char *attr, struct btval *dn,
diff --git usr.sbin/ldapd/ldapd.c usr.sbin/ldapd/ldapd.c
index b41eb2d..0f44b31 100644
--- usr.sbin/ldapd/ldapd.c
+++ usr.sbin/ldapd/ldapd.c
@@ -38,6 +38,7 @@
 #include 
 
 #include "ldapd.h"
+#include "log.h"
 
 voidusage(void);
 voidldapd_sig_handler(int fd, short why, void *data);
diff --git usr.sbin/ldapd/ldapd.h usr.sbin/ldapd/ldapd.h
index 2cb4050..cc1c805 100644
--- usr.sbin/ldapd/ldapd.h
+++ usr.sbin/ldapd/ldapd.h
@@ -464,23 +464,12 @@ intssl_cmp(struct ssl *, struct 
ssl *);
 SPLAY_PROTOTYPE(ssltree, ssl, ssl_nodes, ssl_cmp);
 
 
-/* log.c */
-voidlog_init(int);
-voidlog_verbose(int v);
-voidvlog(int, const char *, va_list);
-voidlogit(int pri, const char *fmt, ...);
-voidlog_warn(const char *, ...);
-voidlog_warnx(const char *, ...);
-voidlog_info(const char *, ...);
-voidlog_debug(const char *, ...);
-__dead void fatal(const char *);
-__dead void fatalx(const char *);
+/* logmsg.c */
 const char *print_host(struct sockaddr_storage *ss, char *buf,
size_t len);
 voidhexdump(void *data, size_t len, const char *fmt, ...);
 void

Re: make art independent of struct sockaddr

2017-01-19 Thread Martin Pieuchot
On 20/01/17(Fri) 03:04, Claudio Jeker wrote:
> I want to use art routing tables with pf addrs and not sockaddrs.
> Art itself does not care but the API requires sockaddr pointers in some
> places. This changes those to void *.
> 
> OK? This is step 2 to a new pf_table backend.

What's the problem with uint8_t?  If possible I'd prefer keeping that
type since it's clear that we're dealing with bytes.

I also think that ``an_dst'' is no longer used and can die.  The value
attached to an art_node is now ``an_rtlist''.  This might be renamed and
we could use a "void *" since you're not going to use list for pf.

That means we could fold ``an_rtlist'' in the union and reduce the size
of 'struct art_node'.



tell clang to treat __guard_local as hidden

2017-01-19 Thread Philip Guenther

Currently, clang generates references to __guard_local as if it had 
default visibility.  This is non-optimal on various archs, so lets tell 
clang that __guard_local is hidden.

I *think* this is the right way to tell clang this and it seems to work on 
amd64, generating
movq__guard_local(%rip), %rax
instead of
movq__guard_local@GOTPCREL(%rip), %rax

Is this the right way to do this in clang, or is there a cleaner way?


Philip

Index: lib/CodeGen/TargetLoweringBase.cpp
===
RCS file: /data/src/openbsd/src/gnu/llvm/lib/CodeGen/TargetLoweringBase.cpp,v
retrieving revision 1.2
diff -u -p -r1.2 TargetLoweringBase.cpp
--- lib/CodeGen/TargetLoweringBase.cpp  14 Jan 2017 20:04:01 -  1.2
+++ lib/CodeGen/TargetLoweringBase.cpp  19 Jan 2017 23:25:08 -
@@ -1818,7 +1818,10 @@ Value *TargetLoweringBase::getIRStackGua
   if (getTargetMachine().getTargetTriple().isOSOpenBSD()) {
 Module  = *IRB.GetInsertBlock()->getParent()->getParent();
 PointerType *PtrTy = Type::getInt8PtrTy(M.getContext());
-return M.getOrInsertGlobal("__guard_local", PtrTy);
+Constant *C = M.getOrInsertGlobal("__guard_local", PtrTy);
+if (GlobalVariable *G = dyn_cast_or_null(C))
+  G->setVisibility(GlobalValue::HiddenVisibility);
+return C;
   }
   return nullptr;
 }



make art independent of struct sockaddr

2017-01-19 Thread Claudio Jeker
I want to use art routing tables with pf addrs and not sockaddrs.
Art itself does not care but the API requires sockaddr pointers in some
places. This changes those to void *.

OK? This is step 2 to a new pf_table backend.
-- 
:wq Claudio

Index: net/art.c
===
RCS file: /cvs/src/sys/net/art.c,v
retrieving revision 1.24
diff -u -p -r1.24 art.c
--- net/art.c   15 Sep 2016 02:00:18 -  1.24
+++ net/art.c   10 Oct 2016 18:16:36 -
@@ -247,7 +247,7 @@ art_findex(struct art_table *at, uint8_t
  * Return the best existing match for a destination.
  */
 struct art_node *
-art_match(struct art_root *ar, uint8_t *addr, struct srp_ref *nsr)
+art_match(struct art_root *ar, void *addr, struct srp_ref *nsr)
 {
struct srp_ref  dsr, ndsr;
void*entry;
@@ -310,7 +310,7 @@ done:
  * it does not exist.
  */
 struct art_node *
-art_lookup(struct art_root *ar, uint8_t *addr, int plen, struct srp_ref *nsr)
+art_lookup(struct art_root *ar, void *addr, int plen, struct srp_ref *nsr)
 {
void*entry;
struct art_table*at;
@@ -368,7 +368,7 @@ done:
  * same destination/mask pair is already present.
  */
 struct art_node *
-art_insert(struct art_root *ar, struct art_node *an, uint8_t *addr, int plen)
+art_insert(struct art_root *ar, struct art_node *an, void *addr, int plen)
 {
struct art_table*at, *child;
struct art_node *node;
@@ -472,7 +472,7 @@ art_table_insert(struct art_root *ar, st
  * Deletion API function.
  */
 struct art_node *
-art_delete(struct art_root *ar, struct art_node *an, uint8_t *addr, int plen)
+art_delete(struct art_root *ar, struct art_node *an, void *addr, int plen)
 {
struct art_table*at;
struct art_node *node;
@@ -922,7 +922,7 @@ moveup:
 }
 
 struct art_node *
-art_get(struct sockaddr *dst, uint8_t plen)
+art_get(void *dst, uint8_t plen)
 {
struct art_node *an;
 
Index: net/art.h
===
RCS file: /cvs/src/sys/net/art.h,v
retrieving revision 1.15
diff -u -p -r1.15 art.h
--- net/art.h   30 Aug 2016 07:42:57 -  1.15
+++ net/art.h   10 Oct 2016 18:16:36 -
@@ -48,7 +48,7 @@ struct rtentry;
 struct art_node {
SRPL_HEAD(, rtentry) an_rtlist; /* Route related to this node */
union {
-   struct sockaddr *an__dst;   /* Destination address (key) */
+   void*an__dst;   /* Destination address (key) */
struct art_node *an__gc;/* Entry on GC list */
}an_pointer;
uint8_t  an_plen;   /* Prefix length */
@@ -58,17 +58,17 @@ struct art_node {
 
 voidart_init(void);
 struct art_root*art_alloc(unsigned int, unsigned int, unsigned int);
-struct art_node *art_insert(struct art_root *, struct art_node *, uint8_t *,
+struct art_node *art_insert(struct art_root *, struct art_node *, void *,
 int);
-struct art_node *art_delete(struct art_root *, struct art_node *, uint8_t *,
+struct art_node *art_delete(struct art_root *, struct art_node *, void *,
 int);
-struct art_node*art_match(struct art_root *, uint8_t *, struct srp_ref 
*);
-struct art_node *art_lookup(struct art_root *, uint8_t *, int,
+struct art_node*art_match(struct art_root *, void *, struct srp_ref *);
+struct art_node *art_lookup(struct art_root *, void *, int,
 struct srp_ref *);
 int art_walk(struct art_root *,
 int (*)(struct art_node *, void *), void *);
 
-struct art_node*art_get(struct sockaddr *, uint8_t);
+struct art_node*art_get(void *, uint8_t);
 voidart_put(struct art_node *);
 
 #endif /* _NET_ART_H_ */



NET_LOCK() take 2, tests wanted!

2017-01-19 Thread Martin Pieuchot
Diff below enables the NET_LOCK(), again.

What's new?

 - The lock ordering problem with fdplock() should now be fixed.  It is
   also documented, fdplock() should be taken first if both locks are 
   needed.

 - Page faults involving NFS, or any other code path already holding the
   NET_LOCK(), have been fixed.  The recursion is similar to the existing
   vnode problem, so I simply added a hack there.

 - I added some NET_ASSERT_UNLOCKED() to help finding other possible
   deadlocks.


Please test it as before and report any problem back to me.

Martin

diff --git sys/kern/kern_rwlock.c sys/kern/kern_rwlock.c
index bdaee0c1ae7..9182b42706a 100644
--- sys/kern/kern_rwlock.c
+++ sys/kern/kern_rwlock.c
@@ -195,6 +195,9 @@ retry:
unsigned long set = o | op->wait_set;
int do_sleep;
 
+   if (panicstr)
+   return (0);
+
rw_enter_diag(rwl, flags);
 
if (flags & RW_NOSLEEP)
@@ -205,7 +208,7 @@ retry:
sleep_setup_signal(, op->wait_prio | PCATCH);
 
do_sleep = !rw_cas(>rwl_owner, o, set);
-
+   NET_ASSERT_UNLOCKED();
sleep_finish(, do_sleep);
if ((flags & RW_INTR) &&
(error = sleep_finish_signal()) != 0)
diff --git sys/kern/kern_synch.c sys/kern/kern_synch.c
index beeefe06458..93468c276b3 100644
--- sys/kern/kern_synch.c
+++ sys/kern/kern_synch.c
@@ -111,6 +111,7 @@ tsleep(const volatile void *ident, int priority, const char 
*wmesg, int timo)
int hold_count;
 #endif
 
+   NET_ASSERT_UNLOCKED();
KASSERT((priority & ~(PRIMASK | PCATCH)) == 0);
 
 #ifdef MULTIPROCESSOR
@@ -170,6 +171,7 @@ msleep(const volatile void *ident, struct mutex *mtx, int 
priority,
int hold_count;
 #endif
 
+   NET_ASSERT_UNLOCKED();
KASSERT((priority & ~(PRIMASK | PCATCH | PNORELOCK)) == 0);
KASSERT(mtx != NULL);
 
diff --git sys/kern/uipc_socket.c sys/kern/uipc_socket.c
index 245210e594a..f7c199bf747 100644
--- sys/kern/uipc_socket.c
+++ sys/kern/uipc_socket.c
@@ -256,7 +256,7 @@ soclose(struct socket *so)
(so->so_state & SS_NBIO))
goto drop;
while (so->so_state & SS_ISCONNECTED) {
-   error = tsleep(>so_timeo,
+   error = rwsleep(>so_timeo, ,
PSOCK | PCATCH, "netcls",
so->so_linger * hz);
if (error)
@@ -615,7 +615,7 @@ sbsync(struct sockbuf *sb, struct mbuf *nextrecord)
  * followed by an optional mbuf or mbufs containing ancillary data,
  * and then zero or more mbufs of data.
  * In order to avoid blocking network for the entire time here, we splx()
- * and release NET_LOCK() while doing the actual copy to user space.
+ * and release ``netlock'' while doing the actual copy to user space.
  * Although the sockbuf is locked, new data may still be appended,
  * and thus we must maintain consistency of the sockbuf during that time.
  *
@@ -800,9 +800,12 @@ dontblock:
if (controlp) {
if (pr->pr_domain->dom_externalize &&
mtod(cm, struct cmsghdr *)->cmsg_type ==
-   SCM_RIGHTS)
-  error = (*pr->pr_domain->dom_externalize)(cm,
-  controllen, flags);
+   SCM_RIGHTS) {
+   NET_UNLOCK(s);
+   error = (*pr->pr_domain->dom_externalize)(
+   cm, controllen, flags);
+  NET_LOCK(s);
+   }
*controlp = cm;
} else {
/*
@@ -1039,7 +1042,7 @@ sorflush(struct socket *so)
struct sockbuf asb;
 
sb->sb_flags |= SB_NOINTR;
-   (void) sblock(sb, M_WAITOK, NULL);
+   (void) sblock(sb, M_WAITOK, );
socantrcvmore(so);
sbunlock(sb);
asb = *sb;
@@ -1528,7 +1531,10 @@ sorwakeup(struct socket *so)
 #endif
sowakeup(so, >so_rcv);
if (so->so_upcall) {
+   /* XXXSMP breaks atomicity */
+   rw_exit_write();
(*(so->so_upcall))(so, so->so_upcallarg, M_DONTWAIT);
+   rw_enter_write();
}
 }
 
diff --git sys/kern/uipc_socket2.c sys/kern/uipc_socket2.c
index 1ac5f515bc5..6dd5abbd473 100644
--- sys/kern/uipc_socket2.c
+++ sys/kern/uipc_socket2.c
@@ -276,7 +276,7 @@ sbwait(struct sockbuf *sb)
NET_ASSERT_LOCKED();
 
sb->sb_flagsintr |= SB_WAIT;
-   return (tsleep(>sb_cc,
+   return (rwsleep(>sb_cc, ,
(sb->sb_flags & SB_NOINTR) ? PSOCK : PSOCK | PCATCH, "netio",

Kill pfsockaddr_union

2017-01-19 Thread Claudio Jeker
pfsockaddr_union needs to die. This fixes two of the uses of it and the
pf_table code will follow later. For bridge we just move the definition
and in pfsync we can actually use the one from ip_ipsp.h since it is used
for that.

OK?
-- 
:wq Claudio

Index: net/if_bridge.h
===
RCS file: /cvs/src/sys/net/if_bridge.h,v
retrieving revision 1.54
diff -u -p -r1.54 if_bridge.h
--- net/if_bridge.h 11 Jan 2017 08:47:48 -  1.54
+++ net/if_bridge.h 18 Jan 2017 14:27:30 -
@@ -407,11 +407,22 @@ struct bridge_iflist {
((struct bridge_iflist *)_bp2)->bridge_sc)
 
 /*
+ * XXX ip_ipsp.h's sockaddr_union should be converted to sockaddr *
+ * passing with correct sa_len, then a good approach for cleaning this
+ * will become more clear.
+ */
+union brsockaddr_union {
+   struct sockaddr sa;
+   struct sockaddr_in  sin;
+   struct sockaddr_in6 sin6;
+};
+
+/*
  * Bridge tunnel tagging
  */
 struct bridge_tunneltag {
-   union pfsockaddr_union  brtag_peer;
-   union pfsockaddr_union  brtag_local;
+   union brsockaddr_union  brtag_peer;
+   union brsockaddr_union  brtag_local;
u_int32_t   brtag_id;
 };
 
Index: net/if_pfsync.h
===
RCS file: /cvs/src/sys/net/if_pfsync.h,v
retrieving revision 1.48
diff -u -p -r1.48 if_pfsync.h
--- net/if_pfsync.h 24 Jan 2015 00:29:06 -  1.48
+++ net/if_pfsync.h 2 Nov 2016 21:02:13 -
@@ -210,10 +210,9 @@ struct pfsync_bus {
 /*
  * TDB
  */
-
 struct pfsync_tdb {
u_int32_t   spi;
-   union pfsockaddr_union  dst;
+   union sockaddr_uniondst;
u_int64_t   rpl;
u_int64_t   cur_bytes;
u_int8_tsproto;



store and count packet stats on ifq structures

2017-01-19 Thread David Gwynne
this has the ifq count the statistics kept for output packets that
we currently count on an ifnet.

unlike the ifnet stats, these are all maintained by the ifq as a
matter of course except for the output errors counter. this means
drivers wont have to account for outgoing packets like they do now,
and they will be counted consistently with the number of bytes
transmitted.

errors can be updated by an interfaces start routine safely because
it is serialised by the ifq_serialiazer.

since most stats are protected by the mutex you can take the mutex
to read the stats consistently. unfortunately there's no mechanism
to serialise the read of the errors, but im not sure we care a lot.
we could just read it twice to see if it stays th same.

this only updates the stats at the moment. their values dont replace
or get rolled into the ifnet stats yet.

they are updated though. eg:

(gdb) print $1->arpcom.ac_if.if_snd
$2 = {ifq_if = 0x40011aae048, ifq_mtx = {mtx_owner = 0x0, mtx_wantipl = 12, 
mtx_oldipl = 2}, ifq_ops = 0x1693920, ifq_q = 0x40011a93700, 
  ifq_len = 0, ifq_oactive = 0, ifq_packets = 0, ifq_bytes = 1908, 
  ifq_qdrops = 619139, ifq_errors = 0, ifq_mcasts = 0, ifq_task_mtx = {
mtx_owner = 0x3, mtx_wantipl = 0, mtx_oldipl = 0}, ifq_task_list = {
tqh_first = 0xc0002, tqh_last = 0x0}, 
  ifq_serializer = 0x40011aae2d8, ifq_start = {t_entry = {tqe_next = 0x0, 
  tqe_prev = 0x}, t_func = 0x, 
t_arg = 0x11fa4a0, t_flags = 1024}, ifq_restart = {t_entry = {
  tqe_next = 0x0, tqe_prev = 0x0}, t_func = 0, t_arg = 0x11fa500, 
t_flags = 1024}, ifq_maxlen = 0}

i want to mvoe the stats here because ifnets will end up with
multiple send rings represented by ifq structures. rather than
serialise at the ifnet level for statistics, we can collect them
on the rings where we have to serialise anyway and aggregate them
for userland later. this in turn means we dont need to maintain
per-cpu stats for ifnets.

ok?

Index: ifq.c
===
RCS file: /cvs/src/sys/net/ifq.c,v
retrieving revision 1.4
diff -u -p -r1.4 ifq.c
--- ifq.c   29 Dec 2015 12:35:43 -  1.4
+++ ifq.c   20 Jan 2017 01:36:06 -
@@ -172,7 +172,7 @@ ifq_init(struct ifqueue *ifq, struct ifn
ifq->ifq_if = ifp;
 
mtx_init(>ifq_mtx, IPL_NET);
-   ifq->ifq_drops = 0;
+   ifq->ifq_qdrops = 0;
 
/* default to priq */
ifq->ifq_ops = _ops;
@@ -214,7 +214,7 @@ ifq_attach(struct ifqueue *ifq, const st
 
while ((m = ml_dequeue()) != NULL) {
if (ifq->ifq_ops->ifqop_enq(ifq, m) != 0) {
-   ifq->ifq_drops++;
+   ifq->ifq_qdrops++;
ml_enqueue(_ml, m);
} else
ifq->ifq_len++;
@@ -246,10 +246,15 @@ ifq_enqueue_try(struct ifqueue *ifq, str
 
mtx_enter(>ifq_mtx);
rv = ifq->ifq_ops->ifqop_enq(ifq, m);
-   if (rv == 0)
+   if (rv == 0) {
ifq->ifq_len++;
-   else
-   ifq->ifq_drops++;
+
+   ifq->ifq_packets++;
+   ifq->ifq_bytes += m->m_pkthdr.len;
+   if (ISSET(m->m_flags, M_MCAST))
+   ifq->ifq_mcasts++;
+   } else
+   ifq->ifq_qdrops++;
mtx_leave(>ifq_mtx);
 
return (rv);
@@ -330,7 +335,7 @@ ifq_purge(struct ifqueue *ifq)
ifq->ifq_ops->ifqop_purge(ifq, );
rv = ifq->ifq_len;
ifq->ifq_len = 0;
-   ifq->ifq_drops += rv;
+   ifq->ifq_qdrops += rv;
mtx_leave(>ifq_mtx);
 
KASSERT(rv == ml_len());
Index: ifq.h
===
RCS file: /cvs/src/sys/net/ifq.h,v
retrieving revision 1.5
diff -u -p -r1.5 ifq.h
--- ifq.h   20 Jan 2016 17:27:16 -  1.5
+++ ifq.h   20 Jan 2017 01:36:06 -
@@ -28,11 +28,17 @@ struct ifqueue {
 
/* mbuf handling */
struct mutex ifq_mtx;
-   uint64_t ifq_drops;
const struct ifq_ops*ifq_ops;
void*ifq_q;
unsigned int ifq_len;
unsigned int ifq_oactive;
+
+   /* statistics */
+   uint64_t ifq_packets;
+   uint64_t ifq_bytes;
+   uint64_t ifq_qdrops;
+   uint64_t ifq_errors;
+   uint64_t ifq_mcasts;
 
/* work serialisation */
struct mutex ifq_task_mtx;



rtsock refactoring

2017-01-19 Thread Claudio Jeker
I sent this diff out some time ago and would really like to get this in.
This is one step on makeing rtsock.c less of a hornets nest.
This reduces the side effects in route_output and simplifies some other
bits as well. For example route_input is less variadic and simpler.

Anyone couragous enough to send me an OK?
-- 
:wq Claudio

Index: net/rtsock.c
===
RCS file: /cvs/src/sys/net/rtsock.c,v
retrieving revision 1.213
diff -u -p -r1.213 rtsock.c
--- net/rtsock.c19 Jan 2017 23:18:29 -  1.213
+++ net/rtsock.c20 Jan 2017 01:37:33 -
@@ -92,7 +92,6 @@
 
 struct sockaddrroute_dst = { 2, PF_ROUTE, };
 struct sockaddrroute_src = { 2, PF_ROUTE, };
-struct sockproto   route_proto = { PF_ROUTE, };
 
 struct walkarg {
int w_op, w_arg, w_given, w_needed, w_tmemsize;
@@ -100,7 +99,7 @@ struct walkarg {
 };
 
 introute_ctloutput(int, struct socket *, int, int, struct mbuf **);
-void   route_input(struct mbuf *m0, ...);
+void   route_input(struct mbuf *m0, unsigned short);
 introute_arp_conflict(struct rtentry *, struct rt_addrinfo *);
 introute_cleargateway(struct rtentry *, void *, unsigned int);
 
@@ -331,7 +330,7 @@ rt_senddesync(void *data)
 }
 
 void
-route_input(struct mbuf *m0, ...)
+route_input(struct mbuf *m0, unsigned short sa_family)
 {
struct rawcb *rp;
struct routecb *rop;
@@ -339,15 +338,10 @@ route_input(struct mbuf *m0, ...)
struct mbuf *m = m0;
int s, sockets = 0;
struct socket *last = NULL;
-   va_list ap;
-   struct sockproto *proto;
struct sockaddr *sosrc, *sodst;

-   va_start(ap, m0);
-   proto = va_arg(ap, struct sockproto *);
-   sosrc = va_arg(ap, struct sockaddr *);
-   sodst = va_arg(ap, struct sockaddr *);
-   va_end(ap);
+   sosrc = _src;
+   sodst = _src;
 
/* ensure that we can access the rtm_type via mtod() */
if (m->m_len < offsetof(struct rt_msghdr, rtm_type) + 1) {
@@ -358,10 +352,15 @@ route_input(struct mbuf *m0, ...)
LIST_FOREACH(rp, , rcb_list) {
if (rp->rcb_socket->so_state & SS_CANTRCVMORE)
continue;
-   if (rp->rcb_proto.sp_family != proto->sp_family)
+   if (rp->rcb_proto.sp_family != PF_ROUTE)
continue;
-   if (rp->rcb_proto.sp_protocol && proto->sp_protocol &&
-   rp->rcb_proto.sp_protocol != proto->sp_protocol)
+   /*
+* If route socket is bound to an address family only send
+* messages that match the address family. Address family
+* agnostic messages are always send.
+*/
+   if (rp->rcb_proto.sp_protocol != 0 && sa_family != 0 &&
+   rp->rcb_proto.sp_protocol != sa_family)
continue;
/*
 * We assume the lower level routines have
@@ -458,36 +457,99 @@ route_input(struct mbuf *m0, ...)
m_freem(m);
 }
 
+struct rt_msghdr *
+rt_report(struct rtentry *rt, u_char type, int seq, int tableid)
+{
+   struct rt_msghdr*rtm;
+   struct rt_addrinfo   info;
+   struct sockaddr_rtlabel  sa_rl;
+   struct sockaddr_in6  sa_mask;
+#ifdef BFD
+   struct sockaddr_bfd  sa_bfd;
+#endif
+#ifdef MPLS
+   struct sockaddr_mpls sa_mpls;
+#endif
+   struct ifnet*ifp = NULL;
+   int  len;
+
+   bzero(, sizeof(info));
+   info.rti_info[RTAX_DST] = rt_key(rt);
+   info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
+   info.rti_info[RTAX_NETMASK] = rt_plen2mask(rt, _mask);
+   info.rti_info[RTAX_LABEL] = rtlabel_id2sa(rt->rt_labelid, _rl);
+#ifdef BFD
+   if (rt->rt_flags & RTF_BFD)
+   info.rti_info[RTAX_BFD] = bfd2sa(rt, _bfd);
+#endif
+#ifdef MPLS
+   if (rt->rt_flags & RTF_MPLS) {
+   bzero(_mpls, sizeof(sa_mpls));
+   sa_mpls.smpls_family = AF_MPLS;
+   sa_mpls.smpls_len = sizeof(sa_mpls);
+   sa_mpls.smpls_label = ((struct rt_mpls *)
+   rt->rt_llinfo)->mpls_label;
+   info.rti_info[RTAX_SRC] = (struct sockaddr *)_mpls;
+   info.rti_mpls = ((struct rt_mpls *)
+   rt->rt_llinfo)->mpls_operation;
+   }
+#endif
+   ifp = if_get(rt->rt_ifidx);
+   if (ifp != NULL) {
+   info.rti_info[RTAX_IFP] = sdltosa(ifp->if_sadl);
+   info.rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr;
+   if (ifp->if_flags & IFF_POINTOPOINT)
+   info.rti_info[RTAX_BRD] = rt->rt_ifa->ifa_dstaddr;
+   }
+   if_put(ifp);
+   /* RTAX_GENMASK, RTAX_AUTHOR, RTAX_SRCMASK ignored */
+
+   /* build new route message */
+   len = rt_msg2(type, RTM_VERSION, , NULL, NULL);
+   /* XXX 

HEAP data structure

2017-01-19 Thread David Gwynne
this is an implementation of a heap data structure, specifically a pairing heap.

it is implemented like the RB trees in that it can be used to
organise arbitrary structs with arbitrary compare functions. eg,
we could queue tasks on a heap and order them by an execution
deadline.

ok?

Index: share/man/man9/HEAP_INIT.9
===
RCS file: share/man/man9/HEAP_INIT.9
diff -N share/man/man9/HEAP_INIT.9
--- /dev/null   1 Jan 1970 00:00:00 -
+++ share/man/man9/HEAP_INIT.9  4 Oct 2016 00:09:00 -
@@ -0,0 +1,207 @@
+.\"$OpenBSD$
+.\"
+.\" Copyright (c) 2016 David Gwynne 
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd $Mdocdate: September 5 2016 $
+.Dt HEAP_INIT 9
+.Os
+.Sh NAME
+.Nm HEAP_INIT ,
+.Nm HEAP_INSERT ,
+.Nm HEAP_REMOVE ,
+.Nm HEAP_FIRST ,
+.Nm HEAP_EXTRACT ,
+.Nm HEAP_CEXTRACT
+.Nd Kernel Heap Data Structure
+.Sh SYNOPSIS
+.In sys/tree.h
+.Fn HEAP_HEAD "NAME"
+.Fn HEAP_PROTOTYPE "NAME" "TYPE"
+.Fc
+.Fo HEAP_GENERATE
+.Fa "NAME"
+.Fa "TYPE"
+.Fa "ENTRY"
+.Fa "int (*compare)(const struct TYPE *, const struct TYPE *)"
+.Fc
+.Ft struct NAME
+.Fn HEAP_INITIALIZER
+.Ft void
+.Fn HEAP_INIT "NAME" "struct NAME *heap"
+.Ft struct TYPE *
+.Fn HEAP_INSERT "NAME" "struct NAME *heap" "struct TYPE *elm"
+.Ft struct TYPE *
+.Fn HEAP_REMOVE "NAME" "struct NAME *heap" "struct TYPE *elm"
+.Ft struct TYPE *
+.Fn HEAP_FIRST "NAME" "struct NAME *heap"
+.Ft struct TYPE *
+.Fn HEAP_EXTRACT "NAME" "struct NAME *heap"
+.Ft struct TYPE *
+.Fn HEAP_CEXTRACT "NAME" "struct NAME *heap" "const struct TYPE *key"
+.Sh DESCRIPTION
+The heap API provides data structures and operations for storing elements
+in a heap. The API implements a pairing heap that sorts elements
+according to a user defined comparison function.
+.Pp
+This API is implemented as a set of functions that operate on generic
+pointers, but users of the API generate wrappers and macros that provide
+type safety when calling the functions.
+.Pp
+In the macro definitions,
+.Fa TYPE
+is the name of a structure that will be stored in a heap.
+The
+.Fa TYPE
+structure must contain an
+heap_entry
+structure that allows the element to be connected to a heap.
+The argument
+.Fa NAME
+is the name of a heap type that can store a particular
+.Fa TYPE
+element.
+.Pp
+The
+.Fn HEAP_HEAD
+macro creates a heap type to store
+.Fa TYPE
+structures as elements in the heap.
+The argument
+.Fa NAME
+must uniquely identify every type of heap that is defined.
+.Pp
+.Fn HEAP_PROTOTYPE
+produces the wrappers for a heap type identified by
+.Fa NAME
+to operate on elements of type
+.Fa TYPE .
+.Pp
+.Fn HEAP_GENERATE
+produces the internal data structures used by the heap
+type identified by
+.Fa NAME
+to operate on elements of type
+.Fa TYPE .
+.Fa ENTRY
+specifies which field in the
+.Fa TYPE
+structure is used to connect elements to
+.Fa NAME
+heaps.
+Elements in the heap are ordered according to the result of comparing
+them with the
+.Fa compare
+function.
+If the first argument to
+.Fa compare
+is to be ordered lower than the second,
+the function returns a value smaller than zero.
+If the first argument is to be ordered higher than the second,
+the function returns a value greater than zero.
+If they are equal, the function returns zero.
+.Pp
+.Fn HEAP_INIT
+initialises
+.Fa heap
+of type
+.Fa NAME
+to an empty state.
+.Pp
+.Fn HEAP_INITIALIZER
+can be used to initialise a declaration of a heap
+to an empty state.
+.Pp
+.Fn HEAP_INSERT
+inserts the element
+.Fa elm
+into the
+.Fa heap
+structure of type
+.Fa NAME .
+.Pp
+.Fn HEAP_REMOVE
+removes the element
+.Fa elm
+from the
+.Fa heap
+of type
+.Fa NAME .
+.Fa elm
+must exist in the
+.Fa heap
+before it is removed.
+.Pp
+.Fn HEAP_FIRST
+returns the lowest ordered element in the
+.Fa heap
+of type
+.Fa NAME .
+.Pp
+.Fn HEAP_EXTRACT
+removes the lowest ordered element from the
+.Fa heap
+of type
+.Fa NAME
+and returns it.
+.Pp
+.Fn HEAP_CEXTRACT
+conditionally removes the lowest ordered element from the
+.Fa heap
+of type
+.Fa NAME
+and returns it if it compares lower than the
+.Fa key
+element.
+.Sh CONTEXT
+.Fn HEAP_INIT ,
+.Fn HEAP_INSERT,
+.Fn HEAP_REMOVE ,
+.Fn HEAP_FIRST ,
+.Fn HEAP_EXTRACT ,
+and
+.Fn HEAP_CEXTRACT
+can be called during 

NET_LOCK() ordering issue

2017-01-19 Thread Martin Pieuchot
Turns out that the NET_LOCK() related hang reported by many is a
deadlock.  One way to prevent it is to ensure that fdplock() is
always taken before the NET_LOCK() when both have to been hold.

This generates the diff below.

Comments, ok?

Index: kern/uipc_socket.c
===
RCS file: /cvs/src/sys/kern/uipc_socket.c,v
retrieving revision 1.171
diff -u -p -r1.171 uipc_socket.c
--- kern/uipc_socket.c  29 Dec 2016 12:12:43 -  1.171
+++ kern/uipc_socket.c  19 Jan 2017 09:14:22 -
@@ -800,9 +800,12 @@ dontblock:
if (controlp) {
if (pr->pr_domain->dom_externalize &&
mtod(cm, struct cmsghdr *)->cmsg_type ==
-   SCM_RIGHTS)
-  error = (*pr->pr_domain->dom_externalize)(cm,
-  controllen, flags);
+   SCM_RIGHTS) {
+   NET_UNLOCK(s);
+   error = (*pr->pr_domain->dom_externalize)(
+   cm, controllen, flags);
+   NET_LOCK(s);
+   }
*controlp = cm;
} else {
/*
Index: kern/uipc_syscalls.c
===
RCS file: /cvs/src/sys/kern/uipc_syscalls.c,v
retrieving revision 1.144
diff -u -p -r1.144 uipc_syscalls.c
--- kern/uipc_syscalls.c29 Dec 2016 12:12:43 -  1.144
+++ kern/uipc_syscalls.c19 Jan 2017 09:03:56 -
@@ -278,6 +278,7 @@ doaccept(struct proc *p, int sock, struc
 
headfp = fp;
 redo:
+   fdplock(fdp);
NET_LOCK(s);
head = headfp->f_data;
if (isdnssocket(head) || (head->so_options & SO_ACCEPTCONN) == 0) {
@@ -312,11 +313,9 @@ redo:
nflag = flags & SOCK_NONBLOCK_INHERIT ? (headfp->f_flag & FNONBLOCK)
: (flags & SOCK_NONBLOCK ? FNONBLOCK : 0);
 
-   fdplock(fdp);
error = falloc(p, , );
if (error == 0 && (flags & SOCK_CLOEXEC))
fdp->fd_ofileflags[tmpfd] |= UF_EXCLOSE;
-   fdpunlock(fdp);
if (error != 0) {
/*
 * Probably ran out of file descriptors.  Wakeup
@@ -336,7 +335,6 @@ redo:
if (head->so_qlen == 0) {
NET_UNLOCK(s);
m_freem(nam);
-   fdplock(fdp);
fdremove(fdp, tmpfd);
closef(fp, p);
fdpunlock(fdp);
@@ -365,7 +363,6 @@ redo:
/* if an error occurred, free the file descriptor */
NET_UNLOCK(s);
m_freem(nam);
-   fdplock(fdp);
fdremove(fdp, tmpfd);
closef(fp, p);
fdpunlock(fdp);
@@ -377,6 +374,7 @@ redo:
m_freem(nam);
 bad:
NET_UNLOCK(s);
+   fdpunlock(fdp);
 out:
FRELE(headfp, p);
return (error);



Re: BFD: route get and route monitor

2017-01-19 Thread Peter Hessler
On 2017 Jan 19 (Thu) at 06:26:25 +0100 (+0100), Peter Hessler wrote:
:On 2016 Dec 17 (Sat) at 14:05:40 +0100 (+0100), Peter Hessler wrote:
::On 2016 Sep 30 (Fri) at 10:16:19 +0200 (+0200), Peter Hessler wrote:
:::This diff makes route get and route monitor work.  sockaddr_bfd is so we
:::can play like the other RTAX_* indexes in rti_info of route messages.
:::
:
:In route(8), only say "up" or "down" for the state of BFD.  use -v or
:-bfd to get details that only matter to debug BFD.
:
:$ route -n get 203.0.113.9   
:   route to: 203.0.113.9
:destination: 203.0.113.9
:   mask: 255.255.255.255
:  interface: em1
: if address: 203.0.113.1
:   priority: 3 ()
:  flags: 
:BFD: up
: use   mtuexpire
:1402 0   922 
:sockaddrs: 
:
:I also fixed a number of things that mpi@ noticed.
:

And now with sockaddr_bfd (and bfd_msghdr for that matter) adjusted for
4 byte boundaries and sized to a power of two.


Index: sbin/route/Makefile
===
RCS file: /cvs/openbsd/src/sbin/route/Makefile,v
retrieving revision 1.13
diff -u -p -u -p -r1.13 Makefile
--- sbin/route/Makefile 19 Jul 2013 14:41:46 -  1.13
+++ sbin/route/Makefile 17 Dec 2016 12:47:35 -
@@ -4,7 +4,7 @@ PROG=   route
 MAN=   route.8
 SRCS=  route.c show.c
 
-CFLAGS+=   -Wall
+CFLAGS+=   -Wall -DBFD
 
 route.o .depend lint tags: keywords.h
 
Index: sbin/route/route.c
===
RCS file: /cvs/openbsd/src/sbin/route/route.c,v
retrieving revision 1.194
diff -u -p -u -p -r1.194 route.c
--- sbin/route/route.c  17 Jan 2017 19:05:47 -  1.194
+++ sbin/route/route.c  19 Jan 2017 03:39:55 -
@@ -100,6 +100,7 @@ const char *bfd_state(unsigned int);
 const char *bfd_diag(unsigned int);
 const char *bfd_calc_uptime(time_t);
 voidprint_bfdmsg(struct rt_msghdr *);
+voidprint_sabfd(struct sockaddr_bfd *, int);
 #endif
 const char *get_linkstate(int, int);
 voidprint_rtmsg(struct rt_msghdr *, int);
@@ -1444,6 +1445,9 @@ print_getmsg(struct rt_msghdr *rtm, int 
struct sockaddr *dst = NULL, *gate = NULL, *mask = NULL, *ifa = NULL;
struct sockaddr_dl *ifp = NULL;
struct sockaddr_rtlabel *sa_rl = NULL;
+#ifdef BFD
+   struct sockaddr_bfd *sa_bfd = NULL;
+#endif
struct sockaddr *mpls = NULL;
struct sockaddr *sa;
char *cp;
@@ -1492,6 +1496,11 @@ print_getmsg(struct rt_msghdr *rtm, int 
case RTA_LABEL:
sa_rl = (struct sockaddr_rtlabel *)sa;
break;
+#ifdef BFD
+   case RTA_BFD:
+   sa_bfd = (struct sockaddr_bfd *)sa;
+   break;
+#endif
}
ADVANCE(cp, sa);
}
@@ -1524,6 +1533,10 @@ print_getmsg(struct rt_msghdr *rtm, int 
printf("\n");
if (sa_rl != NULL)
printf("  label: %s\n", sa_rl->sr_label);
+#ifdef BFD
+   if (sa_bfd)
+   print_sabfd(sa_bfd, rtm->rtm_fmask);
+#endif
 
 #define lock(f)((rtm->rtm_rmx.rmx_locks & __CONCAT(RTV_,f)) ? 'L' : ' 
')
relative_expire = rtm->rtm_rmx.rmx_expire ?
@@ -1626,40 +1639,61 @@ void
 print_bfdmsg(struct rt_msghdr *rtm)
 {
struct bfd_msghdr *bfdm = (struct bfd_msghdr *)rtm;
+
+   printf("\n");
+   print_sabfd(>bm_sa, rtm->rtm_fmask);
+   pmsg_addrs(((char *)rtm + rtm->rtm_hdrlen), rtm->rtm_addrs);
+}
+
+void
+print_sabfd(struct sockaddr_bfd *sa_bfd, int fmask)
+{
struct timeval tv;
 
gettimeofday(, NULL);
 
-   printf(" mode ");
-   switch (bfdm->bm_mode) {
+   printf("BFD:");
+
+   /* only show the state, unless verbose or -bfd */
+   if (!verbose && ((fmask & RTF_BFD) != RTF_BFD)) {
+   printf(" %s\n", bfd_state(sa_bfd->bs_state));
+   return;
+   }
+
+   switch (sa_bfd->bs_mode) {
case BFD_MODE_ASYNC:
-   printf("async");
+   printf(" async");
break;
case BFD_MODE_DEMAND:
-   printf("demand");
+   printf(" demand");
break;
default:
-   printf("unknown %u", bfdm->bm_mode);
+   printf(" unknown %u", sa_bfd->bs_mode);
break;
}
-   printf(" state %s", bfd_state(bfdm->bm_state));
-   printf(" remotestate %s", bfd_state(bfdm->bm_remotestate));
-   printf(" laststate %s", bfd_state(bfdm->bm_laststate));
-
-   printf(" error %d", bfdm->bm_error);
-   printf(" localdiscr %u", bfdm->bm_localdiscr);
-   printf(" remotediscr %u", bfdm->bm_remotediscr);
-   printf(" localdiag %s", bfd_diag(bfdm->bm_localdiag));
-