]> git.proxmox.com Git - mirror_frr.git/blob - tools/frr_babeltrace.py
bgpd: initial batch of evpn lttng tracepoints
[mirror_frr.git] / tools / frr_babeltrace.py
1 #!/usr/bin/env python3
2 '''
3 Usage: frr_babeltrace.py trace_path
4
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
8 that pretty printing.
9
10 Copyright (C) 2021 NVIDIA Corporation
11 Anuradha Karuppiah
12
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)
16 any later version.
17
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
21 more details.
22
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
26 '''
27
28 import ipaddress
29 import socket
30 import sys
31
32 import babeltrace
33
34 ########################### common parsers - start ############################
35 def print_ip_addr(field_val):
36 '''
37 pretty print "struct ipaddr"
38 '''
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)))
42
43 if field_val[0] == socket.AF_INET6:
44 tmp = ''.join('%02x' % fb for fb in field_val[4:])
45 addr = []
46 while tmp:
47 addr.append(tmp[:4])
48 tmp = tmp[4:]
49 addr = ':'.join(addr)
50 return str(ipaddress.IPv6Address(addr))
51
52 if not field_val[0]:
53 return ''
54
55 return field_val
56
57
58 def print_mac(field_val):
59 '''
60 pretty print "u8 mac[6]"
61 '''
62 return ':'.join('%02x' % fb for fb in field_val)
63
64 def print_net_ipv4_addr(field_val):
65 '''
66 pretty print ctf_integer_network ipv4
67 '''
68 return str(ipaddress.IPv4Address(field_val))
69
70 def print_esi(field_val):
71 '''
72 pretty print ethernet segment id, esi_t
73 '''
74 return ':'.join('%02x' % fb for fb in field_val)
75
76 def get_field_list(event):
77 '''
78 only fetch fields added via the TP, skip metadata etc.
79 '''
80 return event.field_list_with_scope(babeltrace.CTFScope.EVENT_FIELDS)
81
82 def parse_event(event, field_parsers):
83 '''
84 Wild card event parser; doesn't make things any prettier
85 '''
86 field_list = get_field_list(event)
87 field_info = {}
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))
92 else:
93 field_info[field] = event.get(field)
94 print(event.name, field_info)
95 ############################ common parsers - end #############################
96
97 ############################ evpn parsers - start #############################
98 def parse_frr_bgp_evpn_mac_ip_zsend(event):
99 '''
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))
107 '''
108 field_parsers = {'ip': print_ip_addr,
109 'mac': print_mac,
110 'esi': print_esi,
111 'vtep': print_net_ipv4_addr}
112
113 parse_event(event, field_parsers)
114
115 def parse_frr_bgp_evpn_bum_vtep_zsend(event):
116 '''
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)
120
121 '''
122 field_parsers = {'vtep': print_net_ipv4_addr}
123
124 parse_event(event, field_parsers)
125
126 def parse_frr_bgp_evpn_mh_nh_rmac_send(event):
127 '''
128 bgp evpn nh-rmac parser; raw format -
129 ctf_array(unsigned char, rmac, &nh->rmac, sizeof(struct ethaddr))
130 '''
131 field_parsers = {'rmac': print_mac}
132
133 parse_event(event, field_parsers)
134
135 ############################ evpn parsers - end #############################
136
137 def main():
138 '''
139 FRR lttng trace output parser; babel trace plugin
140 '''
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}
147
148 # get the trace path from the first command line argument
149 trace_path = sys.argv[1]
150
151 # grab events
152 trace_collection = babeltrace.TraceCollection()
153 trace_collection.add_traces_recursive(trace_path, 'ctf')
154
155 for event in trace_collection.events:
156 if event.name in event_parsers:
157 event_parser = event_parsers.get(event.name)
158 event_parser(event)
159 else:
160 parse_event(event, {})
161
162 if __name__ == '__main__':
163 main()