make ifconfig print vnetids in hex too
so things will look like this: vlan9: flags=8002 mtu 1500 lladdr 00:00:00:00:00:00 index 11 priority 0 llprio 3 vlan: 70 parent interface: vnetid: 70 (0x46) parent: none groups: vlan status: no carrier vxlan0: flags=8802 mtu 1500 lladdr fe:e1:ba:d0:40:78 index 12 priority 0 llprio 3 vnetid: 4096 (0x1000) groups: vxlan media: Ethernet autoselect status: active some tools display "vnetids" as hex, so itd be nice to line them up with ifconfig output a bit easier. Index: sbin/ifconfig/ifconfig.c === RCS file: /cvs/src/sbin/ifconfig/ifconfig.c,v retrieving revision 1.334 diff -u -p -r1.334 ifconfig.c --- sbin/ifconfig/ifconfig.c13 Dec 2016 01:36:21 - 1.334 +++ sbin/ifconfig/ifconfig.c13 Dec 2016 07:01:33 - @@ -3664,7 +3664,7 @@ getvnetid(void) return; } - printf("\tvnetid: %lld\n", ifr.ifr_vnetid); + printf("\tvnetid: %lld (0x%llx)\n", ifr.ifr_vnetid, ifr.ifr_vnetid); } void
stop letting interface up/down fail silently
at the moment if ifconfig foo0 up fails, nothing says so because the kernel doesnt propagate the return code from the IFFLAGS ioctl back to userland. it also reports a link state change before it actually tries to bring the interface up or down. the diff below shuffles the SIOCSIFFLAGS handling in if.c so itll try to run the ioctl first, and only report link state changes if IFF_UP changed. ok? Index: if.c === RCS file: /cvs/src/sys/net/if.c,v retrieving revision 1.464 diff -u -p -r1.464 if.c --- if.c2 Dec 2016 18:32:38 - 1.464 +++ if.c13 Dec 2016 06:55:31 - @@ -1776,20 +1776,26 @@ ifioctl(struct socket *so, u_long cmd, c case SIOCSIFFLAGS: if ((error = suser(p, 0)) != 0) return (error); - if (ifp->if_flags & IFF_UP && (ifr->ifr_flags & IFF_UP) == 0) { - s = splnet(); - if_down(ifp); - splx(s); + + ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) | + (ifr->ifr_flags & ~IFF_CANTCHANGE); + + if (ifp->if_ioctl != NULL) { + error = (*ifp->if_ioctl)(ifp, cmd, data); + if (error != 0) { + ifp->if_flags = oif_flags; + break; + } } - if (ifr->ifr_flags & IFF_UP && (ifp->if_flags & IFF_UP) == 0) { + + if (ISSET(oif_flags ^ ifp->if_flags, IFF_UP)) { s = splnet(); - if_up(ifp); + if (ISSET(ifp->if_flags, IFF_UP)) + if_up(ifp); + else + if_down(ifp); splx(s); } - ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) | - (ifr->ifr_flags & ~IFF_CANTCHANGE); - if (ifp->if_ioctl) - (void) (*ifp->if_ioctl)(ifp, cmd, data); break; case SIOCSIFXFLAGS:
Re: dev/rnd.c more explicit_bzero
That's information is not a secret. > Some functions in rnd have a timespec; make sure to zero it > as already done with other buffers. Also do buf in > dequeue_randomness(). > > - Michael > > > Index: src/sys/dev/rnd.c > === > RCS file: /cvs/src/sys/dev/rnd.c,v > retrieving revision 1.191 > diff -u -p -u -r1.191 rnd.c > --- src/sys/dev/rnd.c 8 Dec 2016 05:32:49 - 1.191 > +++ src/sys/dev/rnd.c 13 Dec 2016 04:49:24 - > @@ -312,6 +312,7 @@ enqueue_randomness(u_int state, u_int va > timeout_add(&rnd_timeout, 1); > > mtx_leave(&entropylock); > + explicit_bzero(&ts, sizeof(ts)); > } > > /* > @@ -388,6 +389,7 @@ dequeue_randomness(void *v) > mtx_enter(&entropylock); > } > mtx_leave(&entropylock); > + explicit_bzero(buf, sizeof(buf)); > } > > /* > @@ -458,6 +460,7 @@ suspend_randomness(void) > dequeue_randomness(NULL); > rs_count = 0; > arc4random_buf(entropy_pool, sizeof(entropy_pool)); > + explicit_bzero(&ts, sizeof(ts)); > } > > void > @@ -473,6 +476,7 @@ resume_randomness(char *buf, size_t bufl > > dequeue_randomness(NULL); > rs_count = 0; > + explicit_bzero(&ts, sizeof(ts)); > } > > static inline void _rs_rekey(u_char *dat, size_t datlen); > @@ -523,6 +527,7 @@ _rs_stir(int do_lock) > mtx_leave(&rndlock); > > explicit_bzero(buf, sizeof(buf)); > + explicit_bzero(&ts, sizeof(ts)); > } > > static inline void >
dev/rnd.c more explicit_bzero
Hi, Some functions in rnd have a timespec; make sure to zero it as already done with other buffers. Also do buf in dequeue_randomness(). - Michael Index: src/sys/dev/rnd.c === RCS file: /cvs/src/sys/dev/rnd.c,v retrieving revision 1.191 diff -u -p -u -r1.191 rnd.c --- src/sys/dev/rnd.c 8 Dec 2016 05:32:49 - 1.191 +++ src/sys/dev/rnd.c 13 Dec 2016 04:49:24 - @@ -312,6 +312,7 @@ enqueue_randomness(u_int state, u_int va timeout_add(&rnd_timeout, 1); mtx_leave(&entropylock); + explicit_bzero(&ts, sizeof(ts)); } /* @@ -388,6 +389,7 @@ dequeue_randomness(void *v) mtx_enter(&entropylock); } mtx_leave(&entropylock); + explicit_bzero(buf, sizeof(buf)); } /* @@ -458,6 +460,7 @@ suspend_randomness(void) dequeue_randomness(NULL); rs_count = 0; arc4random_buf(entropy_pool, sizeof(entropy_pool)); + explicit_bzero(&ts, sizeof(ts)); } void @@ -473,6 +476,7 @@ resume_randomness(char *buf, size_t bufl dequeue_randomness(NULL); rs_count = 0; + explicit_bzero(&ts, sizeof(ts)); } static inline void _rs_rekey(u_char *dat, size_t datlen); @@ -523,6 +527,7 @@ _rs_stir(int do_lock) mtx_leave(&rndlock); explicit_bzero(buf, sizeof(buf)); + explicit_bzero(&ts, sizeof(ts)); } static inline void
Re: umb: aggregate packets on tx
On Mon, Dec 12, 2016 at 02:50:50PM +0100, Gerhard Roth wrote: > The current umb(4) implementation needs one USB transfer for every packet > that is sent. With the following patch, we can now aggregate several > packets from the ifq into one single USB transfer. > > This may speed up the tx path. And even if it doesn't, at least it > reduces the number of transfers required. I applied this diff this morning and everything has been working smoothly so far. There are no obvious regressions that I have noticed. This is on an X1 Carbon (4th Gen) with an EM7455 just like the X260 has. Bryan
Fix formatting of spamd.conf.5
Add missing 'e's at EOL for the heise.de message. Index: spamd.conf.5 === RCS file: /cvs/src/share/man/man5/spamd.conf.5,v retrieving revision 1.16 diff -u -p -r1.16 spamd.conf.5 --- spamd.conf.51 Jun 2016 21:57:03 - 1.16 +++ spamd.conf.512 Dec 2016 16:41:06 - @@ -57,8 +57,8 @@ all:\e nixspam:\e :black:\e - :msg="Your address %A is in the nixspam list\n\ - See http://www.heise.de/ix/nixspam/dnsbl_en/ for details":\ + :msg="Your address %A is in the nixspam list\n\e + See http://www.heise.de/ix/nixspam/dnsbl_en/ for details":\e :method=http:\e :file=www.openbsd.org/spamd/nixspam.gz
Re: multicast: propagate rdomain for add_vif
On 12/12/16(Mon) 16:35, Mike Belopuhov wrote: > On Mon, Dec 12, 2016 at 16:15 +0100, Martin Pieuchot wrote: > > [...] > > Why pass the socket to add_vif() when you only need the rdomain? > > > > It makes add_vif take same arguments as some other functions called > from ip_mrouter_set in that switch statement (like ip_mrouter_init). Makes sense. > > I'm also confused, if you need a rdomain shouldn't you be using > > rtable_l2()? > > > > He has tested with rdomains, but in this particular case you're doing > setsockopt, you don't know what rtable your socket is associated with > and you're just passing the value along. But besides, ifa_ifwithaddr > will call the rtable_l2 itself (which makes sense I guess as we have > to look up within the whole rdomain). I just got confused by the description, it's indeed not rdomain related. ok mpi@
Re: multicast: propagate rdomain for add_vif
On Mon, Dec 12, 2016 at 16:15 +0100, Martin Pieuchot wrote: > On 12/12/16(Mon) 16:09, Rafael Zalamena wrote: > > After trying to run igmpproxy daemon in different rdomains I noted that > > it fails with the following message: > > " > > ERRO: MRT_ADD_VIF; Errno(49): Can't assign requested address > > " > > > > In the following line: > > " > > if ( setsockopt( MRouterFD, IPPROTO_IP, MRT_ADD_VIF, > > (char *)&VifCtl, sizeof( VifCtl ) ) ) > > my_log( LOG_ERR, errno, "MRT_ADD_VIF" ); > > " > > > > With some help from mikeb@ we found out that even though the system is > > configured for multicast (multicast=YES) it is failing to setsockopt(), > > because it wasn't being able to add the address. We traced where was it > > failing and found out that the MRT_ADD_VIF wasn't propagating the rdomain > > so it was always trying to install in the rdomain 0 even when we ran > > igmpproxy on a different domain. > > > > This diff just makes ip_mrouter_set() propagate the rdomain so the > > ifa_ifwithaddr() receives the right rdomain and not fail anymore. > > > > ok? > > Why pass the socket to add_vif() when you only need the rdomain? > It makes add_vif take same arguments as some other functions called from ip_mrouter_set in that switch statement (like ip_mrouter_init). > I'm also confused, if you need a rdomain shouldn't you be using > rtable_l2()? > He has tested with rdomains, but in this particular case you're doing setsockopt, you don't know what rtable your socket is associated with and you're just passing the value along. But besides, ifa_ifwithaddr will call the rtable_l2 itself (which makes sense I guess as we have to look up within the whole rdomain). > > Index: sys/netinet/ip_mroute.c > > === > > RCS file: /home/obsdcvs/src/sys/netinet/ip_mroute.c,v > > retrieving revision 1.93 > > diff -u -p -r1.93 ip_mroute.c > > --- sys/netinet/ip_mroute.c 29 Nov 2016 15:52:12 - 1.93 > > +++ sys/netinet/ip_mroute.c 12 Dec 2016 14:51:37 - > > @@ -130,7 +130,7 @@ int get_vif_cnt(struct sioc_vif_req *); > > int get_vif_ctl(struct vifctl *); > > int ip_mrouter_init(struct socket *, struct mbuf *); > > int get_version(struct mbuf *); > > -int add_vif(struct mbuf *); > > +int add_vif(struct socket *, struct mbuf *); > > int del_vif(struct mbuf *); > > void update_mfc_params(struct mfc *, struct mfcctl2 *); > > void init_mfc_params(struct mfc *, struct mfcctl2 *); > > @@ -293,7 +293,7 @@ ip_mrouter_set(struct socket *so, int op > > error = ip_mrouter_done(); > > break; > > case MRT_ADD_VIF: > > - error = add_vif(*mp); > > + error = add_vif(so, *mp); > > break; > > case MRT_DEL_VIF: > > error = del_vif(*mp); > > @@ -773,8 +773,9 @@ static struct sockaddr_in sin = { sizeof > > * Add a vif to the vif table > > */ > > int > > -add_vif(struct mbuf *m) > > +add_vif(struct socket *so, struct mbuf *m) > > { > > + struct inpcb *inp; > > struct vifctl *vifcp; > > struct vif *vifp; > > struct ifaddr *ifa; > > @@ -809,8 +810,9 @@ add_vif(struct mbuf *m) > > } else > > #endif > > { > > + inp = sotoinpcb(so); > > sin.sin_addr = vifcp->vifc_lcl_addr; > > - ifa = ifa_ifwithaddr(sintosa(&sin), /* XXX */ 0); > > + ifa = ifa_ifwithaddr(sintosa(&sin), inp->inp_rtableid); > > if (ifa == NULL) > > return (EADDRNOTAVAIL); > > } > > >
Re: [patch] turn igmpstat into a set of percpu counters
On 11/12/16(Sun) 19:24, Dimitris Papastamos wrote: > Hi, > > I converted the igmp stats to use percpu counters. This work is > basically the same as what dlg@ did for other parts of the stack. > I looked at the diff and adjusted it for igmp. ok mpi@ > > diff --git a/sys/netinet/igmp.c b/sys/netinet/igmp.c > index 11446ce4188..c2a0a4839b4 100644 > --- a/sys/netinet/igmp.c > +++ b/sys/netinet/igmp.c > @@ -101,13 +101,14 @@ int *igmpctl_vars[IGMPCTL_MAXID] = IGMPCTL_VARS; > int igmp_timers_are_running; > static struct router_info *rti_head; > static struct mbuf *router_alert; > -struct igmpstat igmpstat; > +struct cpumem *igmpcounters; > > void igmp_checktimer(struct ifnet *); > void igmp_sendpkt(struct in_multi *, int, in_addr_t); > int rti_fill(struct in_multi *); > struct router_info * rti_find(struct ifnet *); > void igmp_input_if(struct ifnet *, struct mbuf *, int); > +int igmp_sysctl_igmpstat(void *, size_t *, void *); > > void > igmp_init(void) > @@ -117,6 +118,7 @@ igmp_init(void) > igmp_timers_are_running = 0; > rti_head = 0; > > + igmpcounters = counters_alloc(igps_ncounters, M_COUNTERS); > router_alert = m_get(M_DONTWAIT, MT_DATA); > if (router_alert == NULL) { > printf("%s: no mbuf\n", __func__); > @@ -217,7 +219,7 @@ igmp_input(struct mbuf *m, ...) > iphlen = va_arg(ap, int); > va_end(ap); > > - ++igmpstat.igps_rcv_total; > + igmpstat_inc(igps_rcv_total); > > ifp = if_get(m->m_pkthdr.ph_ifidx); > if (ifp == NULL) { > @@ -248,14 +250,14 @@ igmp_input_if(struct ifnet *ifp, struct mbuf *m, int > iphlen) >* Validate lengths >*/ > if (igmplen < IGMP_MINLEN) { > - ++igmpstat.igps_rcv_tooshort; > + igmpstat_inc(igps_rcv_tooshort); > m_freem(m); > return; > } > minlen = iphlen + IGMP_MINLEN; > if ((m->m_flags & M_EXT || m->m_len < minlen) && > (m = m_pullup(m, minlen)) == NULL) { > - ++igmpstat.igps_rcv_tooshort; > + igmpstat_inc(igps_rcv_tooshort); > return; > } > > @@ -266,7 +268,7 @@ igmp_input_if(struct ifnet *ifp, struct mbuf *m, int > iphlen) > m->m_len -= iphlen; > igmp = mtod(m, struct igmp *); > if (in_cksum(m, igmplen)) { > - ++igmpstat.igps_rcv_badsum; > + igmpstat_inc(igps_rcv_badsum); > m_freem(m); > return; > } > @@ -277,7 +279,7 @@ igmp_input_if(struct ifnet *ifp, struct mbuf *m, int > iphlen) > switch (igmp->igmp_type) { > > case IGMP_HOST_MEMBERSHIP_QUERY: > - ++igmpstat.igps_rcv_queries; > + igmpstat_inc(igps_rcv_queries); > > if (ifp->if_flags & IFF_LOOPBACK) > break; > @@ -292,7 +294,7 @@ igmp_input_if(struct ifnet *ifp, struct mbuf *m, int > iphlen) > rti->rti_age = 0; > > if (ip->ip_dst.s_addr != INADDR_ALLHOSTS_GROUP) { > - ++igmpstat.igps_rcv_badqueries; > + igmpstat_inc(igps_rcv_badqueries); > m_freem(m); > return; > } > @@ -317,7 +319,7 @@ igmp_input_if(struct ifnet *ifp, struct mbuf *m, int > iphlen) > } > } else { > if (!IN_MULTICAST(ip->ip_dst.s_addr)) { > - ++igmpstat.igps_rcv_badqueries; > + igmpstat_inc(igps_rcv_badqueries); > m_freem(m); > return; > } > @@ -367,14 +369,14 @@ igmp_input_if(struct ifnet *ifp, struct mbuf *m, int > iphlen) > break; > > case IGMP_v1_HOST_MEMBERSHIP_REPORT: > - ++igmpstat.igps_rcv_reports; > + igmpstat_inc(igps_rcv_reports); > > if (ifp->if_flags & IFF_LOOPBACK) > break; > > if (!IN_MULTICAST(igmp->igmp_group.s_addr) || > igmp->igmp_group.s_addr != ip->ip_dst.s_addr) { > - ++igmpstat.igps_rcv_badreports; > + igmpstat_inc(igps_rcv_badreports); > m_freem(m); > return; > } > @@ -401,7 +403,7 @@ igmp_input_if(struct ifnet *ifp, struct mbuf *m, int > iphlen) > IN_LOOKUP_MULTI(igmp->igmp_group, ifp, inm); > if (inm != NULL) { > inm->inm_timer = 0; > - ++igmpstat.igps_rcv_ourreports; > + igmpstat_inc(igps_rcv_ourreports); > > switch (inm->inm_state) { > case IGMP_IDLE_MEMBER: > @@ -433,14 +435,14 @@ igmp_input_if(struct ifnet *ifp, struct mbuf *m, int > iphlen) > break; > #endif > > - ++i
Re: multicast: propagate rdomain for add_vif
On 12/12/16(Mon) 16:09, Rafael Zalamena wrote: > After trying to run igmpproxy daemon in different rdomains I noted that > it fails with the following message: > " > ERRO: MRT_ADD_VIF; Errno(49): Can't assign requested address > " > > In the following line: > " > if ( setsockopt( MRouterFD, IPPROTO_IP, MRT_ADD_VIF, > (char *)&VifCtl, sizeof( VifCtl ) ) ) > my_log( LOG_ERR, errno, "MRT_ADD_VIF" ); > " > > With some help from mikeb@ we found out that even though the system is > configured for multicast (multicast=YES) it is failing to setsockopt(), > because it wasn't being able to add the address. We traced where was it > failing and found out that the MRT_ADD_VIF wasn't propagating the rdomain > so it was always trying to install in the rdomain 0 even when we ran > igmpproxy on a different domain. > > This diff just makes ip_mrouter_set() propagate the rdomain so the > ifa_ifwithaddr() receives the right rdomain and not fail anymore. > > ok? Why pass the socket to add_vif() when you only need the rdomain? I'm also confused, if you need a rdomain shouldn't you be using rtable_l2()? > Index: sys/netinet/ip_mroute.c > === > RCS file: /home/obsdcvs/src/sys/netinet/ip_mroute.c,v > retrieving revision 1.93 > diff -u -p -r1.93 ip_mroute.c > --- sys/netinet/ip_mroute.c 29 Nov 2016 15:52:12 - 1.93 > +++ sys/netinet/ip_mroute.c 12 Dec 2016 14:51:37 - > @@ -130,7 +130,7 @@ int get_vif_cnt(struct sioc_vif_req *); > int get_vif_ctl(struct vifctl *); > int ip_mrouter_init(struct socket *, struct mbuf *); > int get_version(struct mbuf *); > -int add_vif(struct mbuf *); > +int add_vif(struct socket *, struct mbuf *); > int del_vif(struct mbuf *); > void update_mfc_params(struct mfc *, struct mfcctl2 *); > void init_mfc_params(struct mfc *, struct mfcctl2 *); > @@ -293,7 +293,7 @@ ip_mrouter_set(struct socket *so, int op > error = ip_mrouter_done(); > break; > case MRT_ADD_VIF: > - error = add_vif(*mp); > + error = add_vif(so, *mp); > break; > case MRT_DEL_VIF: > error = del_vif(*mp); > @@ -773,8 +773,9 @@ static struct sockaddr_in sin = { sizeof > * Add a vif to the vif table > */ > int > -add_vif(struct mbuf *m) > +add_vif(struct socket *so, struct mbuf *m) > { > + struct inpcb *inp; > struct vifctl *vifcp; > struct vif *vifp; > struct ifaddr *ifa; > @@ -809,8 +810,9 @@ add_vif(struct mbuf *m) > } else > #endif > { > + inp = sotoinpcb(so); > sin.sin_addr = vifcp->vifc_lcl_addr; > - ifa = ifa_ifwithaddr(sintosa(&sin), /* XXX */ 0); > + ifa = ifa_ifwithaddr(sintosa(&sin), inp->inp_rtableid); > if (ifa == NULL) > return (EADDRNOTAVAIL); > } >
multicast: propagate rdomain for add_vif
After trying to run igmpproxy daemon in different rdomains I noted that it fails with the following message: " ERRO: MRT_ADD_VIF; Errno(49): Can't assign requested address " In the following line: " if ( setsockopt( MRouterFD, IPPROTO_IP, MRT_ADD_VIF, (char *)&VifCtl, sizeof( VifCtl ) ) ) my_log( LOG_ERR, errno, "MRT_ADD_VIF" ); " With some help from mikeb@ we found out that even though the system is configured for multicast (multicast=YES) it is failing to setsockopt(), because it wasn't being able to add the address. We traced where was it failing and found out that the MRT_ADD_VIF wasn't propagating the rdomain so it was always trying to install in the rdomain 0 even when we ran igmpproxy on a different domain. This diff just makes ip_mrouter_set() propagate the rdomain so the ifa_ifwithaddr() receives the right rdomain and not fail anymore. ok? Index: sys/netinet/ip_mroute.c === RCS file: /home/obsdcvs/src/sys/netinet/ip_mroute.c,v retrieving revision 1.93 diff -u -p -r1.93 ip_mroute.c --- sys/netinet/ip_mroute.c 29 Nov 2016 15:52:12 - 1.93 +++ sys/netinet/ip_mroute.c 12 Dec 2016 14:51:37 - @@ -130,7 +130,7 @@ int get_vif_cnt(struct sioc_vif_req *); int get_vif_ctl(struct vifctl *); int ip_mrouter_init(struct socket *, struct mbuf *); int get_version(struct mbuf *); -int add_vif(struct mbuf *); +int add_vif(struct socket *, struct mbuf *); int del_vif(struct mbuf *); void update_mfc_params(struct mfc *, struct mfcctl2 *); void init_mfc_params(struct mfc *, struct mfcctl2 *); @@ -293,7 +293,7 @@ ip_mrouter_set(struct socket *so, int op error = ip_mrouter_done(); break; case MRT_ADD_VIF: - error = add_vif(*mp); + error = add_vif(so, *mp); break; case MRT_DEL_VIF: error = del_vif(*mp); @@ -773,8 +773,9 @@ static struct sockaddr_in sin = { sizeof * Add a vif to the vif table */ int -add_vif(struct mbuf *m) +add_vif(struct socket *so, struct mbuf *m) { + struct inpcb *inp; struct vifctl *vifcp; struct vif *vifp; struct ifaddr *ifa; @@ -809,8 +810,9 @@ add_vif(struct mbuf *m) } else #endif { + inp = sotoinpcb(so); sin.sin_addr = vifcp->vifc_lcl_addr; - ifa = ifa_ifwithaddr(sintosa(&sin), /* XXX */ 0); + ifa = ifa_ifwithaddr(sintosa(&sin), inp->inp_rtableid); if (ifa == NULL) return (EADDRNOTAVAIL); }
Re: bpf_mtap(9) w/o KERNEL_LOCK
On 10/12/16(Sat) 23:01, Jonathan Matthew wrote: > On Mon, Nov 28, 2016 at 04:01:14PM +0100, Martin Pieuchot wrote: > > Last diff to trade the KERNEL_LOCK for a mutex in order to protect data > > accessed inside bpf_catchpacket(). > > > > Note about the multiples data structures: > > > > - selwakeup() is called in a thread context (task) so we rely on the > > KERNEL_LOCK() to serialize access to kqueue(9) data. > > > > - the global list of descriptor ``bpf_d_list``, accessed via > > bpfilter_lookup() is also protected by the KERNEL_LOCK(). > > > > - bpf_get() increments the refcount of a descriptor. It is needed > > to increment it around ifppromisc() which can sleep. > > > > - A mutex now protects the rotating buffers and their associated > > fields. > > > > - The dance around uiomove(9) is here to check that buffers aren't > > rotated while data is copied to userland. Setting ``b->bd_fbuf'' > > to NULL should be enough to let bpf_catchpacket() to drop the > > patcket. But I added ``__in_uiomove'' to be able to have usable > > panic if something weird happen. > > > > Comments, oks? > > The thing I'm concerned about here is the call to bpf_wakeup() from > bpf_catchpacket() - this modifies the bpf_d refcount outside the kernel lock. > Elsewhere the refcount is modified while holding the kernel lock, with or > without the mutex. It'll never free the bpf_d there, since the bpf_d list > still holds a reference, but the refcount operations aren't atomic, so the > counter could get messed up. Is there a reason not to use atomics there? Good point. Here's an updated diff that uses the atomics and addresses Alexander's comments. Index: net/bpf.c === RCS file: /cvs/src/sys/net/bpf.c,v retrieving revision 1.155 diff -u -p -r1.155 bpf.c --- net/bpf.c 28 Nov 2016 10:16:08 - 1.155 +++ net/bpf.c 12 Dec 2016 14:18:38 - @@ -116,6 +116,9 @@ int bpf_sysctl_locked(int *, u_int, void struct bpf_d *bpfilter_lookup(int); +/* + * Called holding ``bd_mtx''. + */ void bpf_attachd(struct bpf_d *, struct bpf_if *); void bpf_detachd(struct bpf_d *); void bpf_resetd(struct bpf_d *); @@ -260,11 +263,12 @@ bpf_movein(struct uio *uio, u_int linkty /* * Attach file to the bpf interface, i.e. make d listen on bp. - * Must be called at splnet. */ void bpf_attachd(struct bpf_d *d, struct bpf_if *bp) { + MUTEX_ASSERT_LOCKED(&d->bd_mtx); + /* * Point d at bp, and add d to the interface's list of listeners. * Finally, point the driver's bpf cookie at the interface so @@ -287,6 +291,8 @@ bpf_detachd(struct bpf_d *d) { struct bpf_if *bp; + MUTEX_ASSERT_LOCKED(&d->bd_mtx); + bp = d->bd_bif; /* Not attached. */ if (bp == NULL) @@ -313,7 +319,13 @@ bpf_detachd(struct bpf_d *d) int error; d->bd_promisc = 0; + + bpf_get(d); + mtx_leave(&d->bd_mtx); error = ifpromisc(bp->bif_ifp, 0); + mtx_enter(&d->bd_mtx); + bpf_put(d); + if (error && !(error == EINVAL || error == ENODEV)) /* * Something is really wrong if we were able to put @@ -353,6 +365,7 @@ bpfopen(dev_t dev, int flag, int mode, s bd->bd_unit = unit; bd->bd_bufsize = bpf_bufsize; bd->bd_sig = SIGIO; + mtx_init(&bd->bd_mtx, IPL_NET); task_set(&bd->bd_wake_task, bpf_wakeup_cb, bd); if (flag & FNONBLOCK) @@ -372,15 +385,14 @@ int bpfclose(dev_t dev, int flag, int mode, struct proc *p) { struct bpf_d *d; - int s; d = bpfilter_lookup(minor(dev)); - s = splnet(); + mtx_enter(&d->bd_mtx); bpf_detachd(d); bpf_wakeup(d); LIST_REMOVE(d, bd_list); + mtx_leave(&d->bd_mtx); bpf_put(d); - splx(s); return (0); } @@ -391,11 +403,13 @@ bpfclose(dev_t dev, int flag, int mode, * Zero the length of the new store buffer. */ #define ROTATE_BUFFERS(d) \ + KASSERT(d->__in_uiomove == 0); \ + MUTEX_ASSERT_LOCKED(&d->bd_mtx); \ (d)->bd_hbuf = (d)->bd_sbuf; \ (d)->bd_hlen = (d)->bd_slen; \ (d)->bd_sbuf = (d)->bd_fbuf; \ (d)->bd_slen = 0; \ - (d)->bd_fbuf = 0; + (d)->bd_fbuf = NULL; /* * bpfread - read next chunk of packets from buffers */ @@ -403,15 +417,17 @@ int bpfread(dev_t dev, struct uio *uio, int ioflag) { struct bpf_d *d; - int error; - int s; + caddr_t hbuf; + int hlen, error; + + KERNEL_ASSERT_LOCKED(); d = bpfilter_lookup(minor(dev)); if (d->bd_bif == NULL) return (ENXIO); - s = splnet(); bpf_get(d); + mtx_enter(&d->bd_mtx); /* * Restrict application to use a buffer the same size as @@ -460,8 +476,8 @@
Re: dhcrelay(8): filter BOOTREPLY packets
Rafael Zalamena writes: > This diff makes dhcrelay(8) drop packets that were not meant for us. > This is a safety check suggested by jca@ to avoid relaying packets with > the address of other relays. > > ok? ok In the commit message please mention that the most likely source of this kind of packets is the BPF socket. > Index: dhcrelay.c > === > RCS file: /cvs/src/usr.sbin/dhcrelay/dhcrelay.c,v > retrieving revision 1.49 > diff -u -p -r1.49 dhcrelay.c > --- dhcrelay.c8 Dec 2016 19:18:15 - 1.49 > +++ dhcrelay.c8 Dec 2016 19:52:51 - > @@ -276,6 +276,11 @@ relay(struct interface_info *ip, struct > > /* If it's a bootreply, forward it to the client. */ > if (packet->op == BOOTREPLY) { > + /* Filter packet that were not meant for us. */ > + if (packet->giaddr.s_addr != > + interfaces->primary_address.s_addr) > + return; > + > bzero(&to, sizeof(to)); > if (!(packet->flags & htons(BOOTP_BROADCAST))) { > to.sin_addr = packet->yiaddr; > -- jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF DDCC 0DFA 74AE 1524 E7EE
umb: aggregate packets on tx
The current umb(4) implementation needs one USB transfer for every packet that is sent. With the following patch, we can now aggregate several packets from the ifq into one single USB transfer. This may speed up the tx path. And even if it doesn't, at least it reduces the number of transfers required. Gerhard Index: sys/dev/usb/if_umb.c === RCS file: /cvs/src/sys/dev/usb/if_umb.c,v retrieving revision 1.8 diff -u -p -u -p -r1.8 if_umb.c --- sys/dev/usb/if_umb.c25 Nov 2016 12:43:26 - 1.8 +++ sys/dev/usb/if_umb.c12 Dec 2016 13:38:34 - @@ -156,7 +156,7 @@ int umb_decode_connect_info(struct umb int umb_decode_ip_configuration(struct umb_softc *, void *, int); voidumb_rx(struct umb_softc *); voidumb_rxeof(struct usbd_xfer *, void *, usbd_status); -int umb_encap(struct umb_softc *, struct mbuf *); +int umb_encap(struct umb_softc *); voidumb_txeof(struct usbd_xfer *, void *, usbd_status); voidumb_decap(struct umb_softc *, struct usbd_xfer *); @@ -299,6 +299,7 @@ umb_attach(struct device *parent, struct sc->sc_udev = uaa->device; sc->sc_ctrl_ifaceno = uaa->ifaceno; + ml_init(&sc->sc_tx_ml); /* * Some MBIM hardware does not provide the mandatory CDC Union @@ -583,8 +584,25 @@ umb_ncm_setup(struct umb_softc *sc) UGETW(np.wLength) == sizeof (np)) { sc->sc_rx_bufsz = UGETDW(np.dwNtbInMaxSize); sc->sc_tx_bufsz = UGETDW(np.dwNtbOutMaxSize); - } else + sc->sc_maxdgram = UGETW(np.wNtbOutMaxDatagrams); + sc->sc_align = UGETW(np.wNdpOutAlignment); + sc->sc_ndp_div = UGETW(np.wNdpOutDivisor); + sc->sc_ndp_remainder = UGETW(np.wNdpOutPayloadRemainder); + /* Validate values */ + if (!powerof2(sc->sc_align) || sc->sc_align == 0 || + sc->sc_align >= sc->sc_tx_bufsz) + sc->sc_align = sizeof (uint32_t); + if (!powerof2(sc->sc_ndp_div) || sc->sc_ndp_div == 0 || + sc->sc_ndp_div >= sc->sc_tx_bufsz) + sc->sc_ndp_div = sizeof (uint32_t); + if (sc->sc_ndp_remainder >= sc->sc_ndp_div) + sc->sc_ndp_remainder = 0; + } else { sc->sc_rx_bufsz = sc->sc_tx_bufsz = 8 * 1024; + sc->sc_maxdgram = 0; + sc->sc_align = sc->sc_ndp_div = sizeof (uint32_t); + sc->sc_ndp_remainder = 0; + } } int @@ -593,12 +611,12 @@ umb_alloc_xfers(struct umb_softc *sc) if (!sc->sc_rx_xfer) { if ((sc->sc_rx_xfer = usbd_alloc_xfer(sc->sc_udev)) != NULL) sc->sc_rx_buf = usbd_alloc_buffer(sc->sc_rx_xfer, - sc->sc_rx_bufsz + MBIM_HDR32_LEN); + sc->sc_rx_bufsz); } if (!sc->sc_tx_xfer) { if ((sc->sc_tx_xfer = usbd_alloc_xfer(sc->sc_udev)) != NULL) sc->sc_tx_buf = usbd_alloc_buffer(sc->sc_tx_xfer, - sc->sc_tx_bufsz + MBIM_HDR16_LEN); + sc->sc_tx_bufsz); } return (sc->sc_rx_buf && sc->sc_tx_buf) ? 1 : 0; } @@ -617,10 +635,7 @@ umb_free_xfers(struct umb_softc *sc) sc->sc_tx_xfer = NULL; sc->sc_tx_buf = NULL; } - if (sc->sc_tx_m) { - m_freem(sc->sc_tx_m); - sc->sc_tx_m = NULL; - } + ml_purge(&sc->sc_tx_ml); } int @@ -792,35 +807,91 @@ umb_input(struct ifnet *ifp, struct mbuf return 1; } +static inline int +umb_align(size_t bufsz, int offs, int alignment, int remainder) +{ + size_t m = alignment - 1; + int align; + + align = (((size_t)offs + m) & ~m) - alignment + remainder; + if (align < offs) + align += alignment; + if (align > bufsz) + align = bufsz; + return align - offs; +} + +static inline int +umb_padding(void *buf, size_t bufsz, int offs, int alignment, int remainder) +{ + int nb; + + nb = umb_align(bufsz, offs, alignment, remainder); + if (nb > 0) + memset(buf + offs, 0, nb); + return nb; +} + void umb_start(struct ifnet *ifp) { struct umb_softc *sc = ifp->if_softc; - struct mbuf *m_head = NULL; + struct mbuf *m = NULL; + int ndgram = 0; + int offs, plen, len, mlen; + int maxalign; if (usbd_is_dying(sc->sc_udev) || !(ifp->if_flags & IFF_RUNNING) || ifq_is_oactive(&ifp->if_snd)) return; - m_head = ifq_deq_begin(&ifp->if_snd); - if (m_head == NULL) - return; + KASSERT(ml_empty(&sc->sc_tx_ml)); - if (!umb_encap(sc, m_head)) { -
Re: bpf_mtap(9) w/o KERNEL_LOCK
On 07/12/16(Wed) 00:44, Alexander Bluhm wrote: > On Mon, Nov 28, 2016 at 04:01:14PM +0100, Martin Pieuchot wrote: > > @@ -717,7 +753,9 @@ bpfioctl(dev_t dev, u_long cmd, caddr_t > > *(u_int *)addr = size = bpf_maxbufsize; > > else if (size < BPF_MINBUFSIZE) > > *(u_int *)addr = size = BPF_MINBUFSIZE; > > + mtx_enter(&d->bd_mtx); > > d->bd_bufsize = size; > > + mtx_leave(&d->bd_mtx); > > } > > break; > > > > bd_bufsize needs protection, but you only add it in BIOCSBLEN, > you should also put a mutex in BIOCGBLEN. I'm not sure to understand why. The value is only written in ioctl(2) context. The mutex is here to make sure the value wont change while bpf_catchpacket() is executed. > > @@ -778,30 +815,36 @@ bpfioctl(dev_t dev, u_long cmd, caddr_t > > * Get device parameters. > > */ > > case BIOCGDLT: > > + mtx_enter(&d->bd_mtx); > > if (d->bd_bif == NULL) > > error = EINVAL; > > else > > *(u_int *)addr = d->bd_bif->bif_dlt; > > + mtx_leave(&d->bd_mtx); > > break; > > bd_bif is not protected elsewhere. bif_dlt is only set during attach. > So I think you need no mutex here. Indeed. > > > > /* > > * Set device parameters. > > */ > > case BIOCSDLT: > > + mtx_enter(&d->bd_mtx); > > if (d->bd_bif == NULL) > > error = EINVAL; > > else > > error = bpf_setdlt(d, *(u_int *)addr); > > + mtx_leave(&d->bd_mtx); > > break; > > bd_bif needs not protection, so put the mutex only in the else path. > Then it is obvious why it is there. Ack. > > > > /* > > * Set interface name. > > */ > > case BIOCGETIF: > > + mtx_enter(&d->bd_mtx); > > if (d->bd_bif == NULL) > > error = EINVAL; > > else > > bpf_ifname(d->bd_bif->bif_ifp, (struct ifreq *)addr); > > + mtx_leave(&d->bd_mtx); > > break; > > The interface name is not used by bpf without kernel lock. You do > not need a mutex here. Ack. > > @@ -1151,6 +1197,8 @@ filt_bpfread(struct knote *kn, long hint > > { > > struct bpf_d *d = kn->kn_hook; > > > > + KERNEL_ASSERT_LOCKED(); > > + > > kn->kn_data = d->bd_hlen; > > if (d->bd_immediate) > > kn->kn_data += d->bd_slen; > > You need the mutex here to access bd_slen. Ack. > > @@ -1232,12 +1279,10 @@ _bpf_mtap(caddr_t arg, const struct mbuf > > if (!gottime++) > > microtime(&tv); > > > > - KERNEL_LOCK(); > > - s = splnet(); > > + mtx_enter(&d->bd_mtx); > > bpf_catchpacket(d, (u_char *)m, pktlen, slen, cpfn, > > &tv); > > - splx(s); > > - KERNEL_UNLOCK(); > > + mtx_leave(&d->bd_mtx); > > > > if (d->bd_fildrop) > > drop = 1; > > bd_fildrop can be changed by ioctl. Can we expect to read the > correct value without a memory barrier? > > Same question applies to bd_dirfilt. We probably need some. I guess that the actual code works because these events happen occasionally. > bd_rcount is a long value incremented atomically in _bpf_mtap(). > It is read from an other CPU with kernel lock during an ioctl. Is > this sufficient to get a consisten value? Do we also need an atomic > operation when reading it? Do we need a consistent value? > > --- net/bpfdesc.h 22 Aug 2016 10:40:36 - 1.31 > > +++ net/bpfdesc.h 28 Nov 2016 14:51:06 - > > @@ -56,15 +56,17 @@ struct bpf_d { > > * fbuf (free) - When read is done, put cluster here. > > * On receiving, if sbuf is full and fbuf is 0, packet is dropped. > > */ > > + struct mutexbd_mtx; /* protect buffer slots below */ > > caddr_t bd_sbuf;/* store slot */ > > caddr_t bd_hbuf;/* hold slot */ > > caddr_t bd_fbuf;/* free slot */ > > int bd_slen;/* current length of store buffer */ > > int bd_hlen;/* current length of hold buffer */ > > - > > int bd_bufsize; /* absolute length of buffers */ > > So bd_mtx is protecting the fields above. Everything below must > either be not accessed without kernel lock, or only be set during > attach. Is that correct or do I have a wrong understanding of the > SMP model? I'm not sure I understood your sentence, but I think you got the model right :) > > - struct bpf_if * bd_bif; /* interface descriptor */ > > + int __in_uiomove; > > Why do you prefix it with __ ? bd_uiomove would be
Re: efifb(4): WSDISPLAYIO_{GET,SET}PARAM ioctl support
comitted. Thanks! On Sun, 11 Dec 2016 10:32:59 +0100 Anton Lindqvist wrote: > This allows the brightness on my Dell Latitude 3160 to be adjusted > through wsconsctl(1). > > Index: arch/amd64/amd64/efifb.c > === > RCS file: /cvs/src/sys/arch/amd64/amd64/efifb.c,v > retrieving revision 1.9 > diff -u -p -r1.9 efifb.c > --- arch/amd64/amd64/efifb.c 21 Jun 2016 15:24:55 - 1.9 > +++ arch/amd64/amd64/efifb.c 11 Dec 2016 09:25:04 - > @@ -104,6 +104,9 @@ intefifb_load_font(void *, void *, str > > struct cb_framebuffer *cb_find_fb(paddr_t); > > +extern int (*ws_get_param)(struct wsdisplay_param *); > +extern int (*ws_set_param)(struct wsdisplay_param *); > + > const struct cfattach efifb_ca = { > sizeof(struct efifb_softc), efifb_match, efifb_attach, NULL > }; > @@ -235,6 +238,16 @@ efifb_ioctl(void *v, u_long cmd, caddr_t > struct wsdisplay_fbinfo *wdf; > > switch (cmd) { > + case WSDISPLAYIO_GETPARAM: > + if (ws_get_param != NULL) > + return (*ws_get_param)((struct wsdisplay_param *)data); > + else > + return (-1); > + case WSDISPLAYIO_SETPARAM: > + if (ws_set_param != NULL) > + return (*ws_set_param)((struct wsdisplay_param *)data); > + else > + return (-1); > case WSDISPLAYIO_GTYPE: > *(u_int *)data = WSDISPLAY_TYPE_EFIFB; > break; >
ifconfig and tunnels using ipv6 link local addresses
the system is inconsistent wrt to tunnels and ipv6 link local addresses. there are three things to consider here: 1. configuring addresses on a tunnel 2. using addresses to encapsulate traffic 3. reading the addresses a tunnel uses the ioctls used for 1 and 3 use sockaddr_in6 to pass v6 addresses in and out of the kernel for tunnel configuration. sin6 structures have a sin6_scope_id member that is supposed to represent the scope. i get the impression sin6_scope_id wasnt always there thoughway. kame had (has) a hack where it embeds the scope id into bits that are guaranteed to be zero. both ifconfig and the kernel have code to pack sin6_scope_id into a v6 address, and to unpack it later. currently 1 uses getaddrinfo to parse an address on the command line and submit it to the kernel. getaddrinfo reads scope (eg, %ix0) and puts it into sin6_scope_id. for some reason 3 currently assumes that needs to unpack a kame packed address and. that means it reads from the "zero" bits in the address into sin6_scope_id. 1 and 3 are therefore inconsistent. 1 submits a nice neat sin6_scope_id to the kernel, but 3 assumes its a kame packed address. to resolve this im suggesting we pick 1 as the right way to do things. sin6_scope_id is portable, and less confusing. i havent met anyone who likes the kame hack. for 2, ipv6 packets end up in ip6_output, and ip6_output relies on scope embedded into link local addresses. at the moment there are 3 tunnel interfaces that let you use v6 addresses for the enpoints: gif, etherip, and vxlan. they all use the sockaddr_sin6 from userland to fill in a v6 header, but none of them use the scope id. the diff below should fix all this. the most important fix is vxlan. ok? Index: sbin/ifconfig/ifconfig.c === RCS file: /cvs/src/sbin/ifconfig/ifconfig.c,v retrieving revision 1.333 diff -u -p -r1.333 ifconfig.c --- sbin/ifconfig/ifconfig.c10 Nov 2016 14:36:03 - 1.333 +++ sbin/ifconfig/ifconfig.c12 Dec 2016 09:44:48 - @@ -2873,8 +2873,6 @@ phys_status(int force) (void) strlcpy(req.iflr_name, name, sizeof(req.iflr_name)); if (ioctl(s, SIOCGLIFPHYADDR, (caddr_t)&req) < 0) return; - if (req.addr.ss_family == AF_INET6) - in6_fillscopeid((struct sockaddr_in6 *)&req.addr); if (getnameinfo((struct sockaddr *)&req.addr, req.addr.ss_len, psrcaddr, sizeof(psrcaddr), 0, 0, niflag) != 0) strlcpy(psrcaddr, "", sizeof(psrcaddr)); @@ -2883,10 +2881,8 @@ phys_status(int force) if (req.dstaddr.ss_family == AF_INET) dstport = ((struct sockaddr_in *)&req.dstaddr)->sin_port; - else if (req.dstaddr.ss_family == AF_INET6) { - in6_fillscopeid((struct sockaddr_in6 *)&req.dstaddr); + else if (req.dstaddr.ss_family == AF_INET6) dstport = ((struct sockaddr_in6 *)&req.dstaddr)->sin6_port; - } if (getnameinfo((struct sockaddr *)&req.dstaddr, req.dstaddr.ss_len, pdstaddr, sizeof(pdstaddr), 0, 0, niflag) != 0) strlcpy(pdstaddr, "", sizeof(pdstaddr)); Index: sys/net/if_etherip.c === RCS file: /cvs/src/sys/net/if_etherip.c,v retrieving revision 1.7 diff -u -p -r1.7 if_etherip.c --- sys/net/if_etherip.c13 Apr 2016 11:41:15 - 1.7 +++ sys/net/if_etherip.c12 Dec 2016 09:44:48 - @@ -514,18 +514,19 @@ ip6_etherip_output(struct ifnet *ifp, st struct sockaddr_in6 *src, *dst; struct etherip_header *eip; struct ip6_hdr *ip6; + int error; src = (struct sockaddr_in6 *)&sc->sc_src; dst = (struct sockaddr_in6 *)&sc->sc_dst; if (src == NULL || dst == NULL || src->sin6_family != AF_INET6 || dst->sin6_family != AF_INET6) { - m_freem(m); - return EAFNOSUPPORT; + error = EAFNOSUPPORT; + goto drop; } if (IN6_IS_ADDR_UNSPECIFIED(&dst->sin6_addr)) { - m_freem(m); - return ENETUNREACH; + error = ENETUNREACH; + goto drop; } m->m_flags &= ~(M_BCAST|M_MCAST); @@ -552,8 +553,12 @@ ip6_etherip_output(struct ifnet *ifp, st ip6->ip6_nxt = IPPROTO_ETHERIP; ip6->ip6_hlim = ip6_defhlim; ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(struct ip6_hdr)); - ip6->ip6_src = src->sin6_addr; - ip6->ip6_dst = dst->sin6_addr; + error = in6_embedscope(&ip6->ip6_src, src, NULL); + if (error != 0) + goto drop; + error = in6_embedscope(&ip6->ip6_dst, dst, NULL); + if (error != 0) + goto drop; m->m_pkthdr.ph_rtableid = sc->sc_rdomain; @@ -565,6 +570,10 @@ ip6_etherip_output(struct ifnet *ifp, st (sizeof(struct ip6_hdr) + sizeof(struct etherip_header))); return ip
Re: route(8) flush fix
On Mon, Dec 12, 2016 at 10:53:42AM +0100, Martin Pieuchot wrote: > This is a just a cosmetic fix. Currently the netmask of flushed routes > is not printed correctly. The diff below fixes that. > > ok? ok stsp@ > > Index: route.c > === > RCS file: /cvs/src/sbin/route/route.c,v > retrieving revision 1.192 > diff -u -p -r1.192 route.c > --- route.c 24 Sep 2016 19:36:49 - 1.192 > +++ route.c 9 Dec 2016 13:20:04 - > @@ -385,13 +385,17 @@ flushroutes(int argc, char **argv) > if (verbose) > print_rtmsg(rtm, rlen); > else { > + struct sockaddr *mask, *rti_info[RTAX_MAX]; > + > sa = (struct sockaddr *)(next + rtm->rtm_hdrlen); > - printf("%-20.20s ", rtm->rtm_flags & RTF_HOST ? > - routename(sa) : netname(sa, NULL)); /* XXX extract > -netmask */ > - sa = (struct sockaddr *) > - (ROUNDUP(sa->sa_len) + (char *)sa); > - printf("%-20.20s ", routename(sa)); > + > + get_rtaddrs(rtm->rtm_addrs, sa, rti_info); > + > + sa = rti_info[RTAX_DST]; > + mask = rti_info[RTAX_NETMASK]; > + > + p_sockaddr(sa, mask, rtm->rtm_flags, 20); > + p_sockaddr(rti_info[RTAX_GATEWAY], NULL, RTF_HOST, 20); > printf("done\n"); > } > } > Index: show.c > === > RCS file: /cvs/src/sbin/route/show.c,v > retrieving revision 1.107 > diff -u -p -r1.107 show.c > --- show.c5 Sep 2016 14:23:38 - 1.107 > +++ show.c9 Dec 2016 13:19:44 - > @@ -100,7 +100,6 @@ intWID_DST(int); > void pr_rthdr(int); > void p_rtentry(struct rt_msghdr *); > void pr_family(int); > -void p_sockaddr(struct sockaddr *, struct sockaddr *, int, int); > void p_sockaddr_mpls(struct sockaddr *, struct sockaddr *, int, int); > void p_flags(int, char *); > char *routename4(in_addr_t); > @@ -224,7 +223,7 @@ pr_rthdr(int af) > } > } > > -static void > +void > get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info) > { > int i; > Index: show.h > === > RCS file: /cvs/src/sbin/route/show.h,v > retrieving revision 1.11 > diff -u -p -r1.11 show.h > --- show.h18 Jul 2015 00:05:02 - 1.11 > +++ show.h9 Dec 2016 13:19:55 - > @@ -28,7 +28,9 @@ union sockunion { > struct sockaddr_mplssmpls; > }; > > +void get_rtaddrs(int, struct sockaddr *, struct sockaddr **); > void p_rttables(int, u_int, int, char); > +void p_sockaddr(struct sockaddr *, struct sockaddr *, int, int); > char *routename(struct sockaddr *); > char *netname(struct sockaddr *, struct sockaddr *); > char *mpls_op(u_int32_t); >
Re: Proxy ARP and npppd (tun)
On 09/12/16(Fri) 19:42, Erik Lax wrote: > Hi, > > In previous OpenBSD versions (5.9 and eariler) it was possible to do > proxy-arp with the npppd server if the proxy-arp was setup before the > npppd connection was made. As of 6.0 (and todays snapshots) proxy arp > and npppd (tun interfaces) seems to be broken. > > The behavior is now as such; > > - if an proxy arp entry exists (on a given interface), then incoming > packets will be sent out again on the same interface (instead of > forwarded to the tun interface) > > Setup. > > 1. Adding the proxy-arp entry 10.2.50.123 (the npppd/tun0 client ip) > > arp -s 10.2.50.123 00:50:51:b2:e4:c1 permanent pub > > 2. Connect the client, send ping to host on em0, incoming icmp replys > are sent out on em0 again instead of tun0 Could you include the output of "netstat -rnf inet" at this point? > A quirk? > > If the arp entry is deleted (arp -d 10.2.50.124) on the openbsd host, it > starts to work temporarily (the packet is forwarded to the tun > interface) but only because the remote host has an arp cache. Could you include the same output at this point? > Is there an other way of doing this? There's a regression somewhere, thanks for reporting it. a dmesg would also help.
Re: improve gre handling in tcpdump
On Mon, Dec 12, 2016 at 01:02:55PM +1000, David Gwynne wrote: > gre can do more things than tcpdump currently thinks it can. > > specifically, gre can be carried by ipv6, and it can encapsulate > more than just ip and ppp packets. > > as such, this tells tcpdump to look at gre inside ipv6 packets. > > gre uses ethertypes to represent what protocol it contains, so > instead of rolling a gre specific version of ip and ppp protocol > types, just reuse the ether ones. > > also tell tcpdump that gre can contains ipv6, ethernet, and mpls. > > NVGRE is basically a constrained gre header (ie, must be version > 0, must only have the K bit set, must be transether), so this detects > that and prints the NVGRE interpretation of the Key field. that > makes the VSID in NVGRE packets easier to see. > > theres some tweaks to output so it looks ok with and without the > -v optarg. > > ok? ok stsp@ > > Index: print-gre.c > === > RCS file: /cvs/src/usr.sbin/tcpdump/print-gre.c,v > retrieving revision 1.11 > diff -u -p -r1.11 print-gre.c > --- print-gre.c 5 Nov 2015 11:55:21 - 1.11 > +++ print-gre.c 12 Dec 2016 02:48:21 - > @@ -39,6 +39,8 @@ > #include > #include > > +#include > + > #include > #include > > @@ -55,13 +57,15 @@ > #define GRE_AP 0x0080 /* acknowledgment# present */ > #define GRE_VERS0x0007 /* protocol version */ > > -#define GREPROTO_IP 0x0800 /* IP */ > -#define GREPROTO_PPP0x880b /* PPTP */ > - > /* source route entry types */ > #define GRESRE_IP 0x0800 /* IP */ > #define GRESRE_ASN 0xfffe /* ASN */ > > +#define NVGRE_VSID_MASK 0xff00U > +#define NVGRE_VSID_SHIFT 8 > +#define NVGRE_FLOWID_MASK0x00ffU > +#define NVGRE_FLOWID_SHIFT 0 > + > void gre_print_0(const u_char *, u_int); > void gre_print_1(const u_char *, u_int); > void gre_sre_print(u_int16_t, u_int8_t, u_int8_t, const u_char *, u_int); > @@ -82,14 +86,17 @@ gre_print(const u_char *bp, u_int length > } > vers = EXTRACT_16BITS(bp) & GRE_VERS; > > - if (vers == 0) > + switch (vers) { > + case 0: > gre_print_0(bp, len); > - else if (vers == 1) > + break; > + case 1: > gre_print_1(bp, len); > - else > + break; > + default: > printf("gre-unknown-version=%u", vers); > - return; > - > + break; > + } > } > > void > @@ -114,6 +121,8 @@ gre_print_0(const u_char *bp, u_int leng > if (len < 2) > goto trunc; > prot = EXTRACT_16BITS(bp); > + printf("%s", etherproto_string(prot)); > + > len -= 2; > bp += 2; > > @@ -121,21 +130,32 @@ gre_print_0(const u_char *bp, u_int leng > if (len < 2) > goto trunc; > if (vflag) > - printf("sum 0x%x ", EXTRACT_16BITS(bp)); > + printf(" sum 0x%x", EXTRACT_16BITS(bp)); > bp += 2; > len -= 2; > > if (len < 2) > goto trunc; > - printf("off 0x%x ", EXTRACT_16BITS(bp)); > + printf(" off 0x%x", EXTRACT_16BITS(bp)); > bp += 2; > len -= 2; > } > > if (flags & GRE_KP) { > + uint32_t key, vsid; > + > if (len < 4) > goto trunc; > - printf("key=0x%x ", EXTRACT_32BITS(bp)); > + key = EXTRACT_32BITS(bp); > + > + /* maybe NVGRE? */ > + if (flags == (GRE_KP | 0) && prot == ETHERTYPE_TRANSETHER) { > + vsid = (key & NVGRE_VSID_MASK) >> NVGRE_VSID_SHIFT; > + printf(" NVGRE vsid=%u (0x%x)+flowid=0x%02x /", > + vsid, vsid, > + (key & NVGRE_FLOWID_MASK) >> NVGRE_FLOWID_SHIFT); > + } > + printf(" key=%u (0x%x)", key, key); > bp += 4; > len -= 4; > } > @@ -143,7 +163,7 @@ gre_print_0(const u_char *bp, u_int leng > if (flags & GRE_SP) { > if (len < 4) > goto trunc; > - printf("seq %u ", EXTRACT_32BITS(bp)); > + printf(" seq %u", EXTRACT_32BITS(bp)); > bp += 4; > len -= 4; > } > @@ -174,10 +194,21 @@ gre_print_0(const u_char *bp, u_int leng > } > } > > + printf(": "); > + > switch (prot) { > - case GREPROTO_IP: > + case ETHERTYPE_IP: > ip_print(bp, len); > break; > + case ETHERTYPE_IPV6: > + ip6_print(bp, len); > + break; > + case ETHERTYPE_MPLS: > + mpls_print(bp, len); > + break; > + case ETHERTYPE_TRANSETHER: > + ether_pr
route(8) flush fix
This is a just a cosmetic fix. Currently the netmask of flushed routes is not printed correctly. The diff below fixes that. ok? Index: route.c === RCS file: /cvs/src/sbin/route/route.c,v retrieving revision 1.192 diff -u -p -r1.192 route.c --- route.c 24 Sep 2016 19:36:49 - 1.192 +++ route.c 9 Dec 2016 13:20:04 - @@ -385,13 +385,17 @@ flushroutes(int argc, char **argv) if (verbose) print_rtmsg(rtm, rlen); else { + struct sockaddr *mask, *rti_info[RTAX_MAX]; + sa = (struct sockaddr *)(next + rtm->rtm_hdrlen); - printf("%-20.20s ", rtm->rtm_flags & RTF_HOST ? - routename(sa) : netname(sa, NULL)); /* XXX extract - netmask */ - sa = (struct sockaddr *) - (ROUNDUP(sa->sa_len) + (char *)sa); - printf("%-20.20s ", routename(sa)); + + get_rtaddrs(rtm->rtm_addrs, sa, rti_info); + + sa = rti_info[RTAX_DST]; + mask = rti_info[RTAX_NETMASK]; + + p_sockaddr(sa, mask, rtm->rtm_flags, 20); + p_sockaddr(rti_info[RTAX_GATEWAY], NULL, RTF_HOST, 20); printf("done\n"); } } Index: show.c === RCS file: /cvs/src/sbin/route/show.c,v retrieving revision 1.107 diff -u -p -r1.107 show.c --- show.c 5 Sep 2016 14:23:38 - 1.107 +++ show.c 9 Dec 2016 13:19:44 - @@ -100,7 +100,6 @@ int WID_DST(int); voidpr_rthdr(int); voidp_rtentry(struct rt_msghdr *); voidpr_family(int); -voidp_sockaddr(struct sockaddr *, struct sockaddr *, int, int); voidp_sockaddr_mpls(struct sockaddr *, struct sockaddr *, int, int); voidp_flags(int, char *); char *routename4(in_addr_t); @@ -224,7 +223,7 @@ pr_rthdr(int af) } } -static void +void get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info) { int i; Index: show.h === RCS file: /cvs/src/sbin/route/show.h,v retrieving revision 1.11 diff -u -p -r1.11 show.h --- show.h 18 Jul 2015 00:05:02 - 1.11 +++ show.h 9 Dec 2016 13:19:55 - @@ -28,7 +28,9 @@ union sockunion { struct sockaddr_mplssmpls; }; +voidget_rtaddrs(int, struct sockaddr *, struct sockaddr **); voidp_rttables(int, u_int, int, char); +voidp_sockaddr(struct sockaddr *, struct sockaddr *, int, int); char *routename(struct sockaddr *); char *netname(struct sockaddr *, struct sockaddr *); char *mpls_op(u_int32_t);