3 Usage: frr_babeltrace.py trace_path
5 FRR pushes data into lttng tracepoints in the least overhead way possible
6 i.e. as binary-data/crf_arrays. These traces need to be converted into pretty
7 strings for easy greping etc. This script is a babeltrace python plugin for
10 Copyright (C) 2021 NVIDIA Corporation
13 This program is free software; you can redistribute it and/or modify it
14 under the terms of the GNU General Public License as published by the Free
15 Software Foundation; either version 2 of the License, or (at your option)
18 This program is distributed in the hope that it will be useful, but WITHOUT
19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
23 You should have received a copy of the GNU General Public License along
24 with this program; see the file COPYING; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
34 ########################### common parsers - start ############################
35 def print_ip_addr(field_val
):
37 pretty print "struct ipaddr"
39 if field_val
[0] == socket
.AF_INET
:
40 addr
= [str(fv
) for fv
in field_val
[4:8]]
41 return str(ipaddress
.IPv4Address('.'.join(addr
)))
43 if field_val
[0] == socket
.AF_INET6
:
44 tmp
= ''.join('%02x' % fb
for fb
in field_val
[4:])
50 return str(ipaddress
.IPv6Address(addr
))
58 def print_mac(field_val
):
60 pretty print "u8 mac[6]"
62 return ':'.join('%02x' % fb
for fb
in field_val
)
64 def print_net_ipv4_addr(field_val
):
66 pretty print ctf_integer_network ipv4
68 return str(ipaddress
.IPv4Address(field_val
))
70 def print_esi(field_val
):
72 pretty print ethernet segment id, esi_t
74 return ':'.join('%02x' % fb
for fb
in field_val
)
76 def get_field_list(event
):
78 only fetch fields added via the TP, skip metadata etc.
80 return event
.field_list_with_scope(babeltrace
.CTFScope
.EVENT_FIELDS
)
82 def parse_event(event
, field_parsers
):
84 Wild card event parser; doesn't make things any prettier
86 field_list
= get_field_list(event
)
88 for field
in field_list
:
89 if field
in field_parsers
:
90 field_parser
= field_parsers
.get(field
)
91 field_info
[field
] = field_parser(event
.get(field
))
93 field_info
[field
] = event
.get(field
)
94 print(event
.name
, field_info
)
95 ############################ common parsers - end #############################
97 ############################ evpn parsers - start #############################
98 def parse_frr_bgp_evpn_mac_ip_zsend(event
):
100 bgp evpn mac-ip parser; raw format -
101 ctf_array(unsigned char, mac, &pfx->prefix.macip_addr.mac,
102 sizeof(struct ethaddr))
103 ctf_array(unsigned char, ip, &pfx->prefix.macip_addr.ip,
104 sizeof(struct ipaddr))
105 ctf_integer_network_hex(unsigned int, vtep, vtep.s_addr)
106 ctf_array(unsigned char, esi, esi, sizeof(esi_t))
108 field_parsers
= {'ip': print_ip_addr
,
111 'vtep': print_net_ipv4_addr
}
113 parse_event(event
, field_parsers
)
115 def parse_frr_bgp_evpn_bum_vtep_zsend(event
):
117 bgp evpn bum-vtep parser; raw format -
118 ctf_integer_network_hex(unsigned int, vtep,
119 pfx->prefix.imet_addr.ip.ipaddr_v4.s_addr)
122 field_parsers
= {'vtep': print_net_ipv4_addr
}
124 parse_event(event
, field_parsers
)
126 def parse_frr_bgp_evpn_mh_nh_rmac_send(event
):
128 bgp evpn nh-rmac parser; raw format -
129 ctf_array(unsigned char, rmac, &nh->rmac, sizeof(struct ethaddr))
131 field_parsers
= {'rmac': print_mac
}
133 parse_event(event
, field_parsers
)
135 ############################ evpn parsers - end #############################
139 FRR lttng trace output parser; babel trace plugin
141 event_parsers
= {'frr_bgp:evpn_mac_ip_zsend':
142 parse_frr_bgp_evpn_mac_ip_zsend
,
143 'frr_bgp:evpn_bum_vtep_zsend':
144 parse_frr_bgp_evpn_bum_vtep_zsend
,
145 'frr_bgp:evpn_mh_nh_rmac_zsend':
146 parse_frr_bgp_evpn_mh_nh_rmac_send
}
148 # get the trace path from the first command line argument
149 trace_path
= sys
.argv
[1]
152 trace_collection
= babeltrace
.TraceCollection()
153 trace_collection
.add_traces_recursive(trace_path
, 'ctf')
155 for event
in trace_collection
.events
:
156 if event
.name
in event_parsers
:
157 event_parser
= event_parsers
.get(event
.name
)
160 parse_event(event
, {})
162 if __name__
== '__main__':