public inbox for systemtap@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 1/6] SNMP tapset
@ 2009-07-07  3:03 David J. Wilder
  2009-07-20  7:08 ` Wenji Huang
  0 siblings, 1 reply; 3+ messages in thread
From: David J. Wilder @ 2009-07-07  3:03 UTC (permalink / raw)
  To: systemtap

This tapset provides probes used to count TCP SNMP management
events.  The probes mirror many of the SNMP statistics defined
in /usr/include/linux/snmp.h.  Each probe represents a single SNMP
statistic or MIB. Each of the probe's handler is called when system
performs an operation that would alter the associated statistic. Along
with each probe is defined an indexed set of counters used to record
probe hits. The probe handler calls a user supplied callback functions
to determine which counter to alter. The user's callback should returns a
key value that will be used to index the counter. For example a callback
could return a unique value for each socket. This would results in a
separate counter being used for each socket. Here is the prototype of
the callback function the users script must provide:

function tcpmib_filter_key:long (sk:long, op:long)

tcpmib_filter_key() should compute and return a value used to index
the statistical counter.  The probe handler will add the value of op to
the counter. The sk is a pointer to the struct sock being processed at
the time.

Signed-off-by: David Wilder <dwilder@us.ibm.com>

------------------------------------------------------
 tapset/tcpmib.stp |  352 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 352 insertions(+), 0 deletions(-)

diff --git a/tapset/tcpmib.stp b/tapset/tcpmib.stp
new file mode 100644
index 0000000..e3e7690
--- /dev/null
+++ b/tapset/tcpmib.stp
@@ -0,0 +1,352 @@
+/*
+ *      Copyright (C) 2009 IBM Corp.
+ *      This file is part of systemtap, and is free software.  You can
+ *      redistribute it and/or modify it under the terms of the GNU General
+ *      Public License (GPL); either version 2, or (at your option) any
+ *      later version.
+ *      
+ *      Version 1.0     wilder@us.ibm.com     2009-07-06
+ */
+
+/* Global counter definitions for mib TCP_MIB. */
+
+%{
+#include <net/sock.h>
+#include <linux/tcp.h>
+#include <net/tcp_states.h>
+#include <linux/skbuff.h>
+#include <net/route.h>
+%}
+
+global ActiveOpens
+global AttemptFails
+global CurrEstab
+global EstabResets
+// global InErrs, this mib is not yet supported
+global InSegs
+global OutRsts
+global OutSegs
+global PassiveOpens
+global RetransSegs
+
+/**
+ * sfunction tcpmib_get_state - Get a socket's state.
+ *
+ * Returns the sk_state from a struct sock.
+ * @sk: Pointer to a struct sock.
+ *
+ */
+function tcpmib_get_state:long (sk:long)
+%{ /* pure */
+	struct sock *sk = (struct sock *)(long)THIS->sk;
+	THIS->__retvalue = kread(&(sk->sk_state));
+	CATCH_DEREF_FAULT();
+%}
+
+/**
+ * sfunction tcpmib_local_addr - Get the source address.
+ *
+ * Returns the saddr from a struct inet_sock.
+ * @sk: Pointer to a struct inet_sock.
+ *
+ */
+function tcpmib_local_addr:long(sk:long)
+%{ /* pure */
+        struct inet_sock *inet = (struct inet_sock *) (long) THIS->sk;
+        THIS->__retvalue = ntohl(kread(&(inet->saddr)));
+        CATCH_DEREF_FAULT();
+%}
+
+/**
+ * sfunction tcpmib_remote_addr - Get the remote address.
+ *
+ * Returns the daddr from a struct inet_sock.
+ * @sk: Pointer to a struct inet_sock.
+ *
+ */
+function tcpmib_remote_addr:long(sk:long)
+%{ /* pure */
+        struct inet_sock *inet = (struct inet_sock *) (long) THIS->sk;
+        THIS->__retvalue = ntohl(kread(&(inet->daddr)));
+        CATCH_DEREF_FAULT();
+%}
+
+/**
+ * sfunction tcpmib_local_port - Get the local port.
+ *
+ * Returns the sport from a struct inet_sock.
+ * @sk: Pointer to a struct inet_sock.
+ *
+ */
+function tcpmib_local_port:long(sk:long)
+%{ /* pure */
+        struct inet_sock *inet = (struct inet_sock *) (long) THIS->sk;
+        THIS->__retvalue = ntohs(kread(&(inet->sport)));
+        CATCH_DEREF_FAULT();
+%}
+
+/**
+ * sfunction tcpmib_remote_port - Get the remote port.
+ *
+ * Returns the dport from a struct inet_sock.
+ * @sk: Pointer to a struct inet_sock.
+ *
+ */
+function tcpmib_remote_port:long(sk:long)
+%{ /* pure */
+        struct inet_sock *inet = (struct inet_sock *) (long) THIS->sk;
+        THIS->__retvalue = ntohs(kread(&(inet->dport)));
+        CATCH_DEREF_FAULT();
+%}
+
+/**
+ * probe tcpmib.ActiveOpens - Count an active opening of a socket.
+ * @sk:	Pointer to the struct sock being acted on.
+ * @op: Value to be added to the counter (Operation). 
+ *
+ * Counter Name: ActiveOpens
+ * MIB: TCP_MIB_ACTIVEOPENS
+ *
+ */
+probe
+tcpmib.ActiveOpens=kernel.function("tcp_connect").return
+{
+	sk = $sk;
+	op = 1;
+	if ( $return ) next;
+	key = tcpmib_filter_key(sk,op);
+	if ( key ) ActiveOpens[key] += op;
+}
+
+/**
+ * probe tcpmib.AttemptFails - Count a failed attempt to open a socket.
+ * @sk: Pointer to the struct sock being acted on.
+ * @op: Value to be added to the counter (Operation). 
+ *
+ * Counter Name: AttemptFails
+ * MIB: TCP_MIB_ATTEMPTFAILS
+ *
+ */
+probe
+tcpmib.AttemptFails=kernel.function("tcp_done")
+{
+	sk = $sk;
+	state = tcpmib_get_state(sk);
+	op = 1;
+
+	TCP_SYN_SENT = 2;
+	TCP_SYN_RECV = 3;
+	if( state == TCP_SYN_SENT || state == TCP_SYN_RECV){
+		key = tcpmib_filter_key(sk,op);
+		if ( key ) AttemptFails[key] += op;
+	}
+}
+
+/**
+ * probe tcpmib.CurrEstab - Update the count of open sockets.
+ * @sk: Pointer to the struct sock being acted on.
+ * @op: Value to be added to the counter (Operation). 
+ *
+ * Counter Name: CurrEstab
+ * MIB: TCP_MIB_CURRESTAB
+ *
+ */
+probe
+tcpmib.CurrEstab=kernel.function("tcp_set_state")
+{
+	sk = $sk;
+	state = $state;
+	oldstate = tcpmib_get_state(sk);
+
+	TCP_ESTABLISHED = 1;
+	if ( oldstate == TCP_ESTABLISHED ) {
+		op = -1;
+		key = tcpmib_filter_key(sk,op);
+		if ( key ) CurrEstab[key] += op;
+	} else {
+		if ( state == TCP_ESTABLISHED ) {
+			op = 1;
+			key = tcpmib_filter_key(sk,op);
+			if ( key ) CurrEstab[key] += op;
+		}
+	}
+}
+
+/**
+ * probe tcpmib.EstabResets - Count the reset of a socket.
+ * @sk: Pointer to the struct sock being acted on.
+ * @op: Value to be added to the counter (Operation). 
+ *
+ * Counter Name: EstabResets
+ * MIB: TCP_MIB_ESTABRESETS
+ *
+ */
+probe
+tcpmib.EstabResets=kernel.function("tcp_set_state")
+{
+	sk = $sk;
+        state = $state;
+        oldstate = tcpmib_get_state(sk);
+	op = 1;
+
+	TCP_CLOSE = 7;
+	TCP_CLOSE_WAIT = 8;
+	TCP_ESTABLISHED = 1;
+	if ( ( state == TCP_CLOSE ) && 
+	   (oldstate == TCP_CLOSE_WAIT || oldstate == TCP_ESTABLISHED) ){
+        	key = tcpmib_filter_key(sk,op);
+		if ( key ) EstabResets[key] += op;
+	}
+}
+
+/**
+ * probe tcpmib.InSegs - Count an incomming tcp segment.
+ * @sk: Pointer to the struct sock being acted on.
+ * @op: Value to be added to the counter (Operation). 
+ *
+ * Counter Name: InSegs
+ * MIB: TCP_MIB_INSEGS
+ *
+ */
+probe
+tcpmib.InSegs=kernel.function("__inet_lookup_established").return
+{
+        sk=$return
+	op=1
+	key = tcpmib_filter_key(sk,op);
+	if ( key ) InSegs[key] += op;
+}
+
+/**
+ * probe tcpmib.OutRsts - Count the sending of a reset packet.
+ * @sk: Pointer to the struct sock being acted on.
+ * @op: Value to be added to the counter (Operation). 
+ *
+ * Counter Name: OutRsts
+ * MIB: TCP_MIB_OUTRSTS
+ *
+ */
+probe
+tcpmib.OutRsts = 	tcpmib.OutRsts.A,
+			tcpmib.OutRsts.B { }
+
+function _rtn_local:long ()
+%{
+        THIS->__retvalue = RTN_LOCAL;
+%}
+
+function _is_reset:long (skb:long)
+%{ /* pure */
+        struct tcphdr *th;
+        struct sk_buff *skb = (struct sk_buff *)(long)THIS->skb;
+
+	#ifdef NET_SKBUFF_DATA_USES_OFFSET
+		th = (struct tcphdr *)(kread(&(skb->network_header)) + kread(&(skb->head)));
+	#else
+		th = (struct tcphdr *)kread(&(skb->network_header));
+	#endif
+        THIS->__retvalue = th->rst;
+        CATCH_DEREF_FAULT();
+%}
+
+function _tcpmib_input_route_type:long (skb:long)
+%{ /* pure */
+        struct rtable *rt;
+        struct sk_buff *skb = (struct sk_buff *)(long)THIS->skb;
+        rt = (struct rtable *)kread(&(skb->rtable));
+        THIS->__retvalue = kread(&(rt->rt_type));
+        CATCH_DEREF_FAULT();
+%}
+
+/*
+ * note:
+ * tcp_v4_send_reset may be called with a NULL sk.
+ * This happens when sending a reset in response to a syn 
+ * when no socket exists (for example the service is not running).
+ * Without a socket we can't count the reset.
+ */
+probe
+tcpmib.OutRsts.A=kernel.function("tcp_v4_send_reset")
+{
+        sk = $sk;
+        skb = $skb
+        op = 1;
+        if ( _is_reset(skb) ) next
+        if (_tcpmib_input_route_type($skb) != _rtn_local() )
+                next;
+        key = tcpmib_filter_key(sk,op);
+        if ( key ) OutRsts[key] += op;
+}
+
+probe
+tcpmib.OutRsts.B= kernel.function("tcp_send_active_reset")
+{
+	/* Almost correct,
+	 * If alloc_skb() fails it incorrectly bumps TCP_MIB_OUTRSTS,
+	 */
+	sk = $sk;
+	op = 1;
+	key = tcpmib_filter_key(sk,op);
+        if ( key ) OutRsts[key] += op;
+}
+
+/**
+ * probe tcpmib.OutSegs - Count the sending of a TCP segment.
+ * @sk: Pointer to the struct sock being acted on.
+ * @op: Value to be added to the counter (Operation). 
+ *
+ * Counter Name: OutSegs
+ * MIB: TCP_MIB_OUTSEGS
+ *
+ */
+probe
+tcpmib.OutSegs=kernel.function("ip_queue_xmit").return
+{
+	if ( $return < 0 ) next;
+	sk = $skb->sk;
+	op = 1;
+	
+        //  Only count the events with protocol IPPROTO_TCP,6.
+	iphdr = __get_skb_iphdr($skb);
+        if( !(__ip_skb_proto(iphdr) == 6) ) next ;
+	key = tcpmib_filter_key(sk,op);
+	if ( key ) OutSegs[key] += op;
+}
+
+/**
+ * probe tcpmib.PassiveOpens - Count the passive creation of a socket.
+ * @sk: Pointer to the struct sock being acted on.
+ * @op: Value to be added to the counter (Operation). 
+ *
+ * Counter Name: PassiveOpens
+ * MIB: TCP_MIB_PASSIVEOPENS
+ *
+ */
+probe
+tcpmib.PassiveOpens=kernel.function("tcp_v4_syn_recv_sock").return
+{
+        sk = $return;
+        op = 1;
+        if ( !sk ) next;
+        key = tcpmib_filter_key(sk,op);
+        if ( key ) PassiveOpens[key] += op;
+}
+
+/**
+ * probe tcpmib.RetransSegs - Count the retransmission of a TCP segment.
+ * @sk: Pointer to the struct sock being acted on.
+ * @op: Value to be added to the counter (Operation). 
+ *
+ * Counter Name: RetransSegs
+ * MIB: TCP_MIB_RETRANSSEGS
+ *
+ */
+probe
+tcpmib.RetransSegs=kernel.function("tcp_retransmit_skb").return
+{
+	sk = $sk;
+	op = 1;
+	if ( $return ) next;
+	key = tcpmib_filter_key(sk,op);
+	if ( key ) RetransSegs[key] += op;
+}


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH 1/6] SNMP tapset
  2009-07-07  3:03 [PATCH 1/6] SNMP tapset David J. Wilder
@ 2009-07-20  7:08 ` Wenji Huang
  2009-07-20 16:55   ` David J. Wilder
  0 siblings, 1 reply; 3+ messages in thread
From: Wenji Huang @ 2009-07-20  7:08 UTC (permalink / raw)
  To: David J. Wilder; +Cc: systemtap

David J. Wilder wrote:
> This tapset provides probes used to count TCP SNMP management
> events.  The probes mirror many of the SNMP statistics defined

Excellent stuff.
 > + */
 > +function tcpmib_get_state:long (sk:long)
 > +%{ /* pure */
 > +	struct sock *sk = (struct sock *)(long)THIS->sk;
 > +	THIS->__retvalue = kread(&(sk->sk_state));
 > +	CATCH_DEREF_FAULT();
 > +%}

Maybe using cast operator to avoid such kinds of
embedded C functions.
 > +
 > +/**
 > + * sfunction tcpmib_local_addr - Get the source address.
[...]
 > + *
 > +
 > +function _tcpmib_input_route_type:long (skb:long)
 > +%{ /* pure */
 > +        struct rtable *rt;
 > +        struct sk_buff *skb = (struct sk_buff *)(long)THIS->skb;
 > +        rt = (struct rtable *)kread(&(skb->rtable));
 > +        THIS->__retvalue = kread(&(rt->rt_type));
 > +        CATCH_DEREF_FAULT();
 > +%}

There are some changes in sk_buff structure those cause the failures of 
compiling ipmib.stp and tcpmib.stp. rtable and dst fields are deleted 
and some accessors are provided. See:

net: skb->dst accessors
author	Eric Dumazet <eric.dumazet@gmail.com>
	Tue, 2 Jun 2009 05:19:30 +0000 (05:19 +0000)
committer	David S. Miller <davem@davemloft.net>
	Wed, 3 Jun 2009 09:51:04 +0000 (02:51 -0700)
commit	adf30907d63893e4208dfe3f5c88ae12bc2f25d5

net: skb->rtable accessor
author	Eric Dumazet <eric.dumazet@gmail.com>
	Tue, 2 Jun 2009 05:14:27 +0000 (05:14 +0000)
committer	David S. Miller <davem@davemloft.net>
	Wed, 3 Jun 2009 09:51:02 +0000 (02:51 -0700)
commit	511c3f92ad5b6d9f8f6464be1b4f85f0422be91a


Regards,
Wenji

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH 1/6] SNMP tapset
  2009-07-20  7:08 ` Wenji Huang
