Receiving packets with multiple iov's

I’d like to confirm the following: my driver can receive packets on
multiple segments. My intentions is to assemble this packet using a npkt
with one netbuf and several iov’s before passing it to tx_up(). Is this
supported by the tcp/ip stack? I already prototyped it and it doesn’t
seem to work.

Bernard Leclerc

This should work.

-seanb

Bernard Leclerc <bernard.leclerc@mindready.com> wrote:
: I’d like to confirm the following: my driver can receive packets on
: multiple segments. My intentions is to assemble this packet using a npkt
: with one netbuf and several iov’s before passing it to tx_up(). Is this
: supported by the tcp/ip stack? I already prototyped it and it doesn’t
: seem to work.

: Bernard Leclerc

Sean, sorry to tell you it definitely does NOT work!

I’m running 6.1.0A and, to debug my driver, I start a second instance of
io-net this way:

/sbin/io-net -p tcpip -d ip1394

FYI, the driver sends and receives packets from a firewire (ieee-1394)
interface.

In order to avoid copying the incoming data, I build my npkt this way:

pNpkt= ion->alloc_up_npkt(sizeof(pNbuf) + numSegs sizeof(*pNiov ),
(void *) &pNbuf);
TAILQ_INSERT_HEAD(&pNpkt->buffers, pNbuf, ptrs);
pNpkt->org_data = pPacket; /
The original data is stored in
this DYNBUF. */
pNpkt->next = NULL;
pNpkt->tot_iov = numSegs;
pNpkt->iface = 0;
pNpkt->framelen = length;

/* Setup the network buffer */
pNbuf->niov = numSegs;
pNbuf->net_iov = (net_iov_t *)(pNbuf + 1);
for (segNo = 0, pNiov = pNbuf->net_iov; segNo < pNbuf->niov;
segNo++, pNiov++) {
IFN_DYNBUF_LENGTH segLen;
uint8_t *pData;

/* Get the data pointer and the length in the dynbuf segment */
IFN_GET_PTR_DYNBUF_SEG(pData, pPacket, segNo);
IFN_GET_LEN_DYNBUF_SEG(segLen, pPacket, segNo);

pNiov->iov_base = pData;
pNiov->iov_len = segLen;
pNiov->iov_phys = ion->mphys(pData);
}

And then I call tx_up().

I notice that each time a packet has more than 1 iov, it seem to fail to
get up to the application (in this case, the application is telnet).

Right now, I’m considering doing a copy when the incoming data is
scattered on more than one segment. But this will affect the
performance.

Any suggestions?

Bernard Leclerc



Sean Boudreau <seanb@qnx.com> wrote in message
news:a8i0g1$psj$1@nntp.qnx.com

This should work.

-seanb

Bernard Leclerc <> bernard.leclerc@mindready.com> > wrote:
: I’d like to confirm the following: my driver can receive packets on
: multiple segments. My intentions is to assemble this packet using a
npkt
: with one netbuf and several iov’s before passing it to tx_up(). Is
this
: supported by the tcp/ip stack? I already prototyped it and it
doesn’t
: seem to work.

: Bernard Leclerc

Bernard Leclerc <bernard.leclerc@mindready.com> wrote:
: Sean, sorry to tell you it definitely does NOT work!

: I’m running 6.1.0A and, to debug my driver, I start a second instance of
: io-net this way:

: /sbin/io-net -p tcpip -d ip1394

Is this on X86? Does it work with the tiny stack?

: FYI, the driver sends and receives packets from a firewire (ieee-1394)
: interface.

: In order to avoid copying the incoming data, I build my npkt this way:

: pNpkt= ion->alloc_up_npkt(sizeof(pNbuf) + numSegs sizeof(*pNiov ),
: (void *) &pNbuf);
: TAILQ_INSERT_HEAD(&pNpkt->buffers, pNbuf, ptrs);
: pNpkt->org_data = pPacket; /
The original data is stored in
: this DYNBUF. */
: pNpkt->next = NULL;
: pNpkt->tot_iov = numSegs;
: pNpkt->iface = 0;
: pNpkt->framelen = length;

