Add some packet header information to the tracepoint when available:
* ipv4/ipv6 network header
* tcp transport header

Signed-off-by: Geneviève Bastien <[email protected]>
---
 instrumentation/events/lttng-module/net.h | 244 +++++++++++++++++++++++++++++-
 1 file changed, 237 insertions(+), 7 deletions(-)

diff --git a/instrumentation/events/lttng-module/net.h 
b/instrumentation/events/lttng-module/net.h
index e552cf7..b31aea4 100644
--- a/instrumentation/events/lttng-module/net.h
+++ b/instrumentation/events/lttng-module/net.h
@@ -7,8 +7,74 @@
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
 #include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/ipv6.h>
 #include <linux/tracepoint.h>
 #include <linux/version.h>
+#include <net/sock.h>
+
+#ifndef _TRACE_NET_DEF_
+#define _TRACE_NET_DEF_
+
+enum network_header_types {
+       nhtype_none,
+       nhtype_ip,
+       nhtype_ip6,
+       NR_NH_TYPES,
+};
+
+enum transport_header_types {
+       thtype_none,
+       thtype_tcp,
+       NR_TH_TYPES,
+};
+
+static inline unsigned char __get_send_network_header_type(struct sk_buff *skb)
+{
+       if (skb->sk) {
+               if (skb->sk->sk_family == PF_INET)
+                       return nhtype_ip;
+               else if (skb->sk->sk_family == PF_INET6)
+                       return nhtype_ip6;
+       }
+       return nhtype_none;
+}
+
+static inline unsigned char __get_send_transport_header_type(struct sk_buff 
*skb)
+{
+       if (skb->sk) {
+               if (skb->sk->sk_protocol == IPPROTO_TCP)
+                       return thtype_tcp;
+       }
+       return thtype_none;
+}
+
+static inline unsigned char __get_recv_network_header_type(struct sk_buff *skb)
+{
+       if (skb_network_header(skb) != skb->head) {
+               if (skb->protocol == htons(ETH_P_IPV6))
+                       return nhtype_ip6;
+               else if (skb->protocol == htons(ETH_P_IP))
+                       return nhtype_ip;
+       }
+       return nhtype_none;
+}
+
+static inline unsigned char __get_recv_transport_header_type(struct sk_buff 
*skb)
+{
+       if (skb_network_header(skb) != skb->head) {
+               if (!(skb->transport_header <= skb->network_header)) {
+                       if ((skb->protocol == htons(ETH_P_IP) &&
+                                       (ip_hdr(skb)->protocol == IPPROTO_TCP)) 
||
+                               (skb->protocol == htons(ETH_P_IPV6) &&
+                                       (ipv6_hdr(skb)->nexthdr == 
IPPROTO_TCP)))
+                               return thtype_tcp;
+               }
+       }
+       return thtype_none;
+}
+
+#endif /* _TRACE_NET_DEF_ */
 
 TRACE_EVENT(net_dev_xmit,
 
@@ -57,43 +123,207 @@ TRACE_EVENT(net_dev_xmit,
                __get_str(name), __entry->skbaddr, __entry->len, __entry->rc)
 )
 
