]> git.proxmox.com Git - mirror_frr.git/blob - tools/frr_babeltrace.py
bgpd: lttng tracepoint for local events received from zebra
[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 def parse_frr_bgp_evpn_mh_local_es_add_zrecv(event):
136 '''
137 bgp evpn local-es parser; raw format -
138 ctf_array(unsigned char, esi, esi, sizeof(esi_t))
139 ctf_integer_network_hex(unsigned int, vtep, vtep.s_addr)
140 '''
141 field_parsers = {'esi': print_esi,
142 'vtep': print_net_ipv4_addr}
143
144 parse_event(event, field_parsers)
145
146 def parse_frr_bgp_evpn_mh_local_es_del_zrecv(event):
147 '''
148 bgp evpn local-es parser; raw format -
149 ctf_array(unsigned char, esi, esi, sizeof(esi_t))
150 '''
151 field_parsers = {'esi': print_esi}
152
153 parse_event(event, field_parsers)
154
155 def parse_frr_bgp_evpn_mh_local_es_evi_add_zrecv(event):
156 '''
157 bgp evpn local-es-evi parser; raw format -
158 ctf_array(unsigned char, esi, esi, sizeof(esi_t))
159 '''
160 field_parsers = {'esi': print_esi}
161
162 parse_event(event, field_parsers)
163
164 def parse_frr_bgp_evpn_mh_local_es_evi_del_zrecv(event):
165 '''
166 bgp evpn local-es-evi parser; raw format -
167 ctf_array(unsigned char, esi, esi, sizeof(esi_t))
168 '''
169 field_parsers = {'esi': print_esi}
170
171 parse_event(event, field_parsers)
172
173 def parse_frr_bgp_evpn_local_vni_add_zrecv(event):
174 '''
175 bgp evpn local-vni parser; raw format -
176 ctf_integer_network_hex(unsigned int, vtep, vtep.s_addr)
177 ctf_integer_network_hex(unsigned int, mc_grp, mc_grp.s_addr)
178 '''
179 field_parsers = {'vtep': print_net_ipv4_addr,
180 'mc_grp': print_net_ipv4_addr}
181
182 parse_event(event, field_parsers)
183
184 def parse_frr_bgp_evpn_local_l3vni_add_zrecv(event):
185 '''
186 bgp evpn local-l3vni parser; raw format -
187 ctf_integer_network_hex(unsigned int, vtep, vtep.s_addr)
188 ctf_array(unsigned char, svi_rmac, svi_rmac, sizeof(struct ethaddr))
189 ctf_array(unsigned char, vrr_rmac, vrr_rmac, sizeof(struct ethaddr))
190 '''
191 field_parsers = {'vtep': print_net_ipv4_addr,
192 'svi_rmac': print_mac,
193 'vrr_rmac': print_mac}
194
195 parse_event(event, field_parsers)
196
197 def parse_frr_bgp_evpn_local_macip_add_zrecv(event):
198 '''
199 bgp evpn local-mac-ip parser; raw format -
200 ctf_array(unsigned char, ip, ip, sizeof(struct ipaddr))
201 ctf_array(unsigned char, mac, mac, sizeof(struct ethaddr))
202 ctf_array(unsigned char, esi, esi, sizeof(esi_t))
203 '''
204 field_parsers = {'ip': print_ip_addr,
205 'mac': print_mac,
206 'esi': print_esi}
207
208 parse_event(event, field_parsers)
209
210 def parse_frr_bgp_evpn_local_macip_del_zrecv(event):
211 '''
212 bgp evpn local-mac-ip del parser; raw format -
213 ctf_array(unsigned char, ip, ip, sizeof(struct ipaddr))
214 ctf_array(unsigned char, mac, mac, sizeof(struct ethaddr))
215 '''
216 field_parsers = {'ip': print_ip_addr,
217 'mac': print_mac}
218
219 parse_event(event, field_parsers)
220
221 ############################ evpn parsers - end *#############################
222
223 def main():
224 '''
225 FRR lttng trace output parser; babel trace plugin
226 '''
227 event_parsers = {'frr_bgp:evpn_mac_ip_zsend':
228 parse_frr_bgp_evpn_mac_ip_zsend,
229 'frr_bgp:evpn_bum_vtep_zsend':
230 parse_frr_bgp_evpn_bum_vtep_zsend,
231 'frr_bgp:evpn_mh_nh_rmac_zsend':
232 parse_frr_bgp_evpn_mh_nh_rmac_send,
233 'frr_bgp:evpn_mh_local_es_add_zrecv':
234 parse_frr_bgp_evpn_mh_local_es_add_zrecv,
235 'frr_bgp:evpn_mh_local_es_del_zrecv':
236 parse_frr_bgp_evpn_mh_local_es_del_zrecv,
237 'frr_bgp:evpn_mh_local_es_evi_add_zrecv':
238 parse_frr_bgp_evpn_mh_local_es_evi_add_zrecv,
239 'frr_bgp:evpn_mh_local_es_evi_del_zrecv':
240 parse_frr_bgp_evpn_mh_local_es_evi_del_zrecv,
241 'frr_bgp:evpn_local_vni_add_zrecv':
242 parse_frr_bgp_evpn_local_vni_add_zrecv,
243 'frr_bgp:evpn_local_l3vni_add_zrecv':
244 parse_frr_bgp_evpn_local_l3vni_add_zrecv,
245 'frr_bgp:evpn_local_macip_add_zrecv':
246 parse_frr_bgp_evpn_local_macip_add_zrecv,
247 'frr_bgp:evpn_local_macip_del_zrecv':
248 parse_frr_bgp_evpn_local_macip_del_zrecv,
249 }
250
251 # get the trace path from the first command line argument
252 trace_path = sys.argv[1]
253
254 # grab events
255 trace_collection = babeltrace.TraceCollection()
256 trace_collection.add_traces_recursive(trace_path, 'ctf')
257
258 for event in trace_collection.events:
259 if event.name in event_parsers:
260 event_parser = event_parsers.get(event.name)
261 event_parser(event)
262 else:
263 parse_event(event, {})
264
265 if __name__ == '__main__':
266 main()