* [PATCH] tools lib traceevent: Add support for IP address formats
@ 2014-12-17 20:29 David Ahern
2014-12-18 4:26 ` Namhyung Kim
0 siblings, 1 reply; 16+ messages in thread
From: David Ahern @ 2014-12-17 20:29 UTC (permalink / raw)
To: acme, linux-kernel; +Cc: David Ahern, Namhyung Kim, Jiri Olsa, Steven Rostedt
Adds helper for following kernel formats:
%pi4 print an IPv4 address with leading zeros
%pI4 print an IPv4 address without leading zeros
%pi6 print an IPv6 address without colons
%pI6 print an IPv6 address with colons
%pI6c print an IPv6 address with colons
%pISpc print an IP address from a sockaddr
Allows these formats to be used in tracepoints.
Quite a bit of this is adapted from code in lib/vsprintf.c.
Signed-off-by: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
---
tools/lib/traceevent/event-parse.c | 316 +++++++++++++++++++++++++++++++++++++
1 file changed, 316 insertions(+)
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index cf3a44bf1ec3..85ab72c650d3 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -32,6 +32,7 @@
#include <stdint.h>
#include <limits.h>
+#include <netinet/ip6.h>
#include "event-parse.h"
#include "event-utils.h"
@@ -4149,6 +4150,312 @@ static void print_mac_arg(struct trace_seq *s, int mac, void *data, int size,
trace_seq_printf(s, fmt, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
}
+static void print_ip4_addr(struct trace_seq *s, char i, unsigned char *buf)
+{
+ const char *fmt;
+
+ if (i == 'i')
+ fmt = "%03d.%03d.%03d.%03d";
+ else
+ fmt = "%d.%d.%d.%d";
+
+ trace_seq_printf(s, fmt, buf[0], buf[1], buf[2], buf[3]);
+}
+
+static inline bool ipv6_addr_v4mapped(const struct in6_addr *a)
+{
+ return ((unsigned long)(a->s6_addr32[0] | a->s6_addr32[1]) |
+ (unsigned long)(a->s6_addr32[2] ^ htonl(0x0000ffff))) == 0UL;
+}
+
+static inline bool ipv6_addr_is_isatap(const struct in6_addr *addr)
+{
+ return (addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE);
+}
+
+static void print_ip6c_addr(struct trace_seq *s, unsigned char *addr)
+{
+ int i, j, range;
+ unsigned char zerolength[8];
+ int longest = 1;
+ int colonpos = -1;
+ uint16_t word;
+ uint8_t hi, lo;
+ bool needcolon = false;
+ bool useIPv4;
+ struct in6_addr in6;
+
+ memcpy(&in6, addr, sizeof(struct in6_addr));
+
+ useIPv4 = ipv6_addr_v4mapped(&in6) || ipv6_addr_is_isatap(&in6);
+
+ memset(zerolength, 0, sizeof(zerolength));
+
+ if (useIPv4)
+ range = 6;
+ else
+ range = 8;
+
+ /* find position of longest 0 run */
+ for (i = 0; i < range; i++) {
+ for (j = i; j < range; j++) {
+ if (in6.s6_addr16[j] != 0)
+ break;
+ zerolength[i]++;
+ }
+ }
+ for (i = 0; i < range; i++) {
+ if (zerolength[i] > longest) {
+ longest = zerolength[i];
+ colonpos = i;
+ }
+ }
+ if (longest == 1) /* don't compress a single 0 */
+ colonpos = -1;
+
+ /* emit address */
+ for (i = 0; i < range; i++) {
+ if (i == colonpos) {
+ if (needcolon || i == 0)
+ trace_seq_printf(s, ":");
+ trace_seq_printf(s, ":");
+ needcolon = false;
+ i += longest - 1;
+ continue;
+ }
+ if (needcolon) {
+ trace_seq_printf(s, ":");
+ needcolon = false;
+ }
+ /* hex u16 without leading 0s */
+ word = ntohs(in6.s6_addr16[i]);
+ hi = word >> 8;
+ lo = word & 0xff;
+ if (hi)
+ trace_seq_printf(s, "%x%02x", hi, lo);
+ else
+ trace_seq_printf(s, "%x", lo);
+
+ needcolon = true;
+ }
+
+ if (useIPv4) {
+ if (needcolon)
+ trace_seq_printf(s, ":");
+ print_ip4_addr(s, 'I', &in6.s6_addr[12]);
+ }
+
+ return;
+}
+
+static void print_ip6_addr(struct trace_seq *s, char i, unsigned char *buf)
+{
+ int j;
+
+ for (j = 0; j < 16; j += 2) {
+ trace_seq_printf(s, "%02x%02x", buf[j], buf[j+1]);
+ if (i == 'I' && j < 14)
+ trace_seq_printf(s, ":");
+ }
+}
+
+/*
+ * %pi4 print an IPv4 address with leading zeros
+ * %pI4 print an IPv4 address without leading zeros
+ * %pi6 print an IPv6 address without colons
+ * %pI6 print an IPv6 address with colons
+ * %pI6c print an IPv6 address in compressed form with colons
+ * %pISpc print an IP address based on sockaddr; p adds port.
+ */
+static int print_ipv4_arg(struct trace_seq *s, const char *ptr, char i,
+ void *data, int size, struct event_format *event,
+ struct print_arg *arg)
+{
+ unsigned char *buf;
+
+ if (arg->type == PRINT_FUNC) {
+ process_defined_func(s, data, size, event, arg);
+ return 0;
+ }
+
+ if (arg->type != PRINT_FIELD) {
+ trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", arg->type);
+ return 0;
+ }
+
+ if (!arg->field.field) {
+ arg->field.field =
+ pevent_find_any_field(event, arg->field.name);
+ if (!arg->field.field) {
+ do_warning("%s: field %s not found",
+ __func__, arg->field.name);
+ return 0;
+ }
+ }
+
+ buf = data + arg->field.field->offset;
+
+ if (arg->field.field->size != 4) {
+ trace_seq_printf(s, "INVALIDIPv4");
+ return 0;
+ }
+ print_ip4_addr(s, i, buf);
+
+ return 0;
+}
+
+static int print_ipv6_arg(struct trace_seq *s, const char *ptr, char i,
+ void *data, int size, struct event_format *event,
+ struct print_arg *arg)
+{
+ char have_c = 0;
+ unsigned char *buf;
+ int rc = 0;
+
+ /* pI6c */
+ if (*(ptr + 1) == 'c') {
+ have_c = 1;
+ ptr++;
+ rc++;
+ }
+
+ if (arg->type == PRINT_FUNC) {
+ process_defined_func(s, data, size, event, arg);
+ return rc;
+ }
+
+ if (arg->type != PRINT_FIELD) {
+ trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", arg->type);
+ return rc;
+ }
+
+ if (!arg->field.field) {
+ arg->field.field =
+ pevent_find_any_field(event, arg->field.name);
+ if (!arg->field.field) {
+ do_warning("%s: field %s not found",
+ __func__, arg->field.name);
+ return rc;
+ }
+ }
+
+ buf = data + arg->field.field->offset;
+
+ if (arg->field.field->size != 16) {
+ trace_seq_printf(s, "INVALIDIPv6");
+ return rc;
+ }
+
+ if (have_c)
+ print_ip6c_addr(s, buf);
+ else
+ print_ip6_addr(s, i, buf);
+
+ return rc;
+}
+
+static int print_ipsa_arg(struct trace_seq *s, const char *ptr, char i,
+ void *data, int size, struct event_format *event,
+ struct print_arg *arg)
+{
+ char have_c = 0, have_p = 0;
+ unsigned char *buf;
+ struct sockaddr_storage *sa;
+ int rc = 0;
+
+ /* pISpc */
+ if (*(ptr + 1) == 'p') {
+ have_p = 1;
+ ptr++;
+ rc++;
+ }
+ if (*(ptr + 1) == 'c') {
+ have_c = 1;
+ ptr++;
+ rc++;
+ }
+
+ if (arg->type == PRINT_FUNC) {
+ process_defined_func(s, data, size, event, arg);
+ return rc;
+ }
+
+ if (arg->type != PRINT_FIELD) {
+ trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", arg->type);
+ return rc;
+ }
+
+ if (!arg->field.field) {
+ arg->field.field =
+ pevent_find_any_field(event, arg->field.name);
+ if (!arg->field.field) {
+ do_warning("%s: field %s not found",
+ __func__, arg->field.name);
+ return rc;
+ }
+ }
+
+ sa = (struct sockaddr_storage *) (data + arg->field.field->offset);
+
+ if (sa->ss_family == AF_INET) {
+ struct sockaddr_in *sa4 = (struct sockaddr_in *) sa;
+
+ print_ip4_addr(s, i, (unsigned char *) &sa4->sin_addr);
+ if (have_p)
+ trace_seq_printf(s, ":%d", ntohs(sa4->sin_port));
+
+
+ } else if (sa->ss_family == AF_INET6) {
+ struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *) sa;
+
+ if (have_p)
+ trace_seq_printf(s, "[");
+
+ buf = (unsigned char *) &sa6->sin6_addr;
+ if (have_c)
+ print_ip6c_addr(s, buf);
+ else
+ print_ip6_addr(s, i, buf);
+
+ if (have_p)
+ trace_seq_printf(s, "]:%d", ntohs(sa6->sin6_port));
+ }
+
+ return rc;
+}
+
+static int print_ip_arg(struct trace_seq *s, const char *ptr,
+ void *data, int size, struct event_format *event,
+ struct print_arg *arg)
+{
+ char i = *(ptr + 1); /* 'i' or 'I' */
+ char ver;
+ int rc = 0;
+
+ ptr++;
+ rc++;
+
+ ver = *(ptr + 1);
+ ptr++;
+ rc++;
+
+ switch (ver) {
+ case '4':
+ rc += print_ipv4_arg(s, ptr, i, data, size, event, arg);
+ break;
+ case '6':
+ rc += print_ipv6_arg(s, ptr, i, data, size, event, arg);
+ break;
+ case 'S':
+ rc += print_ipsa_arg(s, ptr, i, data, size, event, arg);
+ break;
+ default:
+ return 0;
+ }
+
+ return rc;
+}
+
static int is_printable_array(char *p, unsigned int len)
{
unsigned int i;
@@ -4337,6 +4644,15 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
ptr++;
arg = arg->next;
break;
+ } else if (*(ptr+1) == 'I' || *(ptr+1) == 'i') {
+ int n;
+
+ n = print_ip_arg(s, ptr, data, size, event, arg);
+ if (n > 0) {
+ ptr += n;
+ arg = arg->next;
+ break;
+ }
}
/* fall through */
--
1.9.3 (Apple Git-50)
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH] tools lib traceevent: Add support for IP address formats
2014-12-17 20:29 David Ahern
@ 2014-12-18 4:26 ` Namhyung Kim
2014-12-18 4:32 ` David Ahern
0 siblings, 1 reply; 16+ messages in thread
From: Namhyung Kim @ 2014-12-18 4:26 UTC (permalink / raw)
To: David Ahern; +Cc: acme, linux-kernel, Jiri Olsa, Steven Rostedt
Hi David,
On Wed, Dec 17, 2014 at 01:29:08PM -0700, David Ahern wrote:
> Adds helper for following kernel formats:
> %pi4 print an IPv4 address with leading zeros
> %pI4 print an IPv4 address without leading zeros
> %pi6 print an IPv6 address without colons
> %pI6 print an IPv6 address with colons
> %pI6c print an IPv6 address with colons
> %pISpc print an IP address from a sockaddr
>
> Allows these formats to be used in tracepoints.
>
> Quite a bit of this is adapted from code in lib/vsprintf.c.
>
> Signed-off-by: David Ahern <dsahern@gmail.com>
> Cc: Namhyung Kim <namhyung@kernel.org>
> Cc: Jiri Olsa <jolsa@kernel.org>
> Cc: Steven Rostedt <rostedt@goodmis.org>
> ---
[SNIP]
> +static int print_ip_arg(struct trace_seq *s, const char *ptr,
> + void *data, int size, struct event_format *event,
> + struct print_arg *arg)
> +{
> + char i = *(ptr + 1); /* 'i' or 'I' */
It'd be better if we do it like below..
char i = *ptr++;
Why not passing ptr + 1 to print_ip_arg()?
> + char ver;
> + int rc = 0;
> +
> + ptr++;
> + rc++;
> +
> + ver = *(ptr + 1);
Ditto.
> + ptr++;
> + rc++;
> +
> + switch (ver) {
> + case '4':
> + rc += print_ipv4_arg(s, ptr, i, data, size, event, arg);
> + break;
> + case '6':
> + rc += print_ipv6_arg(s, ptr, i, data, size, event, arg);
> + break;
> + case 'S':
> + rc += print_ipsa_arg(s, ptr, i, data, size, event, arg);
> + break;
> + default:
> + return 0;
> + }
> +
> + return rc;
> +}
> +
> static int is_printable_array(char *p, unsigned int len)
> {
> unsigned int i;
> @@ -4337,6 +4644,15 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
> ptr++;
> arg = arg->next;
> break;
> + } else if (*(ptr+1) == 'I' || *(ptr+1) == 'i') {
> + int n;
> +
> + n = print_ip_arg(s, ptr, data, size, event, arg);
Here..
Thanks,
Namhyung
> + if (n > 0) {
> + ptr += n;
> + arg = arg->next;
> + break;
> + }
> }
>
> /* fall through */
> --
> 1.9.3 (Apple Git-50)
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] tools lib traceevent: Add support for IP address formats
2014-12-18 4:26 ` Namhyung Kim
@ 2014-12-18 4:32 ` David Ahern
2014-12-18 5:04 ` Namhyung Kim
0 siblings, 1 reply; 16+ messages in thread
From: David Ahern @ 2014-12-18 4:32 UTC (permalink / raw)
To: Namhyung Kim
Cc: Arnaldo Carvalho de Melo, linux-kernel, Jiri Olsa, Steven Rostedt
On 12/17/14 9:26 PM, Namhyung Kim wrote:
>
> It'd be better if we do it like below..
>
> char i = *ptr++;
>
> Why not passing ptr + 1 to print_ip_arg()?
>
That parsing loop is a bit weird - and deep. And I only wanted to
consume 'pi' and 'pI' with parse_ip_arg if and only if the next letters
are '4', '6' and 'S'.
David
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] tools lib traceevent: Add support for IP address formats
2014-12-18 4:32 ` David Ahern
@ 2014-12-18 5:04 ` Namhyung Kim
0 siblings, 0 replies; 16+ messages in thread
From: Namhyung Kim @ 2014-12-18 5:04 UTC (permalink / raw)
To: David Ahern
Cc: Arnaldo Carvalho de Melo, linux-kernel, Jiri Olsa, Steven Rostedt
On Wed, Dec 17, 2014 at 09:32:27PM -0700, David Ahern wrote:
> On 12/17/14 9:26 PM, Namhyung Kim wrote:
> >
> >It'd be better if we do it like below..
> >
> > char i = *ptr++;
> >
> >Why not passing ptr + 1 to print_ip_arg()?
> >
>
> That parsing loop is a bit weird - and deep. And I only wanted to consume
> 'pi' and 'pI' with parse_ip_arg if and only if the next letters are '4', '6'
> and 'S'.
Yeah, I know - but I still think you can pass ptr + 1 (but not update
ptr) since everytime you only access to ptr + 1 unless I missed it.
Consuming ptr depends on the return value so it's irrelevant whether
you pass ptr or (ptr + 1) IMHO.
Thanks,
Namhyung
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH] tools lib traceevent: Add support for IP address formats
@ 2014-12-18 15:10 David Ahern
2014-12-18 15:52 ` Arnaldo Carvalho de Melo
2014-12-18 21:45 ` Valdis.Kletnieks
0 siblings, 2 replies; 16+ messages in thread
From: David Ahern @ 2014-12-18 15:10 UTC (permalink / raw)
To: acme, linux-kernel; +Cc: David Ahern, Namhyung Kim, Jiri Olsa, Steven Rostedt
Adds helper for following kernel formats:
%pi4 print an IPv4 address with leading zeros
%pI4 print an IPv4 address without leading zeros
%pi6 print an IPv6 address without colons
%pI6 print an IPv6 address with colons
%pI6c print an IPv6 address with colons
%pISpc print an IP address from a sockaddr
Allows these formats to be used in tracepoints.
Quite a bit of this is adapted from code in lib/vsprintf.c.
v2:
- pass ptr+1 to print_ip_arg per Namhyung's comments
- added field length checks to sockaddr function
Signed-off-by: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
---
tools/lib/traceevent/event-parse.c | 326 +++++++++++++++++++++++++++++++++++++
1 file changed, 326 insertions(+)
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index cf3a44bf1ec3..48d57c9fc476 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -32,6 +32,7 @@
#include <stdint.h>
#include <limits.h>
+#include <netinet/ip6.h>
#include "event-parse.h"
#include "event-utils.h"
@@ -4149,6 +4150,322 @@ static void print_mac_arg(struct trace_seq *s, int mac, void *data, int size,
trace_seq_printf(s, fmt, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
}
+static void print_ip4_addr(struct trace_seq *s, char i, unsigned char *buf)
+{
+ const char *fmt;
+
+ if (i == 'i')
+ fmt = "%03d.%03d.%03d.%03d";
+ else
+ fmt = "%d.%d.%d.%d";
+
+ trace_seq_printf(s, fmt, buf[0], buf[1], buf[2], buf[3]);
+}
+
+static inline bool ipv6_addr_v4mapped(const struct in6_addr *a)
+{
+ return ((unsigned long)(a->s6_addr32[0] | a->s6_addr32[1]) |
+ (unsigned long)(a->s6_addr32[2] ^ htonl(0x0000ffff))) == 0UL;
+}
+
+static inline bool ipv6_addr_is_isatap(const struct in6_addr *addr)
+{
+ return (addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE);
+}
+
+static void print_ip6c_addr(struct trace_seq *s, unsigned char *addr)
+{
+ int i, j, range;
+ unsigned char zerolength[8];
+ int longest = 1;
+ int colonpos = -1;
+ uint16_t word;
+ uint8_t hi, lo;
+ bool needcolon = false;
+ bool useIPv4;
+ struct in6_addr in6;
+
+ memcpy(&in6, addr, sizeof(struct in6_addr));
+
+ useIPv4 = ipv6_addr_v4mapped(&in6) || ipv6_addr_is_isatap(&in6);
+
+ memset(zerolength, 0, sizeof(zerolength));
+
+ if (useIPv4)
+ range = 6;
+ else
+ range = 8;
+
+ /* find position of longest 0 run */
+ for (i = 0; i < range; i++) {
+ for (j = i; j < range; j++) {
+ if (in6.s6_addr16[j] != 0)
+ break;
+ zerolength[i]++;
+ }
+ }
+ for (i = 0; i < range; i++) {
+ if (zerolength[i] > longest) {
+ longest = zerolength[i];
+ colonpos = i;
+ }
+ }
+ if (longest == 1) /* don't compress a single 0 */
+ colonpos = -1;
+
+ /* emit address */
+ for (i = 0; i < range; i++) {
+ if (i == colonpos) {
+ if (needcolon || i == 0)
+ trace_seq_printf(s, ":");
+ trace_seq_printf(s, ":");
+ needcolon = false;
+ i += longest - 1;
+ continue;
+ }
+ if (needcolon) {
+ trace_seq_printf(s, ":");
+ needcolon = false;
+ }
+ /* hex u16 without leading 0s */
+ word = ntohs(in6.s6_addr16[i]);
+ hi = word >> 8;
+ lo = word & 0xff;
+ if (hi)
+ trace_seq_printf(s, "%x%02x", hi, lo);
+ else
+ trace_seq_printf(s, "%x", lo);
+
+ needcolon = true;
+ }
+
+ if (useIPv4) {
+ if (needcolon)
+ trace_seq_printf(s, ":");
+ print_ip4_addr(s, 'I', &in6.s6_addr[12]);
+ }
+
+ return;
+}
+
+static void print_ip6_addr(struct trace_seq *s, char i, unsigned char *buf)
+{
+ int j;
+
+ for (j = 0; j < 16; j += 2) {
+ trace_seq_printf(s, "%02x%02x", buf[j], buf[j+1]);
+ if (i == 'I' && j < 14)
+ trace_seq_printf(s, ":");
+ }
+}
+
+/*
+ * %pi4 print an IPv4 address with leading zeros
+ * %pI4 print an IPv4 address without leading zeros
+ * %pi6 print an IPv6 address without colons
+ * %pI6 print an IPv6 address with colons
+ * %pI6c print an IPv6 address in compressed form with colons
+ * %pISpc print an IP address based on sockaddr; p adds port.
+ */
+static int print_ipv4_arg(struct trace_seq *s, const char *ptr, char i,
+ void *data, int size, struct event_format *event,
+ struct print_arg *arg)
+{
+ unsigned char *buf;
+
+ if (arg->type == PRINT_FUNC) {
+ process_defined_func(s, data, size, event, arg);
+ return 0;
+ }
+
+ if (arg->type != PRINT_FIELD) {
+ trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", arg->type);
+ return 0;
+ }
+
+ if (!arg->field.field) {
+ arg->field.field =
+ pevent_find_any_field(event, arg->field.name);
+ if (!arg->field.field) {
+ do_warning("%s: field %s not found",
+ __func__, arg->field.name);
+ return 0;
+ }
+ }
+
+ buf = data + arg->field.field->offset;
+
+ if (arg->field.field->size != 4) {
+ trace_seq_printf(s, "INVALIDIPv4");
+ return 0;
+ }
+ print_ip4_addr(s, i, buf);
+
+ return 0;
+}
+
+static int print_ipv6_arg(struct trace_seq *s, const char *ptr, char i,
+ void *data, int size, struct event_format *event,
+ struct print_arg *arg)
+{
+ char have_c = 0;
+ unsigned char *buf;
+ int rc = 0;
+
+ /* pI6c */
+ if (*ptr == 'c') {
+ have_c = 1;
+ ptr++;
+ rc++;
+ }
+
+ if (arg->type == PRINT_FUNC) {
+ process_defined_func(s, data, size, event, arg);
+ return rc;
+ }
+
+ if (arg->type != PRINT_FIELD) {
+ trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", arg->type);
+ return rc;
+ }
+
+ if (!arg->field.field) {
+ arg->field.field =
+ pevent_find_any_field(event, arg->field.name);
+ if (!arg->field.field) {
+ do_warning("%s: field %s not found",
+ __func__, arg->field.name);
+ return rc;
+ }
+ }
+
+ buf = data + arg->field.field->offset;
+
+ if (arg->field.field->size != 16) {
+ trace_seq_printf(s, "INVALIDIPv6");
+ return rc;
+ }
+
+ if (have_c)
+ print_ip6c_addr(s, buf);
+ else
+ print_ip6_addr(s, i, buf);
+
+ return rc;
+}
+
+static int print_ipsa_arg(struct trace_seq *s, const char *ptr, char i,
+ void *data, int size, struct event_format *event,
+ struct print_arg *arg)
+{
+ char have_c = 0, have_p = 0;
+ unsigned char *buf;
+ struct sockaddr_storage *sa;
+ int rc = 0;
+
+ /* pISpc */
+ if (*ptr == 'p') {
+ have_p = 1;
+ ptr++;
+ rc++;
+ }
+ if (*ptr == 'c') {
+ have_c = 1;
+ ptr++;
+ rc++;
+ }
+
+ if (arg->type == PRINT_FUNC) {
+ process_defined_func(s, data, size, event, arg);
+ return rc;
+ }
+
+ if (arg->type != PRINT_FIELD) {
+ trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", arg->type);
+ return rc;
+ }
+
+ if (!arg->field.field) {
+ arg->field.field =
+ pevent_find_any_field(event, arg->field.name);
+ if (!arg->field.field) {
+ do_warning("%s: field %s not found",
+ __func__, arg->field.name);
+ return rc;
+ }
+ }
+
+ sa = (struct sockaddr_storage *) (data + arg->field.field->offset);
+
+ if (sa->ss_family == AF_INET) {
+ struct sockaddr_in *sa4 = (struct sockaddr_in *) sa;
+
+ if (arg->field.field->size < sizeof(struct sockaddr_in)) {
+ trace_seq_printf(s, "INVALIDIPv4");
+ return rc;
+ }
+
+ print_ip4_addr(s, i, (unsigned char *) &sa4->sin_addr);
+ if (have_p)
+ trace_seq_printf(s, ":%d", ntohs(sa4->sin_port));
+
+
+ } else if (sa->ss_family == AF_INET6) {
+ struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *) sa;
+
+ if (arg->field.field->size < sizeof(struct sockaddr_in6)) {
+ trace_seq_printf(s, "INVALIDIPv6");
+ return rc;
+ }
+
+ if (have_p)
+ trace_seq_printf(s, "[");
+
+ buf = (unsigned char *) &sa6->sin6_addr;
+ if (have_c)
+ print_ip6c_addr(s, buf);
+ else
+ print_ip6_addr(s, i, buf);
+
+ if (have_p)
+ trace_seq_printf(s, "]:%d", ntohs(sa6->sin6_port));
+ }
+
+ return rc;
+}
+
+static int print_ip_arg(struct trace_seq *s, const char *ptr,
+ void *data, int size, struct event_format *event,
+ struct print_arg *arg)
+{
+ char i = *ptr; /* 'i' or 'I' */
+ char ver;
+ int rc = 0;
+
+ ptr++;
+ rc++;
+
+ ver = *ptr;
+ ptr++;
+ rc++;
+
+ switch (ver) {
+ case '4':
+ rc += print_ipv4_arg(s, ptr, i, data, size, event, arg);
+ break;
+ case '6':
+ rc += print_ipv6_arg(s, ptr, i, data, size, event, arg);
+ break;
+ case 'S':
+ rc += print_ipsa_arg(s, ptr, i, data, size, event, arg);
+ break;
+ default:
+ return 0;
+ }
+
+ return rc;
+}
+
static int is_printable_array(char *p, unsigned int len)
{
unsigned int i;
@@ -4337,6 +4654,15 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
ptr++;
arg = arg->next;
break;
+ } else if (*(ptr+1) == 'I' || *(ptr+1) == 'i') {
+ int n;
+
+ n = print_ip_arg(s, ptr+1, data, size, event, arg);
+ if (n > 0) {
+ ptr += n;
+ arg = arg->next;
+ break;
+ }
}
/* fall through */
--
1.9.3 (Apple Git-50)
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH] tools lib traceevent: Add support for IP address formats
2014-12-18 15:10 [PATCH] tools lib traceevent: Add support for IP address formats David Ahern
@ 2014-12-18 15:52 ` Arnaldo Carvalho de Melo
2014-12-18 15:59 ` David Ahern
2014-12-18 16:27 ` Steven Rostedt
2014-12-18 21:45 ` Valdis.Kletnieks
1 sibling, 2 replies; 16+ messages in thread
From: Arnaldo Carvalho de Melo @ 2014-12-18 15:52 UTC (permalink / raw)
To: David Ahern; +Cc: linux-kernel, Namhyung Kim, Jiri Olsa, Steven Rostedt
Em Thu, Dec 18, 2014 at 08:10:43AM -0700, David Ahern escreveu:
> Adds helper for following kernel formats:
> %pi4 print an IPv4 address with leading zeros
> %pI4 print an IPv4 address without leading zeros
> %pi6 print an IPv6 address without colons
> %pI6 print an IPv6 address with colons
> %pI6c print an IPv6 address with colons
> %pISpc print an IP address from a sockaddr
>
> Allows these formats to be used in tracepoints.
>
> Quite a bit of this is adapted from code in lib/vsprintf.c.
Can't we try as much as possible use that code directly? Something like
we do for lib/rbtree.c in tools/perf/, or like I did recently with
tools/lib/util/find_next_bit.c, i.e. retain at least this kind of
sharing:
diff -u tools/lib/util/find_next_bit.c lib/find_next_bit.c
Should show that only bits that we have not a need at the moment in
tools/ were left behind.
We want to either get fixes for free by directly reusing or notice it
easily, using diff.
- Arnaldo
> v2:
> - pass ptr+1 to print_ip_arg per Namhyung's comments
> - added field length checks to sockaddr function
>
> Signed-off-by: David Ahern <dsahern@gmail.com>
> Cc: Namhyung Kim <namhyung@kernel.org>
> Cc: Jiri Olsa <jolsa@kernel.org>
> Cc: Steven Rostedt <rostedt@goodmis.org>
> ---
> tools/lib/traceevent/event-parse.c | 326 +++++++++++++++++++++++++++++++++++++
> 1 file changed, 326 insertions(+)
>
> diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
> index cf3a44bf1ec3..48d57c9fc476 100644
> --- a/tools/lib/traceevent/event-parse.c
> +++ b/tools/lib/traceevent/event-parse.c
> @@ -32,6 +32,7 @@
> #include <stdint.h>
> #include <limits.h>
>
> +#include <netinet/ip6.h>
> #include "event-parse.h"
> #include "event-utils.h"
>
> @@ -4149,6 +4150,322 @@ static void print_mac_arg(struct trace_seq *s, int mac, void *data, int size,
> trace_seq_printf(s, fmt, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
> }
>
> +static void print_ip4_addr(struct trace_seq *s, char i, unsigned char *buf)
> +{
> + const char *fmt;
> +
> + if (i == 'i')
> + fmt = "%03d.%03d.%03d.%03d";
> + else
> + fmt = "%d.%d.%d.%d";
> +
> + trace_seq_printf(s, fmt, buf[0], buf[1], buf[2], buf[3]);
> +}
> +
> +static inline bool ipv6_addr_v4mapped(const struct in6_addr *a)
> +{
> + return ((unsigned long)(a->s6_addr32[0] | a->s6_addr32[1]) |
> + (unsigned long)(a->s6_addr32[2] ^ htonl(0x0000ffff))) == 0UL;
> +}
> +
> +static inline bool ipv6_addr_is_isatap(const struct in6_addr *addr)
> +{
> + return (addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE);
> +}
> +
> +static void print_ip6c_addr(struct trace_seq *s, unsigned char *addr)
> +{
> + int i, j, range;
> + unsigned char zerolength[8];
> + int longest = 1;
> + int colonpos = -1;
> + uint16_t word;
> + uint8_t hi, lo;
> + bool needcolon = false;
> + bool useIPv4;
> + struct in6_addr in6;
> +
> + memcpy(&in6, addr, sizeof(struct in6_addr));
> +
> + useIPv4 = ipv6_addr_v4mapped(&in6) || ipv6_addr_is_isatap(&in6);
> +
> + memset(zerolength, 0, sizeof(zerolength));
> +
> + if (useIPv4)
> + range = 6;
> + else
> + range = 8;
> +
> + /* find position of longest 0 run */
> + for (i = 0; i < range; i++) {
> + for (j = i; j < range; j++) {
> + if (in6.s6_addr16[j] != 0)
> + break;
> + zerolength[i]++;
> + }
> + }
> + for (i = 0; i < range; i++) {
> + if (zerolength[i] > longest) {
> + longest = zerolength[i];
> + colonpos = i;
> + }
> + }
> + if (longest == 1) /* don't compress a single 0 */
> + colonpos = -1;
> +
> + /* emit address */
> + for (i = 0; i < range; i++) {
> + if (i == colonpos) {
> + if (needcolon || i == 0)
> + trace_seq_printf(s, ":");
> + trace_seq_printf(s, ":");
> + needcolon = false;
> + i += longest - 1;
> + continue;
> + }
> + if (needcolon) {
> + trace_seq_printf(s, ":");
> + needcolon = false;
> + }
> + /* hex u16 without leading 0s */
> + word = ntohs(in6.s6_addr16[i]);
> + hi = word >> 8;
> + lo = word & 0xff;
> + if (hi)
> + trace_seq_printf(s, "%x%02x", hi, lo);
> + else
> + trace_seq_printf(s, "%x", lo);
> +
> + needcolon = true;
> + }
> +
> + if (useIPv4) {
> + if (needcolon)
> + trace_seq_printf(s, ":");
> + print_ip4_addr(s, 'I', &in6.s6_addr[12]);
> + }
> +
> + return;
> +}
> +
> +static void print_ip6_addr(struct trace_seq *s, char i, unsigned char *buf)
> +{
> + int j;
> +
> + for (j = 0; j < 16; j += 2) {
> + trace_seq_printf(s, "%02x%02x", buf[j], buf[j+1]);
> + if (i == 'I' && j < 14)
> + trace_seq_printf(s, ":");
> + }
> +}
> +
> +/*
> + * %pi4 print an IPv4 address with leading zeros
> + * %pI4 print an IPv4 address without leading zeros
> + * %pi6 print an IPv6 address without colons
> + * %pI6 print an IPv6 address with colons
> + * %pI6c print an IPv6 address in compressed form with colons
> + * %pISpc print an IP address based on sockaddr; p adds port.
> + */
> +static int print_ipv4_arg(struct trace_seq *s, const char *ptr, char i,
> + void *data, int size, struct event_format *event,
> + struct print_arg *arg)
> +{
> + unsigned char *buf;
> +
> + if (arg->type == PRINT_FUNC) {
> + process_defined_func(s, data, size, event, arg);
> + return 0;
> + }
> +
> + if (arg->type != PRINT_FIELD) {
> + trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", arg->type);
> + return 0;
> + }
> +
> + if (!arg->field.field) {
> + arg->field.field =
> + pevent_find_any_field(event, arg->field.name);
> + if (!arg->field.field) {
> + do_warning("%s: field %s not found",
> + __func__, arg->field.name);
> + return 0;
> + }
> + }
> +
> + buf = data + arg->field.field->offset;
> +
> + if (arg->field.field->size != 4) {
> + trace_seq_printf(s, "INVALIDIPv4");
> + return 0;
> + }
> + print_ip4_addr(s, i, buf);
> +
> + return 0;
> +}
> +
> +static int print_ipv6_arg(struct trace_seq *s, const char *ptr, char i,
> + void *data, int size, struct event_format *event,
> + struct print_arg *arg)
> +{
> + char have_c = 0;
> + unsigned char *buf;
> + int rc = 0;
> +
> + /* pI6c */
> + if (*ptr == 'c') {
> + have_c = 1;
> + ptr++;
> + rc++;
> + }
> +
> + if (arg->type == PRINT_FUNC) {
> + process_defined_func(s, data, size, event, arg);
> + return rc;
> + }
> +
> + if (arg->type != PRINT_FIELD) {
> + trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", arg->type);
> + return rc;
> + }
> +
> + if (!arg->field.field) {
> + arg->field.field =
> + pevent_find_any_field(event, arg->field.name);
> + if (!arg->field.field) {
> + do_warning("%s: field %s not found",
> + __func__, arg->field.name);
> + return rc;
> + }
> + }
> +
> + buf = data + arg->field.field->offset;
> +
> + if (arg->field.field->size != 16) {
> + trace_seq_printf(s, "INVALIDIPv6");
> + return rc;
> + }
> +
> + if (have_c)
> + print_ip6c_addr(s, buf);
> + else
> + print_ip6_addr(s, i, buf);
> +
> + return rc;
> +}
> +
> +static int print_ipsa_arg(struct trace_seq *s, const char *ptr, char i,
> + void *data, int size, struct event_format *event,
> + struct print_arg *arg)
> +{
> + char have_c = 0, have_p = 0;
> + unsigned char *buf;
> + struct sockaddr_storage *sa;
> + int rc = 0;
> +
> + /* pISpc */
> + if (*ptr == 'p') {
> + have_p = 1;
> + ptr++;
> + rc++;
> + }
> + if (*ptr == 'c') {
> + have_c = 1;
> + ptr++;
> + rc++;
> + }
> +
> + if (arg->type == PRINT_FUNC) {
> + process_defined_func(s, data, size, event, arg);
> + return rc;
> + }
> +
> + if (arg->type != PRINT_FIELD) {
> + trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", arg->type);
> + return rc;
> + }
> +
> + if (!arg->field.field) {
> + arg->field.field =
> + pevent_find_any_field(event, arg->field.name);
> + if (!arg->field.field) {
> + do_warning("%s: field %s not found",
> + __func__, arg->field.name);
> + return rc;
> + }
> + }
> +
> + sa = (struct sockaddr_storage *) (data + arg->field.field->offset);
> +
> + if (sa->ss_family == AF_INET) {
> + struct sockaddr_in *sa4 = (struct sockaddr_in *) sa;
> +
> + if (arg->field.field->size < sizeof(struct sockaddr_in)) {
> + trace_seq_printf(s, "INVALIDIPv4");
> + return rc;
> + }
> +
> + print_ip4_addr(s, i, (unsigned char *) &sa4->sin_addr);
> + if (have_p)
> + trace_seq_printf(s, ":%d", ntohs(sa4->sin_port));
> +
> +
> + } else if (sa->ss_family == AF_INET6) {
> + struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *) sa;
> +
> + if (arg->field.field->size < sizeof(struct sockaddr_in6)) {
> + trace_seq_printf(s, "INVALIDIPv6");
> + return rc;
> + }
> +
> + if (have_p)
> + trace_seq_printf(s, "[");
> +
> + buf = (unsigned char *) &sa6->sin6_addr;
> + if (have_c)
> + print_ip6c_addr(s, buf);
> + else
> + print_ip6_addr(s, i, buf);
> +
> + if (have_p)
> + trace_seq_printf(s, "]:%d", ntohs(sa6->sin6_port));
> + }
> +
> + return rc;
> +}
> +
> +static int print_ip_arg(struct trace_seq *s, const char *ptr,
> + void *data, int size, struct event_format *event,
> + struct print_arg *arg)
> +{
> + char i = *ptr; /* 'i' or 'I' */
> + char ver;
> + int rc = 0;
> +
> + ptr++;
> + rc++;
> +
> + ver = *ptr;
> + ptr++;
> + rc++;
> +
> + switch (ver) {
> + case '4':
> + rc += print_ipv4_arg(s, ptr, i, data, size, event, arg);
> + break;
> + case '6':
> + rc += print_ipv6_arg(s, ptr, i, data, size, event, arg);
> + break;
> + case 'S':
> + rc += print_ipsa_arg(s, ptr, i, data, size, event, arg);
> + break;
> + default:
> + return 0;
> + }
> +
> + return rc;
> +}
> +
> static int is_printable_array(char *p, unsigned int len)
> {
> unsigned int i;
> @@ -4337,6 +4654,15 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
> ptr++;
> arg = arg->next;
> break;
> + } else if (*(ptr+1) == 'I' || *(ptr+1) == 'i') {
> + int n;
> +
> + n = print_ip_arg(s, ptr+1, data, size, event, arg);
> + if (n > 0) {
> + ptr += n;
> + arg = arg->next;
> + break;
> + }
> }
>
> /* fall through */
> --
> 1.9.3 (Apple Git-50)
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] tools lib traceevent: Add support for IP address formats
2014-12-18 15:52 ` Arnaldo Carvalho de Melo
@ 2014-12-18 15:59 ` David Ahern
2014-12-18 16:27 ` Steven Rostedt
1 sibling, 0 replies; 16+ messages in thread
From: David Ahern @ 2014-12-18 15:59 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: linux-kernel, Namhyung Kim, Jiri Olsa, Steven Rostedt
On 12/18/14 8:52 AM, Arnaldo Carvalho de Melo wrote:
> Em Thu, Dec 18, 2014 at 08:10:43AM -0700, David Ahern escreveu:
>> Adds helper for following kernel formats:
>> %pi4 print an IPv4 address with leading zeros
>> %pI4 print an IPv4 address without leading zeros
>> %pi6 print an IPv6 address without colons
>> %pI6 print an IPv6 address with colons
>> %pI6c print an IPv6 address with colons
>> %pISpc print an IP address from a sockaddr
>>
>> Allows these formats to be used in tracepoints.
>>
>> Quite a bit of this is adapted from code in lib/vsprintf.c.
>
> Can't we try as much as possible use that code directly? Something like
By my reading of that file I don't see how it can be reused directly.
David
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] tools lib traceevent: Add support for IP address formats
2014-12-18 15:52 ` Arnaldo Carvalho de Melo
2014-12-18 15:59 ` David Ahern
@ 2014-12-18 16:27 ` Steven Rostedt
2014-12-18 22:16 ` Arnaldo Carvalho de Melo
1 sibling, 1 reply; 16+ messages in thread
From: Steven Rostedt @ 2014-12-18 16:27 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: David Ahern, linux-kernel, Namhyung Kim, Jiri Olsa
On Thu, 18 Dec 2014 12:52:55 -0300
Arnaldo Carvalho de Melo <acme@kernel.org> wrote:
> Em Thu, Dec 18, 2014 at 08:10:43AM -0700, David Ahern escreveu:
> > Adds helper for following kernel formats:
> > %pi4 print an IPv4 address with leading zeros
> > %pI4 print an IPv4 address without leading zeros
> > %pi6 print an IPv6 address without colons
> > %pI6 print an IPv6 address with colons
> > %pI6c print an IPv6 address with colons
> > %pISpc print an IP address from a sockaddr
> >
> > Allows these formats to be used in tracepoints.
> >
> > Quite a bit of this is adapted from code in lib/vsprintf.c.
>
> Can't we try as much as possible use that code directly? Something like
Until we have a true shared library, please no. I'm still taking code
from here and adding it manually to trace-cmd. And also sending patches
to here from what I add to trace-cmd.
I do not want this directly linked to the kernel code. Note, the kernel
internals have no guaranteed API, where this does.
> we do for lib/rbtree.c in tools/perf/, or like I did recently with
> tools/lib/util/find_next_bit.c, i.e. retain at least this kind of
> sharing:
>
> diff -u tools/lib/util/find_next_bit.c lib/find_next_bit.c
Unless we convert code to trace_seq, I don't think this works. My
patches to move seq_buf.c int lib/ have made it into the kernel.
Perhaps we can copy the seq_buf.c code into tools/lib/traceevent, but
that would take some work.
-- Steve
>
> Should show that only bits that we have not a need at the moment in
> tools/ were left behind.
>
> We want to either get fixes for free by directly reusing or notice it
> easily, using diff.
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] tools lib traceevent: Add support for IP address formats
2014-12-18 15:10 [PATCH] tools lib traceevent: Add support for IP address formats David Ahern
2014-12-18 15:52 ` Arnaldo Carvalho de Melo
@ 2014-12-18 21:45 ` Valdis.Kletnieks
2014-12-18 22:13 ` David Ahern
1 sibling, 1 reply; 16+ messages in thread
From: Valdis.Kletnieks @ 2014-12-18 21:45 UTC (permalink / raw)
To: David Ahern; +Cc: acme, linux-kernel, Namhyung Kim, Jiri Olsa, Steven Rostedt
[-- Attachment #1: Type: text/plain, Size: 628 bytes --]
On Thu, 18 Dec 2014 08:10:43 -0700, David Ahern said:
> Adds helper for following kernel formats:
> %pi4 print an IPv4 address with leading zeros
> %pI4 print an IPv4 address without leading zeros
> %pi6 print an IPv6 address without colons
> %pI6 print an IPv6 address with colons
> %pI6c print an IPv6 address with colons
> %pISpc print an IP address from a sockaddr
The description for %pI6C in the changelog doesn't match the code:
> + * %pI6c print an IPv6 address in compressed form with colons
Threw me for a loop for a while trying to figure out how pI6 and pI6c were
different, till I read the code...
[-- Attachment #2: Type: application/pgp-signature, Size: 848 bytes --]
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] tools lib traceevent: Add support for IP address formats
2014-12-18 21:45 ` Valdis.Kletnieks
@ 2014-12-18 22:13 ` David Ahern
2014-12-19 1:41 ` David Ahern
0 siblings, 1 reply; 16+ messages in thread
From: David Ahern @ 2014-12-18 22:13 UTC (permalink / raw)
To: Valdis.Kletnieks
Cc: acme, linux-kernel, Namhyung Kim, Jiri Olsa, Steven Rostedt
On 12/18/14 2:45 PM, Valdis.Kletnieks@vt.edu wrote:
> On Thu, 18 Dec 2014 08:10:43 -0700, David Ahern said:
>> Adds helper for following kernel formats:
>> %pi4 print an IPv4 address with leading zeros
>> %pI4 print an IPv4 address without leading zeros
>> %pi6 print an IPv6 address without colons
>> %pI6 print an IPv6 address with colons
>> %pI6c print an IPv6 address with colons
>> %pISpc print an IP address from a sockaddr
>
> The description for %pI6C in the changelog doesn't match the code:
>
>> + * %pI6c print an IPv6 address in compressed form with colons
>
> Threw me for a loop for a while trying to figure out how pI6 and pI6c were
> different, till I read the code...
>
Per Documentation/printk-formats.txt:
%pI6 0001:0002:0003:0004:0005:0006:0007:0008
%pi6 00010002000300040005000600070008
%pI6c 1:2:3:4:5:6:7:8
For printing IPv6 network-order 16-bit hex addresses. The 'I6' and 'i6'
specifiers result in a printed address with ('I6') or without ('i6')
colon-separators. Leading zeros are always used.
The additional 'c' specifier can be used with the 'I' specifier to
print a compressed IPv6 address as described by
http://tools.ietf.org/html/rfc5952
I do see two mistakes in my patch -- use of 'c' and 'S' requires 'I'.
After that the code that prints pI6c is a slightly modified version of
what is in lib/vsprintf.c so the output between in-kernel tracing (cat
trace_pipe) should match perf-script output. Compare
ip6_compressed_string() in lib/vsprintf.c to print_ip6c_addr() in this
patch.
Are you seeing something different?
David
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] tools lib traceevent: Add support for IP address formats
2014-12-18 16:27 ` Steven Rostedt
@ 2014-12-18 22:16 ` Arnaldo Carvalho de Melo
2014-12-18 22:50 ` David Ahern
0 siblings, 1 reply; 16+ messages in thread
From: Arnaldo Carvalho de Melo @ 2014-12-18 22:16 UTC (permalink / raw)
To: Steven Rostedt; +Cc: David Ahern, linux-kernel, Namhyung Kim, Jiri Olsa
Em Thu, Dec 18, 2014 at 11:27:15AM -0500, Steven Rostedt escreveu:
> On Thu, 18 Dec 2014 12:52:55 -0300
> Arnaldo Carvalho de Melo <acme@kernel.org> wrote:
>
> > Em Thu, Dec 18, 2014 at 08:10:43AM -0700, David Ahern escreveu:
> > > Adds helper for following kernel formats:
> > > %pi4 print an IPv4 address with leading zeros
> > > %pI4 print an IPv4 address without leading zeros
> > > %pi6 print an IPv6 address without colons
> > > %pI6 print an IPv6 address with colons
> > > %pI6c print an IPv6 address with colons
> > > %pISpc print an IP address from a sockaddr
> > > Allows these formats to be used in tracepoints.
> > > Quite a bit of this is adapted from code in lib/vsprintf.c.
> > Can't we try as much as possible use that code directly? Something like
> Until we have a true shared library, please no. I'm still taking code
> from here and adding it manually to trace-cmd. And also sending patches
> to here from what I add to trace-cmd.
> I do not want this directly linked to the kernel code. Note, the kernel
> internals have no guaranteed API, where this does.
If using it directly is frowned upon, at least try to reduce the
differences when copying code, be it by keeping function ordering in the
source code, using the same file name and generally making it easier to
see if changes ocurred on the original file over time.
> > we do for lib/rbtree.c in tools/perf/, or like I did recently with
> > tools/lib/util/find_next_bit.c, i.e. retain at least this kind of
> > sharing:
> > diff -u tools/lib/util/find_next_bit.c lib/find_next_bit.c
> Unless we convert code to trace_seq, I don't think this works. My
> patches to move seq_buf.c int lib/ have made it into the kernel.
> Perhaps we can copy the seq_buf.c code into tools/lib/traceevent, but
> that would take some work.
Well, I thought that what that code was doing was just taking a string,
looking for some specific %LETTER stuff, acting on it and returning the
formatted result, i.e. a vsprintf function, thus I ended up shortcutting
too fast to the conclusion that it was possible, my bad :-)
If take the time to look at the specifics I'll propose something more
concrete, meanwhile, are you ok with David's changes? May I process his
patch?
- Arnaldo
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] tools lib traceevent: Add support for IP address formats
2014-12-18 22:16 ` Arnaldo Carvalho de Melo
@ 2014-12-18 22:50 ` David Ahern
0 siblings, 0 replies; 16+ messages in thread
From: David Ahern @ 2014-12-18 22:50 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo, Steven Rostedt
Cc: linux-kernel, Namhyung Kim, Jiri Olsa
On 12/18/14 3:16 PM, Arnaldo Carvalho de Melo wrote:
> If take the time to look at the specifics I'll propose something more
> concrete, meanwhile, are you ok with David's changes? May I process his
> patch?
I need a v3 to respond to oversights noted responding to
Valdis. Any other comments before I send a v3?
David
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] tools lib traceevent: Add support for IP address formats
2014-12-18 22:13 ` David Ahern
@ 2014-12-19 1:41 ` David Ahern
2014-12-22 17:01 ` Jiri Olsa
0 siblings, 1 reply; 16+ messages in thread
From: David Ahern @ 2014-12-19 1:41 UTC (permalink / raw)
To: Valdis.Kletnieks
Cc: acme, linux-kernel, Namhyung Kim, Jiri Olsa, Steven Rostedt
On 12/18/14 3:13 PM, David Ahern wrote:
> Are you seeing something different?
I put a tracepoint in the ipv4/ipv6 add/del address code. The IPv4 one
prints the address using pi4 and pI4 and the IPv6 using pi6, pI6 and pI6c.
Using ifconfig eth1 1.2.3.4/24
I get this for trace_pipe which uses the in-kernel printf code:
root@localhost:/sys/kernel/debug/tracing/events# cat ../trace_pipe
ifconfig-601 [000] .... 710.660611: ipv4_del_addr:
pI4=1.2.3.4 pi4=001.002.003.004
ifconfig-602 [000] .... 720.833559: ipv4_add_addr:
pI4=1.2.3.4 pi4=001.002.003.004
ifconfig-602 [000] .Ns. 720.833966: ipv6_add_addr:
pi6=fe80000000000000000202fffe020211
pI6=fe80:0000:0000:0000:0002:02ff:fe02:0211 pI6c=fe80::2:2ff:fe02:211
ifconfig-602 [000] .... 720.835413: ipv4_del_addr:
pI4=1.2.3.4 pi4=001.002.003.004
ifconfig-602 [000] .N.. 720.835451: ipv4_add_addr:
pI4=1.2.3.4 pi4=001.002.003.004
And this using perf:
root@localhost:~# perf record -a -e ipv4:* -e ipv6:* --no-buffering |
perf --no-pager script
ifconfig 601 [000] 710.912862: ipv4:ipv4_del_addr:
pI4=1.2.3.4 pi4=001.002.003.004
ifconfig 602 [000] 721.090776: ipv4:ipv4_add_addr:
pI4=1.2.3.4 pi4=001.002.003.004
ifconfig 602 [000] 721.091177: ipv6:ipv6_add_addr:
pi6=fe80000000000000000202fffe020211
pI6=fe80:0000:0000:0000:0002:02ff:fe02:0211 pI6c=fe80::2:2ff:fe02:211
ifconfig 602 [000] 721.092626: ipv4:ipv4_del_addr:
pI4=1.2.3.4 pi4=001.002.003.004
ifconfig 602 [000] 721.092648: ipv4:ipv4_add_addr:
pI4=1.2.3.4 pi4=001.002.003.004
(Don't be fooled by the differing timestamps; data collected from both
using the same exact command. timestamp differences are perf vs tracing.)
which suggest with the patch perf output matches tracing.
David
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] tools lib traceevent: Add support for IP address formats
2014-12-19 1:41 ` David Ahern
@ 2014-12-22 17:01 ` Jiri Olsa
2014-12-22 17:10 ` David Ahern
0 siblings, 1 reply; 16+ messages in thread
From: Jiri Olsa @ 2014-12-22 17:01 UTC (permalink / raw)
To: David Ahern
Cc: Valdis.Kletnieks, acme, linux-kernel, Namhyung Kim, Jiri Olsa,
Steven Rostedt
On Thu, Dec 18, 2014 at 06:41:58PM -0700, David Ahern wrote:
> On 12/18/14 3:13 PM, David Ahern wrote:
> >Are you seeing something different?
>
> I put a tracepoint in the ipv4/ipv6 add/del address code. The IPv4 one
> prints the address using pi4 and pI4 and the IPv6 using pi6, pI6 and pI6c.
apart from your tracepoints, is there another tracepoint using this?
I couldn't find any.. I dont think it's a problem.. just wanted to
try it ;-)
thanks,
jirka
>
> Using ifconfig eth1 1.2.3.4/24
>
> I get this for trace_pipe which uses the in-kernel printf code:
>
> root@localhost:/sys/kernel/debug/tracing/events# cat ../trace_pipe
> ifconfig-601 [000] .... 710.660611: ipv4_del_addr: pI4=1.2.3.4
> pi4=001.002.003.004
> ifconfig-602 [000] .... 720.833559: ipv4_add_addr: pI4=1.2.3.4
> pi4=001.002.003.004
> ifconfig-602 [000] .Ns. 720.833966: ipv6_add_addr:
> pi6=fe80000000000000000202fffe020211
> pI6=fe80:0000:0000:0000:0002:02ff:fe02:0211 pI6c=fe80::2:2ff:fe02:211
> ifconfig-602 [000] .... 720.835413: ipv4_del_addr: pI4=1.2.3.4
> pi4=001.002.003.004
> ifconfig-602 [000] .N.. 720.835451: ipv4_add_addr: pI4=1.2.3.4
> pi4=001.002.003.004
>
>
> And this using perf:
> root@localhost:~# perf record -a -e ipv4:* -e ipv6:* --no-buffering | perf
> --no-pager script
>
> ifconfig 601 [000] 710.912862: ipv4:ipv4_del_addr: pI4=1.2.3.4
> pi4=001.002.003.004
> ifconfig 602 [000] 721.090776: ipv4:ipv4_add_addr: pI4=1.2.3.4
> pi4=001.002.003.004
> ifconfig 602 [000] 721.091177: ipv6:ipv6_add_addr:
> pi6=fe80000000000000000202fffe020211
> pI6=fe80:0000:0000:0000:0002:02ff:fe02:0211 pI6c=fe80::2:2ff:fe02:211
> ifconfig 602 [000] 721.092626: ipv4:ipv4_del_addr: pI4=1.2.3.4
> pi4=001.002.003.004
> ifconfig 602 [000] 721.092648: ipv4:ipv4_add_addr: pI4=1.2.3.4
> pi4=001.002.003.004
>
> (Don't be fooled by the differing timestamps; data collected from both using
> the same exact command. timestamp differences are perf vs tracing.)
>
> which suggest with the patch perf output matches tracing.
>
> David
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] tools lib traceevent: Add support for IP address formats
2014-12-22 17:01 ` Jiri Olsa
@ 2014-12-22 17:10 ` David Ahern
2014-12-22 17:28 ` Jiri Olsa
0 siblings, 1 reply; 16+ messages in thread
From: David Ahern @ 2014-12-22 17:10 UTC (permalink / raw)
To: Jiri Olsa
Cc: Valdis.Kletnieks, acme, linux-kernel, Namhyung Kim, Jiri Olsa,
Steven Rostedt
[-- Attachment #1: Type: text/plain, Size: 608 bytes --]
On 12/22/14 10:01 AM, Jiri Olsa wrote:
> apart from your tracepoints, is there another tracepoint using this?
> I couldn't find any.. I dont think it's a problem.. just wanted to
> try it;-)
grrr... i was hoping no one would ask that question. I am not aware of
any in tree. We use it locally in custom tracepoints in the networking
stack (from what I can tell netdev will not take -- LTTng tried many
years ago) and in a couple of klms.
The attached patch is what I used to test (plus our local versions). It
is derived from a patch on the 3.4 kernel which allows us to trace
address changes.
David
[-- Attachment #2: tracepoints-to-test-IP-address-format-output.patch --]
[-- Type: text/plain, Size: 5419 bytes --]
>From bedfad82a159226f06a8035f6a7622fce6df7a0a Mon Sep 17 00:00:00 2001
From: David Ahern <dsahern@gmail.com>
Date: Thu, 18 Dec 2014 19:03:28 -0700
Subject: [PATCH 2/2] tracepoints to test IP address format output
Signed-off-by: David Ahern <dsahern@gmail.com>
---
include/trace/events/ipv4.h | 42 ++++++++++++++++++++++++++++++++++++++++++
include/trace/events/ipv6.h | 44 ++++++++++++++++++++++++++++++++++++++++++++
net/core/net-traces.c | 2 ++
net/ipv4/devinet.c | 4 ++++
net/ipv6/addrconf.c | 4 ++++
5 files changed, 96 insertions(+)
create mode 100644 include/trace/events/ipv4.h
create mode 100644 include/trace/events/ipv6.h
diff --git a/include/trace/events/ipv4.h b/include/trace/events/ipv4.h
new file mode 100644
index 000000000000..24e1e8a8b843
--- /dev/null
+++ b/include/trace/events/ipv4.h
@@ -0,0 +1,42 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM ipv4
+
+#if !defined(_TRACE_EVENTS_IPV4_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_EVENTS_IPV4_H
+
+#include <linux/inetdevice.h>
+#include <linux/tracepoint.h>
+
+DECLARE_EVENT_CLASS(ipv4_addr_template,
+
+ TP_PROTO(struct in_ifaddr *ifa,
+ struct in_device *in_dev),
+
+ TP_ARGS(ifa, in_dev),
+
+ TP_STRUCT__entry(
+ __array(__u8, addr, 4)
+ ),
+
+ TP_fast_assign(
+ memcpy(&__entry->addr, &ifa->ifa_address, 4);
+ ),
+
+ TP_printk("pI4=%pI4 pi4=%pi4",
+ __entry->addr, __entry->addr)
+);
+
+DEFINE_EVENT(ipv4_addr_template, ipv4_add_addr,
+ TP_PROTO(struct in_ifaddr *ifa, struct in_device *in_dev),
+ TP_ARGS(ifa, in_dev)
+);
+
+DEFINE_EVENT(ipv4_addr_template, ipv4_del_addr,
+ TP_PROTO(struct in_ifaddr *ifa, struct in_device *in_dev),
+ TP_ARGS(ifa, in_dev)
+);
+
+#endif /* _TRACE_EVENTS_IPV4_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/include/trace/events/ipv6.h b/include/trace/events/ipv6.h
new file mode 100644
index 000000000000..db1ae85eaa0c
--- /dev/null
+++ b/include/trace/events/ipv6.h
@@ -0,0 +1,44 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM ipv6
+
+#if !defined(_TRACE_EVENTS_IPV6_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_EVENTS_IPV6_H
+
+#include <net/if_inet6.h>
+#include <linux/tracepoint.h>
+
+DECLARE_EVENT_CLASS(ipv6_addr_template,
+
+ TP_PROTO(struct inet6_ifaddr *ifa),
+
+ TP_ARGS(ifa),
+
+ TP_STRUCT__entry(
+ __array(__u8, addr, (int)sizeof(struct in6_addr))
+ ),
+
+ TP_fast_assign(
+ memcpy(&__entry->addr, &ifa->addr, (int)sizeof(struct in6_addr));
+ ),
+
+ TP_printk("pi6=%pi6 pI6=%pI6 pI6c=%pI6c",
+ __entry->addr, __entry->addr, __entry->addr)
+);
+
+DEFINE_EVENT(ipv6_addr_template, ipv6_add_addr,
+
+ TP_PROTO(struct inet6_ifaddr *ifa),
+
+ TP_ARGS(ifa)
+);
+DEFINE_EVENT(ipv6_addr_template, ipv6_del_addr,
+
+ TP_PROTO(struct inet6_ifaddr *ifa),
+
+ TP_ARGS(ifa)
+);
+
+#endif /* _TRACE_EVENTS_IPV6_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/net/core/net-traces.c b/net/core/net-traces.c
index ba3c0120786c..b564a28852d1 100644
--- a/net/core/net-traces.c
+++ b/net/core/net-traces.c
@@ -31,6 +31,8 @@
#include <trace/events/napi.h>
#include <trace/events/sock.h>
#include <trace/events/udp.h>
+#include <trace/events/ipv4.h>
+#include <trace/events/ipv6.h>
EXPORT_TRACEPOINT_SYMBOL_GPL(kfree_skb);
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 214882e7d6de..aa6ba2ad93fd 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -64,6 +64,7 @@
#include <net/rtnetlink.h>
#include <net/net_namespace.h>
#include <net/addrconf.h>
+#include <trace/events/ipv4.h>
#include "fib_lookup.h"
@@ -358,6 +359,7 @@ static void __inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
inet_hash_remove(ifa);
*ifap1 = ifa->ifa_next;
+ trace_ipv4_del_addr(ifa, in_dev);
rtmsg_ifa(RTM_DELADDR, ifa, nlh, portid);
blocking_notifier_call_chain(&inetaddr_chain,
NETDEV_DOWN, ifa);
@@ -395,6 +397,7 @@ static void __inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
is valid, it will try to restore deleted routes... Grr.
So that, this order is correct.
*/
+ trace_ipv4_del_addr(ifa1, in_dev);
rtmsg_ifa(RTM_DELADDR, ifa1, nlh, portid);
blocking_notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa1);
@@ -476,6 +479,7 @@ static int __inet_insert_ifa(struct in_ifaddr *ifa, struct nlmsghdr *nlh,
ifa->ifa_next = *ifap;
*ifap = ifa;
+ trace_ipv4_add_addr(ifa, in_dev);
inet_hash_insert(dev_net(in_dev->dev), ifa);
cancel_delayed_work(&check_lifetime_work);
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index f7c8bbeb27b7..294cb618baf5 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -90,6 +90,7 @@
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/export.h>
+#include <trace/events/ipv6.h>
/* Set to 3 to get tracing... */
#define ACONF_DEBUG 2
@@ -874,6 +875,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr,
in6_dev_hold(idev);
/* For caller */
in6_ifa_hold(ifa);
+ trace_ipv6_add_addr(ifa);
/* Add to big hash table */
hash = inet6_addr_hash(addr);
@@ -1658,8 +1660,10 @@ static void addrconf_dad_stop(struct inet6_ifaddr *ifp, int dad_failed)
} else {
spin_unlock_bh(&ifp->lock);
}
+ trace_ipv6_del_addr(ifp);
ipv6_del_addr(ifp);
} else {
+ trace_ipv6_del_addr(ifp);
ipv6_del_addr(ifp);
}
}
--
1.9.3 (Apple Git-50)
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH] tools lib traceevent: Add support for IP address formats
2014-12-22 17:10 ` David Ahern
@ 2014-12-22 17:28 ` Jiri Olsa
0 siblings, 0 replies; 16+ messages in thread
From: Jiri Olsa @ 2014-12-22 17:28 UTC (permalink / raw)
To: David Ahern
Cc: Valdis.Kletnieks, acme, linux-kernel, Namhyung Kim, Jiri Olsa,
Steven Rostedt
On Mon, Dec 22, 2014 at 10:10:02AM -0700, David Ahern wrote:
> On 12/22/14 10:01 AM, Jiri Olsa wrote:
> >apart from your tracepoints, is there another tracepoint using this?
> >I couldn't find any.. I dont think it's a problem.. just wanted to
> >try it;-)
>
> grrr... i was hoping no one would ask that question. I am not aware of any
> in tree. We use it locally in custom tracepoints in the networking stack
> (from what I can tell netdev will not take -- LTTng tried many years ago)
> and in a couple of klms.
hehe ;-) as I said I dont think this is a problem, as people can add their
own tracepoints (like you did) with print fmt allowing anything that could
go into printk..
>
> The attached patch is what I used to test (plus our local versions). It is
> derived from a patch on the 3.4 kernel which allows us to trace address
> changes.
thanks,
jirka
>
> David
> From bedfad82a159226f06a8035f6a7622fce6df7a0a Mon Sep 17 00:00:00 2001
> From: David Ahern <dsahern@gmail.com>
> Date: Thu, 18 Dec 2014 19:03:28 -0700
> Subject: [PATCH 2/2] tracepoints to test IP address format output
>
> Signed-off-by: David Ahern <dsahern@gmail.com>
> ---
> include/trace/events/ipv4.h | 42 ++++++++++++++++++++++++++++++++++++++++++
> include/trace/events/ipv6.h | 44 ++++++++++++++++++++++++++++++++++++++++++++
> net/core/net-traces.c | 2 ++
> net/ipv4/devinet.c | 4 ++++
> net/ipv6/addrconf.c | 4 ++++
> 5 files changed, 96 insertions(+)
> create mode 100644 include/trace/events/ipv4.h
> create mode 100644 include/trace/events/ipv6.h
>
> diff --git a/include/trace/events/ipv4.h b/include/trace/events/ipv4.h
> new file mode 100644
> index 000000000000..24e1e8a8b843
> --- /dev/null
> +++ b/include/trace/events/ipv4.h
> @@ -0,0 +1,42 @@
> +#undef TRACE_SYSTEM
> +#define TRACE_SYSTEM ipv4
> +
> +#if !defined(_TRACE_EVENTS_IPV4_H) || defined(TRACE_HEADER_MULTI_READ)
> +#define _TRACE_EVENTS_IPV4_H
> +
> +#include <linux/inetdevice.h>
> +#include <linux/tracepoint.h>
> +
> +DECLARE_EVENT_CLASS(ipv4_addr_template,
> +
> + TP_PROTO(struct in_ifaddr *ifa,
> + struct in_device *in_dev),
> +
> + TP_ARGS(ifa, in_dev),
> +
> + TP_STRUCT__entry(
> + __array(__u8, addr, 4)
> + ),
> +
> + TP_fast_assign(
> + memcpy(&__entry->addr, &ifa->ifa_address, 4);
> + ),
> +
> + TP_printk("pI4=%pI4 pi4=%pi4",
> + __entry->addr, __entry->addr)
> +);
> +
> +DEFINE_EVENT(ipv4_addr_template, ipv4_add_addr,
> + TP_PROTO(struct in_ifaddr *ifa, struct in_device *in_dev),
> + TP_ARGS(ifa, in_dev)
> +);
> +
> +DEFINE_EVENT(ipv4_addr_template, ipv4_del_addr,
> + TP_PROTO(struct in_ifaddr *ifa, struct in_device *in_dev),
> + TP_ARGS(ifa, in_dev)
> +);
> +
> +#endif /* _TRACE_EVENTS_IPV4_H */
> +
> +/* This part must be outside protection */
> +#include <trace/define_trace.h>
> diff --git a/include/trace/events/ipv6.h b/include/trace/events/ipv6.h
> new file mode 100644
> index 000000000000..db1ae85eaa0c
> --- /dev/null
> +++ b/include/trace/events/ipv6.h
> @@ -0,0 +1,44 @@
> +#undef TRACE_SYSTEM
> +#define TRACE_SYSTEM ipv6
> +
> +#if !defined(_TRACE_EVENTS_IPV6_H) || defined(TRACE_HEADER_MULTI_READ)
> +#define _TRACE_EVENTS_IPV6_H
> +
> +#include <net/if_inet6.h>
> +#include <linux/tracepoint.h>
> +
> +DECLARE_EVENT_CLASS(ipv6_addr_template,
> +
> + TP_PROTO(struct inet6_ifaddr *ifa),
> +
> + TP_ARGS(ifa),
> +
> + TP_STRUCT__entry(
> + __array(__u8, addr, (int)sizeof(struct in6_addr))
> + ),
> +
> + TP_fast_assign(
> + memcpy(&__entry->addr, &ifa->addr, (int)sizeof(struct in6_addr));
> + ),
> +
> + TP_printk("pi6=%pi6 pI6=%pI6 pI6c=%pI6c",
> + __entry->addr, __entry->addr, __entry->addr)
> +);
> +
> +DEFINE_EVENT(ipv6_addr_template, ipv6_add_addr,
> +
> + TP_PROTO(struct inet6_ifaddr *ifa),
> +
> + TP_ARGS(ifa)
> +);
> +DEFINE_EVENT(ipv6_addr_template, ipv6_del_addr,
> +
> + TP_PROTO(struct inet6_ifaddr *ifa),
> +
> + TP_ARGS(ifa)
> +);
> +
> +#endif /* _TRACE_EVENTS_IPV6_H */
> +
> +/* This part must be outside protection */
> +#include <trace/define_trace.h>
> diff --git a/net/core/net-traces.c b/net/core/net-traces.c
> index ba3c0120786c..b564a28852d1 100644
> --- a/net/core/net-traces.c
> +++ b/net/core/net-traces.c
> @@ -31,6 +31,8 @@
> #include <trace/events/napi.h>
> #include <trace/events/sock.h>
> #include <trace/events/udp.h>
> +#include <trace/events/ipv4.h>
> +#include <trace/events/ipv6.h>
>
> EXPORT_TRACEPOINT_SYMBOL_GPL(kfree_skb);
>
> diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
> index 214882e7d6de..aa6ba2ad93fd 100644
> --- a/net/ipv4/devinet.c
> +++ b/net/ipv4/devinet.c
> @@ -64,6 +64,7 @@
> #include <net/rtnetlink.h>
> #include <net/net_namespace.h>
> #include <net/addrconf.h>
> +#include <trace/events/ipv4.h>
>
> #include "fib_lookup.h"
>
> @@ -358,6 +359,7 @@ static void __inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
> inet_hash_remove(ifa);
> *ifap1 = ifa->ifa_next;
>
> + trace_ipv4_del_addr(ifa, in_dev);
> rtmsg_ifa(RTM_DELADDR, ifa, nlh, portid);
> blocking_notifier_call_chain(&inetaddr_chain,
> NETDEV_DOWN, ifa);
> @@ -395,6 +397,7 @@ static void __inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
> is valid, it will try to restore deleted routes... Grr.
> So that, this order is correct.
> */
> + trace_ipv4_del_addr(ifa1, in_dev);
> rtmsg_ifa(RTM_DELADDR, ifa1, nlh, portid);
> blocking_notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa1);
>
> @@ -476,6 +479,7 @@ static int __inet_insert_ifa(struct in_ifaddr *ifa, struct nlmsghdr *nlh,
> ifa->ifa_next = *ifap;
> *ifap = ifa;
>
> + trace_ipv4_add_addr(ifa, in_dev);
> inet_hash_insert(dev_net(in_dev->dev), ifa);
>
> cancel_delayed_work(&check_lifetime_work);
> diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
> index f7c8bbeb27b7..294cb618baf5 100644
> --- a/net/ipv6/addrconf.c
> +++ b/net/ipv6/addrconf.c
> @@ -90,6 +90,7 @@
> #include <linux/proc_fs.h>
> #include <linux/seq_file.h>
> #include <linux/export.h>
> +#include <trace/events/ipv6.h>
>
> /* Set to 3 to get tracing... */
> #define ACONF_DEBUG 2
> @@ -874,6 +875,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr,
> in6_dev_hold(idev);
> /* For caller */
> in6_ifa_hold(ifa);
> + trace_ipv6_add_addr(ifa);
>
> /* Add to big hash table */
> hash = inet6_addr_hash(addr);
> @@ -1658,8 +1660,10 @@ static void addrconf_dad_stop(struct inet6_ifaddr *ifp, int dad_failed)
> } else {
> spin_unlock_bh(&ifp->lock);
> }
> + trace_ipv6_del_addr(ifp);
> ipv6_del_addr(ifp);
> } else {
> + trace_ipv6_del_addr(ifp);
> ipv6_del_addr(ifp);
> }
> }
> --
> 1.9.3 (Apple Git-50)
>
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2014-12-22 17:29 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-12-18 15:10 [PATCH] tools lib traceevent: Add support for IP address formats David Ahern
2014-12-18 15:52 ` Arnaldo Carvalho de Melo
2014-12-18 15:59 ` David Ahern
2014-12-18 16:27 ` Steven Rostedt
2014-12-18 22:16 ` Arnaldo Carvalho de Melo
2014-12-18 22:50 ` David Ahern
2014-12-18 21:45 ` Valdis.Kletnieks
2014-12-18 22:13 ` David Ahern
2014-12-19 1:41 ` David Ahern
2014-12-22 17:01 ` Jiri Olsa
2014-12-22 17:10 ` David Ahern
2014-12-22 17:28 ` Jiri Olsa
-- strict thread matches above, loose matches on Subject: below --
2014-12-17 20:29 David Ahern
2014-12-18 4:26 ` Namhyung Kim
2014-12-18 4:32 ` David Ahern
2014-12-18 5:04 ` Namhyung Kim
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 NNTP newsgroup(s).