Re: ospf6d: refactor kernel route message handling

2019-12-11 Thread Remi Locherer
On Wed, Dec 11, 2019 at 04:38:38PM +0100, Denis Fondras wrote:
> On Tue, Dec 10, 2019 at 09:51:12PM +0100, Remi Locherer wrote:
> > Unfortunately redistribute does not work anymore.
> > 
> 
> Indeed, simple tests are too simple...
> 
> Here is an updated diff.

ok remi@

> 
> Index: kroute.c
> ===
> RCS file: /cvs/src/usr.sbin/ospf6d/kroute.c,v
> retrieving revision 1.60
> diff -u -p -r1.60 kroute.c
> --- kroute.c  2 Jan 2019 21:32:55 -   1.60
> +++ kroute.c  11 Dec 2019 14:51:25 -
> @@ -80,7 +80,7 @@ struct kroute_node  *kroute_match(struct 
>  
>  int  protect_lo(void);
>  void get_rtaddrs(int, struct sockaddr *, struct sockaddr **);
> -void if_change(u_short, int, struct if_data *);
> +void if_change(u_short, int, struct if_data *, struct sockaddr_dl *);
>  void if_newaddr(u_short, struct sockaddr_in6 *,
>   struct sockaddr_in6 *, struct sockaddr_in6 *);
>  void if_deladdr(u_short, struct sockaddr_in6 *,
> @@ -90,6 +90,7 @@ voidif_announce(void *);
>  int  send_rtmsg(int, int, struct kroute *);
>  int  dispatch_rtmsg(void);
>  int  fetchtable(void);
> +int  rtmsg_process(char *, size_t); 
>  
>  RB_HEAD(kroute_tree, kroute_node)krt;
>  RB_PROTOTYPE(kroute_tree, kroute_node, entry, kroute_compare)
> @@ -801,7 +802,8 @@ get_rtaddrs(int addrs, struct sockaddr *
>  }
>  
>  void
> -if_change(u_short ifindex, int flags, struct if_data *ifd)
> +if_change(u_short ifindex, int flags, struct if_data *ifd,
> +struct sockaddr_dl *sdl)
>  {
>   struct kroute_node  *kr, *tkr;
>   struct iface*iface;
> @@ -809,7 +811,7 @@ if_change(u_short ifindex, int flags, st
>  
>   wasvalid = kif_validate(ifindex);
>  
> - if ((iface = kif_update(ifindex, flags, ifd, NULL)) == NULL) {
> + if ((iface = kif_update(ifindex, flags, ifd, sdl)) == NULL) {
>   log_warn("if_change: kif_update(%u)", ifindex);
>   return;
>   }
> @@ -1135,12 +1137,8 @@ fetchtable(void)
>  {
>   size_t   len;
>   int  mib[7];
> - char*buf, *next, *lim;
> - struct rt_msghdr*rtm;
> - struct sockaddr *sa, *rti_info[RTAX_MAX];
> - struct sockaddr_in6 *sa_in6;
> - struct sockaddr_rtlabel *label;
> - struct kroute_node  *kr;
> + char*buf;
> + int  rv;
>  
>   mib[0] = CTL_NET;
>   mib[1] = PF_ROUTE;
> @@ -1164,102 +1162,10 @@ fetchtable(void)
>   return (-1);
>   }
>  
> - lim = buf + len;
> - for (next = buf; next < lim; next += rtm->rtm_msglen) {
> - rtm = (struct rt_msghdr *)next;
> - if (rtm->rtm_version != RTM_VERSION)
> - continue;
> - sa = (struct sockaddr *)(next + rtm->rtm_hdrlen);
> - get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
> -
> - if ((sa = rti_info[RTAX_DST]) == NULL)
> - continue;
> -
> - /* Skip ARP/ND cache and broadcast routes. */
> - if (rtm->rtm_flags & (RTF_LLINFO|RTF_BROADCAST))
> - continue;
> -
> - if ((kr = calloc(1, sizeof(struct kroute_node))) == NULL) {
> - log_warn("fetchtable");
> - free(buf);
> - return (-1);
> - }
> -
> - kr->r.flags = F_KERNEL;
> - kr->r.priority = rtm->rtm_priority;
> -
> - switch (sa->sa_family) {
> - case AF_INET6:
> - kr->r.prefix =
> - ((struct sockaddr_in6 *)sa)->sin6_addr;
> - sa_in6 = (struct sockaddr_in6 *)rti_info[RTAX_NETMASK];
> - if (rtm->rtm_flags & RTF_STATIC)
> - kr->r.flags |= F_STATIC;
> - if (rtm->rtm_flags & RTF_BLACKHOLE)
> - kr->r.flags |= F_BLACKHOLE;
> - if (rtm->rtm_flags & RTF_REJECT)
> - kr->r.flags |= F_REJECT;
> - if (rtm->rtm_flags & RTF_DYNAMIC)
> - kr->r.flags |= F_DYNAMIC;
> - if (sa_in6 != NULL) {
> - if (sa_in6->sin6_len == 0)
> - break;
> - kr->r.prefixlen =
> - mask2prefixlen(sa_in6);
> - } else if (rtm->rtm_flags & RTF_HOST)
> - kr->r.prefixlen = 128;
> - else
> - fatalx("classful IPv6 route?!!");
> - break;
> - default:
> - free(kr);
> - continue;
> - }
> -
> - kr->r.ifindex = 

Re: ripd: memory leak and double free/use-after-free

2019-12-11 Thread Remi Locherer
On Wed, Dec 11, 2019 at 10:11:58AM +0100, Sebastian Benoit wrote:
> Remi Locherer(remi.loche...@relo.ch) on 2019.12.10 22:39:32 +0100:
> > On Tue, Dec 10, 2019 at 07:05:27PM +0100, Hiltjo Posthuma wrote:
> > > Hi,
> > > 
> > > While looking at the code of ripd:
> > > 
> > > I think there are (also) 2 small memleaks in a debug/error path
> > > (IMSG_REQUEST_ADD and IMSG_RESPONSE_ADD). It breaks out before adding the
> > > struct rip_route as an entry by the add_entry function (which adds it and 
> > > adds
> > > a reference count) in the log_debug block.
> > > 
> > > clang-analyzer also pointed at a double-free and use of free'd data: the
> > > function kroute_insert frees kr and returns -1 when struct kroute is 
> > > duplicate.
> > > 
> > > Patch below (untested):
> > > 
> > 
> > OK remi@
> 
> go ahead and commit it, ok benno@

Thank you for the patch! I just committed it.

Remi

> 
> > 
> > > 
> > > diff --git a/usr.sbin/ripd/kroute.c b/usr.sbin/ripd/kroute.c
> > > index 6e7449e0909..71758a75e44 100644
> > > --- a/usr.sbin/ripd/kroute.c
> > > +++ b/usr.sbin/ripd/kroute.c
> > > @@ -183,8 +183,7 @@ kr_change_fib(struct kroute_node *kr, struct kroute 
> > > *kroute, int action)
> > >  
> > >   if (kroute_insert(kr) == -1) {
> > >   log_debug("kr_update_fib: cannot insert %s",
> > > - inet_ntoa(kr->r.nexthop));
> > > - free(kr);
> > > + inet_ntoa(kroute->nexthop));
> > >   }
> > >   } else
> > >   kr->r.nexthop.s_addr = kroute->nexthop.s_addr;
> > > diff --git a/usr.sbin/ripd/ripe.c b/usr.sbin/ripd/ripe.c
> > > index d83901e245f..1f6f9b6583f 100644
> > > --- a/usr.sbin/ripd/ripe.c
> > > +++ b/usr.sbin/ripd/ripe.c
> > > @@ -351,6 +351,7 @@ ripe_dispatch_rde(int fd, short event, void *bula)
> > >   NULL) {
> > >   log_debug("unknown neighbor id %u",
> > >   imsg.hdr.peerid);
> > > + free(rr);
> > >   break;
> > >   }
> > >   add_entry(>rq_list, rr);
> > > @@ -396,6 +397,7 @@ ripe_dispatch_rde(int fd, short event, void *bula)
> > >   if ((nbr = nbr_find_peerid(imsg.hdr.peerid)) == NULL) {
> > >   log_debug("unknown neighbor id %u",
> > >   imsg.hdr.peerid);
> > > + free(rr);
> > >   break;
> > >   }
> > >   iface = nbr->iface;
> > > 
> > > -- 
> > > Kind regards,
> > > Hiltjo
> > > 
> > 
> 



Re: login_passwd: reject challenge service

2019-12-11 Thread Thomas L.
On Thu, 5 Dec 2019 13:35:40 +
"Lindner, Thomas 1. (Nokia - DE/Nuremberg)"
 wrote:
> The (untested) patch below makes login_passwd behave as described in
> the manpage.

I've now been able to test the patch and login/su/doas/ssh still work
as expected. All the other login_* styles in base are well behaved. Is
there a reason that this should not be done?

Kind regards,

Thomas

diff --git libexec/login_passwd/login.c libexec/login_passwd/login.c
index 09e683a7366..486d8bfcb8a 100644
--- libexec/login_passwd/login.c
+++ libexec/login_passwd/login.c
@@ -137,7 +137,7 @@ main(int argc, char **argv)
password = readpassphrase("Password:", pbuf,
sizeof(pbuf), RPP_ECHO_OFF); break;
case MODE_CHALLENGE:
-   fprintf(back, BI_AUTH "\n");
+   fprintf(back, BI_SILENT "\n");
exit(0);
break;
default:



Re: patch: make sdiff tty-aware

2019-12-11 Thread Theo de Raadt
I'm not sure I understand the goal of the signal handler.

sdiff is moving forward through the file, only.  If you are in a pager,
you want to increase the width for the later output not yet visible?
the normal way one does that in programs which don't backtrack and
re-output, is by restarting the program.

You don't want a mix of shorter, then longer.  If you are using a pager,
I suspect at least one of the next lines is already be buffered out.  So
I don't understand how this will create output which looks correct.

I think you should remove the signal handler.

Marc Espie  wrote:

> This patch allows sdiff to auto-detect tty width,
> by passing -w auto
> 
> More importantly, sdiff will adjust its variables on the fly for
> subsequent lines (I don't know if redrawing the current
> lines when the tty changes is advisable).
> 
> It's pretty straightforward, tested thru sysmerge.
> 
> Doesn't seem it's standardized anywhere, I'm not sure having a functionality 
> that's
> not in gnu-sdiff would be an issue ?
> 
> 
> Index: sdiff.c
> ===
> RCS file: /cvs/src/usr.bin/sdiff/sdiff.c,v
> retrieving revision 1.37
> diff -u -p -r1.37 sdiff.c
> --- sdiff.c   28 Sep 2018 18:21:52 -  1.37
> +++ sdiff.c   11 Dec 2019 16:42:25 -
> @@ -17,12 +17,14 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include "common.h"
>  #include "extern.h"
> @@ -43,7 +45,9 @@ struct diffline {
>  };
>  
>  static void astrcat(char **, const char *);
> +static void compute_width(void);
>  static void enqueue(char *, char, char *);
> +static void find_width(void);
>  static char *mktmpcpy(const char *);
>  static void freediff(struct diffline *);
>  static void int_usage(void);
> @@ -55,12 +59,16 @@ static void printd(FILE *, size_t);
>  static void println(const char *, const char, const char *);
>  static void processq(void);
>  static void prompt(const char *, const char *);
> +static void recompute_width(void);
>  __dead static void usage(void);
> +static void window_changed(int);
>  static char *xfgets(FILE *);
>  
>  SIMPLEQ_HEAD(, diffline) diffhead = SIMPLEQ_HEAD_INITIALIZER(diffhead);
>  size_tline_width;/* width of a line (two columns and divider) */
>  size_twidth; /* width of each column */
> +size_twflag = WIDTH;
> +volatile sig_atomic_t got_signal = 0;
>  size_tfile1ln, file2ln;  /* line number of file1 and file2 */
>  int   Iflag = 0; /* ignore sets matching regexp */
>  int   lflag; /* print only left column for identical lines */
> @@ -153,11 +161,47 @@ FAIL:
>   exit(2);
>  }
>  
> +static void
> +window_changed(int sig __attribute__((__unused__)))
> +{
> + got_signal = 1;
> +}
> +
> +static void
> +find_width(void)
> +{
> + struct winsize ws;
> +
> + if (ioctl(0, TIOCGWINSZ, ) != 0) {
> + wflag = WIDTH;
> + signal(SIGWINCH, SIG_DFL);
> + } else
> + wflag = ws.ws_col;
> +}
> +
> +static void
> +recompute_width(void)
> +{
> + find_width();
> + compute_width();
> +}
> +
> +static void
> +compute_width(void)
> +{
> + /* Subtract column divider and divide by two. */
> + width = (wflag - 3) / 2;
> + /* Make sure line_width can fit in size_t. */
> + if (width > (SIZE_MAX - 3) / 2)
> + errx(2, "width is too large: %zu", width);
> + line_width = width * 2 + 3;
> +}
> +
>  int
>  main(int argc, char **argv)
>  {
>   FILE *diffpipe, *file1, *file2;
> - size_t diffargc = 0, wflag = WIDTH;
> + size_t diffargc = 0;
>   int ch, fd[2], status;
>   pid_t pid;
>   const char *outfile = NULL;
> @@ -236,6 +280,11 @@ main(int argc, char **argv)
>   diffargv[diffargc++] = "-w";
>   break;
>   case 'w':
> + if (strcmp(optarg, "auto") == 0) {
> + signal(SIGWINCH, window_changed);
> + find_width();
> + break;
> + }
>   wflag = strtonum(optarg, WIDTH_MIN,
>   INT_MAX, );
>   if (errstr)
> @@ -273,7 +322,7 @@ main(int argc, char **argv)
>   if (unveil(_PATH_BSHELL, "x") == -1)
>   err(2, "unveil");
>   }
> - if (pledge("stdio rpath wpath cpath proc exec", NULL) == -1)
> + if (pledge("stdio rpath wpath cpath proc exec tty", NULL) == -1)
>   err(2, "pledge");
>  
>   /*
> @@ -302,12 +351,7 @@ main(int argc, char **argv)
>   /* Add NULL to end of array to indicate end of array. */
>   diffargv[diffargc++] = NULL;
>  
> - /* Subtract column divider and divide by two. */
> - width = (wflag - 3) / 2;
> - /* Make sure line_width can fit in size_t. */
> - if (width > (SIZE_MAX - 3) / 

Re: ospf6d: convert sendto() to sendmsg()

2019-12-11 Thread Claudio Jeker
On Wed, Dec 11, 2019 at 04:52:53PM +0100, Denis Fondras wrote:
> Use sendmsg() instead of sendto() like ospfd(8) does.
> 
> Index: database.c
> ===
> RCS file: /cvs/src/usr.sbin/ospf6d/database.c,v
> retrieving revision 1.16
> diff -u -p -r1.16 database.c
> --- database.c10 May 2019 13:50:34 -  1.16
> +++ database.c8 Dec 2019 14:55:57 -
> @@ -147,7 +147,7 @@ send_db_description(struct nbr *nbr)
>   goto fail;
>  
>   /* transmit packet */
> - ret = send_packet(nbr->iface, buf->buf, buf->wpos, );
> + ret = send_packet(nbr->iface, buf, );
>  done:
>   ibuf_free(buf);
>   return (ret);
> Index: hello.c
> ===
> RCS file: /cvs/src/usr.sbin/ospf6d/hello.c,v
> retrieving revision 1.18
> diff -u -p -r1.18 hello.c
> --- hello.c   22 Feb 2018 07:43:29 -  1.18
> +++ hello.c   8 Dec 2019 14:55:57 -
> @@ -104,7 +104,7 @@ send_hello(struct iface *iface)
>   if (upd_ospf_hdr(buf, iface))
>   goto fail;
>  
> - ret = send_packet(iface, buf->buf, buf->wpos, );
> + ret = send_packet(iface, buf, );
>  
>   ibuf_free(buf);
>   return (ret);
> Index: lsack.c
> ===
> RCS file: /cvs/src/usr.sbin/ospf6d/lsack.c,v
> retrieving revision 1.6
> diff -u -p -r1.6 lsack.c
> --- lsack.c   25 Oct 2014 03:23:49 -  1.6
> +++ lsack.c   8 Dec 2019 14:55:57 -
> @@ -55,7 +55,7 @@ send_ls_ack(struct iface *iface, struct 
>   if (upd_ospf_hdr(buf, iface))
>   goto fail;
>  
> - ret = send_packet(iface, buf->buf, buf->wpos, );
> + ret = send_packet(iface, buf, );
>  
>   ibuf_free(buf);
>   return (ret);
> Index: lsreq.c
> ===
> RCS file: /cvs/src/usr.sbin/ospf6d/lsreq.c,v
> retrieving revision 1.9
> diff -u -p -r1.9 lsreq.c
> --- lsreq.c   10 May 2019 13:50:34 -  1.9
> +++ lsreq.c   8 Dec 2019 14:55:58 -
> @@ -77,7 +77,7 @@ send_ls_req(struct nbr *nbr)
>   if (upd_ospf_hdr(buf, nbr->iface))
>   goto fail;
>  
> - ret = send_packet(nbr->iface, buf->buf, buf->wpos, );
> + ret = send_packet(nbr->iface, buf, );
>  
>   ibuf_free(buf);
>   return (ret);
> Index: lsupdate.c
> ===
> RCS file: /cvs/src/usr.sbin/ospf6d/lsupdate.c,v
> retrieving revision 1.13
> diff -u -p -r1.13 lsupdate.c
> --- lsupdate.c28 Jan 2015 22:03:17 -  1.13
> +++ lsupdate.c8 Dec 2019 14:55:58 -
> @@ -227,7 +227,7 @@ send_ls_update(struct ibuf *buf, struct 
>   if (upd_ospf_hdr(buf, iface))
>   goto fail;
>  
> - ret = send_packet(iface, buf->buf, buf->wpos, );
> + ret = send_packet(iface, buf, );
>  
>   ibuf_free(buf);
>   return (ret);
> Index: ospfe.h
> ===
> RCS file: /cvs/src/usr.sbin/ospf6d/ospfe.h,v
> retrieving revision 1.19
> diff -u -p -r1.19 ospfe.h
> --- ospfe.h   25 Oct 2014 03:23:49 -  1.19
> +++ ospfe.h   8 Dec 2019 14:55:58 -
> @@ -228,7 +228,7 @@ struct lsa_hdr*lsa_hdr_new(void);
>  /* packet.c */
>  int   gen_ospf_hdr(struct ibuf *, struct iface *, u_int8_t);
>  int   upd_ospf_hdr(struct ibuf *, struct iface *);
> -int   send_packet(struct iface *, void *, size_t, struct in6_addr *);
> +int   send_packet(struct iface *, struct ibuf *, struct in6_addr *);
>  void  recv_packet(int, short, void *);
>  
>  char *pkt_ptr;   /* packet buffer */
> Index: packet.c
> ===
> RCS file: /cvs/src/usr.sbin/ospf6d/packet.c,v
> retrieving revision 1.15
> diff -u -p -r1.15 packet.c
> --- packet.c  10 May 2019 01:29:31 -  1.15
> +++ packet.c  8 Dec 2019 14:55:58 -
> @@ -78,10 +78,12 @@ upd_ospf_hdr(struct ibuf *buf, struct if
>  
>  /* send and receive packets */
>  int
> -send_packet(struct iface *iface, void *pkt, size_t len,
> +send_packet(struct iface *iface, struct ibuf *buf,
>  struct in6_addr *dst)
>  {
> - struct sockaddr_in6  sa6;
> + struct sockaddr_in6 sa6;
> + struct msghdr   msg;
> + struct ioveciov[2];

There is only one iov in use so make this iov[1];

>  
>   /* setup buffer */
>   bzero(, sizeof(sa6));
> @@ -102,8 +104,15 @@ send_packet(struct iface *iface, void *p
>   return (-1);
>   }
>  
> - if (sendto(iface->fd, pkt, len, 0, (struct sockaddr *),
> - sizeof(sa6)) == -1) {
> + bzero(, sizeof(msg));
> + msg.msg_name = 
> + msg.msg_namelen = sizeof(sa6);
> + iov[0].iov_base = buf->buf;
> + iov[0].iov_len = ibuf_size(buf);
> + msg.msg_iov = iov;
> + msg.msg_iovlen = 1;
> +
> + if (sendmsg(iface->fd, , 0) == -1) {
>  

re-enable iwm(4) firmware Tx retries

2019-12-11 Thread Stefan Sperling
Back in February we disabled iwm firmware Tx retries at lower rates.
This improved MiRA's Tx rate selection because bad rates do actually
look bad, rather than being compensated for by firmware retries.
The result was increased Tx throughput. The original discussion is here:
https://marc.info/?l=openbsd-tech=155067514103877=2

This approach has a drawback: If a given Tx rate is bad we will lose all
frames sent at that rate. This results in user-visiable packet loss.
The diff below attempts to reduce such user-visible packet loss by
allowing the firmware to retry at lower rates again, but only if MiRA
is not currently probing for a new rate.

I hope this will reduce observable packet loss while still selecting
the best Tx rate. Lightly tested on 8265. More tests welcome.

diff refs/heads/master refs/heads/probing-fixed-rate
blob - dff9f8047f5c0300a4ddde4d9b090f58c28dd8f9 (mode 644)
blob + 8608228c4d05ae6711e55644d50114bacd2e79e3 (mode 600)
--- sys/dev/pci/if_iwm.c
+++ sys/dev/pci/if_iwm.c
@@ -453,6 +453,8 @@ int iwm_run(struct iwm_softc *);
 intiwm_run_stop(struct iwm_softc *);
 struct ieee80211_node *iwm_node_alloc(struct ieee80211com *);
 void   iwm_calib_timeout(void *);
+void   iwm_setrates_task(void *);
+void   iwm_setrates(struct iwm_node *);
 intiwm_media_change(struct ifnet *);
 void   iwm_newstate_task(void *);
 intiwm_newstate(struct ieee80211com *, enum ieee80211_state, int);
@@ -4161,13 +4163,21 @@ iwm_rx_tx_cmd_single(struct iwm_softc *sc, struct iwm_
if (txfail)
in->in_mn.txfail += tx_resp->frame_count;
if (ic->ic_state == IEEE80211_S_RUN && !in->ht_force_cck) {
-   int otxmcs = ni->ni_txmcs;
-
ieee80211_mira_choose(>in_mn, ic, >in_ni);
+   /* 
+* If MiRA has chosen a new TX rate we must update
+* the firwmare's LQ rate table from process context.
+* ni_txmcs may change again before the task runs so
+* cache the chosen rate in the iwm_node structure.
+*/
+   if (ni->ni_txmcs != in->chosen_txmcs) {
+   in->chosen_txmcs = ni->ni_txmcs;
+   iwm_add_task(sc, systq, >setrates_task);
+   }
 
/* Fall back to CCK rates if MCS 0 is failing. */
if (txfail && IEEE80211_IS_CHAN_2GHZ(ni->ni_chan) &&
-   otxmcs == 0 && ni->ni_txmcs == 0)
+   in->chosen_txmcs == 0 && ni->ni_txmcs == 0)
iwm_enable_ht_cck_fallback(sc, in);
}
}
@@ -4693,14 +4703,35 @@ iwm_tx_fill_cmd(struct iwm_softc *sc, struct iwm_node 
ridx = sc->sc_fixed_ridx;
} else if (ic->ic_fixed_rate != -1) {
ridx = sc->sc_fixed_ridx;
-   } else if ((ni->ni_flags & IEEE80211_NODE_HT) && !in->ht_force_cck) {
+   } else if ((ni->ni_flags & IEEE80211_NODE_HT) && !in->ht_force_cck &&
+   ieee80211_mira_is_probing(>in_mn)) {
+   /* Keep Tx rate constant while mira is probing. */
ridx = iwm_mcs2ridx[ni->ni_txmcs];
-   } else {
+   } else if ((ni->ni_flags & IEEE80211_NODE_HT) && in->ht_force_cck) {
uint8_t rval;
rval = (rs->rs_rates[ni->ni_txrate] & IEEE80211_RATE_VAL);
ridx = iwm_rval2ridx(rval);
if (ridx < min_ridx)
ridx = min_ridx;
+   } else {
+   int i;
+   /* Use firmware rateset retry table. */
+   tx->initial_rate_index = 0;
+   tx->tx_flags |= htole32(IWM_TX_CMD_FLG_STA_RATE);
+   if (ni->ni_flags & IEEE80211_NODE_HT) {
+   ridx = iwm_mcs2ridx[ni->ni_txmcs];
+   return _rates[ridx];
+   }
+   ridx = (IEEE80211_IS_CHAN_5GHZ(ni->ni_chan)) ?
+   IWM_RIDX_OFDM : IWM_RIDX_CCK;
+   for (i = 0; i < ni->ni_rates.rs_nrates; i++) {
+   if (iwm_rates[i].rate == (ni->ni_txrate &
+   IEEE80211_RATE_VAL)) {
+   ridx = i;
+   break;
+   }
+   }
+   return _rates[ridx];
}
 
rinfo = _rates[ridx];
@@ -6631,6 +6662,9 @@ iwm_run(struct iwm_softc *sc)
/* Start at lowest available bit-rate, AMRR will raise. */
in->in_ni.ni_txrate = 0;
in->in_ni.ni_txmcs = 0;
+   in->chosen_txrate = 0;
+   in->chosen_txmcs = 0;
+   iwm_setrates(in);
 
timeout_add_msec(>sc_calib_to, 500);
iwm_led_enable(sc);
@@ -6703,6 +6737,16 @@ iwm_calib_timeout(void *arg)
((ni->ni_flags & IEEE80211_NODE_HT) == 0 || in->ht_force_cck) &&
ic->ic_opmode 

Re: ospf6d: convert sendto() to sendmsg()

2019-12-11 Thread Denis Fondras
On Wed, Dec 11, 2019 at 07:06:26PM +0100, Claudio Jeker wrote:
> While it makes sense to pass the ibuf like in ospfd I see no reason to
> switch to sendmsg(). In ospfd this is done to prepend the IP header but
> that seems not needed here. Is there another reason to switch to
> sendmsg()?
> 

Nothing more than what deraadt@ said, just make the code look similar to ospfd.

> -- 
> :wq Claudio



Re: ospf6d: convert sendto() to sendmsg()

2019-12-11 Thread Theo de Raadt
Claudio Jeker  wrote:

> On Wed, Dec 11, 2019 at 04:52:53PM +0100, Denis Fondras wrote:
> > Use sendmsg() instead of sendto() like ospfd(8) does.
> > 
> > Index: database.c
> > ===
> > RCS file: /cvs/src/usr.sbin/ospf6d/database.c,v
> > retrieving revision 1.16
> > diff -u -p -r1.16 database.c
> > --- database.c  10 May 2019 13:50:34 -  1.16
> > +++ database.c  8 Dec 2019 14:55:57 -
> > @@ -147,7 +147,7 @@ send_db_description(struct nbr *nbr)
> > goto fail;
> >  
> > /* transmit packet */
> > -   ret = send_packet(nbr->iface, buf->buf, buf->wpos, );
> > +   ret = send_packet(nbr->iface, buf, );
> >  done:
> > ibuf_free(buf);
> > return (ret);
> > Index: hello.c
> > ===
> > RCS file: /cvs/src/usr.sbin/ospf6d/hello.c,v
> > retrieving revision 1.18
> > diff -u -p -r1.18 hello.c
> > --- hello.c 22 Feb 2018 07:43:29 -  1.18
> > +++ hello.c 8 Dec 2019 14:55:57 -
> > @@ -104,7 +104,7 @@ send_hello(struct iface *iface)
> > if (upd_ospf_hdr(buf, iface))
> > goto fail;
> >  
> > -   ret = send_packet(iface, buf->buf, buf->wpos, );
> > +   ret = send_packet(iface, buf, );
> >  
> > ibuf_free(buf);
> > return (ret);
> > Index: lsack.c
> > ===
> > RCS file: /cvs/src/usr.sbin/ospf6d/lsack.c,v
> > retrieving revision 1.6
> > diff -u -p -r1.6 lsack.c
> > --- lsack.c 25 Oct 2014 03:23:49 -  1.6
> > +++ lsack.c 8 Dec 2019 14:55:57 -
> > @@ -55,7 +55,7 @@ send_ls_ack(struct iface *iface, struct 
> > if (upd_ospf_hdr(buf, iface))
> > goto fail;
> >  
> > -   ret = send_packet(iface, buf->buf, buf->wpos, );
> > +   ret = send_packet(iface, buf, );
> >  
> > ibuf_free(buf);
> > return (ret);
> > Index: lsreq.c
> > ===
> > RCS file: /cvs/src/usr.sbin/ospf6d/lsreq.c,v
> > retrieving revision 1.9
> > diff -u -p -r1.9 lsreq.c
> > --- lsreq.c 10 May 2019 13:50:34 -  1.9
> > +++ lsreq.c 8 Dec 2019 14:55:58 -
> > @@ -77,7 +77,7 @@ send_ls_req(struct nbr *nbr)
> > if (upd_ospf_hdr(buf, nbr->iface))
> > goto fail;
> >  
> > -   ret = send_packet(nbr->iface, buf->buf, buf->wpos, );
> > +   ret = send_packet(nbr->iface, buf, );
> >  
> > ibuf_free(buf);
> > return (ret);
> > Index: lsupdate.c
> > ===
> > RCS file: /cvs/src/usr.sbin/ospf6d/lsupdate.c,v
> > retrieving revision 1.13
> > diff -u -p -r1.13 lsupdate.c
> > --- lsupdate.c  28 Jan 2015 22:03:17 -  1.13
> > +++ lsupdate.c  8 Dec 2019 14:55:58 -
> > @@ -227,7 +227,7 @@ send_ls_update(struct ibuf *buf, struct 
> > if (upd_ospf_hdr(buf, iface))
> > goto fail;
> >  
> > -   ret = send_packet(iface, buf->buf, buf->wpos, );
> > +   ret = send_packet(iface, buf, );
> >  
> > ibuf_free(buf);
> > return (ret);
> > Index: ospfe.h
> > ===
> > RCS file: /cvs/src/usr.sbin/ospf6d/ospfe.h,v
> > retrieving revision 1.19
> > diff -u -p -r1.19 ospfe.h
> > --- ospfe.h 25 Oct 2014 03:23:49 -  1.19
> > +++ ospfe.h 8 Dec 2019 14:55:58 -
> > @@ -228,7 +228,7 @@ struct lsa_hdr  *lsa_hdr_new(void);
> >  /* packet.c */
> >  int gen_ospf_hdr(struct ibuf *, struct iface *, u_int8_t);
> >  int upd_ospf_hdr(struct ibuf *, struct iface *);
> > -int send_packet(struct iface *, void *, size_t, struct in6_addr *);
> > +int send_packet(struct iface *, struct ibuf *, struct in6_addr *);
> >  voidrecv_packet(int, short, void *);
> >  
> >  char   *pkt_ptr;   /* packet buffer */
> > Index: packet.c
> > ===
> > RCS file: /cvs/src/usr.sbin/ospf6d/packet.c,v
> > retrieving revision 1.15
> > diff -u -p -r1.15 packet.c
> > --- packet.c10 May 2019 01:29:31 -  1.15
> > +++ packet.c8 Dec 2019 14:55:58 -
> > @@ -78,10 +78,12 @@ upd_ospf_hdr(struct ibuf *buf, struct if
> >  
> >  /* send and receive packets */
> >  int
> > -send_packet(struct iface *iface, void *pkt, size_t len,
> > +send_packet(struct iface *iface, struct ibuf *buf,
> >  struct in6_addr *dst)
> >  {
> > -   struct sockaddr_in6  sa6;
> > +   struct sockaddr_in6 sa6;
> > +   struct msghdr   msg;
> > +   struct ioveciov[2];
> >  
> > /* setup buffer */
> > bzero(, sizeof(sa6));
> > @@ -102,8 +104,15 @@ send_packet(struct iface *iface, void *p
> > return (-1);
> > }
> >  
> > -   if (sendto(iface->fd, pkt, len, 0, (struct sockaddr *),
> > -   sizeof(sa6)) == -1) {
> > +   bzero(, sizeof(msg));
> > +   msg.msg_name = 
> > +   msg.msg_namelen = sizeof(sa6);
> > +   

Re: ospf6d: convert sendto() to sendmsg()

2019-12-11 Thread Claudio Jeker
On Wed, Dec 11, 2019 at 04:52:53PM +0100, Denis Fondras wrote:
> Use sendmsg() instead of sendto() like ospfd(8) does.
> 
> Index: database.c
> ===
> RCS file: /cvs/src/usr.sbin/ospf6d/database.c,v
> retrieving revision 1.16
> diff -u -p -r1.16 database.c
> --- database.c10 May 2019 13:50:34 -  1.16
> +++ database.c8 Dec 2019 14:55:57 -
> @@ -147,7 +147,7 @@ send_db_description(struct nbr *nbr)
>   goto fail;
>  
>   /* transmit packet */
> - ret = send_packet(nbr->iface, buf->buf, buf->wpos, );
> + ret = send_packet(nbr->iface, buf, );
>  done:
>   ibuf_free(buf);
>   return (ret);
> Index: hello.c
> ===
> RCS file: /cvs/src/usr.sbin/ospf6d/hello.c,v
> retrieving revision 1.18
> diff -u -p -r1.18 hello.c
> --- hello.c   22 Feb 2018 07:43:29 -  1.18
> +++ hello.c   8 Dec 2019 14:55:57 -
> @@ -104,7 +104,7 @@ send_hello(struct iface *iface)
>   if (upd_ospf_hdr(buf, iface))
>   goto fail;
>  
> - ret = send_packet(iface, buf->buf, buf->wpos, );
> + ret = send_packet(iface, buf, );
>  
>   ibuf_free(buf);
>   return (ret);
> Index: lsack.c
> ===
> RCS file: /cvs/src/usr.sbin/ospf6d/lsack.c,v
> retrieving revision 1.6
> diff -u -p -r1.6 lsack.c
> --- lsack.c   25 Oct 2014 03:23:49 -  1.6
> +++ lsack.c   8 Dec 2019 14:55:57 -
> @@ -55,7 +55,7 @@ send_ls_ack(struct iface *iface, struct 
>   if (upd_ospf_hdr(buf, iface))
>   goto fail;
>  
> - ret = send_packet(iface, buf->buf, buf->wpos, );
> + ret = send_packet(iface, buf, );
>  
>   ibuf_free(buf);
>   return (ret);
> Index: lsreq.c
> ===
> RCS file: /cvs/src/usr.sbin/ospf6d/lsreq.c,v
> retrieving revision 1.9
> diff -u -p -r1.9 lsreq.c
> --- lsreq.c   10 May 2019 13:50:34 -  1.9
> +++ lsreq.c   8 Dec 2019 14:55:58 -
> @@ -77,7 +77,7 @@ send_ls_req(struct nbr *nbr)
>   if (upd_ospf_hdr(buf, nbr->iface))
>   goto fail;
>  
> - ret = send_packet(nbr->iface, buf->buf, buf->wpos, );
> + ret = send_packet(nbr->iface, buf, );
>  
>   ibuf_free(buf);
>   return (ret);
> Index: lsupdate.c
> ===
> RCS file: /cvs/src/usr.sbin/ospf6d/lsupdate.c,v
> retrieving revision 1.13
> diff -u -p -r1.13 lsupdate.c
> --- lsupdate.c28 Jan 2015 22:03:17 -  1.13
> +++ lsupdate.c8 Dec 2019 14:55:58 -
> @@ -227,7 +227,7 @@ send_ls_update(struct ibuf *buf, struct 
>   if (upd_ospf_hdr(buf, iface))
>   goto fail;
>  
> - ret = send_packet(iface, buf->buf, buf->wpos, );
> + ret = send_packet(iface, buf, );
>  
>   ibuf_free(buf);
>   return (ret);
> Index: ospfe.h
> ===
> RCS file: /cvs/src/usr.sbin/ospf6d/ospfe.h,v
> retrieving revision 1.19
> diff -u -p -r1.19 ospfe.h
> --- ospfe.h   25 Oct 2014 03:23:49 -  1.19
> +++ ospfe.h   8 Dec 2019 14:55:58 -
> @@ -228,7 +228,7 @@ struct lsa_hdr*lsa_hdr_new(void);
>  /* packet.c */
>  int   gen_ospf_hdr(struct ibuf *, struct iface *, u_int8_t);
>  int   upd_ospf_hdr(struct ibuf *, struct iface *);
> -int   send_packet(struct iface *, void *, size_t, struct in6_addr *);
> +int   send_packet(struct iface *, struct ibuf *, struct in6_addr *);
>  void  recv_packet(int, short, void *);
>  
>  char *pkt_ptr;   /* packet buffer */
> Index: packet.c
> ===
> RCS file: /cvs/src/usr.sbin/ospf6d/packet.c,v
> retrieving revision 1.15
> diff -u -p -r1.15 packet.c
> --- packet.c  10 May 2019 01:29:31 -  1.15
> +++ packet.c  8 Dec 2019 14:55:58 -
> @@ -78,10 +78,12 @@ upd_ospf_hdr(struct ibuf *buf, struct if
>  
>  /* send and receive packets */
>  int
> -send_packet(struct iface *iface, void *pkt, size_t len,
> +send_packet(struct iface *iface, struct ibuf *buf,
>  struct in6_addr *dst)
>  {
> - struct sockaddr_in6  sa6;
> + struct sockaddr_in6 sa6;
> + struct msghdr   msg;
> + struct ioveciov[2];
>  
>   /* setup buffer */
>   bzero(, sizeof(sa6));
> @@ -102,8 +104,15 @@ send_packet(struct iface *iface, void *p
>   return (-1);
>   }
>  
> - if (sendto(iface->fd, pkt, len, 0, (struct sockaddr *),
> - sizeof(sa6)) == -1) {
> + bzero(, sizeof(msg));
> + msg.msg_name = 
> + msg.msg_namelen = sizeof(sa6);
> + iov[0].iov_base = buf->buf;
> + iov[0].iov_len = ibuf_size(buf);
> + msg.msg_iov = iov;
> + msg.msg_iovlen = 1;
> +
> + if (sendmsg(iface->fd, , 0) == -1) {
>   log_warn("send_packet: error sending 

patch: make sdiff tty-aware

2019-12-11 Thread Marc Espie
This patch allows sdiff to auto-detect tty width,
by passing -w auto

More importantly, sdiff will adjust its variables on the fly for
subsequent lines (I don't know if redrawing the current
lines when the tty changes is advisable).

It's pretty straightforward, tested thru sysmerge.

Doesn't seem it's standardized anywhere, I'm not sure having a functionality 
that's
not in gnu-sdiff would be an issue ?


Index: sdiff.c
===
RCS file: /cvs/src/usr.bin/sdiff/sdiff.c,v
retrieving revision 1.37
diff -u -p -r1.37 sdiff.c
--- sdiff.c 28 Sep 2018 18:21:52 -  1.37
+++ sdiff.c 11 Dec 2019 16:42:25 -
@@ -17,12 +17,14 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
 
 #include "common.h"
 #include "extern.h"
@@ -43,7 +45,9 @@ struct diffline {
 };
 
 static void astrcat(char **, const char *);
+static void compute_width(void);
 static void enqueue(char *, char, char *);
+static void find_width(void);
 static char *mktmpcpy(const char *);
 static void freediff(struct diffline *);
 static void int_usage(void);
@@ -55,12 +59,16 @@ static void printd(FILE *, size_t);
 static void println(const char *, const char, const char *);
 static void processq(void);
 static void prompt(const char *, const char *);
+static void recompute_width(void);
 __dead static void usage(void);
+static void window_changed(int);
 static char *xfgets(FILE *);
 
 SIMPLEQ_HEAD(, diffline) diffhead = SIMPLEQ_HEAD_INITIALIZER(diffhead);
 size_t  line_width;/* width of a line (two columns and divider) */
 size_t  width; /* width of each column */
+size_t  wflag = WIDTH;
+volatile sig_atomic_t got_signal = 0;
 size_t  file1ln, file2ln;  /* line number of file1 and file2 */
 int Iflag = 0; /* ignore sets matching regexp */
 int lflag; /* print only left column for identical lines */
@@ -153,11 +161,47 @@ FAIL:
exit(2);
 }
 
+static void
+window_changed(int sig __attribute__((__unused__)))
+{
+   got_signal = 1;
+}
+
+static void
+find_width(void)
+{
+   struct winsize ws;
+
+   if (ioctl(0, TIOCGWINSZ, ) != 0) {
+   wflag = WIDTH;
+   signal(SIGWINCH, SIG_DFL);
+   } else
+   wflag = ws.ws_col;
+}
+
+static void
+recompute_width(void)
+{
+   find_width();
+   compute_width();
+}
+
+static void
+compute_width(void)
+{
+   /* Subtract column divider and divide by two. */
+   width = (wflag - 3) / 2;
+   /* Make sure line_width can fit in size_t. */
+   if (width > (SIZE_MAX - 3) / 2)
+   errx(2, "width is too large: %zu", width);
+   line_width = width * 2 + 3;
+}
+
 int
 main(int argc, char **argv)
 {
FILE *diffpipe, *file1, *file2;
-   size_t diffargc = 0, wflag = WIDTH;
+   size_t diffargc = 0;
int ch, fd[2], status;
pid_t pid;
const char *outfile = NULL;
@@ -236,6 +280,11 @@ main(int argc, char **argv)
diffargv[diffargc++] = "-w";
break;
case 'w':
+   if (strcmp(optarg, "auto") == 0) {
+   signal(SIGWINCH, window_changed);
+   find_width();
+   break;
+   }
wflag = strtonum(optarg, WIDTH_MIN,
INT_MAX, );
if (errstr)
@@ -273,7 +322,7 @@ main(int argc, char **argv)
if (unveil(_PATH_BSHELL, "x") == -1)
err(2, "unveil");
}
-   if (pledge("stdio rpath wpath cpath proc exec", NULL) == -1)
+   if (pledge("stdio rpath wpath cpath proc exec tty", NULL) == -1)
err(2, "pledge");
 
/*
@@ -302,12 +351,7 @@ main(int argc, char **argv)
/* Add NULL to end of array to indicate end of array. */
diffargv[diffargc++] = NULL;
 
-   /* Subtract column divider and divide by two. */
-   width = (wflag - 3) / 2;
-   /* Make sure line_width can fit in size_t. */
-   if (width > (SIZE_MAX - 3) / 2)
-   errx(2, "width is too large: %zu", width);
-   line_width = width * 2 + 3;
+   compute_width();
 
if (pipe(fd))
err(2, "pipe");
@@ -522,6 +566,11 @@ static void
 println(const char *s1, const char div, const char *s2)
 {
size_t col;
+
+   if (got_signal) {
+   got_signal = 0;
+   recompute_width();
+   }
 
/* Print first column.  Skips if s1 == NULL. */
col = 0;



ospf6d: convert sendto() to sendmsg()

2019-12-11 Thread Denis Fondras
Use sendmsg() instead of sendto() like ospfd(8) does.

Index: database.c
===
RCS file: /cvs/src/usr.sbin/ospf6d/database.c,v
retrieving revision 1.16
diff -u -p -r1.16 database.c
--- database.c  10 May 2019 13:50:34 -  1.16
+++ database.c  8 Dec 2019 14:55:57 -
@@ -147,7 +147,7 @@ send_db_description(struct nbr *nbr)
goto fail;
 
/* transmit packet */
-   ret = send_packet(nbr->iface, buf->buf, buf->wpos, );
+   ret = send_packet(nbr->iface, buf, );
 done:
ibuf_free(buf);
return (ret);
Index: hello.c
===
RCS file: /cvs/src/usr.sbin/ospf6d/hello.c,v
retrieving revision 1.18
diff -u -p -r1.18 hello.c
--- hello.c 22 Feb 2018 07:43:29 -  1.18
+++ hello.c 8 Dec 2019 14:55:57 -
@@ -104,7 +104,7 @@ send_hello(struct iface *iface)
if (upd_ospf_hdr(buf, iface))
goto fail;
 
-   ret = send_packet(iface, buf->buf, buf->wpos, );
+   ret = send_packet(iface, buf, );
 
ibuf_free(buf);
return (ret);
Index: lsack.c
===
RCS file: /cvs/src/usr.sbin/ospf6d/lsack.c,v
retrieving revision 1.6
diff -u -p -r1.6 lsack.c
--- lsack.c 25 Oct 2014 03:23:49 -  1.6
+++ lsack.c 8 Dec 2019 14:55:57 -
@@ -55,7 +55,7 @@ send_ls_ack(struct iface *iface, struct 
if (upd_ospf_hdr(buf, iface))
goto fail;
 
-   ret = send_packet(iface, buf->buf, buf->wpos, );
+   ret = send_packet(iface, buf, );
 
ibuf_free(buf);
return (ret);
Index: lsreq.c
===
RCS file: /cvs/src/usr.sbin/ospf6d/lsreq.c,v
retrieving revision 1.9
diff -u -p -r1.9 lsreq.c
--- lsreq.c 10 May 2019 13:50:34 -  1.9
+++ lsreq.c 8 Dec 2019 14:55:58 -
@@ -77,7 +77,7 @@ send_ls_req(struct nbr *nbr)
if (upd_ospf_hdr(buf, nbr->iface))
goto fail;
 
-   ret = send_packet(nbr->iface, buf->buf, buf->wpos, );
+   ret = send_packet(nbr->iface, buf, );
 
ibuf_free(buf);
return (ret);
Index: lsupdate.c
===
RCS file: /cvs/src/usr.sbin/ospf6d/lsupdate.c,v
retrieving revision 1.13
diff -u -p -r1.13 lsupdate.c
--- lsupdate.c  28 Jan 2015 22:03:17 -  1.13
+++ lsupdate.c  8 Dec 2019 14:55:58 -
@@ -227,7 +227,7 @@ send_ls_update(struct ibuf *buf, struct 
if (upd_ospf_hdr(buf, iface))
goto fail;
 
-   ret = send_packet(iface, buf->buf, buf->wpos, );
+   ret = send_packet(iface, buf, );
 
ibuf_free(buf);
return (ret);
Index: ospfe.h
===
RCS file: /cvs/src/usr.sbin/ospf6d/ospfe.h,v
retrieving revision 1.19
diff -u -p -r1.19 ospfe.h
--- ospfe.h 25 Oct 2014 03:23:49 -  1.19
+++ ospfe.h 8 Dec 2019 14:55:58 -
@@ -228,7 +228,7 @@ struct lsa_hdr  *lsa_hdr_new(void);
 /* packet.c */
 int gen_ospf_hdr(struct ibuf *, struct iface *, u_int8_t);
 int upd_ospf_hdr(struct ibuf *, struct iface *);
-int send_packet(struct iface *, void *, size_t, struct in6_addr *);
+int send_packet(struct iface *, struct ibuf *, struct in6_addr *);
 voidrecv_packet(int, short, void *);
 
 char   *pkt_ptr;   /* packet buffer */
Index: packet.c
===
RCS file: /cvs/src/usr.sbin/ospf6d/packet.c,v
retrieving revision 1.15
diff -u -p -r1.15 packet.c
--- packet.c10 May 2019 01:29:31 -  1.15
+++ packet.c8 Dec 2019 14:55:58 -
@@ -78,10 +78,12 @@ upd_ospf_hdr(struct ibuf *buf, struct if
 
 /* send and receive packets */
 int
-send_packet(struct iface *iface, void *pkt, size_t len,
+send_packet(struct iface *iface, struct ibuf *buf,
 struct in6_addr *dst)
 {
-   struct sockaddr_in6  sa6;
+   struct sockaddr_in6 sa6;
+   struct msghdr   msg;
+   struct ioveciov[2];
 
/* setup buffer */
bzero(, sizeof(sa6));
@@ -102,8 +104,15 @@ send_packet(struct iface *iface, void *p
return (-1);
}
 
-   if (sendto(iface->fd, pkt, len, 0, (struct sockaddr *),
-   sizeof(sa6)) == -1) {
+   bzero(, sizeof(msg));
+   msg.msg_name = 
+   msg.msg_namelen = sizeof(sa6);
+   iov[0].iov_base = buf->buf;
+   iov[0].iov_len = ibuf_size(buf);
+   msg.msg_iov = iov;
+   msg.msg_iovlen = 1;
+
+   if (sendmsg(iface->fd, , 0) == -1) {
log_warn("send_packet: error sending packet on interface %s",
iface->name);
return (-1);



Re: ospf6d: refactor kernel route message handling

2019-12-11 Thread Denis Fondras
On Tue, Dec 10, 2019 at 09:51:12PM +0100, Remi Locherer wrote:
> Unfortunately redistribute does not work anymore.
> 

Indeed, simple tests are too simple...

Here is an updated diff.

Index: kroute.c
===
RCS file: /cvs/src/usr.sbin/ospf6d/kroute.c,v
retrieving revision 1.60
diff -u -p -r1.60 kroute.c
--- kroute.c2 Jan 2019 21:32:55 -   1.60
+++ kroute.c11 Dec 2019 14:51:25 -
@@ -80,7 +80,7 @@ struct kroute_node*kroute_match(struct 
 
 intprotect_lo(void);
 void   get_rtaddrs(int, struct sockaddr *, struct sockaddr **);
-void   if_change(u_short, int, struct if_data *);
+void   if_change(u_short, int, struct if_data *, struct sockaddr_dl *);
 void   if_newaddr(u_short, struct sockaddr_in6 *,
struct sockaddr_in6 *, struct sockaddr_in6 *);
 void   if_deladdr(u_short, struct sockaddr_in6 *,
@@ -90,6 +90,7 @@ void  if_announce(void *);
 intsend_rtmsg(int, int, struct kroute *);
 intdispatch_rtmsg(void);
 intfetchtable(void);
+intrtmsg_process(char *, size_t); 
 
 RB_HEAD(kroute_tree, kroute_node)  krt;
 RB_PROTOTYPE(kroute_tree, kroute_node, entry, kroute_compare)
@@ -801,7 +802,8 @@ get_rtaddrs(int addrs, struct sockaddr *
 }
 
 void
-if_change(u_short ifindex, int flags, struct if_data *ifd)
+if_change(u_short ifindex, int flags, struct if_data *ifd,
+struct sockaddr_dl *sdl)
 {
struct kroute_node  *kr, *tkr;
struct iface*iface;
@@ -809,7 +811,7 @@ if_change(u_short ifindex, int flags, st
 
wasvalid = kif_validate(ifindex);
 
-   if ((iface = kif_update(ifindex, flags, ifd, NULL)) == NULL) {
+   if ((iface = kif_update(ifindex, flags, ifd, sdl)) == NULL) {
log_warn("if_change: kif_update(%u)", ifindex);
return;
}
@@ -1135,12 +1137,8 @@ fetchtable(void)
 {
size_t   len;
int  mib[7];
-   char*buf, *next, *lim;
-   struct rt_msghdr*rtm;
-   struct sockaddr *sa, *rti_info[RTAX_MAX];
-   struct sockaddr_in6 *sa_in6;
-   struct sockaddr_rtlabel *label;
-   struct kroute_node  *kr;
+   char*buf;
+   int  rv;
 
mib[0] = CTL_NET;
mib[1] = PF_ROUTE;
@@ -1164,102 +1162,10 @@ fetchtable(void)
return (-1);
}
 
-   lim = buf + len;
-   for (next = buf; next < lim; next += rtm->rtm_msglen) {
-   rtm = (struct rt_msghdr *)next;
-   if (rtm->rtm_version != RTM_VERSION)
-   continue;
-   sa = (struct sockaddr *)(next + rtm->rtm_hdrlen);
-   get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
-
-   if ((sa = rti_info[RTAX_DST]) == NULL)
-   continue;
-
-   /* Skip ARP/ND cache and broadcast routes. */
-   if (rtm->rtm_flags & (RTF_LLINFO|RTF_BROADCAST))
-   continue;
-
-   if ((kr = calloc(1, sizeof(struct kroute_node))) == NULL) {
-   log_warn("fetchtable");
-   free(buf);
-   return (-1);
-   }
-
-   kr->r.flags = F_KERNEL;
-   kr->r.priority = rtm->rtm_priority;
-
-   switch (sa->sa_family) {
-   case AF_INET6:
-   kr->r.prefix =
-   ((struct sockaddr_in6 *)sa)->sin6_addr;
-   sa_in6 = (struct sockaddr_in6 *)rti_info[RTAX_NETMASK];
-   if (rtm->rtm_flags & RTF_STATIC)
-   kr->r.flags |= F_STATIC;
-   if (rtm->rtm_flags & RTF_BLACKHOLE)
-   kr->r.flags |= F_BLACKHOLE;
-   if (rtm->rtm_flags & RTF_REJECT)
-   kr->r.flags |= F_REJECT;
-   if (rtm->rtm_flags & RTF_DYNAMIC)
-   kr->r.flags |= F_DYNAMIC;
-   if (sa_in6 != NULL) {
-   if (sa_in6->sin6_len == 0)
-   break;
-   kr->r.prefixlen =
-   mask2prefixlen(sa_in6);
-   } else if (rtm->rtm_flags & RTF_HOST)
-   kr->r.prefixlen = 128;
-   else
-   fatalx("classful IPv6 route?!!");
-   break;
-   default:
-   free(kr);
-   continue;
-   }
-
-   kr->r.ifindex = rtm->rtm_index;
-   if ((sa = rti_info[RTAX_GATEWAY]) != NULL)
-   switch (sa->sa_family) {
-   case 

Re: ripd: memory leak and double free/use-after-free

2019-12-11 Thread Sebastian Benoit
Remi Locherer(remi.loche...@relo.ch) on 2019.12.10 22:39:32 +0100:
> On Tue, Dec 10, 2019 at 07:05:27PM +0100, Hiltjo Posthuma wrote:
> > Hi,
> > 
> > While looking at the code of ripd:
> > 
> > I think there are (also) 2 small memleaks in a debug/error path
> > (IMSG_REQUEST_ADD and IMSG_RESPONSE_ADD). It breaks out before adding the
> > struct rip_route as an entry by the add_entry function (which adds it and 
> > adds
> > a reference count) in the log_debug block.
> > 
> > clang-analyzer also pointed at a double-free and use of free'd data: the
> > function kroute_insert frees kr and returns -1 when struct kroute is 
> > duplicate.
> > 
> > Patch below (untested):
> > 
> 
> OK remi@

go ahead and commit it, ok benno@

> 
> > 
> > diff --git a/usr.sbin/ripd/kroute.c b/usr.sbin/ripd/kroute.c
> > index 6e7449e0909..71758a75e44 100644
> > --- a/usr.sbin/ripd/kroute.c
> > +++ b/usr.sbin/ripd/kroute.c
> > @@ -183,8 +183,7 @@ kr_change_fib(struct kroute_node *kr, struct kroute 
> > *kroute, int action)
> >  
> > if (kroute_insert(kr) == -1) {
> > log_debug("kr_update_fib: cannot insert %s",
> > -   inet_ntoa(kr->r.nexthop));
> > -   free(kr);
> > +   inet_ntoa(kroute->nexthop));
> > }
> > } else
> > kr->r.nexthop.s_addr = kroute->nexthop.s_addr;
> > diff --git a/usr.sbin/ripd/ripe.c b/usr.sbin/ripd/ripe.c
> > index d83901e245f..1f6f9b6583f 100644
> > --- a/usr.sbin/ripd/ripe.c
> > +++ b/usr.sbin/ripd/ripe.c
> > @@ -351,6 +351,7 @@ ripe_dispatch_rde(int fd, short event, void *bula)
> > NULL) {
> > log_debug("unknown neighbor id %u",
> > imsg.hdr.peerid);
> > +   free(rr);
> > break;
> > }
> > add_entry(>rq_list, rr);
> > @@ -396,6 +397,7 @@ ripe_dispatch_rde(int fd, short event, void *bula)
> > if ((nbr = nbr_find_peerid(imsg.hdr.peerid)) == NULL) {
> > log_debug("unknown neighbor id %u",
> > imsg.hdr.peerid);
> > +   free(rr);
> > break;
> > }
> > iface = nbr->iface;
> > 
> > -- 
> > Kind regards,
> > Hiltjo
> > 
>