Re: make tcpdump show 11n mode correctly
Anybody? Did I write too much of a wall of text to explain the diff? In that case, just read the diff. It should make sense. On Sun, Dec 11, 2016 at 04:38:44PM +0100, Stefan Sperling wrote: > This diff makes 'tcpdump -i iwn0 -y IEEE802_11_RADIO' show the > correct mode for a channel in 11n mode. > Before: > > After: > > > Unfortunately this requires a kernel tweak because the kernel must > be more careful about the channel flags it passes to userland. > > Channels exist in the 11b/g (2GHz) and 11a (5GHz) ranges. > So net80211 has a "mode" concept, where a given mode is available > if supported channels exist in a particular range. And there is the > default "auto" mode which picks one of the other available modes. > (This may not be the best design but it is how it was designed > historically. Changing this is not in my radar.) > > The HT-channel flag is set to indicate whether a channel may be used > in 11n mode. In practice this is just the superset of all channels > supported by the device. When 11n support was introduced it was easier to > fold the new 11n mode into the existing code with a flag like this, and > avoid letting 11n mode be a special case which works against this design. > > And this HT-channel flag is set regardless of whether we're currently in > 11n mode because we need this flag to enter 11n mode from another mode. > A mode which has no channels available to it is not available. > So the kernel needs this flag to be set on all channels at all times > if the driver supports 11n. > > Now, we copy this flag out to userspace even in non-11n modes. > If the kernel instead omits the HT-channel flag from the userspace copy if > the current mode is not 11n, then tcpdump can inspect this flag to detect > whether the channel is in fact an "11n" channel and print the mode correctly. > > In the end, this is just a cosmetic fix. If this is too much code > churn and quirks for too little gain, I am happy to drop this diff. > > Index: sys/dev/pci/if_iwm.c > === > RCS file: /cvs/src/sys/dev/pci/if_iwm.c,v > retrieving revision 1.154 > diff -u -p -r1.154 if_iwm.c > --- sys/dev/pci/if_iwm.c 10 Dec 2016 19:03:53 - 1.154 > +++ sys/dev/pci/if_iwm.c 11 Dec 2016 14:54:58 - > @@ -3339,14 +3339,17 @@ iwm_rx_rx_mpdu(struct iwm_softc *sc, str > if (sc->sc_drvbpf != NULL) { > struct mbuf mb; > struct iwm_rx_radiotap_header *tap = &sc->sc_rxtap; > + uint16_t chan_flags; > > tap->wr_flags = 0; > if (phy_info->phy_flags & htole16(IWM_PHY_INFO_FLAG_SHPREAMBLE)) > tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; > tap->wr_chan_freq = > htole16(ic->ic_channels[phy_info->channel].ic_freq); > - tap->wr_chan_flags = > - htole16(ic->ic_channels[phy_info->channel].ic_flags); > + chan_flags = ic->ic_channels[phy_info->channel].ic_flags; > + if (ic->ic_curmode != IEEE80211_MODE_11N) > + chan_flags &= ~IEEE80211_CHAN_HT; > + tap->wr_chan_flags = htole16(chan_flags); > tap->wr_dbm_antsignal = (int8_t)rssi; > tap->wr_dbm_antnoise = (int8_t)sc->sc_noise; > tap->wr_tsft = phy_info->system_timestamp; > @@ -3991,10 +3994,14 @@ iwm_tx(struct iwm_softc *sc, struct mbuf > if (sc->sc_drvbpf != NULL) { > struct mbuf mb; > struct iwm_tx_radiotap_header *tap = &sc->sc_txtap; > + uint16_t chan_flags; > > tap->wt_flags = 0; > tap->wt_chan_freq = htole16(ni->ni_chan->ic_freq); > - tap->wt_chan_flags = htole16(ni->ni_chan->ic_flags); > + chan_flags = ni->ni_chan->ic_flags; > + if (ic->ic_curmode != IEEE80211_MODE_11N) > + chan_flags &= ~IEEE80211_CHAN_HT; > + tap->wt_chan_flags = htole16(chan_flags); > if ((ni->ni_flags & IEEE80211_NODE_HT) && > !IEEE80211_IS_MULTICAST(wh->i_addr1) && > type == IEEE80211_FC0_TYPE_DATA && > Index: sys/dev/pci/if_iwn.c > === > RCS file: /cvs/src/sys/dev/pci/if_iwn.c,v > retrieving revision 1.178 > diff -u -p -r1.178 if_iwn.c > --- sys/dev/pci/if_iwn.c 10 Dec 2016 13:22:07 - 1.178 > +++ sys/dev/pci/if_iwn.c 11 Dec 2016 14:54:25 - > @@ -2130,14 +2130,17 @@ iwn_rx_done(struct iwn_softc *sc, struct > if (sc->sc_drvbpf != NULL) { > struct mbuf mb; > struct iwn_rx_radiotap_header *tap = &sc->sc_rxtap; > + uint16_t chan_flags; > > tap->wr_flags = 0; > if (stat->flags & htole16(IWN_STAT_FLAG_SHPREAMBLE)) > tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; > tap->wr_chan_freq = >
Re: kernel diagnostic assertion "ifa == rt->rt_ifa", rt_ifa_addlocal
On 17/12/16(Sat) 07:52, Stefan Sperling wrote: > On Sat, Dec 17, 2016 at 02:33:37AM +0100, Alexander Bluhm wrote: > > Hi, > > > > If rt_ifa_addlocal() in in_ifinit() fails, the address has been > > added to the interface address list, but the local route is missing. > > This inconsistency can result in a panic later. > > > > panic: kernel diagnostic assertion "ifa == rt->rt_ifa" failed: file > > "/crypt/home/bluhm/openbsd/cvs/src/sys/netinet/if_ether.c", line 206 > > > > I have seen this crash in production on a 5.9 system and could > > reproduce it on -current by inducing an error in rt_ifa_addlocal(). > > > > So in case of an error, remove the interface address to get a > > consistent state again. > > > > ok? Haha, I have a similar diff in my tree! I couldn't find a way to make rt_ifa_addlocal() fail, but I agree this is needed. ok mpi@ > The little dance with an aditional error variable is a bit confusing. > It would be nice to avoid the extra variable. But off-hand I could not > find a simpler diff which keeps the semantics of re-adding the original > address if the ioctl errors. So your approach seems fine. The proper way to simplify this mess is to always call in_ifinit() with newifaddr = 1. But it is the kind of work nobody want to spend her time on.
Re: BFD: route get and route monitor
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. : :OK? Updated output, requested by Theo. A normal get will show just the bfd state, use "-bfd" to get all of the information. OK? $ 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: 4 (connected) flags: BFD: async state up remote up use mtuexpire 83924 0 133 sockaddrs: $ route -n get 203.0.113.9 -bfd 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: 4 (connected) flags: BFD: async state up remote up laststate down error 0 diag none remote neighbor-down discr 186919089 remote 55 uptime 05d 2h07m29s mintx 100 minrx 100 minecho 0 multiplier 3 use mtuexpire 83923 0 229 sockaddrs: 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.193 diff -u -p -u -p -r1.193 route.c --- sbin/route/route.c 13 Dec 2016 08:40:54 - 1.193 +++ sbin/route/route.c 17 Dec 2016 12:47:35 - @@ -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); @@ -1443,6 +1444,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; @@ -1491,6 +1495,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); } @@ -1523,6 +1532,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 ? @@ -1625,12 +1638,21 @@ void print_bfdmsg(struct rt_msghdr *rtm) { struct bfd_msghdr *bfdm = (struct bfd_msghdr *)rtm; + + printf("\n"); + print_sabfd(&bfdm->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(&tv, NULL); - printf(" mode "); - switch (bfdm->bm_mode) { + printf("BFD: "); + switch (sa_bfd->bs_mode) { case BFD_MODE_ASYNC: printf("async"); break; @@ -1638,27 +1660,36 @@ print_bfdmsg(struct rt_msghdr *rtm) 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)); - printf(" remotediag %s", bfd_diag(bfdm->bm_remotediag)); - printf(" uptime %s", bfd_calc_uptime(tv.t