tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: tap(4) interface management



On Wed, May 13, 2009 at 03:03:37PM +0100, Iain Hibbert wrote:
> Hi,
>    regarding btpand(8) which uses a tap(4) device to provide Ethernet over
> Bluetooth services, I have been looking at adding some features relating
> to the daemon actively monitoring the interface for various settings
> rather than having them fixed at startup or requiring a config file. Such
> as:
> 
> 1. btpand currently exits in client mode if the connection is lost, but I
>    also wanted it to exit if the interface is marked down locally.
> 
> 2. btpand running as a server registers a service record with the service
>    discovery daemon, including protocols available and subnet masks for
>    IPv4 and IPv6. I want to provide the actual values in use.
> 
> 3. the BNEP protocol has filtering options (mandatory to support) to cut
>    out unwanted ethernet packet types on a limited bandwidth connection.
>    btpand could monitor the address families configured on the tap interface
>    and enable/disable protocols as required.
> 
>   Some of this can be handled as-is with a routing socket (as per attached
> patch) but not quite all as it only notifies changes to the IFF_UP flag
> and interface addresses and I would additionally like to notice changes to
> other flags (IFF_NOARP at least, possibly IFF_LINKn etc later) and the
> interface media settings (which can map to elements in the service
> record).
> 
>   So, I'm thinking of how to get where I'm wanting to be, the options seem
> to be either extending the routing socket to provide additional messages,
> or extending the tap driver to be able to signal changes to its owner.
> 
>   Extending the routing socket is possible although its a global
> interface. A RTM_IFINFO message is currently sent out when interface
> status is changed, but it does contain the entire if_flags field and is
> not only for IFF_UP changes (so, extra messages are not problematic). Its
> fairly simple to emit messages for SIOCSIFFLAGS (as per second attached
> patch) but I haven't found any way to get the media settings this way, it
> would require adding a RTM_MEDIA message type which I haven't looked into.

> +/* rtmsg sockaddr alignment from src/sys/net/rtsock.c */
> +#define ROUNDUP(a) \
> +     ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))

FWIW, <net/route.h> defines this as RT_ROUNDUP().

> Common subdirectories: /usr/src/sys/net/agr/CVS and agr/CVS
> --- /usr/src/sys/net/if.c     2009-02-24 10:05:47.000000000 +0000
> +++ if.c      2009-04-06 17:12:15.000000000 +0100
> @@ -1481,8 +1481,12 @@ ifioctl_common(struct ifnet *ifp, u_long
>                       if_up(ifp);
>                       splx(s);
>               }
> -             ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) |
> -                     (ifr->ifr_flags &~ IFF_CANTCHANGE);
> +             if (((ifr->ifr_flags ^ ifp->if_flags) & ~IFF_CANTCHANGE)) {
> +                     ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE)
> +                         | (ifr->ifr_flags & ~IFF_CANTCHANGE);
> +
> +                     rt_ifmsg(ifp);
> +             }
>               break;
>       case SIOCGIFFLAGS:
>               ifr = data;

if_up() and if_down() call rt_ifmsg(), too, so that if IFF_UP changes,
you will get two routing messages instead of one.  Not a big deal, but
probably not what you intended.  This may do DTRT:

        case SIOCSIFFLAGS:
                ifr = data;
                if (ifp->if_flags & IFF_UP && (ifr->ifr_flags & IFF_UP) == 0) {
                        s = splnet();
                        if_down(ifp);
                        splx(s);
                } else if (ifr->ifr_flags & IFF_UP &&
                           (ifp->if_flags & IFF_UP) == 0) {
                        s = splnet();
                        if_up(ifp);
                        splx(s);
                } else if (((ifr->ifr_flags ^ ifp->if_flags) & ~IFF_CANTCHANGE))
                        rt_ifmsg(ifp);
                ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) |
                        (ifr->ifr_flags &~ IFF_CANTCHANGE);
                break;

Dave

-- 
David Young             OJC Technologies
dyoung%ojctech.com@localhost      Urbana, IL * (217) 278-3933


Home | Main Index | Thread Index | Old Index