tech-net archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: Enable to send packets on if_loop via bpf
On Tue, Nov 22, 2022 at 12:49 AM Greg Troxel <gdt%lexort.com@localhost> wrote:
>
>
> Ryota Ozaki <ozaki.ryota%gmail.com@localhost> writes:
>
> > In the specification DLT_NULL assumes a protocol family in the host
> > byte order followed by a payload. Interfaces of DLT_NULL uses
> > bpf_mtap_af to pass a mbuf prepending a protocol family. All interfaces
> > follow the spec and work well.
> >
> > OTOH, bpf_write to interfaces of DLT_NULL is a bit of a sad situation.
> > A writing data to an interface of DLT_NULL is treated as a raw data
> > (I don't know why); the data is passed to the interface's output routine
> > as is with dst (sa_family=AF_UNSPEC). tun seems to be able
> > to handle such raw data but the others can't handle the data (probably
> > the data will be dropped like if_loop).
>
> Summarizing and commenting to make sure I'm not confused
>
> on receive/read, DLT_NULL prepends AF in host byte order
> on transmit/write, it just sends with AF_UNSPCE
>
> This seems broken as it is asymmetric, and is bad because it throws
> away information that is hard to reliably recreate. On the other hand
> this is for link-layer formats, and it seems that some interfaces have
> an AF that is not really part of what is transmitted, even though
> really it is. For example tun is using an IP proto byte to specify AF
> and really this is part of the link protocol. Except we pretend it
> isn't.
I found the following sentence in bpf.4:
A packet can be sent out on the network by writing to a bpf file
descriptor. The writes are unbuffered, meaning only one packet can be
processed per write. Currently, only writes to Ethernets and SLIP links
are supported.
So bpf_write to interfaces of DLT_NULL may be simply unsupported on
NetBSD...
>
> > Correcting bpf_write to assume a prepending protocol family will
> > save some interfaces like gif and gre but won't save others like stf
> > and wg. Even worse, the change may break existing users of tun
> > that want to treat data as is (though I don't know if users exist).
> >
> > BTW, prepending a protocol family on tun is a different protocol from
> > DLT_NULL of bpf. tun has three protocol modes and doesn't always prepend
> > a protocol family. (And also the network byte order is used on tun
> > as gert says while DLT_NULL assumes the host byte order.)
>
> wow.
>
> > So my fix will:
> > - keep DLT_NULL of if_loop to not break bpf_mtap_af, and
> > - unchange DLT_NULL handling in bpf_write except for if_loop to bother
> > existing users.
> > The patch looks like this:
> >
> > @@ -447,6 +448,14 @@ bpf_movein(struct uio *uio, int linktype,
> > uint64_t mtu, struct mbuf **mp,
> > m0->m_len -= hlen;
> > }
> >
> > + if (linktype == DLT_NULL && ifp->if_type == IFT_LOOP) {
> > + uint32_t af;
> > + memcpy(&af, mtod(m0, void *), sizeof(af));
> > + sockp->sa_family = af;
> > + m0->m_data += sizeof(af);
> > + m0->m_len -= sizeof(af);
> > + }
> > +
> > *mp = m0;
> > return (0);
>
> That seems ok to me.
Thanks.
>
>
> I think the long-term right fix is to define DLT_AF which has an AF word
> in host order on receive and transmit always, and to modify interfaces
> to use it whenever they are AF aware at all. In this case tun would
> fill in the AF word from the IP proto field, and you'd get a
> transformed/regularized AF word when really the "link layer packet" had
> the IP proto field. But that's ok as it's just cleanup and reversible.
I think introducing DLT_AF is a bit of a tough task because DLT_* definitions
are managed by us.
ozaki-r
Home |
Main Index |
Thread Index |
Old Index