Skip to content

Commit

Permalink
ip6: add tracing for ip6 nodes
Browse files Browse the repository at this point in the history
Implement tracing for ip6/icmp6/ndp nodes.

Signed-off-by: Christophe Fontaine <cfontain@redhat.com>
  • Loading branch information
christophefontaine committed Oct 11, 2024
1 parent d95a2aa commit eeae9af
Show file tree
Hide file tree
Showing 11 changed files with 148 additions and 0 deletions.
9 changes: 9 additions & 0 deletions modules/ip6/datapath/gr_ip6_datapath.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,13 @@ void ndp_update_nexthop(
const struct rte_ether_addr *mac
);

struct trace_ip6_data {
struct rte_ipv6_addr src;
struct rte_ipv6_addr dst;
uint8_t hop_limits;
uint8_t proto;
};

int format_ip6_data(void *data, char *buf, size_t len);

#endif
27 changes: 27 additions & 0 deletions modules/ip6/datapath/icmp6_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <gr_ip6_datapath.h>
#include <gr_log.h>
#include <gr_mbuf.h>
#include <gr_trace.h>

#include <rte_byteorder.h>
#include <rte_ether.h>
Expand All @@ -24,6 +25,26 @@ enum {
EDGE_COUNT,
};

struct trace_icmp6_data {
uint16_t type;
};

static int format_icmp6_data(void *data, char *buf, size_t len) {
struct trace_icmp6_data *t = data;
static const char *ICMP6_STR[UINT16_MAX] = {
[ICMP6_TYPE_ECHO_REQUEST] = "Echo Request",
[ICMP6_TYPE_ECHO_REPLY] = "Echo Reply",
[ICMP6_TYPE_NEIGH_SOLICIT] = "Neighbor Solicitation",
[ICMP6_TYPE_NEIGH_ADVERT] = "Neighbor Advertisement",
[ICMP6_TYPE_ROUTER_SOLICIT] = "Router Solicitation",
[ICMP6_TYPE_ROUTER_ADVERT] = "Router Advertisement",
};
if (ICMP6_STR[t->type])
return snprintf(buf, len, "%s", ICMP6_STR[t->type]);
else
return snprintf(buf, len, "type: %d", t->type);
}

