On Sat, Feb 27, 2016 at 03:20:49PM +0100, Martin Pieuchot wrote:
> On 26/02/16(Fri) 17:38, Matthieu Herrb wrote:
> > My hosting ISP is using a routing model where every machine has
> > a IP address with a /32 mask and uses a default route specificed at
> > the link level.
> [...]
> > For OpenBSD this setup maps to
> > 
> > hostname.em0:
> > 
> >     inet 92.224.149.DDD/32
> >     ! route add 91.224.148.0/32 -link -iface em0
> > 
> > /etc/mygate:
> > 
> >     91.224.148.0
> > 
> > While this works when configured manually (an ARP request is generated
> > by the route add -link command and both the ARP and route entries show
> > up), it tends to not beeing stable (ie the default route disapears):
> > 
> > 1. on boot while I explicitely see the '! route' command output in
> >   dmesg -s, the default route doesn't work after the boot, the /32
> >   route has disapeared once the machine reaches the login: prompt to
> >   let me connect on console and check it. If I run the command manualy
> >   again, the route becomes active again and is useable.
> >   So it seems that something flushes the ARP table after executing the
> >   route command in /etc/hostname.if
> > 
> > 2. but if I quiese the network for 20mn to let the ARP entry for the
> >   router time out, then again the associated route disapears.
> > 
> > I can work around these problems by putting a permanent ARP entry for
> > the router in rc.local, but I'd like to know if there isn't some kind
> > of bug that needs to be fixed there.
> > 
> > This kind of routing setup seems popular among cloud style VM hosting
> > providers, and with the growing support for running OpenBSD as a
> > guest, I guess this is going to become a more frequent issue.
> 
> The problem here is that you're generating the route entry manually so
> when the ARP timer will expire the entry will be removed.

Yes that matches my analysis.
> 
> Instead of adding a "link" entry I would add a cloning route that will
> generate it.  The first diff below changes route(8) to not add a
> RTF_GATEWAY flag when creating a RTF_CLONING entry.  With it you should
> be able to add a working cloning route with:
> 
> # route add 91.224.148.0 -netmask 255.255.255.255 -cloning 92.224.149.DDD
> 
> Note that the CIDR notation wont work due to another route(8)
> limitation.

Yes with your first patch that works.
> 
> If this approach is acceptable, the second diff makes sure RTF_CLONING
> is never set with RTF_GATEWAY or RTF_HOST.  Claudio do you think this
> could have any drawback?

I've also included it in the kernel on that machine for testing.

> 
> Index: route.c
> ===================================================================
> RCS file: /cvs/src/sbin/route/route.c,v
> retrieving revision 1.182
> diff -u -p -r1.182 route.c
> --- route.c   3 Dec 2015 08:00:49 -0000       1.182
> +++ route.c   27 Feb 2016 14:02:56 -0000
> @@ -629,7 +629,7 @@ newroute(int argc, char **argv)
>       flags |= RTF_UP;
>       if (ishost)
>               flags |= RTF_HOST;
> -     if (iflag == 0)
> +     if (iflag == 0 && !(flags & RTF_CLONING))
>               flags |= RTF_GATEWAY;
>       for (attempts = 1; ; attempts++) {
>               errno = 0;
> 
> 
> 
> 
> Index: net/rtsock.c
> ===================================================================
> RCS file: /cvs/src/sys/net/rtsock.c,v
> retrieving revision 1.186
> diff -u -p -r1.186 rtsock.c
> --- net/rtsock.c      12 Jan 2016 09:27:46 -0000      1.186
> +++ net/rtsock.c      27 Feb 2016 14:09:56 -0000
> @@ -558,6 +558,12 @@ route_output(struct mbuf *m, ...)
>       rtm->rtm_flags &= ~(RTF_DONE|RTF_CLONED);
>       rtm->rtm_fmask &= RTF_FMASK;
>  
> +     if ((rtm->rtm_flags & (RTF_CLONING|RTF_GATEWAY|RTF_HOST)) ==
> +         (RTF_CLONING|RTF_GATEWAY|RTF_HOST)) {
> +             error = EINVAL;
> +             goto fail;
> +     }
> +
>       if (rtm->rtm_priority != 0) {
>               if (rtm->rtm_priority > RTP_MAX ||
>                   rtm->rtm_priority == RTP_LOCAL) {

-- 
Matthieu Herrb

Attachment: signature.asc
Description: PGP signature

Reply via email to