Skip to content
  • Neil Horman's avatar
    af_packet: add interframe drop cmsg (v6) · 97775007
    Neil Horman authored
    
    
    Add Ancilliary data to better represent loss information
    
    I've had a few requests recently to provide more detail regarding frame loss
    during an AF_PACKET packet capture session.  Specifically the requestors want to
    see where in a packet sequence frames were lost, i.e. they want to see that 40
    frames were lost between frames 302 and 303 in a packet capture file.  In order
    to do this we need:
    
    1) The kernel to export this data to user space
    2) The applications to make use of it
    
    This patch addresses item (1).  It does this by doing the following:
    
    A) Anytime we drop a frame for which we would increment po->stats.tp_drops, we
    also no increment a stats called po->stats.tp_gap.
    
    B) Every time we successfully enqueue a frame to sk_receive_queue, we record the
    value of po->stats.tp_gap in skb->mark.  skb->cb would nominally be the place to
    record this, but since all the space there is used up, we're overloading
    skb->mark.  Its safe to do since any enqueued packet is guaranteed to be
    unshared at this point, and skb->mark isn't used for anything else in the rx
    path to the application.  After we record tp_gap in the skb, we zero
    po->stats.tp_gap.  This allows us to keep a counter of the number of frames lost
    between any two enqueued packets
    
    C) When the application goes to dequeue a frame from the packet socket, we look
    at skb->mark for that frame.  If it is non-zero, we add a cmsg chunk to the
    msghdr of level SOL_PACKET and type PACKET_GAPDATA.  Its a 32 bit integer that
    represents the number of frames lost between this packet and the last previous
    frame received.
    
    Note there is a chance that if there is frame loss after a receive, and then the
    socket is closed, some gap data might be lost.  This is covered by the use of
    the PACKET_AUXDATA socket option, which gives total loss data.  With a bit of
    math, the final gap can be determined that way.
    
    I've tested this patch myself, and it works well.
    
    Signed-off-by: default avatarNeil Horman <nhorman@tuxdriver.com>
    Signed-off-by: default avatarEric Dumazet <eric.dumazet@gmail.com>
    
     include/linux/if_packet.h |    2 ++
     net/packet/af_packet.c    |   33 +++++++++++++++++++++++++++++++++
     2 files changed, 35 insertions(+)
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    97775007