-DECLARE_EVENT_CLASS(net_dev_template,
+#ifdef TRACE_METADATA
+
+TRACEPOINT_ENUM(net, network_header, TP_TYPE(unsigned char),
+       TP_ENUM(
+               V(nhtype_none)
+               V(nhtype_ip)
+               V(nhtype_ip6)
+       )
+)
+
+TRACEPOINT_ENUM(net, transport_header, TP_TYPE(unsigned char),
+       TP_ENUM(
+               V(thtype_none)
+               V(thtype_tcp)
+       )
+)
+
+TRACEPOINT_STRUCT_RAW(net, empty_struct,
+
+       TP_PROTO(struct sk_buff *skb),
+
+       TP_ARGS(skb),
+
+       TP_FIELDS(
+       )
+)
+
+TRACEPOINT_STRUCT_RAW(net, ip_fields,
+
+       TP_PROTO(struct iphdr *hdr),
+
+       TP_ARGS(hdr),
+
+       TP_FIELDS(__field_hex(unsigned char,    ihl_version)
+               __field_network(unsigned char, tos)
+               __field_network(unsigned short, tot_len)
+               __field_network_hex(unsigned short, id)
+               __field_network(unsigned short, frag_off)
+               __field_network(unsigned char, ttl)
+               __field_network_hex(unsigned char, protocol)
+               __field_network_hex(unsigned short, checksum)
+               __field_network_hex(unsigned int, saddr)
+               __field_network_hex(unsigned int, daddr)
+       )
+)
+
+TRACEPOINT_STRUCT_RAW(net, ipv6_fields,
+
+       TP_PROTO(struct ipv6hdr *hdr),
+
+       TP_ARGS(hdr),
+
+       TP_FIELDS(__field_hex(unsigned char,    prio_version)
+               __array(char, flow_lbl, 3)
+               __field_network(unsigned short, payload_len)
+               __field_network_hex(unsigned char, nexthdr)
+               __field_network(unsigned char, hop_limit)
+               __array_hex(unsigned short, saddr, 8)
+               __array_hex(unsigned short, daddr, 8)
+       )
+)
+
+TRACEPOINT_STRUCT_RAW(net, tcp_fields,
+
+       TP_PROTO(struct tcphdr *hdr),
+
+       TP_ARGS(hdr),
+
+       TP_FIELDS(__field_network(unsigned short,       source)
+               __field_network(unsigned short, dest)
+               __field_network_hex(unsigned int,       seq)
+               __field_network_hex(unsigned int,       ack_seq)
+               __field_network_hex(unsigned short,     flags)
+               __field_network_hex(unsigned short, window)
+               __field_network_hex(unsigned short, check)
+               __field_network_hex(unsigned short, urg_ptr)
+       )
+)
+
+TRACEPOINT_VARIANT(net, network,
+
+       TP_PROTO(unsigned char enum_val, struct sk_buff *skb),
+
+       TP_ARGS(skb),
+
+       net, network_header, enum_val,
+
+       TP_VARIANTS(
+               TP_VARIANT(nhtype_none, __struct(net, empty_struct, 
nhtype_none, skb))
+               TP_VARIANT(nhtype_ip, __struct(net, ip_fields, nhtype_ip, 
ip_hdr(skb)))
+               TP_VARIANT(nhtype_ip6, __struct(net, ipv6_fields, nhtype_ip6, 
ipv6_hdr(skb)))
+       ),
+
+       TP_fast_assign(
+               TP_variants_assign(
+                       TP_variant_assign(nhtype_none, tp_memcpy_struct(net, 
empty_struct, nhtype_none, skb))
+                       TP_variant_assign(nhtype_ip, tp_memcpy_struct(net, 
ip_fields, nhtype_ip, ip_hdr(skb)))
+                       TP_variant_assign(nhtype_ip6, tp_memcpy_struct(net, 
ipv6_fields, nhtype_ip6, ipv6_hdr(skb)))
+               )
+       )
+)
+
+TRACEPOINT_VARIANT(net, transport,
+
+       TP_PROTO(unsigned char enum_val, struct sk_buff *skb),
+
+       TP_ARGS(skb),
+
+       net, transport_header, enum_val,
+
+       TP_VARIANTS(
+               TP_VARIANT(thtype_none, __struct(net, empty_struct, 
thtype_none, skb))
+               TP_VARIANT(thtype_tcp, __struct(net, tcp_fields, thtype_tcp, 
tcp_hdr(skb)))
+       ),
+
+       TP_fast_assign(
+               TP_variants_assign(
+                       TP_variant_assign(thtype_none, tp_memcpy_struct(net, 
empty_struct, thtype_none, skb))
+                       TP_variant_assign(thtype_tcp, tp_memcpy_struct(net, 
tcp_fields, thtype_tcp, tcp_hdr(skb)))
+               )
+       )
+)
+
+#endif
+
+DECLARE_EVENT_CLASS(net_dev_template_send,
 
        TP_PROTO(struct sk_buff *skb),
 
        TP_ARGS(skb),
 
        TP_STRUCT__entry(
-               __field(        void *,         skbaddr         )
-               __field(        unsigned int,   len             )
-               __string(       name,           skb->dev->name  )
+               __field(void *, skbaddr)
+               __field(unsigned int, len)
+               __string(name, skb->dev->name)
+               __field_enum(net, network_header, unsigned char, network_header)
+               __variant(net, network, network_fields, network_header, 
__get_send_network_header_type(skb), skb)
+               __field_enum(net, transport_header, unsigned char, 
transport_header)
+               __variant(net, transport, transport_fields, transport_header, 
__get_send_transport_header_type(skb), skb)
+       ),
+
+       TP_fast_assign(
+               tp_assign(skbaddr, skb)
+               tp_assign(len, skb->len)
+               tp_strcpy(name, skb->dev->name)
+               tp_assign(network_header, __get_send_network_header_type(skb))
+               tp_assign_variant(net, network, network_fields, 
__get_send_network_header_type(skb), skb)
+               tp_assign(transport_header, 
__get_send_transport_header_type(skb))
+               tp_assign_variant(net, transport, transport_fields, 
__get_send_transport_header_type(skb), skb)
+       ),
+
+       TP_printk("dev=%s skbaddr=%p len=%u",
+               __get_str(name), __entry->skbaddr, __entry->len)
+)
+
+DECLARE_EVENT_CLASS(net_dev_template_recv,
+
+       TP_PROTO(struct sk_buff *skb),
+
+       TP_ARGS(skb),
+
+       TP_STRUCT__entry(
+               __field(void *, skbaddr)
+               __field(unsigned int, len)
+               __string(name, skb->dev->name)
+               __field_enum(net, network_header, unsigned char, network_header)
+               __variant(net, network, network_fields, network_header, 
__get_recv_network_header_type(skb), skb)
+               __field_enum(net, transport_header, unsigned char, 
transport_header)
+               __variant(net, transport, transport_fields, transport_header, 
__get_recv_transport_header_type(skb), skb)
+
        ),
 
        TP_fast_assign(
                tp_assign(skbaddr, skb)
                tp_assign(len, skb->len)
                tp_strcpy(name, skb->dev->name)
+               tp_assign(network_header, __get_recv_network_header_type(skb))
+               tp_assign_variant(net, network, network_fields, 
__get_recv_network_header_type(skb), skb)
+               tp_assign(transport_header, 
__get_recv_transport_header_type(skb))
+               tp_assign_variant(net, transport, transport_fields, 
__get_recv_transport_header_type(skb), skb)
        ),
 
        TP_printk("dev=%s skbaddr=%p len=%u",
                __get_str(name), __entry->skbaddr, __entry->len)
 )
 
-DEFINE_EVENT(net_dev_template, net_dev_queue,
+DEFINE_EVENT(net_dev_template_send, net_dev_queue,
 
        TP_PROTO(struct sk_buff *skb),
 
        TP_ARGS(skb)
 )
 
-DEFINE_EVENT(net_dev_template, netif_receive_skb,
+DEFINE_EVENT(net_dev_template_recv, netif_receive_skb,
 
        TP_PROTO(struct sk_buff *skb),
 
        TP_ARGS(skb)
 )
 
-DEFINE_EVENT(net_dev_template, netif_rx,
+DEFINE_EVENT(net_dev_template_recv, netif_rx,
 
        TP_PROTO(struct sk_buff *skb),
 
-- 
1.8.2.1


_______________________________________________
lttng-dev mailing list
[email protected]
http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev

Reply via email to