static uint16_t
icmp6_input_process(struct rte_graph *graph, struct rte_node *node, void **objs, uint16_t nb_objs) {
struct ip6_local_mbuf_data *d;
Expand All @@ -37,6 +58,11 @@ icmp6_input_process(struct rte_graph *graph, struct rte_node *node, void **objs,
icmp6 = rte_pktmbuf_mtod(mbuf, struct icmp6 *);
d = ip6_local_mbuf_data(mbuf);

if (unlikely(gr_mbuf_trace_is_set(mbuf))) {
struct trace_icmp6_data *t = gr_trace_add(node, mbuf, sizeof(*t));
t->type = icmp6->type;
}

switch (icmp6->type) {
case ICMP6_TYPE_ECHO_REQUEST:
if (icmp6->code != 0) {
Expand Down Expand Up @@ -91,6 +117,7 @@ static struct rte_node_register icmp6_input_node = {
static struct gr_node_info icmp6_input_info = {
.node = &icmp6_input_node,
.register_callback = icmp6_input_register,
.ext_funcs.format_trace = format_icmp6_data,
};

GR_NODE_REGISTER(icmp6_input_info);
Expand Down
4 changes: 4 additions & 0 deletions modules/ip6/datapath/icmp6_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <gr_ip6_datapath.h>
#include <gr_log.h>
#include <gr_mbuf.h>
#include <gr_trace.h>

#include <rte_graph_worker.h>
#include <rte_ip.h>
Expand Down Expand Up @@ -61,6 +62,9 @@ static uint16_t icmp6_output_process(
o->input_iface = iface;
edge = OUTPUT;
next:
if (unlikely(gr_mbuf_trace_is_set(mbuf)))
gr_trace_add(node, mbuf, 0);

rte_node_enqueue_x1(graph, node, edge, mbuf);
}

Expand Down
22 changes: 22 additions & 0 deletions modules/ip6/datapath/ip6_error.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <gr_ip6_datapath.h>
#include <gr_log.h>
#include <gr_mbuf.h>
#include <gr_trace.h>

#include <rte_common.h>
#include <rte_graph_worker.h>
Expand All @@ -20,6 +21,20 @@ enum edges {
EDGE_COUNT,
};

struct trace_ip6_error_data {
icmp6_type_t icmp_type;
};

static int format_ip6_error_data(void *data, char *buf, size_t len) {
struct trace_ip6_error_data *d = data;
static const char *icmp_error[UINT16_MAX] = {
[ICMP6_ERR_DEST_UNREACH] = "Destination unreachable",
[ICMP6_ERR_TTL_EXCEEDED] = "TTL exceeded",
};

return snprintf(buf, len, "%s", icmp_error[d->icmp_type]);
}

static uint16_t
ip6_error_process(struct rte_graph *graph, struct rte_node *node, void **objs, uint16_t nb_objs) {
struct icmp6_err_dest_unreach *du;
Expand Down Expand Up @@ -71,6 +86,11 @@ ip6_error_process(struct rte_graph *graph, struct rte_node *node, void **objs, u
break;
}

if (unlikely(gr_mbuf_trace_is_set(mbuf))) {
struct trace_ip6_error_data *t = gr_trace_add(node, mbuf, sizeof(*t));
t->icmp_type = icmp_type;
}

icmp6 = (struct icmp6 *)rte_pktmbuf_prepend(mbuf, sizeof(*icmp6));
if (unlikely(icmp6 == NULL || ip == NULL)) {
edge = NO_HEADROOM;
Expand Down Expand Up @@ -138,10 +158,12 @@ static struct rte_node_register ttl_exceeded_node = {

static struct gr_node_info dest_unreach_info = {
.node = &dest_unreach_node,
.ext_funcs.format_trace = format_ip6_error_data,
};

static struct gr_node_info ttl_exceeded_info = {
.node = &ttl_exceeded_node,
.ext_funcs.format_trace = format_ip6_error_data,
};

GR_NODE_REGISTER(dest_unreach_info);
Expand Down
3 changes: 3 additions & 0 deletions modules/ip6/datapath/ip6_forward.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Copyright (c) 2024 Robin Jarry

#include <gr_graph.h>
#include <gr_trace.h>

#include <rte_fib6.h>
#include <rte_graph_worker.h>
Expand All @@ -23,6 +24,8 @@ ip6_forward_process(struct rte_graph *graph, struct rte_node *node, void **objs,
for (i = 0; i < nb_objs; i++) {
mbuf = objs[i];
ip = rte_pktmbuf_mtod(mbuf, struct rte_ipv6_hdr *);
if (unlikely(gr_mbuf_trace_is_set(mbuf)))
gr_trace_add(node, mbuf, 0);

if (ip->hop_limits <= 1) {
rte_node_enqueue_x1(graph, node, TTL_EXCEEDED, mbuf);
Expand Down
58 changes: 58 additions & 0 deletions modules/ip6/datapath/ip6_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <gr_ip6_control.h>
#include <gr_ip6_datapath.h>
#include <gr_log.h>
#include <gr_trace.h>

#include <rte_byteorder.h>
#include <rte_errno.h>
Expand All @@ -28,6 +29,55 @@ enum edges {
EDGE_COUNT,
};

int format_ip6_data(void *data, char *buf, size_t len) {
struct trace_ip6_data *t = data;
char src[INET6_ADDRSTRLEN];
char dst[INET6_ADDRSTRLEN];

static const char *protos[UINT8_MAX] = {
[0] = "IPv6 Hop-by-Hop",
[1] = "ICMP",
[2] = "IGMP",
[4] = "IP in IP",
[6] = "TCP",
[17] = "UDP",
[27] = "Reliable Data Protocol",
[41] = "IPv6 Encapsulation",
[43] = "IPv6 Routing Header",
[44] = "IPv6 Fragment Header",
[47] = "GRE",
[50] = "ESP",
[51] = "Authentication Header",
[58] = "IPv6 ICMP",
[59] = "IPv6 No Next Header",
[60] = "IPv6 Destination Options",
[89] = "OSPF",
[112] = "VRRP",
[132] = "SCTP",
[136] = "UDP Lite",
[137] = "MPLS In IP",
[145] = "NSH",
};

inet_ntop(AF_INET6, &t->src, src, sizeof(src));
inet_ntop(AF_INET6, &t->dst, dst, sizeof(dst));

if (protos[t->proto])
return snprintf(
buf,
len,
"%s -> %s next proto %s ttl %d",
src,
dst,
protos[t->proto],
t->hop_limits
);
else
return snprintf(
buf, len, "%s -> %s next proto %d ttl %d", src, dst, t->proto, t->hop_limits
);
}

static uint16_t
ip6_input_process(struct rte_graph *graph, struct rte_node *node, void **objs, uint16_t nb_objs) {
struct ip6_output_mbuf_data *d;
Expand Down Expand Up @@ -110,6 +160,13 @@ ip6_input_process(struct rte_graph *graph, struct rte_node *node, void **objs, u
edge = FORWARD;

next:
if (unlikely(gr_mbuf_trace_is_set(mbuf))) {
struct trace_ip6_data *t = gr_trace_add(node, mbuf, sizeof(*t));
t->src = ip->src_addr;
t->dst = ip->dst_addr;
t->proto = ip->proto;
t->hop_limits = ip->hop_limits;
}
// Store the resolved next hop for ip6_output to avoid a second route lookup.
d->nh = nh;
rte_node_enqueue_x1(graph, node, edge, mbuf);
Expand Down Expand Up @@ -143,6 +200,7 @@ static struct rte_node_register input_node = {
static struct gr_node_info info = {
.node = &input_node,
.register_callback = ip6_input_register,
.ext_funcs.format_trace = format_ip6_data,
};

GR_NODE_REGISTER(info);
Expand Down
4 changes: 4 additions & 0 deletions modules/ip6/datapath/ip6_local.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <gr_ip6_control.h>
#include <gr_ip6_datapath.h>
#include <gr_log.h>
#include <gr_trace.h>

#include <rte_graph_worker.h>
#include <rte_ip6.h>
Expand Down Expand Up @@ -81,6 +82,9 @@ static uint16_t ip6_input_local_process(
break;
}
next:
if (unlikely(gr_mbuf_trace_is_set(m)))
gr_trace_add(node, m, 0);

rte_node_enqueue_x1(graph, node, edge, m);
}

Expand Down
9 changes: 9 additions & 0 deletions modules/ip6/datapath/ip6_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <gr_ip6_datapath.h>
#include <gr_log.h>
#include <gr_mbuf.h>
#include <gr_trace.h>

#include <rte_byteorder.h>
#include <rte_ether.h>
Expand Down Expand Up @@ -150,6 +151,13 @@ ip6_output_process(struct rte_graph *graph, struct rte_node *node, void **objs,
eth_data->iface = iface;
sent++;
next:
if (unlikely(gr_mbuf_trace_is_set(mbuf))) {
struct trace_ip6_data *t = gr_trace_add(node, mbuf, sizeof(*t));
t->src = ip->src_addr;
t->dst = ip->dst_addr;
t->proto = ip->proto;
t->hop_limits = ip->hop_limits;
}
rte_node_enqueue_x1(graph, node, edge, mbuf);
}

Expand All @@ -170,6 +178,7 @@ static struct rte_node_register output_node = {

static struct gr_node_info info = {
.node = &output_node,
.ext_funcs.format_trace = format_ip6_data,
};

GR_NODE_REGISTER(info);
Expand Down
6 changes: 6 additions & 0 deletions modules/ip6/datapath/ndp_na_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <gr_ip6_datapath.h>
#include <gr_log.h>
#include <gr_mbuf.h>
#include <gr_trace.h>

#include <rte_byteorder.h>
#include <rte_ether.h>
Expand Down Expand Up @@ -135,9 +136,14 @@ static uint16_t ndp_na_input_process(
ASSERT_NDP(lladdr_found);

ndp_update_nexthop(graph, node, remote, iface, &lladdr);

if (unlikely(gr_mbuf_trace_is_set(mbuf)))
gr_trace_aggregate(mbuf);
rte_pktmbuf_free(mbuf);
continue;
next:
if (unlikely(gr_mbuf_trace_is_set(mbuf)))
gr_trace_add(node, mbuf, 0);
rte_node_enqueue_x1(graph, node, next, mbuf);
}

Expand Down
3 changes: 3 additions & 0 deletions modules/ip6/datapath/ndp_ns_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <gr_ip6_datapath.h>
#include <gr_log.h>
#include <gr_mbuf.h>
#include <gr_trace.h>

#include <rte_byteorder.h>
#include <rte_ether.h>
Expand Down Expand Up @@ -160,6 +161,8 @@ static uint16_t ndp_ns_input_process(

next = IP_OUTPUT;
next:
if (unlikely(gr_mbuf_trace_is_set(mbuf)))
gr_trace_add(node, mbuf, 0);
rte_node_enqueue_x1(graph, node, next, mbuf);
}

Expand Down
3 changes: 3 additions & 0 deletions modules/ip6/datapath/ndp_ns_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <gr_ip6_datapath.h>
#include <gr_log.h>
#include <gr_macro.h>
#include <gr_trace.h>

#include <rte_byteorder.h>
#include <rte_errno.h>
Expand Down Expand Up @@ -98,6 +99,8 @@ static uint16_t ndp_ns_output_process(
ip6_output_mbuf_data(mbuf)->nh = nh;
next = OUTPUT;
next:
if (unlikely(gr_mbuf_trace_is_set(mbuf)))
gr_trace_add(node, mbuf, 0);
rte_node_enqueue_x1(graph, node, next, mbuf);
}

Expand Down

0 comments on commit eeae9af

Please sign in to comment.