Re: nd6_output() and NULL routes

2016-05-23 Thread Alexander Bluhm
On Mon, May 23, 2016 at 04:55:06PM +0200, Martin Pieuchot wrote:
> +++ net/pf.c  23 May 2016 14:43:19 -
> +++ net/pf_norm.c 23 May 2016 14:48:01 -

I have tested the pf part with regress/sys/net/pf_forward.  This
is OK bluhm@.

> @@ -1532,42 +1527,17 @@ nd6_output(struct ifnet *ifp, struct mbu
...
> - /*
> -  * Since nd6_is_addr_neighbor() internally calls nd6_lookup(),
> -  * the condition below is not very efficient.  But we believe
> -  * it is tolerable, because this should be a rare case.
> -  */
> - if (nd6_is_addr_neighbor(dst, ifp)) {
> - rt = nd6_lookup(&dst->sin6_addr, 1, ifp,
> - ifp->if_rdomain);
> - if (rt != NULL) {
> - created = 1;
> - ln = (struct llinfo_nd6 *)rt->rt_llinfo;
> - }
> - }

I cannot see where the nd6_lookup() has moved to.  Where does it
happen now?

> + if (!ISSET(rt->rt_flags, RTF_LLINFO)) {
> + char addr[INET6_ADDRSTRLEN];
> + log(LOG_DEBUG, "%s: %s: route contains no ND information\n",
> + __func__, inet_ntop(AF_INET6,
> + &satosin6(rt_key(rt))->sin6_addr, addr, sizeof(addr)));
> + m_freem(m);
> + return (EINVAL);
>   }

I think EINVAL is for invalid input from user land.  Would EHOSTUNREACH
be more appropriate?

There should be more real world testing with the ether_output() and
nd6_output() part.  Can you commit pf and send the diff that assumes
rt != NULL for v4 and v6 output?

bluhm



Re: Patch for man to ignore trailing spaces in man.conf

2016-05-23 Thread Mayukh Bose
> From: todd.mil...@courtesan.com
> To: mayukh_b...@hotmail.com
> CC: tech@openbsd.org; schwa...@openbsd.org
> Subject: Re: Patch for man to ignore trailing spaces in man.conf
> Date: Mon, 23 May 2016 10:01:54 -0600
> 
> Your patch got munged by your mailer. Here's a different patch
> that achieves the same thing and also removes the requirement that
> the last line in man.conf end with a newline.
> 
> - todd
> 
> Index: usr.bin/mandoc/manpath.c
> ===
> RCS file: /cvs/src/usr.bin/mandoc/manpath.c,v
> retrieving revision 1.17
> diff -u -p -u -r1.17 manpath.c
> --- usr.bin/mandoc/manpath.c  7 Nov 2015 17:58:52 -   1.17
> +++ usr.bin/mandoc/manpath.c  23 May 2016 15:59:09 -
> @@ -173,13 +173,12 @@ manconf_file(struct manconf *conf, const
> 
> while ((linelen = getline(&line, &linesz, stream)) != -1) {
> cp = line;
> - ep = cp + linelen;
> - if (ep[-1] != '\n')
> - break;
> - *--ep = '\0';
> + ep = cp + linelen - 1;
> + while (ep> cp && isspace((unsigned char)*ep))
> + *ep-- = '\0';
> while (isspace((unsigned char)*cp))
> cp++;
> - if (*cp == '#')
> + if (cp == ep || *cp == '#')
> continue;
> 
> for (tok = 0; tok < sizeof(toks)/sizeof(toks[0]); tok++) {

Thanks much. I like your patch better too.

Cheers,
Mayukh


Re: Patch for man to ignore trailing spaces in man.conf

2016-05-23 Thread Ingo Schwarze
Hi Todd,

Todd C. Miller wrote on Mon, May 23, 2016 at 10:01:54AM -0600:

> Your patch got munged by your mailer.  Here's a different patch
> that achieves the same thing and also removes the requirement that
> the last line in man.conf end with a newline.

OK schwarze@.

Thanks,
  Ingo


> Index: usr.bin/mandoc/manpath.c
> ===
> RCS file: /cvs/src/usr.bin/mandoc/manpath.c,v
> retrieving revision 1.17
> diff -u -p -u -r1.17 manpath.c
> --- usr.bin/mandoc/manpath.c  7 Nov 2015 17:58:52 -   1.17
> +++ usr.bin/mandoc/manpath.c  23 May 2016 15:59:09 -
> @@ -173,13 +173,12 @@ manconf_file(struct manconf *conf, const
>  
>   while ((linelen = getline(&line, &linesz, stream)) != -1) {
>   cp = line;
> - ep = cp + linelen;
> - if (ep[-1] != '\n')
> - break;
> - *--ep = '\0';
> + ep = cp + linelen - 1;
> + while (ep > cp && isspace((unsigned char)*ep))
> + *ep-- = '\0';
>   while (isspace((unsigned char)*cp))
>   cp++;
> - if (*cp == '#')
> + if (cp == ep || *cp == '#')
>   continue;
>  
>   for (tok = 0; tok < sizeof(toks)/sizeof(toks[0]); tok++) {
> 



Re: MBIM Patch - Part 2 of 4

2016-05-23 Thread Gerhard Roth

On 23.05.2016 17:47, Martin Pieuchot wrote:

On 23/05/16(Mon) 16:51, Gerhard Roth wrote:

Why do you need to set a default route in the first place?


Just like PPP this was designed as a point-to-point interface. The idea
is that once you get an uplink, all traffic should be routed through it.


Sure, my point is can you add the route *once* you get an uplink?



Ok, all of this was meant to be an intermediate solution ;)

The idea was that once the MBIM driver was accepted into the OpenBSD
kernel, the information provided by the MBIM_CID_IP_CONFIGURATION msg
would generate an extended version of the RTM_IFINFO routing message.
This message would pass the DNS server and the default gateway that
was reported by the provider up to any listeners as RTAX_DNS1,
RTAX_DNS2, and RTAX_GATEWAY.

Then I would write a daemon sitting there and listening for this kind
of routing messages and once it receives them, perform the required
actions, i.e. updating /etc/resolv.conf and/or setting the default
route.

But that was planned as a second step. The first step would be the
simple solution we have there right now. And because it would go
away later on, I didn't give it too much thought.


Gerhard



Re: libfuse: null-terminate argv (fuse_opt_insert_arg)

2016-05-23 Thread Hiltjo Posthuma
On Fri, May 20, 2016 at 10:57:10PM +0800, Ray Lai wrote:
> On Thu, 19 May 2016 18:57:50 +0200
> Hiltjo Posthuma  wrote:
> 
> > Hi peoples,
> > 
> > This diff makes sure to NUL-terminate argv when parsing options in libfuse.
> > The upstream/other libfuse does it this way. This fixes an issue with the
> > sysutils/sshfs port, it uses execvp(3) on the fuse_args argv and this gave
> > an error "bad address".
> > 
> > 
> > Index: fuse_opt.c
> > ===
> > RCS file: /cvs/src/lib/libfuse/fuse_opt.c,v
> > retrieving revision 1.15
> > diff -u -p -r1.15 fuse_opt.c
> > --- fuse_opt.c  19 Oct 2015 17:24:07 -  1.15
> > +++ fuse_opt.c  19 May 2016 16:50:39 -
> > @@ -353,7 +353,7 @@ fuse_opt_insert_arg(struct fuse_args *ar
> > if (p < 0 || p > args->argc)
> > return (-1);
> >  
> > -   av = reallocarray(args->argv, args->argc + 1, sizeof(*av));
> > +   av = reallocarray(args->argv, args->argc + 2, sizeof(*av));
> > if (av == NULL)
> > return (-1);
> >  
> > @@ -365,6 +365,7 @@ fuse_opt_insert_arg(struct fuse_args *ar
> >  
> > args->argc++;
> > args->argv = av;
> > +   args->argv[args->argc] = NULL;
> > for (i = p; i < args->argc; i++) {
> > next_arg = args->argv[i];
> > args->argv[i] = this_arg;
> > 
> > 
> > [0] upstream libfuse fuse_opt_add_arg:
> > https://github.com/libfuse/libfuse/blob/master/lib/fuse_opt.c#L62
> > 
> 
> This looks correct, but don't forget about free_argv() and alloc_argv().
> 

I discussed with Ray his concerns of the patch off-list. We agreed there is no
memory leak or invalid use of argv AFAICT.

Can this patch be applied to base libfuse?

-- 
Kind regards,
Hiltjo



Re: MBIM Patch - Part 2 of 4

2016-05-23 Thread Martin Pieuchot
On 23/05/16(Mon) 16:40, Stuart Henderson wrote:
> What I don't understand is why routing to a point-to-point interface needs
> anything other than the interface name to be used for the destination.

It doesn't really need anything else.  At least not from the network
stack point of view.

Well I'm lying, it needs somebody who can do the plumbing :)



Re: Patch for man to ignore trailing spaces in man.conf

2016-05-23 Thread Todd C. Miller
Your patch got munged by your mailer.  Here's a different patch
that achieves the same thing and also removes the requirement that
the last line in man.conf end with a newline.

 - todd

Index: usr.bin/mandoc/manpath.c
===
RCS file: /cvs/src/usr.bin/mandoc/manpath.c,v
retrieving revision 1.17
diff -u -p -u -r1.17 manpath.c
--- usr.bin/mandoc/manpath.c7 Nov 2015 17:58:52 -   1.17
+++ usr.bin/mandoc/manpath.c23 May 2016 15:59:09 -
@@ -173,13 +173,12 @@ manconf_file(struct manconf *conf, const
 
while ((linelen = getline(&line, &linesz, stream)) != -1) {
cp = line;
-   ep = cp + linelen;
-   if (ep[-1] != '\n')
-   break;
-   *--ep = '\0';
+   ep = cp + linelen - 1;
+   while (ep > cp && isspace((unsigned char)*ep))
+   *ep-- = '\0';
while (isspace((unsigned char)*cp))
cp++;
-   if (*cp == '#')
+   if (cp == ep || *cp == '#')
continue;
 
for (tok = 0; tok < sizeof(toks)/sizeof(toks[0]); tok++) {



Re: Patch for man to ignore trailing spaces in man.conf

2016-05-23 Thread Gregor Best
Hi Mayukh,

On Sun, May 22, 2016 at 11:17:18PM -0700, Mayukh Bose wrote:
> [...]
> Here's my patch to fix this:
> [...]

Ironically, your patch about whitespace handling has mangled whitespace.
Can you send it again? Maybe your MUA tried sending it as some sort of
formatted text instead of plain text.

-- 
Gregor



Re: MBIM Patch - Part 2 of 4

2016-05-23 Thread Martin Pieuchot
On 23/05/16(Mon) 16:51, Gerhard Roth wrote:
> On Mon, 23 May 2016 16:18:29 +0200 Martin Pieuchot  wrote:
> > On 23/05/16(Mon) 15:38, Gerhard Roth wrote:
> > > This is part 2 of the MBIM patch. It adds the mbim driver to i386
> > > +/*
> > > + * Some devices are picky about too frequent control messages.
> > > + * Query device state not more often than every 0.5 secs.
> > > + */
> > > +struct timeval mbim_update_rate = { 0, 50 };
> > > +int mbim_delay = 4000;
> > > +
> > > +/*
> > > + * Normally, MBIM devices are detected by their interface class and 
> > > subclass.
> > > + * But for some models that have multiple configurations, it is better to
> > > + * match by vendor and product id so that we can select the desired
> > > + * configuration ourselves.
> > > + *
> > > + * OTOH, some devices identifiy themself als an MBIM device but fail to 
> > > speak
> > > + * the MBIM protocol.
> > > + */
> > 
> > Why is it better?  This is just working around usb_probe_and_attach()
> > and require developer to add an entry for every device we need to
> > support.
> 
> I just thought that some modules that are already in use say with a
> umsm config would otherwise change to mbim and break the setup. The idea
> was to keep existing modules first as they are now and start adding
> new one to the list.

Well the rule is first match win.  Since umsm(4) uses a vendor/product
table as long as you don't add your device to this table it should be
ok.

> > > +void
> > > +mbim_watchdog(struct ifnet *ifp)
> > > +{
> > > + struct mbim_softc *sc = ifp->if_softc;
> > > +
> > > + if (usbd_is_dying(sc->sc_udev))
> > > + return;
> > > +
> > > + ifp->if_oerrors++;
> > > + log(LOG_WARNING, "%s: watchdog timeout\n", DEVNAM(sc));
> > 
> > Watchdog are run in a task now, so it should be possible to stop/start
> > devices even if you need to sleep.
> 
> What do you mean? That there's no need for the usbd_is_dying() call?

I mean that most of the watchdog for USB drivers do nothing
because historically they could not call _stop() and _start().

PCI devices generally print a message then call _init() which does
_stop() and _start().  It should be possible to do the same for USB
devices now.

> > 
> > This is crazy :)   No driver should ever modify `ia' directly.  This
> > code should call in_control() via the ioctl path.
> 
> As mentioned in a previous mail: this was mostly copied from
> if_spppsubr.c:sppp_set_ip_addrs(). But doing an SIOCSIFADDR
> ioctl() from inside the kernel seems weird, too.

SIOCAIFADDR/SIOCDIFADDR It is the way to go.  The driver should not
manipulate addresses or route entry.


> > > +/* Code copied from if_spppsubr.c */
> > > +void
> > > +mbim_update_gw(struct ifnet *ifp)
> > > +{
> > > + unsigned int tid;
> > > +
> > > + /* update routing table */
> > > + for (tid = 0; tid <= RT_TABLEID_MAX; tid++) {
> > > + while (rtable_walk(tid, AF_INET, mbim_update_gw_walker, ifp) ==
> > > + EAGAIN)
> > > + ;   /* nothing */
> > > + }
> > > +}
> > > +
> > > +int
> > > +mbim_update_gw_walker(struct rtentry *rt, void *arg, unsigned int id)
> > > +{
> > > + struct ifnet *ifp = arg;
> > > +
> > > + if (rt->rt_ifidx == ifp->if_index) {
> > > + if (rt->rt_ifa->ifa_dstaddr->sa_family !=
> > > + rt->rt_gateway->sa_family ||
> > > + !ISSET(rt->rt_flags, RTF_GATEWAY))
> > > + return 0;   /* do not modify non-gateway routes */
> > > + log(LOG_INFO, "%s: update gw %s -> %s\n", DEVNAM(ifp->if_softc),
> > > + mbim_ntop(rt->rt_gateway),
> > > + mbim_ntop(rt->rt_ifa->ifa_dstaddr));
> > > + rt_setgate(rt, rt->rt_ifa->ifa_dstaddr);
> > > + }
> > 
> > This is the kind of horrors I have been removing during the past years.
> > 
> > Why do you need to set a default route in the first place?
> 
> Just like PPP this was designed as a point-to-point interface. The idea
> is that once you get an uplink, all traffic should be routed through it.

Sure, my point is can you add the route *once* you get an uplink?

> What other sensible routing could there be? Only routing some selected IP
> addresses through your mobile uplink doesn't seem like the normal use case.

I'm not talking about "sensible routing",  I'm saying that copy/paste
programing is bad, especially if you copy the wrong pattern that we have
in the kernel.

> > > +void
> > > +mbim_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
> > > +{
> > > + struct mbim_softc *sc = priv;
> > > + struct ifnet *ifp = GET_IFP(sc);
> > > +
> > > + if (usbd_is_dying(sc->sc_udev) || !(ifp->if_flags & IFF_RUNNING))
> > > + return;
> > > +
> > > + if (status != USBD_NORMAL_COMPLETION) {
> > > + if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
> > > + return;
> > > + if (usbd_ratecheck(&sc->sc_rx_ratechk))
> > > + DPRINTF("%s: rx error: %s\n", DEVNAM(sc),
> > > + usbd_errstr(sta

Re: MBIM Patch - Part 2 of 4

2016-05-23 Thread Theo de Raadt
> > Just like PPP this was designed as a point-to-point interface. The idea
> > is that once you get an uplink, all traffic should be routed through it.
> > 
> > What other sensible routing could there be? Only routing some selected IP
> > addresses through your mobile uplink doesn't seem like the normal use case.
> 
> Routing just certain destinations over a particular PPP is definitely
> valid, and I think the same applies here. (Maybe you have a fast ISP and a
> cheap ISP and want to use the fast one for some VPN or important traffic).
> 
> What I don't understand is why routing to a point-to-point interface needs
> anything other than the interface name to be used for the destination.

Such a choice being made at the driver level is quite a layer violation.
Pants on fire...



Re: MBIM Patch - Part 2 of 4

2016-05-23 Thread Stuart Henderson
On 2016/05/23 16:51, Gerhard Roth wrote:
> > This is the kind of horrors I have been removing during the past years.
> > 
> > Why do you need to set a default route in the first place?
> 
> Just like PPP this was designed as a point-to-point interface. The idea
> is that once you get an uplink, all traffic should be routed through it.
> 
> What other sensible routing could there be? Only routing some selected IP
> addresses through your mobile uplink doesn't seem like the normal use case.

Routing just certain destinations over a particular PPP is definitely
valid, and I think the same applies here. (Maybe you have a fast ISP and a
cheap ISP and want to use the fast one for some VPN or important traffic).

What I don't understand is why routing to a point-to-point interface needs
anything other than the interface name to be used for the destination.



Patch for man to ignore trailing spaces in man.conf

2016-05-23 Thread Mayukh Bose
Hi all,  I used pkg_add to add jdk and after installation, it told me to 
add /usr/local/jdk-1.7.0/man to man.conf. Therefore, I googled on modifying 
man.conf and came across the OpenBSD man page 
online:http://man.openbsd.org/OpenBSD-current/man5/man.conf.5
I cut-and-pasted the EXAMPLES section into /etc/man.conf exactly as stated from 
the webpage and then added an extra line for the jdk manpath:manpath 
/usr/share/man 
manpath /usr/X11R6/man 
manpath /usr/local/man
manpath /usr/local/jdk-1.7.0/man
And after this, "man java" worked fine, but "man man", "man printf", "man 
man.conf" etc. stopped working! After a bit of debugging, I found that the 
problem was that the manpath lines for the first two lines had trailing spaces 
at the end (I had cut/pasted them from the webpage above, but it appears the 
page has the trailing spaces in it as well). So I figured I should fix man so 
that it properly handles trailing spaces in man.conf. Here's my patch to fix 
this:
$ cvs -d anon...@anoncvs.usa.openbsd.org:/cvs diffcvs server: Diffing .Index: 
manpath.c===RCS 
file: /cvs/src/usr.bin/mandoc/manpath.c,vretrieving revision 1.17diff -u -p 
-r1.17 manpath.c--- manpath.c   7 Nov 2015 17:58:52 -   1.17+++ 
manpath.c   23 May 2016 06:15:00 -@@ -176,7 +176,14 @@ manconf_file(struct 
manconf *conf, constep = cp + linelen;if 
(ep[-1] != '\n')break;-   *--ep = '\0';+
   ep--;+   while (ep > cp && isspace(*ep)) {+  
 *ep = '\0';+   ep--;+   }+ 
  if (ep == cp)+   continue;+while 
(isspace((unsigned char)*cp))cp++;if 
(*cp == '#')
Cheers,Mayukh 

Re: MBIM Patch - Part 2 of 4

2016-05-23 Thread Theo de Raadt
> > Why is it better?  This is just working around usb_probe_and_attach()
> > and require developer to add an entry for every device we need to
> > support.
> 
> I just thought that some modules that are already in use say with a
> umsm config would otherwise change to mbim and break the setup. The idea
> was to keep existing modules first as they are now and start adding
> new one to the list.

Please start simple, and solve that problem later.  Too much arriving in
one set of diffs.



Re: MBIM Patch - Part 1 of 4

2016-05-23 Thread Martin Pieuchot
On 23/05/16(Mon) 16:18, Gerhard Roth wrote:
> > > The mbim interface is a point-to-point type interface and will
> > > update the default route, once it is registered in the network.
> > 
> > Can't you insert the route later instead of updating it?
> 
> Have to try. I fact this part of the code is more or less copied from
> sppp_update_gw() in if_spppsubr.c

Yes please.  sppp_* way of doing things should die.

> > > [...] uhub.c may be needed: some modules appear at the usb bus just
> > > to detach themselves again and then reappear shortly after.
> > 
> > Do you know why?  On which controller?
> 
> Oh, I don't think this is a problem of the controller. It's the device
> itself that just detaches and re-attaches again. Guess the firmware has
> a bug. Here's an example:
> 
> usbd_fill_iface_data: bad max packet size
> usbd_fill_iface_data: bad max packet size
> ugen2 at uhub4 port 2 "Sierra Wireless, Incorporated EM8805" rev 2.00/0.00 
> addr 3
> ugen2: setting configuration index 0 failed
> ugen2 detached

This looks like a timing issue before reloading the descriptor.

You could try to increase the timeout in usbd_new_device().

Alternatively, does the diff below help?  It might be incomplete, but
the code fetching the device descriptor in our stack is for sure outdated.

Index: usb_subr.c
===
RCS file: /cvs/src/sys/dev/usb/usb_subr.c,v
retrieving revision 1.123
diff -u -p -r1.123 usb_subr.c
--- usb_subr.c  23 May 2016 11:31:12 -  1.123
+++ usb_subr.c  23 May 2016 14:40:29 -
@@ -1048,7 +1048,12 @@ usbd_new_device(struct device *parent, s
dev->def_ep_desc.bDescriptorType = UDESC_ENDPOINT;
dev->def_ep_desc.bEndpointAddress = USB_CONTROL_ENDPOINT;
dev->def_ep_desc.bmAttributes = UE_CONTROL;
-   USETW(dev->def_ep_desc.wMaxPacketSize, USB_MAX_IPACKET);
+
+   if (speed == USB_SPEED_LOW)
+   USETW(dev->def_ep_desc.wMaxPacketSize, USB_MAX_IPACKET);
+   else
+   USETW(dev->def_ep_desc.wMaxPacketSize, 64);
+
dev->def_ep_desc.bInterval = 0;
 
dev->quirks = &usbd_no_quirk;



Re: nd6_output() and NULL routes

2016-05-23 Thread Martin Pieuchot
On 23/05/16(Mon) 15:59, Alexander Bluhm wrote:
> On Mon, May 23, 2016 at 02:47:02PM +0200, Martin Pieuchot wrote:
> > @@ -750,7 +750,15 @@ pf_refragment6(struct mbuf **m0, struct 
> > if (ifp == NULL) {
> > ip6_forward(m, 0);
> > } else if ((u_long)m->m_pkthdr.len <= ifp->if_mtu) {
> > -   nd6_output(ifp, m, dst, NULL);
> > +   struct rtentry *rt;
> > +   rt = rtalloc(sin6tosa(dst), RT_RESOLVE,
> > +   m->m_pkthdr.ph_rtableid);
> 
> Should we place the rtalloc() outside of the loop and use the same
> route or all fragments?

That would be a performance improvement!

> > @@ -1507,20 +1507,15 @@ nd6_output(struct ifnet *ifp, struct mbu
> > struct mbuf *m = m0;
> > struct rtentry *rt = rt0;
> > struct llinfo_nd6 *ln = NULL;
> > -   int created = 0, error = 0;
> > +   int error = 0;
> >  
> > if (IN6_IS_ADDR_MULTICAST(&dst->sin6_addr))
> > goto sendpkt;
> 
> No kassert rt0 != NULL in here in nd6_output() ?

nop because next step is to merge nd6_output() and nd6_storelladdr()
into nd6_resolve() and match the behavior of arpresolve().  So the
KASSERT() in ether_output() should be enough.

Index: net/pf.c
===
RCS file: /cvs/src/sys/net/pf.c,v
retrieving revision 1.971
diff -u -p -r1.971 pf.c
--- net/pf.c23 May 2016 12:26:28 -  1.971
+++ net/pf.c23 May 2016 14:43:19 -
@@ -5665,11 +5665,13 @@ pf_route6(struct mbuf **m, struct pf_rul
 {
struct mbuf *m0;
struct sockaddr_in6 *dst, sin6;
+   struct rtentry  *rt = NULL;
struct ip6_hdr  *ip6;
struct ifnet*ifp = NULL;
struct pf_addr   naddr;
struct pf_src_node  *sns[PF_SN_MAX];
struct m_tag*mtag;
+   unsigned int rtableid;
 
if (m == NULL || *m == NULL || r == NULL ||
(dir != PF_IN && dir != PF_OUT) || oifp == NULL)
@@ -5702,6 +5704,7 @@ pf_route6(struct mbuf **m, struct pf_rul
dst->sin6_family = AF_INET6;
dst->sin6_len = sizeof(*dst);
dst->sin6_addr = ip6->ip6_dst;
+   rtableid = m0->m_pkthdr.ph_rtableid;
 
if (!r->rt) {
m0->m_pkthdr.pf.flags |= PF_TAG_GENERATED;
@@ -5754,7 +5757,13 @@ pf_route6(struct mbuf **m, struct pf_rul
if ((mtag = m_tag_find(m0, PACKET_TAG_PF_REASSEMBLED, NULL))) {
(void) pf_refragment6(&m0, mtag, dst, ifp);
} else if ((u_long)m0->m_pkthdr.len <= ifp->if_mtu) {
-   nd6_output(ifp, m0, dst, NULL);
+   rt = rtalloc(sin6tosa(dst), RT_RESOLVE, rtableid);
+   if (rt == NULL) {
+   ip6stat.ip6s_noroute++;
+   goto bad;
+   }
+   nd6_output(ifp, m0, dst, rt);
+   rtfree(rt);
} else {
icmp6_error(m0, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu);
}
Index: net/pf_norm.c
===
RCS file: /cvs/src/sys/net/pf_norm.c,v
retrieving revision 1.183
diff -u -p -r1.183 pf_norm.c
--- net/pf_norm.c   24 Nov 2015 13:37:16 -  1.183
+++ net/pf_norm.c   23 May 2016 14:48:01 -
@@ -687,6 +687,7 @@ pf_refragment6(struct mbuf **m0, struct 
 {
struct mbuf *m = *m0, *t;
struct pf_fragment_tag  *ftag = (struct pf_fragment_tag *)(mtag + 1);
+   struct rtentry  *rt = NULL;
u_int32_tmtu;
u_int16_thdrlen, extoff, maxlen;
u_int8_t proto;
@@ -742,6 +743,16 @@ pf_refragment6(struct mbuf **m0, struct 
DPFPRINTF(LOG_NOTICE, "refragment error %d", error);
action = PF_DROP;
}
+
+   if (ifp == NULL) {
+   rt = rtalloc(sin6tosa(dst), RT_RESOLVE,
+   m->m_pkthdr.ph_rtableid);
+   if (rt == NULL) {
+   ip6stat.ip6s_noroute++;
+   error = -1;
+   }
+   }
+
for (t = m; m; m = t) {
t = m->m_nextpkt;
m->m_nextpkt = NULL;
@@ -750,7 +761,7 @@ pf_refragment6(struct mbuf **m0, struct 
if (ifp == NULL) {
ip6_forward(m, 0);
} else if ((u_long)m->m_pkthdr.len <= ifp->if_mtu) {
-   nd6_output(ifp, m, dst, NULL);
+   nd6_output(ifp, m, dst, rt);
} else {
icmp6_error(m, ICMP6_PACKET_TOO_BIG, 0,
ifp->if_mtu);
@@ -759,6 +770,7 @@ pf_refragment6(struct mbuf **m0, struct 
m_freem(m);
}
}
+   rtfree(rt);
 
return

Re: MBIM Patch - Part 2 of 4

2016-05-23 Thread Gerhard Roth
On Mon, 23 May 2016 16:18:29 +0200 Martin Pieuchot  wrote:
> On 23/05/16(Mon) 15:38, Gerhard Roth wrote:
> > This is part 2 of the MBIM patch. It adds the mbim driver to i386
> 
> Comments inline.

Replies too.


> 
> > Index: sys/dev/usb/if_mbim.c
> > ===
> > RCS file: sys/dev/usb/if_mbim.c
> > diff -N sys/dev/usb/if_mbim.c
> > --- /dev/null   1 Jan 1970 00:00:00 -
> > +++ sys/dev/usb/if_mbim.c   23 May 2016 09:50:08 -
> > +
> > +struct cfdriver mbim_cd = {
> > +   NULL, "mbim", DV_DULL
> > +};
> > +
> > +struct cfattach mbim_ca = {
> > +   sizeof (struct mbim_softc),
> > +   mbim_match,
> > +   mbim_attach,
> > +   mbim_detach,
> > +   mbim_activate,
> > +};
> 
> This struct can be const.

Will do


> 
> > +/*
> > + * Some devices are picky about too frequent control messages.
> > + * Query device state not more often than every 0.5 secs.
> > + */
> > +struct timeval mbim_update_rate = { 0, 50 };
> > +int mbim_delay = 4000;
> > +
> > +/*
> > + * Normally, MBIM devices are detected by their interface class and 
> > subclass.
> > + * But for some models that have multiple configurations, it is better to
> > + * match by vendor and product id so that we can select the desired
> > + * configuration ourselves.
> > + *
> > + * OTOH, some devices identifiy themself als an MBIM device but fail to 
> > speak
> > + * the MBIM protocol.
> > + */
> 
> Why is it better?  This is just working around usb_probe_and_attach()
> and require developer to add an entry for every device we need to
> support.

I just thought that some modules that are already in use say with a
umsm config would otherwise change to mbim and break the setup. The idea
was to keep existing modules first as they are now and start adding
new one to the list.


> 
> > +int
> > +mbim_match(struct device *parent, void *match, void *aux)
> > +{
> > +   struct usb_attach_arg *uaa = aux;
> > +   usb_interface_descriptor_t *id;
> > +
> > +   if (usb_lookup(mbim_blacklist, uaa->vendor, uaa->product) != NULL)
> > +   return UMATCH_NONE;
> > +   if (mbim_lookup(uaa->vendor, uaa->product) != NULL)
> > +   return UMATCH_VENDOR_PRODUCT;
> > +   if (!uaa->iface)
> > +   return UMATCH_NONE;
> > +   if (!uaa->iface ||
> > +   (id = usbd_get_interface_descriptor(uaa->iface)) == NULL)
> > +   return UMATCH_NONE;
> > +   if (id->bInterfaceClass != UICLASS_CDC ||
> > +   id->bInterfaceSubClass !=
> > +   UISUBCLASS_MOBILE_BROADBAND_INTERFACE_MODEL ||
> > +   id->bNumEndpoints != 1)
> > +   return UMATCH_NONE;
> > +
> > +   return UMATCH_DEVCLASS_DEVSUBCLASS;
> > +}
> > +
> > +void
> > +mbim_attach(struct device *parent, struct device *self, void *aux)
> > +{
> > +   struct mbim_softc *sc = (struct mbim_softc *)self;
> > +   struct usb_attach_arg *uaa = aux;
> > +   usbd_status status;
> > +   struct usbd_desc_iter iter;
> > +   const usb_descriptor_t *desc;
> > +   int  v;
> > +   struct mbim_descriptor *md;
> > +   int  i;
> > +   struct usbd_interface *ctrl_iface = NULL;
> > +   int  ctrl_ep;
> > +   uint8_t  data_ifaceno;
> > +   usb_interface_descriptor_t *id;
> > +   usb_config_descriptor_t *cd;
> > +   usb_endpoint_descriptor_t *ed;
> > +   int  s;
> > +   struct ifnet *ifp;
> > +   int  hard_mtu;
> > +
> > +   sc->sc_udev = uaa->device;
> > +
> > +   if (uaa->configno < 0) {
> > +   uaa->configno = mbim_lookup(uaa->vendor, uaa->product)->confno;
> > +   DPRINTF("%s: switching to config #%d\n", DEVNAM(sc),
> > +   uaa->configno);
> > +   status = usbd_set_config_no(sc->sc_udev, uaa->configno, 1);
> > +   if (status) {
> > +   printf("%s: failed to switch to config #%d: %s\n",
> > +   DEVNAM(sc), uaa->configno, usbd_errstr(status));
> > +   goto fail;
> > +   }
> > +   }
> > +
> > +   sc->sc_ver_maj = sc->sc_ver_min = -1;
> > +   usbd_desc_iter_init(sc->sc_udev, &iter);
> > +   hard_mtu = MBIM_MAXSEGSZ_MINVAL;
> > +   while ((desc = usbd_desc_iter_next(&iter))) {
> > +   if (desc->bDescriptorType != UDESC_CS_INTERFACE)
> > +   continue;
> > +   switch (desc->bDescriptorSubtype) {
> > +   case UDESCSUB_MBIM:
> > +   md = (struct mbim_descriptor *)desc;
> > +   v = UGETW(md->bcdMBIMVersion);
> > +   sc->sc_ver_maj = MBIM_VER_MAJOR(v);
> > +   sc->sc_ver_min = MBIM_VER_MINOR(v);
> > +   sc->sc_ctrl_len = UGETW(md->wMaxControlMessage);
> > +   /* Never trust a USB device! Could try to exploit us */
> > +   if (sc->sc_ctrl_len < MBIM_CTRLMSG_MINLEN ||
> > +   sc->sc_ctrl_len > MBIM_CTRLMSG_MAXLEN) {
> > +   printf("%s: control message len %d out of "
> > +   "bounds [%d .. %d]\n", DEVNAM(sc),
> 

Re: MBIM Patch - Part 2 of 4

2016-05-23 Thread Martin Pieuchot
On 23/05/16(Mon) 15:38, Gerhard Roth wrote:
> This is part 2 of the MBIM patch. It adds the mbim driver to i386

Comments inline.

> Index: sys/dev/usb/if_mbim.c
> ===
> RCS file: sys/dev/usb/if_mbim.c
> diff -N sys/dev/usb/if_mbim.c
> --- /dev/null 1 Jan 1970 00:00:00 -
> +++ sys/dev/usb/if_mbim.c 23 May 2016 09:50:08 -
> +
> +struct cfdriver mbim_cd = {
> + NULL, "mbim", DV_DULL
> +};
> +
> +struct cfattach mbim_ca = {
> + sizeof (struct mbim_softc),
> + mbim_match,
> + mbim_attach,
> + mbim_detach,
> + mbim_activate,
> +};

This struct can be const.

> +/*
> + * Some devices are picky about too frequent control messages.
> + * Query device state not more often than every 0.5 secs.
> + */
> +struct timeval mbim_update_rate = { 0, 50 };
> +int mbim_delay = 4000;
> +
> +/*
> + * Normally, MBIM devices are detected by their interface class and subclass.
> + * But for some models that have multiple configurations, it is better to
> + * match by vendor and product id so that we can select the desired
> + * configuration ourselves.
> + *
> + * OTOH, some devices identifiy themself als an MBIM device but fail to speak
> + * the MBIM protocol.
> + */

Why is it better?  This is just working around usb_probe_and_attach()
and require developer to add an entry for every device we need to
support.

> +int
> +mbim_match(struct device *parent, void *match, void *aux)
> +{
> + struct usb_attach_arg *uaa = aux;
> + usb_interface_descriptor_t *id;
> +
> + if (usb_lookup(mbim_blacklist, uaa->vendor, uaa->product) != NULL)
> + return UMATCH_NONE;
> + if (mbim_lookup(uaa->vendor, uaa->product) != NULL)
> + return UMATCH_VENDOR_PRODUCT;
> + if (!uaa->iface)
> + return UMATCH_NONE;
> + if (!uaa->iface ||
> + (id = usbd_get_interface_descriptor(uaa->iface)) == NULL)
> + return UMATCH_NONE;
> + if (id->bInterfaceClass != UICLASS_CDC ||
> + id->bInterfaceSubClass !=
> + UISUBCLASS_MOBILE_BROADBAND_INTERFACE_MODEL ||
> + id->bNumEndpoints != 1)
> + return UMATCH_NONE;
> +
> + return UMATCH_DEVCLASS_DEVSUBCLASS;
> +}
> +
> +void
> +mbim_attach(struct device *parent, struct device *self, void *aux)
> +{
> + struct mbim_softc *sc = (struct mbim_softc *)self;
> + struct usb_attach_arg *uaa = aux;
> + usbd_status status;
> + struct usbd_desc_iter iter;
> + const usb_descriptor_t *desc;
> + int  v;
> + struct mbim_descriptor *md;
> + int  i;
> + struct usbd_interface *ctrl_iface = NULL;
> + int  ctrl_ep;
> + uint8_t  data_ifaceno;
> + usb_interface_descriptor_t *id;
> + usb_config_descriptor_t *cd;
> + usb_endpoint_descriptor_t *ed;
> + int  s;
> + struct ifnet *ifp;
> + int  hard_mtu;
> +
> + sc->sc_udev = uaa->device;
> +
> + if (uaa->configno < 0) {
> + uaa->configno = mbim_lookup(uaa->vendor, uaa->product)->confno;
> + DPRINTF("%s: switching to config #%d\n", DEVNAM(sc),
> + uaa->configno);
> + status = usbd_set_config_no(sc->sc_udev, uaa->configno, 1);
> + if (status) {
> + printf("%s: failed to switch to config #%d: %s\n",
> + DEVNAM(sc), uaa->configno, usbd_errstr(status));
> + goto fail;
> + }
> + }
> +
> + sc->sc_ver_maj = sc->sc_ver_min = -1;
> + usbd_desc_iter_init(sc->sc_udev, &iter);
> + hard_mtu = MBIM_MAXSEGSZ_MINVAL;
> + while ((desc = usbd_desc_iter_next(&iter))) {
> + if (desc->bDescriptorType != UDESC_CS_INTERFACE)
> + continue;
> + switch (desc->bDescriptorSubtype) {
> + case UDESCSUB_MBIM:
> + md = (struct mbim_descriptor *)desc;
> + v = UGETW(md->bcdMBIMVersion);
> + sc->sc_ver_maj = MBIM_VER_MAJOR(v);
> + sc->sc_ver_min = MBIM_VER_MINOR(v);
> + sc->sc_ctrl_len = UGETW(md->wMaxControlMessage);
> + /* Never trust a USB device! Could try to exploit us */
> + if (sc->sc_ctrl_len < MBIM_CTRLMSG_MINLEN ||
> + sc->sc_ctrl_len > MBIM_CTRLMSG_MAXLEN) {
> + printf("%s: control message len %d out of "
> + "bounds [%d .. %d]\n", DEVNAM(sc),
> + sc->sc_ctrl_len, MBIM_CTRLMSG_MINLEN,
> + MBIM_CTRLMSG_MAXLEN);
> + /* cont. anyway */
> + }
> + sc->sc_maxpktlen = UGETW(md->wMaxSegmentSize);
> + if (sc->sc_maxpktlen < MBIM_MAXSEGSZ_MINVAL) {
> + printf("%s: ignoring invalid segment size %d\n",
> +

Re: MBIM Patch - Part 1 of 4

2016-05-23 Thread Gerhard Roth
On Mon, 23 May 2016 15:54:36 +0200 Martin Pieuchot  wrote:
> On 23/05/16(Mon) 15:37, Gerhard Roth wrote:
> > I have this stuff around quite a while now, but since patrick@ asked
> > me repeatedly, I think it is time to share this now.
> > 
> > This is a patch that adds support for the "Mobile Broadband Interface
> > Model" (MBIM) from http://www.usb.org/. It allows to attach UMTS/LTE
> > USB devices as a network interface.
> 
> That's great!
> 
> > I'm not asking for OKs at this time, but hope that some people will
> > give it test. I tested with two different Sierra Wireless modules
> > (EM8805, MC8305) and each one behaved a little bit different.
> > 
> > In order to configure the network interface, this is what you do:
> > 
> > # ifconfig mbim0 pin 1234 apn internet.t-mobile
> 
> I'd like to bikeshed early, we're trying to prefix all new USB driver
> name with 'u'.  So I'd suggest a rename when this goes in tree.

Of course no problem. Will fix that with the next version of the patch.


> 
> > # ifconfig mbim0 inet 0.0.0.1 0.0.0.2
> > # route delete default
> > # route add -ifp mbim0 default 0.0.0.2
> > # ifconfig mbim0 up
> >
> > The mbim interface is a point-to-point type interface and will
> > update the default route, once it is registered in the network.
> 
> Can't you insert the route later instead of updating it?

Have to try. I fact this part of the code is more or less copied from
sppp_update_gw() in if_spppsubr.c


> 
> > [...] uhub.c may be needed: some modules appear at the usb bus just
> > to detach themselves again and then reappear shortly after.
> 
> Do you know why?  On which controller?

Oh, I don't think this is a problem of the controller. It's the device
itself that just detaches and re-attaches again. Guess the firmware has
a bug. Here's an example:

usbd_fill_iface_data: bad max packet size
usbd_fill_iface_data: bad max packet size
ugen2 at uhub4 port 2 "Sierra Wireless, Incorporated EM8805" rev 2.00/0.00 addr 
3
ugen2: setting configuration index 0 failed
ugen2 detached
mbim1 at uhub4 port 2 "Sierra Wireless, Incorporated EM8805" rev 2.00/0.06 addr 
3


Gerhard



Re: nd6_output() and NULL routes

2016-05-23 Thread Alexander Bluhm
On Mon, May 23, 2016 at 02:47:02PM +0200, Martin Pieuchot wrote:
> @@ -5506,6 +5506,7 @@ pf_route(struct mbuf **m, struct pf_rule
>   int  error = 0;
>   unsigned int rtableid;
>  
> +
>   if (m == NULL || *m == NULL || r == NULL ||
>   (dir != PF_IN && dir != PF_OUT) || oifp == NULL)
>   panic("pf_route: invalid parameters");

No double empty line please.

> @@ -750,7 +750,15 @@ pf_refragment6(struct mbuf **m0, struct 
>   if (ifp == NULL) {
>   ip6_forward(m, 0);
>   } else if ((u_long)m->m_pkthdr.len <= ifp->if_mtu) {
> - nd6_output(ifp, m, dst, NULL);
> + struct rtentry *rt;
> + rt = rtalloc(sin6tosa(dst), RT_RESOLVE,
> + m->m_pkthdr.ph_rtableid);

Should we place the rtalloc() outside of the loop and use the same
route or all fragments?

> + if (rt == NULL) {
> + ip6stat.ip6s_noroute++;

m_freem(m) is missing, you leak a mbuf in this case.

> + } else {
> + nd6_output(ifp, m, dst, rt);
> + rtfree(rt);
> + }
>   } else {
>   icmp6_error(m, ICMP6_PACKET_TOO_BIG, 0,
>   ifp->if_mtu);

> @@ -1507,20 +1507,15 @@ nd6_output(struct ifnet *ifp, struct mbu
>   struct mbuf *m = m0;
>   struct rtentry *rt = rt0;
>   struct llinfo_nd6 *ln = NULL;
> - int created = 0, error = 0;
> + int error = 0;
>  
>   if (IN6_IS_ADDR_MULTICAST(&dst->sin6_addr))
>   goto sendpkt;

No kassert rt0 != NULL in here in nd6_output() ?

>  
> - /*
> -  * next hop determination.
> -  */
> - if (rt0 != NULL) {
> - error = rt_checkgate(rt0, &rt);
> - if (error) {
> - m_freem(m);
> - return (error);
> - }
> + error = rt_checkgate(rt0, &rt);
> + if (error) {
> + m_freem(m);
> + return (error);
>   }
>  
>   if (nd6_need_cache(ifp) == 0)



Re: MBIM Patch - Part 3 of 4

2016-05-23 Thread Theo de Raadt
This is a highly invasive change to ifconfig, for such a minor feature.

I suspect this will overflow the ramdisks.



Re: MBIM Patch - Part 1 of 4

2016-05-23 Thread Martin Pieuchot
On 23/05/16(Mon) 15:37, Gerhard Roth wrote:
> I have this stuff around quite a while now, but since patrick@ asked
> me repeatedly, I think it is time to share this now.
> 
> This is a patch that adds support for the "Mobile Broadband Interface
> Model" (MBIM) from http://www.usb.org/. It allows to attach UMTS/LTE
> USB devices as a network interface.

That's great!

> I'm not asking for OKs at this time, but hope that some people will
> give it test. I tested with two different Sierra Wireless modules
> (EM8805, MC8305) and each one behaved a little bit different.
> 
> In order to configure the network interface, this is what you do:
> 
>   # ifconfig mbim0 pin 1234 apn internet.t-mobile

I'd like to bikeshed early, we're trying to prefix all new USB driver
name with 'u'.  So I'd suggest a rename when this goes in tree.

>   # ifconfig mbim0 inet 0.0.0.1 0.0.0.2
>   # route delete default
>   # route add -ifp mbim0 default 0.0.0.2
>   # ifconfig mbim0 up
>
> The mbim interface is a point-to-point type interface and will
> update the default route, once it is registered in the network.

Can't you insert the route later instead of updating it?

> [...] uhub.c may be needed: some modules appear at the usb bus just
> to detach themselves again and then reappear shortly after.

Do you know why?  On which controller?

> Index: sys/dev/usb/uhub.c
> ===
> RCS file: /cvs/src/sys/dev/usb/uhub.c,v
> retrieving revision 1.88
> diff -u -p -u -p -r1.88 uhub.c
> --- sys/dev/usb/uhub.c29 Nov 2015 16:30:48 -  1.88
> +++ sys/dev/usb/uhub.c23 May 2016 09:50:08 -
> @@ -523,7 +523,9 @@ uhub_port_connect(struct uhub_softc *sc,
>  {
>   struct usbd_port *up = &sc->sc_hub->hub->ports[port-1];
>   int speed;
> + int retry = 1;
>  
> +again:
>   /* We have a connect status change, handle it. */
>   usbd_clear_port_feature(sc->sc_hub, port, UHF_C_PORT_CONNECTION);
>  
> @@ -613,6 +615,11 @@ uhub_port_connect(struct uhub_softc *sc,
>* some other serious problem.  Since we cannot leave
>* at 0 we have to disable the port instead.
>*/
> + if (retry--) {
> + printf("%s: port %d: retrying\n", DEVNAME(sc), port);
> + goto again;
> + }
> +
>   printf("%s: device problem, disabling port %d\n", DEVNAME(sc),
>   port);
>   usbd_clear_port_feature(sc->sc_hub, port, UHF_PORT_ENABLE);



MBIM Patch - Part 1 of 4

2016-05-23 Thread Gerhard Roth
I have this stuff around quite a while now, but since patrick@ asked
me repeatedly, I think it is time to share this now.

This is a patch that adds support for the "Mobile Broadband Interface
Model" (MBIM) from http://www.usb.org/. It allows to attach UMTS/LTE
USB devices as a network interface.

I'm not asking for OKs at this time, but hope that some people will
give it test. I tested with two different Sierra Wireless modules
(EM8805, MC8305) and each one behaved a little bit different.

In order to configure the network interface, this is what you do:

# ifconfig mbim0 pin 1234 apn internet.t-mobile
# ifconfig mbim0 inet 0.0.0.1 0.0.0.2
# route delete default
# route add -ifp mbim0 default 0.0.0.2
# ifconfig mbim0 up

The mbim interface is a point-to-point type interface and will
update the default route, once it is registered in the network.

To get extended information on the interface use:

# ifconfig mbim0 devinfo


The patch comes in 4 parts. This is the first part that provides
some changes required to the rest of the kernel. Esp. the change
in uhub.c may be needed: some modules appear at the usb bus just
to detach themselves again and then reappear shortly after.

After patching, please do a

# cd /sys/dev/usb
# make

to rebuild usbdevs.h and usbdevs_data.h.

In case of problems, please add

option MBIM_DEBUG

to generic and set the variable 'mbim_debug'.

Have fun,

Gerhard


Index: sys/dev/usb/uhub.c
===
RCS file: /cvs/src/sys/dev/usb/uhub.c,v
retrieving revision 1.88
diff -u -p -u -p -r1.88 uhub.c
--- sys/dev/usb/uhub.c  29 Nov 2015 16:30:48 -  1.88
+++ sys/dev/usb/uhub.c  23 May 2016 09:50:08 -
@@ -523,7 +523,9 @@ uhub_port_connect(struct uhub_softc *sc,
 {
struct usbd_port *up = &sc->sc_hub->hub->ports[port-1];
int speed;
+   int retry = 1;
 
+again:
/* We have a connect status change, handle it. */
usbd_clear_port_feature(sc->sc_hub, port, UHF_C_PORT_CONNECTION);
 
@@ -613,6 +615,11 @@ uhub_port_connect(struct uhub_softc *sc,
 * some other serious problem.  Since we cannot leave
 * at 0 we have to disable the port instead.
 */
+   if (retry--) {
+   printf("%s: port %d: retrying\n", DEVNAME(sc), port);
+   goto again;
+   }
+
printf("%s: device problem, disabling port %d\n", DEVNAME(sc),
port);
usbd_clear_port_feature(sc->sc_hub, port, UHF_PORT_ENABLE);
Index: sys/dev/usb/usb.h
===
RCS file: /cvs/src/sys/dev/usb/usb.h,v
retrieving revision 1.54
diff -u -p -u -p -r1.54 usb.h
--- sys/dev/usb/usb.h   28 Feb 2016 17:57:50 -  1.54
+++ sys/dev/usb/usb.h   23 May 2016 09:50:08 -
@@ -508,6 +508,7 @@ typedef struct usb_port_status usb_port_
 #define UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL 6
 #define UISUBCLASS_ATM_NETWORKING_CONTROL_MODEL 7
 #define UISUBCLASS_MOBILE_DIRECT_LINE_MODEL10
+#define UISUBCLASS_MOBILE_BROADBAND_INTERFACE_MODEL 14
 #define   UIPROTO_CDC_AT   1
 
 #define UICLASS_HID0x03
@@ -545,6 +546,7 @@ typedef struct usb_port_status usb_port_
 
 #define UICLASS_CDC_DATA   0x0a
 #define  UISUBCLASS_DATA   0
+#define   UIPROTO_DATA_MBIM0x02/* MBIM */
 #define   UIPROTO_DATA_ISDNBRI 0x30/* Physical iface */
 #define   UIPROTO_DATA_HDLC0x31/* HDLC */
 #define   UIPROTO_DATA_TRANSPARENT 0x32/* Transparent */
Index: sys/dev/usb/usbdevs
===
RCS file: /cvs/src/sys/dev/usb/usbdevs,v
retrieving revision 1.664
diff -u -p -u -p -r1.664 usbdevs
--- sys/dev/usb/usbdevs 20 May 2016 02:04:24 -  1.664
+++ sys/dev/usb/usbdevs 23 May 2016 09:50:08 -
@@ -3832,7 +3832,9 @@ product SIERRA AC881U 0x6856  881U
 product SIERRA AC885U  0x6880  885U
 product SIERRA C01SW   0x6890  C01SW
 product SIERRA USB305  0x68a3  USB305
+product SIERRA MC8305  0x9011  MC8305
 product SIERRA MC8355  0x9013  MC8355
+product SIERRA EM8805  0x9041  EM8805
 product SIERRA AIRCARD_770S0x9053  Aircard 770S
 
 /* Sigmatel products */
Index: sys/net/if_types.h
===
RCS file: /cvs/src/sys/net/if_types.h,v
retrieving revision 1.20
diff -u -p -u -p -r1.20 if_types.h
--- sys/net/if_types.h  7 Mar 2016 19:33:26 -   1.20
+++ sys/net/if_types.h  23 May 2016 09:50:09 -
@@ -268,5 +268,6 @@
 #defineIFT_CARP0xf7/* Common Address Redundancy 
Protocol */
 #define IFT_BLUETOOTH  0xf8/* Bluetooth */
 #define IFT_PFLOW  0xf9/*

MBIM Patch - Part 4 of 4

2016-05-23 Thread Gerhard Roth
This is the final patch for MBIM which adds a manual page for
mbim(4).


Index: share/man/man4/Makefile
===
RCS file: /cvs/src/share/man/man4/Makefile,v
retrieving revision 1.621
diff -u -p -u -p -r1.621 Makefile
--- share/man/man4/Makefile 11 May 2016 21:52:49 -  1.621
+++ share/man/man4/Makefile 23 May 2016 09:50:08 -
@@ -33,9 +33,9 @@ MAN=  aac.4 ac97.4 acphy.4 \
ix.4 ixgb.4 jmb.4 jme.4 jmphy.4 \
kate.4 km.4 ksyms.4 kue.4 lc.4 lge.4 lii.4 lisa.4 lm.4 \
lmenv.4 lmn.4 lmtemp.4 lo.4 lpt.4 lxtphy.4 luphy.4 \
-   maestro.4 mainbus.4 malo.4 maxds.4 maxtmp.4 mbg.4 midi.4 mii.4 mfi.4 \
-   mfii.4 mlphy.4 moscom.4 mos.4 mpe.4 mpath.4 mpi.4 mpii.4 mpu.4 msk.4 \
-   mpw.4 msts.4 mtd.4 mtdphy.4 multicast.4 mtio.4 myx.4 \
+   maestro.4 mainbus.4 malo.4 maxds.4 maxtmp.4 mbg.4 mbim.4 midi.4 mii.4 \
+   mfi.4 mfii.4 mlphy.4 moscom.4 mos.4 mpe.4 mpath.4 mpi.4 mpii.4 mpu.4 \
+   msk.4 mpw.4 msts.4 mtd.4 mtdphy.4 multicast.4 mtio.4 myx.4 \
ne.4 neo.4 nep.4 netintro.4 nfe.4 nge.4 nmea.4 \
nsclpcsio.4 nsgphy.4 nsphy.4 nsphyter.4 null.4 nviic.4 nvme.4 nvt.4 \
oce.4 ohci.4 options.4 onewire.4 oosiop.4 osiop.4 otus.4 \
Index: share/man/man4/mbim.4
===
RCS file: share/man/man4/mbim.4
diff -N share/man/man4/mbim.4
--- /dev/null   1 Jan 1970 00:00:00 -
+++ share/man/man4/mbim.4   23 May 2016 09:50:08 -
@@ -0,0 +1,95 @@
+.\" Copyright (c) 2016 genua mbH
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\"
+.\"- Redistributions of source code must retain the above copyright
+.\"  notice, this list of conditions and the following disclaimer.
+.\"- Redistributions in binary form must reproduce the above
+.\"  copyright notice, this list of conditions and the following
+.\"  disclaimer in the documentation and/or other materials provided
+.\"  with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+.\" "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+.\" COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+.\" CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+.\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $OpenBSD$
+.\"
+.Dd $Mdocdate$
+.Dt MBIM 4
+.Os
+.Sh NAME
+.Nm mbim
+.Nd USB Mobile Broadband Interface Model
+.Sh SYNOPSIS
+.Cd "mbim*  at uhub?"
+.Sh DESCRIPTION
+The
+.Nm
+driver provides support for USB MBIM devices. Those devices allow to
+establish connections via celluar networks such as GPRS, UMTS, LTE, etc.
+.Pp
+The
+.Nm
+device appears as a regular point-to-point network interface,
+transporting raw IP frames.
+.Pp
+Required configuration parameters like PIN and APN have to be set
+via
+.Xr ifconfig 8 .
+Once the SIM card has has been unlocked with the correct PIN, it
+will remain in this state until the device is power-cycled.
+In case the device is connected to an "always-on" USB port,
+it is possible to connect to a provider without entering the
+PIN again even afer a reboot of the system.
+.Pp
+If a default gateway route is configured for the
+.Nm
+network interface, the driver will modify the destination IP address
+dynamically, according to the information sent by the network provider.
+.Sh HARDWARE
+The following devices are known to be supported by the
+.Nm
+driver:
+.Pp
+.Bl -tag -width Ds -offset indent -compact
+.It Tn Sierra Wireless MC8305
+.It Tn Sierra Wireless EM8805
+.El
+.Pp
+There are probably a lot more devices that also work flawlessly.
+If some devices fail to provide a confirming MBIM implementation,
+their vendor and product IDs should be added to the driver's blacklist
+manually.  Since most device offer multiple interfaces, blacklisted ones
+will probably be attached by some other driver, e.g.
+.Xr umsm 4 .
+.Sh SEE ALSO
+.Xr intro 4 ,
+.Xr netintro 4 ,
+.Xr usb 4 ,
+.Xr hostname.if 5 ,
+.Xr ifconfig 8
+.Xr route 8
+.Rs
+.%T "Universal Serial Bus Communications Class Subclass Specification for 
Mobile Broadband Interface Model"
+.%U http://www.usb.org/developers/docs/devclass_docs/MBIM10Errata1_073013.zip
+.Re
+.Sh CAVEATS
+The
+.Nm
+driver currently does not support IPv6 addresses.
+.Pp
+Roaming can be prevented by the driver. Thi

MBIM Patch - Part 3 of 4

2016-05-23 Thread Gerhard Roth
Part 3 of the MBIM patch updates ifconfig(8).


Index: sbin/ifconfig/ifconfig.8
===
RCS file: /cvs/src/sbin/ifconfig/ifconfig.8,v
retrieving revision 1.267
diff -u -p -u -p -r1.267 ifconfig.8
--- sbin/ifconfig/ifconfig.86 Apr 2016 10:07:14 -   1.267
+++ sbin/ifconfig/ifconfig.823 May 2016 09:50:08 -
@@ -519,6 +519,8 @@ tunnel
 .Xr vxlan 4 )
 .It
 .Xr vlan 4
+.It
+.Xr mbim 4
 .El
 .\" BRIDGE
 .Sh BRIDGE
@@ -1645,6 +1647,71 @@ will be assigned 802.1Q tag 5.
 Disassociate from the parent interface.
 This breaks the link between the vlan interface and its parent,
 clears its vlan tag, flags, and link address, and shuts the interface down.
+.El
+.\" MBIM
+.Sh MBIM
+.nr nS 1
+.Bk -words
+.Nm ifconfig
+.Ar mbim-interface
+.Op Cm pin Ar pin
+.Op Cm chgpin Ar oldpin Ar newpin
+.Op Cm puk Ar puk Ar newpin
+.Op Oo Fl Oc Ns Cm apn Ar apn
+.Op Oo Fl Oc Ns Cm class Ar class,class,...
+.Op Oo Fl Oc Ns Cm roaming
+.Ek
+.nr nS 0
+.Pp
+The following options are available for an
+.Xr mbim 4
+interface:
+.Bl -tag -width Ds
+.It Cm pin Ar pin
+Enter the PIN required to unlock the SIM card. Most SIM cards will not
+allow to establish a network association without providing a PIN.
+.It Cm chgpin Ar oldpin Ar newpin
+Permanently changes the PIN of the SIM card from the current value
+.Ar oldpin
+to
+.Ar newpin .
+.It Cm puk Ar puk Ar newpin
+Sets the PIN of the SIM card to
+.Ar newpin
+using the PUK
+.Ar puk
+to validate the request.
+.It Cm apn Ar apn
+Set the "Access Point Name" required by your network provider.
+.It Fl apn
+Clear the current "Access Point Name" value.
+.It Cm class
+List all available cell classes.
+.It Cm class Ar class,class,...
+Set the preferred cell classes. Apart from those listed by
+.Nm Cm class
+the following aliases can be used:
+.Ar 4G,
+.Ar 3G,
+and
+.Ar 2G.
+.It Fl class
+Clear any cell class preferences.
+.It Cm roaming
+Enable data roaming.
+.It Fl roaming
+Disable data roaming.
+.It Cm up
+As soon as the interface is marked as "up", the
+.Xr mbim 4
+device will try to establish a data connection with the service provider.
+.It Cm down
+Marking the interface as "down" will terminate any existing data connection
+and deregister with the service provider.
+.It Cm devinfo
+Provides some additional information about the
+.Xr mbim 4
+device, e.g. the IMEI number.
 .El
 .Sh EXAMPLES
 Assign the
Index: sbin/ifconfig/ifconfig.c
===
RCS file: /cvs/src/sbin/ifconfig/ifconfig.c,v
retrieving revision 1.322
diff -u -p -u -p -r1.322 ifconfig.c
--- sbin/ifconfig/ifconfig.c3 May 2016 17:52:33 -   1.322
+++ sbin/ifconfig/ifconfig.c23 May 2016 09:50:08 -
@@ -107,6 +107,8 @@
 #include 
 
 #include "brconfig.h"
+#include 
+#include 
 
 #define MINIMUM(a, b)  (((a) < (b)) ? (a) : (b))
 #define MAXIMUM(a, b)  (((a) > (b)) ? (a) : (b))
@@ -143,8 +145,10 @@ intLflag = 1;
 
 intshowmediaflag;
 intshowcapsflag;
+intshowdevinfoflag;
 intshownet80211chans;
 intshownet80211nodes;
+intshowclasses;
 
 void   notealias(const char *, int);
 void   setifaddr(const char *, int);
@@ -275,6 +279,19 @@ void   unsetifdesc(const char *, int);
 void   printifhwfeatures(const char *, int);
 void   setpair(const char *, int);
 void   unsetpair(const char *, int);
+void   mbim_status(void);
+void   mbim_devinfo(const char *, int);
+void   mbim_printclasses(char *, int);
+intmbim_parse_classes(const char *);
+void   mbim_setpin(const char *, int);
+void   mbim_chgpin(const char *, const char *);
+void   mbim_puk(const char *, const char *);
+void   mbim_pinop(int, int, const char *, const char *);
+void   mbim_apn(const char *, int);
+void   mbim_setclass(const char *, int);
+void   mbim_roaming(const char *, int);
+void   utf16_to_char(uint16_t *, int, char *, size_t);
+intchar_to_utf16(const char *, uint16_t *, size_t);
 #else
 void   setignore(const char *, int);
 #endif
@@ -486,6 +503,16 @@ const struct   cmd {
{ "-descr", 1,  0,  unsetifdesc },
{ "wol",IFXF_WOL,   0,  setifxflags },
{ "-wol",   -IFXF_WOL,  0,  setifxflags },
+   { "devinfo",NEXTARG0,   0,  mbim_devinfo },
+   { "pin",NEXTARG,0,  mbim_setpin },
+   { "chgpin", NEXTARG2,   0,  NULL, mbim_chgpin },
+   { "puk",NEXTARG2,   0,  NULL, mbim_puk },
+   { "apn",NEXTARG,0,  mbim_apn },
+   { "-apn",   -1, 0,  mbim_apn },
+   { "class",  NEXTARG0,   0,  mbim_setclass },
+   { "-class", -1, 0,  mbim_setclass },
+   { "roaming",1,  0,  mbim_roaming },
+   { "-roaming",   0,  0,  mbim_roaming

MBIM Patch - Part 2 of 4

2016-05-23 Thread Gerhard Roth
This is part 2 of the MBIM patch. It adds the mbim driver to i386
and amd64 kernels.


Index: sys/arch/amd64/conf/GENERIC
===
RCS file: /cvs/src/sys/arch/amd64/conf/GENERIC,v
retrieving revision 1.418
diff -u -p -u -p -r1.418 GENERIC
--- sys/arch/amd64/conf/GENERIC 7 May 2016 23:10:50 -   1.418
+++ sys/arch/amd64/conf/GENERIC 23 May 2016 09:50:08 -
@@ -279,6 +279,7 @@ urtw*   at uhub?# Realtek 8187
 rsu*   at uhub?# Realtek RTL8188SU/RTL8191SU/RTL8192SU
 urtwn* at uhub?# Realtek RTL8188CU/RTL8192CU
 udcf*  at uhub?# Gude Expert mouseCLOCK
+mbim*  at uhub?# Mobile Broadband Interface Model
 uthum* at uhidev?  # TEMPerHUM sensor
 ugold* at uhidev?  # gold TEMPer sensor
 utrh*  at uhidev?  # USBRH sensor
Index: sys/arch/i386/conf/GENERIC
===
RCS file: /cvs/src/sys/arch/i386/conf/GENERIC,v
retrieving revision 1.814
diff -u -p -u -p -r1.814 GENERIC
--- sys/arch/i386/conf/GENERIC  24 Apr 2016 17:30:31 -  1.814
+++ sys/arch/i386/conf/GENERIC  23 May 2016 09:50:08 -
@@ -14,6 +14,9 @@ include   "../../../conf/GENERIC"
 maxusers   80  # estimated number of users
 
 option USER_PCICONF# user-space PCI configuration
+option USB_DEBUG
+#optionUHUB_DEBUG
+option EHCI_DEBUG
 
 #optionVM86# Virtual 8086 emulation
 option KVM86   # Kernel Virtual 8086 emulation
@@ -314,6 +317,7 @@ rsu*at uhub?# Realtek 
RTL8188SU/RTL81
 urtwn* at uhub?# Realtek RTL8188CU/RTL8192CU
 udcf*  at uhub?# Gude Expert mouseCLOCK
 umbg*  at uhub?# Meinberg Funkuhren USB5131
+mbim*  at uhub?# Mobile Broadband Interface Model
 uthum* at uhidev?  # TEMPerHUM sensor
 ugold* at uhidev?  # gold TEMPer sensor
 utrh*  at uhidev?  # USBRH sensor
Index: sys/dev/usb/files.usb
===
RCS file: /cvs/src/sys/dev/usb/files.usb,v
retrieving revision 1.126
diff -u -p -u -p -r1.126 files.usb
--- sys/dev/usb/files.usb   8 Jan 2016 15:54:13 -   1.126
+++ sys/dev/usb/files.usb   23 May 2016 09:50:08 -
@@ -397,6 +397,11 @@ device otus: ether, ifnet, ifmedia, wlan
 attach otus at uhub
 file   dev/usb/if_otus.c   otus
 
+# Mobile Broadband Interface Model
+device mbim: ifnet, ifmedia
+attach mbim at uhub
+file   dev/usb/if_mbim.c   mbim
+
 # USB logical device
 device usbf {}
 attach usbf at usbdev
Index: sys/dev/usb/if_mbim.c
===
RCS file: sys/dev/usb/if_mbim.c
diff -N sys/dev/usb/if_mbim.c
--- /dev/null   1 Jan 1970 00:00:00 -
+++ sys/dev/usb/if_mbim.c   23 May 2016 09:50:08 -
@@ -0,0 +1,2487 @@
+/* $OpenBSD$ */
+
+/*
+ * Copyright (c) 2016 genua mbH
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Mobile Broadband Interface Model
+ * http://www.usb.org/developers/docs/devclass_docs/MBIM-Compliance-1.0.pdf
+ */
+#include "bpfilter.h"
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#if NBPFILTER > 0
+#include 
+#endif
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#ifdef MBIM_DEBUG
+#define DPRINTF(x...)  \
+   do { if (mbim_debug) log(LOG_DEBUG, x); } while (0)
+
+#define DPRINTFN(n, x...)  \
+   do { if (mbim_debug >= (n)) log(LOG_DEBUG, x); } while (0)
+
+#define DDUMPN(n, b, l)
\
+   do {\
+   if (mbim_debug >= (n))  \
+   mbim

bridge, carp and HW-vlan

2016-05-23 Thread Martin Pieuchot
HW-vlan breaks our if_input() design because vlan packets are
decapsulated before calling if_input().

So it doesn't matter in which order you configured your pseudo-driver,
they all have to deal with this layer violation.

Here's a jumbo diff for carp(4) and bridge(4).

Index: net/if_bridge.c
===
RCS file: /cvs/src/sys/net/if_bridge.c,v
retrieving revision 1.278
diff -u -p -r1.278 if_bridge.c
--- net/if_bridge.c 12 Apr 2016 06:20:30 -  1.278
+++ net/if_bridge.c 23 May 2016 13:17:08 -
@@ -1063,6 +1063,18 @@ bridge_process(struct ifnet *ifp, struct
if ((sc->sc_if.if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
goto reenqueue;
 
+#if NVLAN > 0
+   /*
+* If the underlying interface removed the VLAN header itself,
+* add it back.
+*/
+   if (ISSET(m->m_flags, M_VLANTAG)) {
+   m = vlan_inject(m, ETHERTYPE_VLAN, m->m_pkthdr.ether_vtag);
+   if (m == NULL)
+   return;
+   }
+#endif
+
 #if NBPFILTER > 0
if (sc->sc_if.if_bpf)
bpf_mtap_ether(sc->sc_if.if_bpf, m, BPF_DIRECTION_IN);
Index: netinet/ip_carp.c
===
RCS file: /cvs/src/sys/netinet/ip_carp.c,v
retrieving revision 1.289
diff -u -p -r1.289 ip_carp.c
--- netinet/ip_carp.c   18 May 2016 03:46:03 -  1.289
+++ netinet/ip_carp.c   23 May 2016 13:14:48 -
@@ -80,6 +80,10 @@
 #include 
 #endif
 
+#if NVLAN > 0
+#include 
+#endif
+
 #include 
 
 struct carp_mc_entry {
@@ -1398,6 +1402,15 @@ carp_input(struct ifnet *ifp0, struct mb
struct carp_if *cif;
struct carp_softc *sc;
struct srp_ref sr;
+
+#if NVLAN > 0
+   /*
+* If the underlying interface removed the VLAN header itself,
+* it's not for us.
+*/
+   if (ISSET(m->m_flags, M_VLANTAG))
+   return (0);
+#endif
 
eh = mtod(m, struct ether_header *);
cif = (struct carp_if *)cookie;



nd6_output() and NULL routes

2016-05-23 Thread Martin Pieuchot
This is the companion diff to the ether_output() one.  Since bluhm@
mentioned it, here it is!

The idea is, once again, to stop inserting cloned route entries in L2
functions.  The only place that insert cloned route entries should be
inside rtalloc(9) when RT_RESOLVE is passed.

Index: net/pf.c
===
RCS file: /cvs/src/sys/net/pf.c,v
retrieving revision 1.971
diff -u -p -r1.971 pf.c
--- net/pf.c23 May 2016 12:26:28 -  1.971
+++ net/pf.c23 May 2016 12:39:54 -
@@ -5506,6 +5506,7 @@ pf_route(struct mbuf **m, struct pf_rule
int  error = 0;
unsigned int rtableid;
 
+
if (m == NULL || *m == NULL || r == NULL ||
(dir != PF_IN && dir != PF_OUT) || oifp == NULL)
panic("pf_route: invalid parameters");
@@ -5665,11 +5666,13 @@ pf_route6(struct mbuf **m, struct pf_rul
 {
struct mbuf *m0;
struct sockaddr_in6 *dst, sin6;
+   struct rtentry  *rt = NULL;
struct ip6_hdr  *ip6;
struct ifnet*ifp = NULL;
struct pf_addr   naddr;
struct pf_src_node  *sns[PF_SN_MAX];
struct m_tag*mtag;
+   unsigned int rtableid;
 
if (m == NULL || *m == NULL || r == NULL ||
(dir != PF_IN && dir != PF_OUT) || oifp == NULL)
@@ -5702,6 +5705,7 @@ pf_route6(struct mbuf **m, struct pf_rul
dst->sin6_family = AF_INET6;
dst->sin6_len = sizeof(*dst);
dst->sin6_addr = ip6->ip6_dst;
+   rtableid = m0->m_pkthdr.ph_rtableid;
 
if (!r->rt) {
m0->m_pkthdr.pf.flags |= PF_TAG_GENERATED;
@@ -5754,7 +5758,13 @@ pf_route6(struct mbuf **m, struct pf_rul
if ((mtag = m_tag_find(m0, PACKET_TAG_PF_REASSEMBLED, NULL))) {
(void) pf_refragment6(&m0, mtag, dst, ifp);
} else if ((u_long)m0->m_pkthdr.len <= ifp->if_mtu) {
-   nd6_output(ifp, m0, dst, NULL);
+   rt = rtalloc(sin6tosa(dst), RT_RESOLVE, rtableid);
+   if (rt == NULL) {
+   ip6stat.ip6s_noroute++;
+   goto bad;
+   }
+   nd6_output(ifp, m0, dst, rt);
+   rtfree(rt);
} else {
icmp6_error(m0, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu);
}
Index: net/pf_norm.c
===
RCS file: /cvs/src/sys/net/pf_norm.c,v
retrieving revision 1.183
diff -u -p -r1.183 pf_norm.c
--- net/pf_norm.c   24 Nov 2015 13:37:16 -  1.183
+++ net/pf_norm.c   23 May 2016 12:39:55 -
@@ -750,7 +750,15 @@ pf_refragment6(struct mbuf **m0, struct 
if (ifp == NULL) {
ip6_forward(m, 0);
} else if ((u_long)m->m_pkthdr.len <= ifp->if_mtu) {
-   nd6_output(ifp, m, dst, NULL);
+   struct rtentry *rt;
+   rt = rtalloc(sin6tosa(dst), RT_RESOLVE,
+   m->m_pkthdr.ph_rtableid);
+   if (rt == NULL) {
+   ip6stat.ip6s_noroute++;
+   } else {
+   nd6_output(ifp, m, dst, rt);
+   rtfree(rt);
+   }
} else {
icmp6_error(m, ICMP6_PACKET_TOO_BIG, 0,
ifp->if_mtu);
Index: netinet6/nd6.c
===
RCS file: /cvs/src/sys/netinet6/nd6.c,v
retrieving revision 1.179
diff -u -p -r1.179 nd6.c
--- netinet6/nd6.c  17 May 2016 08:29:14 -  1.179
+++ netinet6/nd6.c  23 May 2016 12:39:55 -
@@ -1507,20 +1507,15 @@ nd6_output(struct ifnet *ifp, struct mbu
struct mbuf *m = m0;
struct rtentry *rt = rt0;
struct llinfo_nd6 *ln = NULL;
-   int created = 0, error = 0;
+   int error = 0;
 
if (IN6_IS_ADDR_MULTICAST(&dst->sin6_addr))
goto sendpkt;
 
-   /*
-* next hop determination.
-*/
-   if (rt0 != NULL) {
-   error = rt_checkgate(rt0, &rt);
-   if (error) {
-   m_freem(m);
-   return (error);
-   }
+   error = rt_checkgate(rt0, &rt);
+   if (error) {
+   m_freem(m);
+   return (error);
}
 
if (nd6_need_cache(ifp) == 0)
@@ -1532,42 +1527,17 @@ nd6_output(struct ifnet *ifp, struct mbu
 * At this point, the destination of the packet must be a unicast
 * or an anycast address(i.e. not a multicast).
 */
-
-   /* Look up the neighbor cache for the nexthop */
-   if (rt != NULL && (rt->rt_flags & RT

Unused USB ioctl(2)s

2016-05-23 Thread Martin Pieuchot
No point in keeping these.  ok?

Index: sys/dev/usb/ugen.c
===
RCS file: /cvs/src/sys/dev/usb/ugen.c,v
retrieving revision 1.93
diff -u -p -r1.93 ugen.c
--- sys/dev/usb/ugen.c  17 Mar 2016 21:36:48 -  1.93
+++ sys/dev/usb/ugen.c  23 May 2016 11:41:32 -
@@ -953,7 +953,6 @@ ugen_do_ioctl(struct ugen_softc *sc, int
struct usb_endpoint_desc *ed;
usb_endpoint_descriptor_t *edesc;
struct usb_alt_interface *ai;
-   struct usb_string_desc *si;
u_int8_t conf, alt;
 
DPRINTFN(5, ("ugenioctl: cmd=%08lx\n", cmd));
@@ -1130,16 +1129,6 @@ ugen_do_ioctl(struct ugen_softc *sc, int
error = uiomove((void *)cdesc, len, &uio);
free(cdesc, M_TEMP, 0);
return (error);
-   }
-   case USB_GET_STRING_DESC:
-   {
-   int len;
-   si = (struct usb_string_desc *)addr;
-   err = usbd_get_string_desc(sc->sc_udev, si->usd_string_index,
-   si->usd_language_id, &si->usd_desc, &len);
-   if (err)
-   return (EINVAL);
-   break;
}
case USB_DO_REQUEST:
{
Index: sys/dev/usb/uhid.c
===
RCS file: /cvs/src/sys/dev/usb/uhid.c,v
retrieving revision 1.65
diff -u -p -r1.65 uhid.c
--- sys/dev/usb/uhid.c  3 Mar 2016 18:13:24 -   1.65
+++ sys/dev/usb/uhid.c  23 May 2016 11:41:20 -
@@ -357,8 +357,7 @@ int
 uhid_do_ioctl(struct uhid_softc *sc, u_long cmd, caddr_t addr,
  int flag, struct proc *p)
 {
-   usbd_status err;
-   int rc, size;
+   int rc;
 
DPRINTFN(2, ("uhidioctl: cmd=%lx\n", cmd));
 
@@ -392,17 +391,6 @@ uhid_do_ioctl(struct uhid_softc *sc, u_l
usbd_fill_deviceinfo(sc->sc_hdev.sc_udev,
 (struct usb_device_info *)addr, 1);
break;
-
-case USB_GET_STRING_DESC:
-   {
-   struct usb_string_desc *si = (struct usb_string_desc *)addr;
-   err = usbd_get_string_desc(sc->sc_hdev.sc_udev,
-   si->usd_string_index,
-   si->usd_language_id, &si->usd_desc, &size);
-   if (err)
-   return (EINVAL);
-   break;
-   }
 
case USB_GET_REPORT_DESC:
case USB_GET_REPORT:
Index: sys/dev/usb/umodem.c
===
RCS file: /cvs/src/sys/dev/usb/umodem.c,v
retrieving revision 1.59
diff -u -p -r1.59 umodem.c
--- sys/dev/usb/umodem.c14 Mar 2015 03:38:50 -  1.59
+++ sys/dev/usb/umodem.c23 May 2016 11:40:41 -
@@ -47,7 +47,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -121,7 +120,6 @@ voidumodem_rts(struct umodem_softc *, i
 void   umodem_break(struct umodem_softc *, int);
 void   umodem_set_line_state(struct umodem_softc *);
 intumodem_param(void *, int, struct termios *);
-intumodem_ioctl(void *, int, u_long, caddr_t, int, struct proc *);
 intumodem_open(void *, int portno);
 void   umodem_close(void *, int portno);
 void   umodem_intr(struct usbd_xfer *, void *, usbd_status);
@@ -130,7 +128,7 @@ struct ucom_methods umodem_methods = {
umodem_get_status,
umodem_set,
umodem_param,
-   umodem_ioctl,
+   NULL,
umodem_open,
umodem_close,
NULL,
@@ -562,38 +560,6 @@ umodem_param(void *addr, int portno, str
return (1);
}
return (0);
-}
-
-int
-umodem_ioctl(void *addr, int portno, u_long cmd, caddr_t data, int flag,
-struct proc *p)
-{
-   struct umodem_softc *sc = addr;
-   int error = 0;
-
-   if (usbd_is_dying(sc->sc_udev))
-   return (EIO);
-
-   DPRINTF(("umodem_ioctl: cmd=0x%08lx\n", cmd));
-
-   switch (cmd) {
-   case USB_GET_CM_OVER_DATA:
-   *(int *)data = sc->sc_cm_over_data;
-   break;
-
-   case USB_SET_CM_OVER_DATA:
-   if (*(int *)data != sc->sc_cm_over_data) {
-   /* XXX change it */
-   }
-   break;
-
-   default:
-   DPRINTF(("umodem_ioctl: unknown\n"));
-   error = ENOTTY;
-   break;
-   }
-
-   return (error);
 }
 
 void
Index: sys/dev/usb/uplcom.c
===
RCS file: /cvs/src/sys/dev/usb/uplcom.c,v
retrieving revision 1.66
diff -u -p -r1.66 uplcom.c
--- sys/dev/usb/uplcom.c14 Mar 2015 03:38:50 -  1.66
+++ sys/dev/usb/uplcom.c23 May 2016 11:39:55 -
@@ -119,9 +119,6 @@ void uplcom_rts(struct uplcom_softc *, i
 void uplcom_break(struct uplcom_softc *, int);
 void uplcom_set_line_state(struct uplcom_softc *);
 void uplcom_get_status(void *, int portno, u_char 

Re: Enforce ether_output() requirements

2016-05-23 Thread Martin Pieuchot
On 23/05/16(Mon) 13:52, Alexander Bluhm wrote:
> On Wed, May 18, 2016 at 10:56:34PM +0200, Martin Pieuchot wrote:
> > Diff below convert the last offender explicitly passing NULL to an
> > if_output() function: pf_route().
> 
> There is another one in phyint_send6() at netinet6/ip6_mroute.c:
> /*
>  * We just call if_output instead of nd6_output here, since
>  * we need no ND for a multicast forwarded packet...right?
>  */
> error = ifp->if_output(ifp, mb_copy, sin6tosa(&ro.ro_dst),
> NULL);

This is ok because the packet has M_MCAST set.

> I wonder wether pf_route6() should pass the route to nd6_output()
> for consistency.  But pf_refragment6() also uses NULL, and I guess
> IPv6 has much more issues.

This is my next diff.

> > I'm interested in tests but keep in mind that it is highly probable
> > that some code paths still path a NULL pointer as last argument, if
> > rtalloc(9) fails and its return is not checked.  That's why I added
> > a KASSERT(), to fix these cases.
> 
> I have tested your route-to code with /usr/src/regress/sys/net/pf_forward.
> Some tests fail, it seems that we have issues with path mtu discovery
> in current.  But it is not related to this change.  So OK bluhm@
> for the pf_route() part.

Thanks.

> 
> > 
> > Index: net/if_ethersubr.c
> > ===
> > RCS file: /cvs/src/sys/net/if_ethersubr.c,v
> > retrieving revision 1.236
> > diff -u -p -r1.236 if_ethersubr.c
> > --- net/if_ethersubr.c  18 May 2016 20:15:14 -  1.236
> > +++ net/if_ethersubr.c  18 May 2016 20:45:47 -
> > @@ -193,8 +193,12 @@ ether_output(struct ifnet *ifp, struct m
> > struct mbuf *mcopy = NULL;
> > struct ether_header *eh;
> > struct arpcom *ac = (struct arpcom *)ifp;
> > +   sa_family_t af = dst->sa_family;
> > int error = 0;
> >  
> > +   KASSERT(rt != NULL || ISSET(m->m_flags, M_MCAST|M_BCAST) ||
> > +   af == AF_UNSPEC || af == pseudo_AF_HDRCMPLT);
> > +
> >  #ifdef DIAGNOSTIC
> > if (ifp->if_rdomain != rtable_l2(m->m_pkthdr.ph_rtableid)) {
> > printf("%s: trying to send packet on wrong domain. "
> > @@ -208,7 +212,7 @@ ether_output(struct ifnet *ifp, struct m
> > if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
> > senderr(ENETDOWN);
> >  
> > -   switch (dst->sa_family) {
> > +   switch (af) {
> > case AF_INET:
> > error = arpresolve(ifp, rt, m, dst, edst);
> > if (error)
> > Index: net/pf.c
> > ===
> > RCS file: /cvs/src/sys/net/pf.c,v
> > retrieving revision 1.970
> > diff -u -p -r1.970 pf.c
> > --- net/pf.c3 May 2016 12:13:38 -   1.970
> > +++ net/pf.c18 May 2016 20:45:49 -
> > @@ -5574,6 +5574,12 @@ pf_route(struct mbuf **m, struct pf_rule
> > s->rt_addr.v4.s_addr;
> > ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL;
> > }
> > +
> > +   rt = rtalloc(sintosa(dst), RT_RESOLVE, rtableid);
> > +   if (rt == NULL) {
> > +   ipstat.ips_noroute++;
> > +   goto bad;
> > +   }
> > }
> > if (ifp == NULL)
> > goto bad;
> > @@ -5602,7 +5608,7 @@ pf_route(struct mbuf **m, struct pf_rule
> > ipstat.ips_outswcsum++;
> > ip->ip_sum = in_cksum(m0, ip->ip_hl << 2);
> > }
> > -   error = ifp->if_output(ifp, m0, sintosa(dst), NULL);
> > +   error = ifp->if_output(ifp, m0, sintosa(dst), rt);
> > goto done;
> > }
> >  
> > @@ -5631,7 +5637,7 @@ pf_route(struct mbuf **m, struct pf_rule
> > m1 = m0->m_nextpkt;
> > m0->m_nextpkt = 0;
> > if (error == 0)
> > -   error = ifp->if_output(ifp, m0, sintosa(dst), NULL);
> > +   error = ifp->if_output(ifp, m0, sintosa(dst), rt);
> > else
> > m_freem(m0);
> > }
> > Index: netinet/if_ether.c
> > ===
> > RCS file: /cvs/src/sys/netinet/if_ether.c,v
> > retrieving revision 1.207
> > diff -u -p -r1.207 if_ether.c
> > --- netinet/if_ether.c  18 May 2016 20:15:14 -  1.207
> > +++ netinet/if_ether.c  18 May 2016 20:45:50 -
> > @@ -294,40 +294,28 @@ arpresolve(struct ifnet *ifp, struct rte
> > return (0);
> > }
> >  
> > -   if (rt0 != NULL) {
> > -   error = rt_checkgate(rt0, &rt);
> > -   if (error) {
> > -   m_freem(m);
> > -   return (error);
> > -   }
> > +   error = rt_checkgate(rt0, &rt);
> > +   if (error) {
> > +   m_freem(m);
> > +   return (error);
> > +   }
> >  
> > -   if ((rt->rt_flags & RTF_LLINFO) == 0) {
> > -   

Re: Enforce ether_output() requirements

2016-05-23 Thread Alexander Bluhm
On Wed, May 18, 2016 at 10:56:34PM +0200, Martin Pieuchot wrote:
> Diff below convert the last offender explicitly passing NULL to an
> if_output() function: pf_route().

There is another one in phyint_send6() at netinet6/ip6_mroute.c:
/*
 * We just call if_output instead of nd6_output here, since
 * we need no ND for a multicast forwarded packet...right?
 */
error = ifp->if_output(ifp, mb_copy, sin6tosa(&ro.ro_dst),
NULL);

I wonder wether pf_route6() should pass the route to nd6_output()
for consistency.  But pf_refragment6() also uses NULL, and I guess
IPv6 has much more issues.

> I'm interested in tests but keep in mind that it is highly probable
> that some code paths still path a NULL pointer as last argument, if
> rtalloc(9) fails and its return is not checked.  That's why I added
> a KASSERT(), to fix these cases.

I have tested your route-to code with /usr/src/regress/sys/net/pf_forward.
Some tests fail, it seems that we have issues with path mtu discovery
in current.  But it is not related to this change.  So OK bluhm@
for the pf_route() part.

> 
> Index: net/if_ethersubr.c
> ===
> RCS file: /cvs/src/sys/net/if_ethersubr.c,v
> retrieving revision 1.236
> diff -u -p -r1.236 if_ethersubr.c
> --- net/if_ethersubr.c18 May 2016 20:15:14 -  1.236
> +++ net/if_ethersubr.c18 May 2016 20:45:47 -
> @@ -193,8 +193,12 @@ ether_output(struct ifnet *ifp, struct m
>   struct mbuf *mcopy = NULL;
>   struct ether_header *eh;
>   struct arpcom *ac = (struct arpcom *)ifp;
> + sa_family_t af = dst->sa_family;
>   int error = 0;
>  
> + KASSERT(rt != NULL || ISSET(m->m_flags, M_MCAST|M_BCAST) ||
> + af == AF_UNSPEC || af == pseudo_AF_HDRCMPLT);
> +
>  #ifdef DIAGNOSTIC
>   if (ifp->if_rdomain != rtable_l2(m->m_pkthdr.ph_rtableid)) {
>   printf("%s: trying to send packet on wrong domain. "
> @@ -208,7 +212,7 @@ ether_output(struct ifnet *ifp, struct m
>   if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
>   senderr(ENETDOWN);
>  
> - switch (dst->sa_family) {
> + switch (af) {
>   case AF_INET:
>   error = arpresolve(ifp, rt, m, dst, edst);
>   if (error)
> Index: net/pf.c
> ===
> RCS file: /cvs/src/sys/net/pf.c,v
> retrieving revision 1.970
> diff -u -p -r1.970 pf.c
> --- net/pf.c  3 May 2016 12:13:38 -   1.970
> +++ net/pf.c  18 May 2016 20:45:49 -
> @@ -5574,6 +5574,12 @@ pf_route(struct mbuf **m, struct pf_rule
>   s->rt_addr.v4.s_addr;
>   ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL;
>   }
> +
> + rt = rtalloc(sintosa(dst), RT_RESOLVE, rtableid);
> + if (rt == NULL) {
> + ipstat.ips_noroute++;
> + goto bad;
> + }
>   }
>   if (ifp == NULL)
>   goto bad;
> @@ -5602,7 +5608,7 @@ pf_route(struct mbuf **m, struct pf_rule
>   ipstat.ips_outswcsum++;
>   ip->ip_sum = in_cksum(m0, ip->ip_hl << 2);
>   }
> - error = ifp->if_output(ifp, m0, sintosa(dst), NULL);
> + error = ifp->if_output(ifp, m0, sintosa(dst), rt);
>   goto done;
>   }
>  
> @@ -5631,7 +5637,7 @@ pf_route(struct mbuf **m, struct pf_rule
>   m1 = m0->m_nextpkt;
>   m0->m_nextpkt = 0;
>   if (error == 0)
> - error = ifp->if_output(ifp, m0, sintosa(dst), NULL);
> + error = ifp->if_output(ifp, m0, sintosa(dst), rt);
>   else
>   m_freem(m0);
>   }
> Index: netinet/if_ether.c
> ===
> RCS file: /cvs/src/sys/netinet/if_ether.c,v
> retrieving revision 1.207
> diff -u -p -r1.207 if_ether.c
> --- netinet/if_ether.c18 May 2016 20:15:14 -  1.207
> +++ netinet/if_ether.c18 May 2016 20:45:50 -
> @@ -294,40 +294,28 @@ arpresolve(struct ifnet *ifp, struct rte
>   return (0);
>   }
>  
> - if (rt0 != NULL) {
> - error = rt_checkgate(rt0, &rt);
> - if (error) {
> - m_freem(m);
> - return (error);
> - }
> + error = rt_checkgate(rt0, &rt);
> + if (error) {
> + m_freem(m);
> + return (error);
> + }
>  
> - if ((rt->rt_flags & RTF_LLINFO) == 0) {
> - log(LOG_DEBUG, "%s: %s: route contains no arp"
> - " information\n", __func__, inet_ntop(AF_INET,
> - &satosin(rt_key(rt))->sin_addr, addr,
> - sizeof(addr)