On Dec 29, 2013, at 7:50 AM, Stuart Kendrick <stuart.kendrick.sea@xxxxxxxxx> wrote:
> OK, I think I'm following what you're telling me:
>
> From http://lxr.linux.no/#linux+v3.8/net/core/dev.c
> [...]
> 2361 if (!list_empty(&ptype_all
> ))
>
> 2362 dev_queue_xmit_nit(skb, dev
> );
>
> 2363
> 2364 skb_len = skb->len
> ;
>
> 2365 rc = ops->ndo_start_xmit(skb, dev
> );
>
> 2366 trace_net_dev_xmit(skb, rc, dev, skb_len
> );
>
> 2367 if (rc == NETDEV_TX_OK
> )
>
> 2368 txq_trans_update(txq
> );
>
> 2369 return rc
> ;
>
> 2370
> }
>
> 2371
> 2372gso
> :
>
> 2373 do {
> [...]
>
> So libpcap gets called somewhere inside dev_queue_xmit_nit(),
Or, rather, inside dev_queue_xmit_nit(), the packet is delivered to various sockets, and the sockets libpcap sets up are among them.
> and since I see the TCP SYNs in the on-board pcap, I conclude that my precious TCP SYNs reach line #2362
> Line #2364 is just an assignment ... in Line #2365, we call ndo_start_xmit() with the same arguments we sent to dev_queue_xmit_nit() ... I infer from your comment that ndo_start_xmit() gets implemented inside device drivers
More precisely, ndo_start_xmit is a member of a structure, and contains a pointer to a function and, in the case of your network adapter:
> 849 .ndo_start_xmit = e1000_xmit_frame,
it points to e1000_xmit_frame().
> For example:
> if (test_bit(__E1000_DOWN, &adapter->state)) {
> dev_kfree_skb_any(skb);
> return NETDEV_TX_OK;
> }
>
> ## Does this mean that if link is down, return "Yay! Transmitted successfully" ? --sk
Well, let's look at the NETDEV_TX_ return values:
enum netdev_tx {
__NETDEV_TX_MIN = INT_MIN, /* make sure enum is signed */
NETDEV_TX_OK = 0x00, /* driver took care of packet */
NETDEV_TX_BUSY = 0x10, /* driver tx path was busy*/
NETDEV_TX_LOCKED = 0x20, /* driver tx lock was already taken */
};
So if the link is down, it returns "the transmit path wasn't busy and nobody'd taken the lock, so I was able to take care of the packet, even if that just meant dropping it on the floor".
Ethernet doesn't guarantee packet delivery, so, if the caller cares whether the packet arrives, it needs to implement a protocol that provides acknowledgements, as, for example, TCP does, and retransmit the packet if it doesn't receive an acknowledgement in a reasonable amount of time.
> ## Does this mean that if I've been asked to transmit a zero length frame, that I return "Yay! Transmitted successfully!" ? --sk
See above.
> (1) Am I on the right track here, poking through e1000_xmit_frame() inside netdev.c, in my search for where my precious TCP SYNs get dropped?
If that's the device on which connection requests to the server should go, it's probably as good a place as any to start tracking.
> (2) Is there a generic way to ask the kernel to leave tracks in syslog as it transmits frames, to give me clues as to where e1000e is dropping my TCP SYNs?
You might look at SystemTap:
http://sourceware.org/systemtap/
to see whether you can ask it to report calls to and returns from particular kernel functions, for example.