Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Packet tracing #139

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open

Packet tracing #139

wants to merge 5 commits into from

Conversation

trackpick
Copy link

Hi Eddie,

We've been using this at Meraki since about February and it's proved very useful. Thought you might like to merge it.

 Thanks,
 Patrick

Patrick Verkaik added 5 commits November 8, 2014 18:34
Allow packets to be marked for tracing. With each push or pull of a
packet marked for tracing, Click chatters a line indicating the source
and destination elements and ports.  Also, Click chatters a line when a
traced packet is killed.  The output looks like this (from a testie):

  traced_packet: trace_push [0] -> [0] RoundRobinSwitch@3
  traced_packet: RoundRobinSwitch@3 [0] -> [0] isw
  traced_packet: isw [0] -> [0] Discard@5
  traced_packet: killed

Arbitrary elements can mark packets for tracing. However, the typical
way to mark packets is through the Trace element added in the next
commit.

I opted for a really simple implementation: a static Packet member that
stores a pointer to the traced packet. (Note that non-static Packet
members are not allowed in the Linux case.) This pointer is never
dereferenced - it just lets pushes and pulls identify a traced packet.
The implementation is not entirely thread safe: in particular, on
platforms where pointer assignment is not atomic, the pointer may end up
containing garbage. However, since the pointer is only used for
comparison and this is just a debugging feature, this should be OK.  The
static packet pointer is cleared whenever a traced packet is killed or
leaves Click. I believe linuxmodule's ToDevice and ToHost are the only
places a packet leaves Click without being killed.

With this implementation, only one packet can be traced at a time. In
particular, this means that normally you can't start tracing a packet if
another packet is still being traced. This behaviour can be changed
using the 'preempt' argument to set_traced().

Asa Zernik added code for printing the output port for push() and the
input port for pull(). Jignesh Patel added code for preempting tracing.

Reviewed-by: [email protected]
Signed-off-by: Patrick Verkaik <[email protected]>
To debug where certain packets end up going, you can insert a Trace
element somewhere on a click path (e.g., as it is received from a
device). You would typically precede Trace with an (IP)Classifier to
pick out the packets you're actually interested in.

Trace has a LIMIT parameter (default 1) that limits the number of
packets marked in order to avoid overwhelming Linux with too many
chatters.  It also has a convenience 'poke' handler that sets the state
such that the next packet going through Trace will get marked (taking
care of setting _limit, resetting _count, and clearing a possibly bogus
traced packet pointer).

An optional second output port helps with printing which packets were
actually marked for tracing. A clone of each marked packet is emitted on
this port.

Preemption can be configured on per Trace element basis using the
PREEMPT config parameter or 'preempt' handler, or it can be set globally
for all Trace elements using the 'global_preempt' handler. If
global_preempt is set then some Trace elements can be set to not preempt
using the IGNOREGLOBALPREEMPT config parameter or ignoreglobalpreempt
handler.

Jignesh Patel added code for preempting tracing.

Reviewed-by: [email protected]
Signed-off-by: Patrick Verkaik <[email protected]>
…igure option"

This should be regenerated. I have an older version of autoconf.

Signed-off-by: Patrick Verkaik <[email protected]>
In Linux click, Packet::kill() is called on a packet just once -- when
the user of the packet discards the packet -- at which time the packet
is recycled. Sharing data among packets to implement clone() is handled
outside of Packet, and killing clones of a packet does not affect the
cloned packet.

In userlevel (and other non-Linux) click, packets share data by having a
clone keep a reference to the cloned packet. When the clone is killed,
Packet internally calls kill() on the referenced packet to decrement a
reference count and (if the reference count drops to 0) recycle the
packet.  This means that a packet's kill() may be called several times:
once when the packet's user discards the packet and once each time a
clone is killed.

Unfortunately, the userlevel click behaviour breaks any code in kill()
that needs to run only when a packet is discarded by its user, in
particular packet tracing code.  For packet tracing, a packet may get
untraced prematurely if a clone of the packet is killed before the
packet itself.  This change fixes the issue by factoring out
dec_use_count() and having Packet use that instead of kill() to drop a
reference to a packet.

Reviewed-by: [email protected]
Signed-off-by: Patrick Verkaik <[email protected]>
@bcronje
Copy link
Contributor

bcronje commented Aug 20, 2015

@trackpick This would be a really helpful addition to Click for us. @kohler any chance you might relook this PR?

@trackpick
Copy link
Author

@kohler did you ever get to take a look at this? I recently another variant that relies on stack traces instead (messier output but less overhead). If you're interested I can update this pull request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants