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 hard. 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 performed. > 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 description. 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. --chris