]> git.proxmox.com Git - mirror_frr.git/blob - tools/frr_babeltrace.py
doc: Add `show ipv6 rpf X:X::X:X` command to docs
[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()