Explorar o código

core: Add icmp tracing

Add events to trace the uplink and downlink ping sequences
through unfragmented icmp echo requests and echo responses.

CRs-Fixed: 2984040
Change-Id: Ibb9176b6f583beeab43e983c7b700248759d1e67
Signed-off-by: Subash Abhinov Kasiviswanathan <[email protected]>
Subash Abhinov Kasiviswanathan %!s(int64=4) %!d(string=hai) anos
pai
achega
35c1472b09
Modificáronse 3 ficheiros con 103 adicións e 1 borrados
  1. 1 0
      core/rmnet_handlers.c
  2. 53 1
      core/rmnet_trace.h
  3. 49 0
      core/rmnet_vnd.c

+ 1 - 0
core/rmnet_handlers.c

@@ -51,6 +51,7 @@ EXPORT_TRACEPOINT_SYMBOL(rmnet_err);
 EXPORT_TRACEPOINT_SYMBOL(rmnet_freq_update);
 EXPORT_TRACEPOINT_SYMBOL(rmnet_freq_reset);
 EXPORT_TRACEPOINT_SYMBOL(rmnet_freq_boost);
+EXPORT_TRACEPOINT_SYMBOL(print_icmp_rx);
 
 
 

+ 53 - 1
core/rmnet_trace.h

@@ -117,7 +117,7 @@ TRACE_EVENT(print_skb_gso,
 	TP_ARGS(skb, src, dest, ip_proto, xport_proto, saddr, daddr),
 
 	TP_STRUCT__entry(
-		__field(void *,	skbaddr)
+		__field(void *, skbaddr)
 		__field(int, len)
 		__field(int, data_len)
 		__field(__be16, src)
@@ -148,6 +148,58 @@ TRACE_EVENT(print_skb_gso,
 		__get_str(daddr), be16_to_cpu(__entry->dest))
 );
 
+DECLARE_EVENT_CLASS(print_icmp,
+
+	TP_PROTO(struct sk_buff *skb, u16 ip_proto, u8 type, __be16 sequence,
+		const char *saddr, const char *daddr),
+
+	TP_ARGS(skb, ip_proto, type, sequence, saddr, daddr),
+
+	TP_STRUCT__entry(
+		__field(void *, skbaddr)
+		__field(int, len)
+		__field(u16, ip_proto)
+		__field(u8, type)
+		__field(__be16, sequence)
+		__string(saddr, saddr)
+		__string(daddr, daddr)
+	),
+
+	TP_fast_assign(
+		__entry->skbaddr = skb;
+		__entry->len = skb->len;
+		__entry->ip_proto = ip_proto;
+		__entry->type = type;
+		__entry->sequence = sequence;
+		__assign_str(saddr, saddr);
+		__assign_str(daddr, daddr);
+	),
+
+	TP_printk("ICMP: skbaddr=%pK, len=%d, [%s] type=%u sequence=%u source=%s dest=%s",
+		__entry->skbaddr, __entry->len,
+		__entry->ip_proto == htons(ETH_P_IP) ? "IPv4" : "IPv6",
+		__entry->type, be16_to_cpu(__entry->sequence), __get_str(saddr),
+		__get_str(daddr))
+);
+
+DEFINE_EVENT
+	(print_icmp, print_icmp_tx,
+
+	TP_PROTO(struct sk_buff *skb, u16 ip_proto, u8 type, __be16 sequence,
+		const char *saddr, const char *daddr),
+
+	TP_ARGS(skb, ip_proto, type, sequence, saddr, daddr)
+);
+
+DEFINE_EVENT
+	(print_icmp, print_icmp_rx,
+
+	TP_PROTO(struct sk_buff *skb, u16 ip_proto, u8 type, __be16 sequence,
+		const char *saddr, const char *daddr),
+
+	TP_ARGS(skb, ip_proto, type, sequence, saddr, daddr)
+);
+
 /*****************************************************************************/
 /* Trace events for rmnet_perf module */
 /*****************************************************************************/

+ 49 - 0
core/rmnet_vnd.c

@@ -20,7 +20,10 @@
 #include <linux/ipv6.h>
 #include <linux/tcp.h>
 #include <linux/inet.h>
+#include <linux/icmp.h>
+#include <linux/icmpv6.h>
 #include <net/pkt_sched.h>
+#include <net/ipv6.h>
 #include "rmnet_config.h"
 #include "rmnet_handlers.h"
 #include "rmnet_private.h"
@@ -250,6 +253,52 @@ static u16 rmnet_vnd_select_queue(struct net_device *dev,
 	int boost_trigger = 0;
 	int txq = 0;
 
+	if (trace_print_icmp_tx_enabled()) {
+		char saddr[INET6_ADDRSTRLEN], daddr[INET6_ADDRSTRLEN];
+		u16 ip_proto = 0;
+		__be16 sequence = 0;
+		u8 type = 0;
+
+		memset(saddr, 0, INET6_ADDRSTRLEN);
+		memset(daddr, 0, INET6_ADDRSTRLEN);
+
+		if (skb->protocol == htons(ETH_P_IP)) {
+			if (ip_hdr(skb)->protocol != IPPROTO_ICMP)
+				goto skip_trace_print_icmp_tx;
+
+			if (icmp_hdr(skb)->type != ICMP_ECHOREPLY &&
+			    icmp_hdr(skb)->type != ICMP_ECHO)
+				goto skip_trace_print_icmp_tx;
+
+			ip_proto = htons(ETH_P_IP);
+			type = icmp_hdr(skb)->type;
+			sequence = icmp_hdr(skb)->un.echo.sequence;
+			snprintf(saddr, INET6_ADDRSTRLEN, "%pI4", &ip_hdr(skb)->saddr);
+			snprintf(daddr, INET6_ADDRSTRLEN, "%pI4", &ip_hdr(skb)->daddr);
+		}
+
+		if (skb->protocol == htons(ETH_P_IPV6)) {
+			if (ipv6_hdr(skb)->nexthdr != NEXTHDR_ICMP)
+				goto skip_trace_print_icmp_tx;
+
+			if (icmp6_hdr(skb)->icmp6_type != ICMPV6_ECHO_REQUEST &&
+			    icmp6_hdr(skb)->icmp6_type != ICMPV6_ECHO_REPLY)
+				goto skip_trace_print_icmp_tx;
+
+			ip_proto = htons(ETH_P_IPV6);
+			type = icmp6_hdr(skb)->icmp6_type;
+			sequence = icmp6_hdr(skb)->icmp6_sequence;
+			snprintf(saddr, INET6_ADDRSTRLEN, "%pI6", &ipv6_hdr(skb)->saddr);
+			snprintf(daddr, INET6_ADDRSTRLEN, "%pI6", &ipv6_hdr(skb)->daddr);
+		}
+
+		if (!ip_proto)
+			goto skip_trace_print_icmp_tx;
+
+		trace_print_icmp_tx(skb, ip_proto, type, sequence, saddr, daddr);
+	}
+
+skip_trace_print_icmp_tx:
 	if (trace_print_skb_gso_enabled()) {
 		char saddr[INET6_ADDRSTRLEN], daddr[INET6_ADDRSTRLEN];
 		u16 ip_proto = 0, xport_proto = 0;