: /* Setup the network buffer */
: pNbuf->niov = numSegs;
: pNbuf->net_iov = (net_iov_t *)(pNbuf + 1);
: for (segNo = 0, pNiov = pNbuf->net_iov; segNo < pNbuf->niov;
: segNo++, pNiov++) {
: IFN_DYNBUF_LENGTH segLen;
: uint8_t *pData;

: /* Get the data pointer and the length in the dynbuf segment */
: IFN_GET_PTR_DYNBUF_SEG(pData, pPacket, segNo);
: IFN_GET_LEN_DYNBUF_SEG(segLen, pPacket, segNo);

: pNiov->iov_base = pData;
: pNiov->iov_len = segLen;

Does the sum of segLen equal pNpkt->framelen? Is this less then the
mtu you advertised?

: pNiov->iov_phys = ion->mphys(pData);
: }

: And then I call tx_up().

You need to call ion->reg_tx_done() on the npkt prior to calling ion->tx_up().
What’s the return code from ion->tx_up()? The general sequence after the above
should look something like:

ion->reg_tx_done(reg_hdl, npkt, NULL);
if(ion->tx_up(reg_hdl, npkt, …) == 0)
ion->tx_done(reg_hdl, npkt);

Does ‘netstat -in’ show any Ierrs? ‘netstat -pip’, ‘netstat -ptcp’ show
any errors?

-seanb

: I notice that each time a packet has more than 1 iov, it seem to fail to
: get up to the application (in this case, the application is telnet).

: Right now, I’m considering doing a copy when the incoming data is
: scattered on more than one segment. But this will affect the
: performance.

: Any suggestions?

: Bernard Leclerc



: Sean Boudreau <seanb@qnx.com> wrote in message
: news:a8i0g1$psj$1@nntp.qnx.com
:>
:> This should work.
:>
:> -seanb
:>
:> Bernard Leclerc <bernard.leclerc@mindready.com> wrote:
:> : I’d like to confirm the following: my driver can receive packets on
:> : multiple segments. My intentions is to assemble this packet using a
: npkt
:> : with one netbuf and several iov’s before passing it to tx_up(). Is
: this
:> : supported by the tcp/ip stack? I already prototyped it and it
: doesn’t
:> : seem to work.
:>
:> : Bernard Leclerc
:>
:>

Sean Boudreau <seanb@qnx.com> wrote in message
news:a8kein$l26$1@nntp.qnx.com

Is this on X86? Does it work with the tiny stack?

Yes, I’m running on a Pentium II 400 MHz. I haven’t tried with the tiny
stack yet. I’ll give it a try and report later on.

Does the sum of segLen equal pNpkt->framelen? Is this less then the
mtu you advertised?

Yes, the sum of the length of all segments equal the length of the
frame. Also, the frame length is less than or equal to our advertised
mtu.

You need to call ion->reg_tx_done() on the npkt prior to calling
ion->tx_up().
What’s the return code from ion->tx_up()? The general sequence after
the above
should look something like:

ion->reg_tx_done(reg_hdl, npkt, NULL);
if(ion->tx_up(reg_hdl, npkt, …) == 0)
ion->tx_done(reg_hdl, npkt);

As far as I remember, reg_tx_done returns 0 and tx_up returns a positive
value since I haven’t seen my messages printed in case -1 or 0 is
returned.

Does ‘netstat -in’ show any Ierrs? ‘netstat -pip’, ‘netstat -ptcp’
show
any errors?

Again, as I remember, no errors were reported by any of the netstat
output.


I’ll run more tests and monitor closely various output from netstat.
I’ll get back to you later if I found something worth mentioning.

Thanks for your help Sean.

Bernard Leclerc