tech-kern archive

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

Re: Lua in-kernel (lbuf library)

First, I find the usage of the "buf" terminology confusing.  In kernel
context I associate "buf" with the file system buffe cache "buf" structure.
Packet buffers a called "mbufs".  I would appreciate it if the terminology
was consistent with the kernel or at least not confusing.

Also, having to switch mentally between zero-based arrays in the kernel C
code and 1-based arrays in the Lua code make my head ache.

On Thu, Oct 10, 2013 at 03:15:54PM -0300, Lourival Vieira Neto wrote:
> C API:
> lbuf_new(lua_State L, void * buffer, size_t length, lua_Alloc free, bool net);
> * creates a new lbuf userdatum and pushes it on the Lua stack. The net
> flag indicates if it is necessary to perform endianness conversion.

I what is "buffer" and how does it relate to mbufs?  How do I create a new
"lbuf" from an mbuf? Or from an array of bytes?

In order to indicate that endianness conversion is necessary I need to
know the future uses of the buffer.  Clairvoyance excepted, that is kinda

If you are going to make the buffers endianness aware, why not record the
endianness that the packet is encoded in.  And byteswapping can be
performed automatically depending on the consumers endianness.  I think
this way a lot of redundant code can be avoided.

And you don't describe under what circumstances endianness convresion is

> Lua API:
> - array access (1)
> lbuf:mask(alignment [, offset, length])
> buf[ix] ~> accesses 'alignment' bits from 'alignment*(ix -1)+offset' position
> e.g.:
> buf:mask(3)
> buf[3] ~> accesses 3 bits from bit-6 position

What does that mean? Does it return the top-most 2 bits from the first
byte plus the least significant bit fom the second byte of the buffer?
What is 'length' for?
How does endianness conversion fit in?

> - array access (2)
> buf:mask{ length_pos1, length_pos2, ... }
> buf[ix] ~> accesses 'length_pos(ix)' bits from 'length_pos1 + ...
> length_pos(ix-1)' position
> e.g.:
> buf:mask{ 2, 2, 32, 9 }
> buf[2] ~> accesses 2 bits from bit-2 position

What exactly would "buf[3]" return.  Please be explicit in whether you are
counting byte offsets or bit offsets.  I can't figure that out from your

Personally, the idea of making array access to the buffer depend on
state stored in the buffer does not look appealing to me.  It prevents
buffers to be passed around because consumers don't know what they will
get back on array access.

> buf:mask{ field = { offset, length }, ... }
> buf.field ~> 'field.length' bits from 'offset' position

This actually makes some sense to me.

> buf:segment(offset [, length])
> returns a new lbuf corresponding a 'buf' segment.

What is a a 'segment' actually?

> - mask reusing
> lbuf.mask{ ... }

This makes sense again...

> function filter(packet)
>   packet:mask(ethernet_mask)
>   if packet.type == 0x88CC then
>     lldp_pdu = packet.segment(payload_offset):mask(lldp_mask)
>     if packet.version < 1 return DROP end
>   end
>   return PASS
> end

... except the code seems to be not runnable. Where does 'payload_offset'
come from? And don't you mean lldp_pdu.version?

I find it not helpful when the examples do not actually work.


Home | Main Index | Thread Index | Old Index