@ 2009-07-20 16:55   ` David J. Wilder
  0 siblings, 0 replies; 3+ messages in thread
From: David J. Wilder @ 2009-07-20 16:55 UTC (permalink / raw)
  To: wenji.huang; +Cc: systemtap

Thanks for the references. I will fix that up.

I have not made the switch to @cast yet but plan to soon.  I need this
to work with older version of stap at for now.


On Mon, 2009-07-20 at 15:07 +0800, Wenji Huang wrote:
> David J. Wilder wrote:
> > This tapset provides probes used to count TCP SNMP management
> > events.  The probes mirror many of the SNMP statistics defined
> 
> Excellent stuff.
>  > + */
>  > +function tcpmib_get_state:long (sk:long)
>  > +%{ /* pure */
>  > +	struct sock *sk = (struct sock *)(long)THIS->sk;
>  > +	THIS->__retvalue = kread(&(sk->sk_state));
>  > +	CATCH_DEREF_FAULT();
>  > +%}
> 
> Maybe using cast operator to avoid such kinds of
> embedded C functions.
>  > +
>  > +/**
>  > + * sfunction tcpmib_local_addr - Get the source address.
> [...]
>  > + *
>  > +
>  > +function _tcpmib_input_route_type:long (skb:long)
>  > +%{ /* pure */
>  > +        struct rtable *rt;
>  > +        struct sk_buff *skb = (struct sk_buff *)(long)THIS->skb;
>  > +        rt = (struct rtable *)kread(&(skb->rtable));
>  > +        THIS->__retvalue = kread(&(rt->rt_type));
>  > +        CATCH_DEREF_FAULT();
>  > +%}
> 
> There are some changes in sk_buff structure those cause the failures of 
> compiling ipmib.stp and tcpmib.stp. rtable and dst fields are deleted 
> and some accessors are provided. See:
> 
> net: skb->dst accessors
> author	Eric Dumazet <eric.dumazet@gmail.com>
> 	Tue, 2 Jun 2009 05:19:30 +0000 (05:19 +0000)
> committer	David S. Miller <davem@davemloft.net>
> 	Wed, 3 Jun 2009 09:51:04 +0000 (02:51 -0700)
> commit	adf30907d63893e4208dfe3f5c88ae12bc2f25d5
> 
> net: skb->rtable accessor
> author	Eric Dumazet <eric.dumazet@gmail.com>
> 	Tue, 2 Jun 2009 05:14:27 +0000 (05:14 +0000)
> committer	David S. Miller <davem@davemloft.net>
> 	Wed, 3 Jun 2009 09:51:02 +0000 (02:51 -0700)
> commit	511c3f92ad5b6d9f8f6464be1b4f85f0422be91a
> 
> 
> Regards,
> Wenji

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2009-07-20 16:55 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-07-07  3:03 [PATCH 1/6] SNMP tapset David J. Wilder
2009-07-20  7:08 ` Wenji Huang
2009-07-20 16:55   ` David J. Wilder

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).