2 """ Please make sure you read the README COMPLETELY BEFORE reading anything below.
3 It is very critical that you read coding guidelines in Section E in README file.
13 def IterateProcChannels(proc
):
14 """ Iterate through all channels in the given process
17 proc - the proc object
18 returns: nothing, this is meant to be used as a generator function
19 kc - yields each kern_channel in the process
22 proc_filedesc
= proc
.p_fd
23 proc_lastfile
= unsigned(proc_filedesc
.fd_lastfile
)
24 proc_ofiles
= proc_filedesc
.fd_ofiles
27 while count
<= proc_lastfile
:
28 if unsigned(proc_ofiles
[count
]) != 0:
29 proc_fd_fglob
= proc_ofiles
[count
].fp_glob
30 if (unsigned(proc_fd_fglob
.fg_ops
.fo_type
) == 10):
31 yield Cast(proc_fd_fglob
.fg_data
, 'kern_channel *')
34 def IterateKernChannelRings(kc
, kind
):
35 """ Iterate through all rings on a given channel
44 rings
= kc
.ch_na
.na_rx_rings
46 rings
= kc
.ch_na
.na_tx_rings
48 rings
= kc
.ch_na
.na_alloc_rings
50 rings
= kc
.ch_na
.na_free_rings
52 # note that ch_last is actually one greater than the last
53 # as per the comment in ch_connect
54 for i
in xrange(kc
.ch_first
[kind
], kc
.ch_last
[kind
]):
55 yield addressof(rings
[i
])
57 # Note this is broken if you have type summaries enabled
58 # because we are summarizing the pointer to the structure
59 # and not the structure itself. Unfortunately, that's
60 # the pattern used elsewhere.
61 # Trying to actually use the type summary will blow up
62 # because it has a linked list pointer to itself
64 @lldb_type_summary(['kern_channel_t', 'kern_channel *'])
65 @header('{:<20s} {:<36s}'.format('kern_channel', 'uuid'))
66 def GetKernChannelSummary(kc
):
67 """ Summarizes a kern_channel and related information
69 returns: str - summary of kern_channel
72 format_string
= '{o: <#020x} {u: <36s}'
73 return format_string
.format(
75 u
=GetUUIDSummary(kc
.ch_info
.cinfo_ch_id
))
77 @lldb_type_summary(['__kern_channel_ring *'])
78 @header('{:<20s} {:<65s} {:>10s} | {:<5s} {:<5s} | {:<5s} {:<5s} | {:<5s} {:<5s}'.format(
79 'kernchannelring', 'name', 'flags', 'kh', 'kt', 'rh', 'rt', 'h', 't'))
80 def GetKernChannelRingSummary(kring
):
81 """ Summarizes a __kern_channel_ring and related information
83 returns: str - summary of kern_channel_ring
86 format_string
= '{o: <#020x} "{name: <63s}" {flags: >#010x} | {kh: <5d} {kt: <5d} | {rh: <5d} {rt: <5d} | {h: <5d} {t: <5d}'
87 return format_string
.format(
90 flags
=kring
.ckr_flags
,
95 h
=kring
.ckr_ring
.ring_head
,
96 t
=kring
.ckr_ring
.ring_tail
)
98 @lldb_command('showprocchannels')
99 def ShowProcChannels(cmd_args
=None):
100 """ Show the skywalk channels for a given process.
102 usage: showprocchannels <proc_t>
106 raise ArgumentError('missing struct proc * argument')
108 proc
= kern
.GetValueFromAddress(cmd_args
[0], 'proc_t')
110 print GetKernChannelSummary
.header
111 for kc
in IterateProcChannels(proc
):
112 print GetKernChannelSummary(kc
)
114 @lldb_command('showchannelrings')
115 def ShowChannelRings(cmd_args
=None):
116 """ Show the skywalk rings for a given channel.
118 usage: showchannelrings <struct kern_channel *>
122 raise ArgumentError('missing struct kern_channel * argument')
124 kc
= kern
.GetValueFromAddress(cmd_args
[0], 'kern_channel *')
127 print GetKernChannelRingSummary
.header
128 for ring
in IterateKernChannelRings(kc
, 0) :
129 print GetKernChannelRingSummary(ring
)
132 print GetKernChannelRingSummary
.header
133 for ring
in IterateKernChannelRings(kc
, 1) :
134 print GetKernChannelRingSummary(ring
)
137 print GetKernChannelRingSummary
.header
138 for ring
in IterateKernChannelRings(kc
, 2) :
139 print GetKernChannelRingSummary(ring
)
142 print GetKernChannelRingSummary
.header
143 for ring
in IterateKernChannelRings(kc
, 3) :
144 print GetKernChannelRingSummary(ring
)
146 def SkmemCacheModeAsString(mode
) :
148 SKM_MODE_NOCACHE
= 0x1
151 if (mode
& SKM_MODE_NOCACHE
) :
155 if (mode
& SKM_MODE_AUDIT
) :
162 @lldb_command('showskmemcache')
163 def ShowSkmemCache(cmd_args
=None) :
164 """ Show the global list of skmem caches
167 format_string
= "{:<4s} {:<18s} {:<4s} {:<4s} {:<4s} {:<4s} {:<4s} {:<4s} {:<4s} {:<4s} {:<4s} {:<s}"
168 print format_string
.format("", "ADDR", "BUFI", "BUFM", "RESC", "SLCR", "SLDE", "SLAL", "SLFR", "DECO", "MODE", "NAME")
171 skmhead
= kern
.globals.skmem_cache_head
173 for skm
in IterateTAILQ_HEAD(skmhead
, "skm_link") :
174 format_string
= "{:>4d}: 0x{:<08x} {:<4d} {:<4d} {:<4d} {:<4d} {:<4d} {:<4d} {:<4d} {:<4d} {:<4s} \"{:<s}\""
175 print format_string
.format(i
, skm
, skm
.skm_bufinuse
, skm
.skm_bufmax
, skm
.skm_rescale
, skm
.skm_sl_create
, skm
.skm_sl_destroy
, skm
.skm_sl_alloc
, skm
.skm_sl_free
, skm
.skm_depot_contention
, SkmemCacheModeAsString(skm
.skm_mode
), str(skm
.skm_name
))
178 @lldb_command('showskmemslab')
179 def ShowBufCtl(cmd_args
=None) :
180 """ Show slabs and bufctls of a skmem cache
183 if (cmd_args
== None or len(cmd_args
) == 0) :
184 print "Missing argument 0 (skmem_cache address)."
187 skm
= kern
.GetValueFromAddress(cmd_args
[0], 'skmem_cache *')
189 for slab
in IterateTAILQ_HEAD(skm
.skm_sl_partial
, "sl_link") :
190 format_string
= "{:<08x} {:<4d} 0x{:<08x} 0x{:08x}"
191 print format_string
.format(slab
, slab
.sl_refcnt
, slab
.sl_base
, slab
.sl_basem
)
193 for slab
in IterateTAILQ_HEAD(skm
.skm_sl_empty
, "sl_link") :
194 format_string
= "{:<08x} {:<4d} 0x{:<08x} 0x{:08x}"
195 print format_string
.format(slab
, slab
.sl_refcnt
, slab
.sl_base
, slab
.sl_basem
)
197 def SkmemArenaTypeAsString(type) :
199 SKMEM_ARENA_TYPE_NEXUS
= 0
200 SKMEM_ARENA_TYPE_NECP
= 1
201 SKMEM_ARENA_TYPE_SYSTEM
= 2
203 if (type == SKMEM_ARENA_TYPE_NEXUS
) :
204 out_string
+= "NEXUS"
205 elif (type == SKMEM_ARENA_TYPE_NECP
) :
207 elif (type == SKMEM_ARENA_TYPE_SYSTEM
) :
208 out_string
+= "SYSTEM"
214 @lldb_command('showskmemarena')
215 def ShowSkmemArena(cmd_args
=None) :
216 """ Show the global list of skmem arenas
220 arhead
= kern
.globals.skmem_arena_head
222 for ar
in IterateTAILQ_HEAD(arhead
, "ar_link") :
223 format_string
= "{:>4d}: 0x{:<08x} {:<6s} {:>5d} KB \"{:<s}\""
224 print format_string
.format(i
, ar
, SkmemArenaTypeAsString(ar
.ar_type
), ar
.ar_mapsize
>> 10, str(ar
.ar_name
))
227 @lldb_command('showskmemregion')
228 def ShowSkmemRegion(cmd_args
=None) :
229 """ Show the global list of skmem regions
233 skrhead
= kern
.globals.skmem_region_head
235 for skr
in IterateTAILQ_HEAD(skrhead
, "skr_link") :
236 format_string
= "{:>4d}: 0x{:<08x} \"{:<s}\""
237 print format_string
.format(i
, skr
, str(skr
.skr_name
))
240 @lldb_command('showchannelupphash')
241 def ShowChannelUppHash(cmd_args
=None) :
242 """ Show channel user packet pool hash chain
245 if (cmd_args
== None or len(cmd_args
) == 0) :
246 print "Missing argument 0 (skmem_cache address)."
249 ch
= kern
.GetValueFromAddress(cmd_args
[0], 'kern_channel *')
250 KERN_CHANNEL_UPP_HTBL_SIZE
= 256
252 for i
in range(KERN_CHANNEL_UPP_HTBL_SIZE
) :
253 bkt
= addressof(ch
.ch_upp_hash_table
[i
])
254 format_string
= "{:>4d} 0x{:<08x}"
255 print format_string
.format(i
, bkt
)
256 for kqum
in IterateListEntry(bkt
.upp_head
, 'struct __kern_quantum *',
257 'qum_upp_link', list_prefix
='s') :
258 format_string
= "0x{:<08x}"
259 print format_string
.format(kqum
)
261 @lldb_type_summary(['struct ns *'])
262 @header('{:<20s} {:<5s} {:<48s} {:<4s}'.format('ns', 'proto', 'addr', 'nreservations'))
263 def GetStructNsSummary(ns
):
264 """ Summarizes a struct ns from the netns
266 returns: str - summary of struct ns
269 if (ns
.ns_proto
== IPPROTO_TCP
):
271 elif (ns
.ns_proto
== IPPROTO_UDP
):
274 proto
= str(ns
.ns_proto
)
276 if (ns
.ns_addr_len
== sizeof('struct in_addr')):
277 addr
= GetInAddrAsString(addressof(ns
.ns_inaddr
))
278 elif (ns
.ns_addr_len
== sizeof('struct in6_addr')):
279 addr
= GetIn6AddrAsString(ns
.ns_in6addr
.__u6_addr
.__u6_addr
8)
281 addr
= str(ns_addr
) + " bad len {:u}".format(ns
.ns_addr_len
)
283 format_string
= '{o:#020x} {p:<5s} {a:<48s} {n:<4d}'
285 """ show ports and refs, one per line
287 ports_string
= "ports & refs\n"
288 for f
in IterateRBTreeEntry(ns
.ns_reservations
, 'struct ns_reservation *', 'nsr_link'):
289 ports_string
+= "\t%u" % f
.nsr_port
290 ports_string
+= "\tlisten %d\tskywalk %d\tbsd %d\tpf %d\n" % (f
.nsr_refs
[0], f
.nsr_refs
[1], f
.nsr_refs
[2], f
.nsr_refs
[3])
291 """ show just the ports, not refs
293 ports_string = "\nports:\t"
294 for f in IterateRBTreeEntry(ns.ns_reservations, 'struct ns_reservation *', 'nsr_link'):
295 if (len(ports_string)-offs > 70):
296 ports_string += "\n\t"
297 offs = len(ports_string)
298 ports_string += " %u" % f.nsr_port
301 return format_string
.format(
305 n
=ns
.ns_n_reservations
) + ports_string
307 @lldb_command('shownetns')
308 def ShowNetNS(cmd_args
=None):
309 """ Show the netns table
311 print"\nnetns_namespaces:"
312 print GetStructNsSummary
.header
314 namespaces
= kern
.globals.netns_namespaces
315 for ns
in IterateRBTreeEntry(namespaces
, 'struct ns *', 'ns_link'):
316 print GetStructNsSummary(ns
)
318 print "\nwild: (these should be duplicated above)"
319 print GetStructNsSummary
.header
321 print GetStructNsSummary(kern
.globals.netns_global_wild
[i
])
324 print GetStructNsSummary
.header
326 print GetStructNsSummary(kern
.globals.netns_global_non_wild
[i
])
329 @lldb_type_summary(['struct ns_token *'])
330 @header('{:<20s} {:<5s} {:<48s} {:<12s} {:<8s} {:<38s} {:<38s} {:<12s}'.format('nt', 'proto', 'addr', 'port', 'owner', 'ifp', 'parent', 'flags'))
331 def GetNsTokenSummary(nt
):
332 """ Summarizes a struct ns from the netns
334 returns: str - summary of struct ns
337 if (nt
.nt_proto
== IPPROTO_TCP
):
339 elif (nt
.nt_proto
== IPPROTO_UDP
):
342 proto
= str(nt
.nt_proto
)
344 if (nt
.nt_addr_len
== sizeof('struct in_addr')):
345 addr
= GetInAddrAsString(addressof(nt
.nt_inaddr
))
346 elif (nt
.nt_addr_len
== sizeof('struct in6_addr')):
347 addr
= GetIn6AddrAsString(nt
.nt_in6addr
.__u6_addr
.__u6_addr
8)
349 addr
= str(nt_addr
) + " bad len {:u}".format(nt
.nt_addr_len
)
351 format_string
= '{o:#020x} {p:<5s} {a:<48s} {pt:<12s} {wn:<8s} {ifp:38s} {pa:38s} {f:#012x}'
353 ports
= "%u" % nt
.nt_port
355 ifp
= "(struct ifnet *)" + hex(nt
.nt_ifp
)
357 if ((nt
.nt_flags
& 0x7) == 0x00):
359 parent
= "(void *)" + hex(nt
.nt_parent
)
360 elif ((nt
.nt_flags
& 0x7) == 0x01):
362 parent
= "(struct flow_entry *)" + hex(nt
.nt_parent_skywalk
)
363 elif ((nt
.nt_flags
& 0x7) == 0x02): # XXX xnudefines?
365 parent
= "(struct inpcb *)" + hex(nt
.nt_parent_bsd
)
366 elif ((nt
.nt_flags
& 0x7) == 0x03): # XXX xnudefines?
368 parent
= "(void *)" + hex(nt
.nt_parent
)
370 return format_string
.format(
380 @lldb_command("showallnetnstokens")
381 def ShowAllNetNSTokens(cmd_args
=None):
382 """ show all netns tokens
385 tokenhead
= kern
.globals.netns_all_tokens
386 print GetNsTokenSummary
.header
387 for nt
in IterateListEntry(tokenhead
, 'struct ns_token *', 'nt_all_link', list_prefix
='s'):
388 print GetNsTokenSummary(nt
)
390 @lldb_command("shownetnstokens")
391 def ShowNetNSTokens(cmd_args
=None):
392 """ show netns tokens attached to an ifp
393 with no args, shows unbound tokens
396 if (cmd_args
== None or len(cmd_args
) == 0):
397 print "No ifp argument provided, showing unbound tokens"
398 tokenhead
= kern
.globals.netns_unbound_tokens
399 elif len(cmd_args
) > 0:
400 ifp
= kern
.GetValueFromAddress(cmd_args
[0], 'ifnet *')
401 print "Showing tokens for ifp %r" % ifp
402 tokenhead
= ifp
.if_netns_tokens
404 print "Missing ifp argument 0 in shownetnstokens"
408 print GetNsTokenSummary
.header
409 for nt
in IterateListEntry(tokenhead
, 'struct ns_token *', 'nt_ifp_link', list_prefix
='s'):
410 print GetNsTokenSummary(nt
)
412 def IterateSTAILQ_HEAD(headval
, element_name
):
413 iter_val
= headval
.stqh_first
414 while unsigned(iter_val
) != 0 :
416 iter_val
= iter_val
.__getattr
__(element_name
).stqe_next
419 @lldb_command("shownexuschannels")
420 def ShowNexusChannels(cmd_args
=None):
421 """ show nexus channels
423 if (cmd_args
== None or len(cmd_args
) == 0):
424 print "Missing argument 0 (kern_nexus address)."
427 nx
= kern
.GetValueFromAddress(cmd_args
[0], 'kern_nexus *')
430 format_string
= "{:>4s} {:<18s} {:>4s} {:<7s} {:<7s} {:<18s} {:<18s} {:<18s} {:>8s} {:6s} {:<18s} {:>4s} {:s}"
431 print format_string
.format("", "addr", "refs", "txrings", "rxrings", "arena", "ioskmap", "mapaddr", "mapsize", "maprdr", "na", "fd", "process")
433 for ch
in IterateSTAILQ_HEAD(nx
.nx_ch_head
, "ch_link"):
434 format_string
= "{:>4d}: 0x{:<08x} {:>4d} [{:2d},{:2d}] [{:2d},{:2d}] 0x{:<08x} 0x{:<08x} 0x{:<16x} {:>8d} {:>6d} 0x{:<08x} {:>4d} {:s}({:d})"
435 print format_string
.format(i
, ch
, ch
.ch_refcnt
, ch
.ch_first
[0], ch
.ch_last
[0], ch
.ch_first
[1], ch
.ch_last
[1], ch
.ch_mmap
.ami_arena
, ch
.ch_mmap
.ami_mapref
, ch
.ch_mmap
.ami_mapaddr
, ch
.ch_mmap
.ami_mapsize
, ch
.ch_mmap
.ami_redirect
, ch
.ch_na
, ch
.ch_fd
, ch
.ch_name
, ch
.ch_pid
)
438 for ch
in IterateSTAILQ_HEAD(nx
.nx_ch_nonxref_head
, "ch_link"):
439 format_string
= "{:>4d}: 0x{:<08x} {:>4d} [{:2d},{:2d}] [{:2d},{:2d}] 0x{:<08x} 0x{:<08x} 0x{:<16x} {:>8d} {:>6d} 0x{:<08x} {:>4d} {:s}({:d})"
440 print format_string
.format(i
, ch
, ch
.ch_refcnt
, ch
.ch_first
[0], ch
.ch_last
[0], ch
.ch_first
[1], ch
.ch_last
[1], ch
.ch_mmap
.ami_arena
, ch
.ch_mmap
.ami_mapref
, ch
.ch_mmap
.ami_mapaddr
, ch
.ch_mmap
.ami_mapsize
, ch
.ch_mmap
.ami_redirect
, ch
.ch_na
, ch
.ch_fd
, ch
.ch_name
, ch
.ch_pid
)
443 def IterateProcNECP(proc
):
444 """ Iterate through all NECP descriptors in the given process
447 proc - the proc object
448 returns: nothing, this is meant to be used as a generator function
449 necp - yields each necp_fd_data in the process
452 proc_filedesc
= proc
.p_fd
453 proc_lastfile
= unsigned(proc_filedesc
.fd_lastfile
)
454 proc_ofiles
= proc_filedesc
.fd_ofiles
457 while count
<= proc_lastfile
:
458 if unsigned(proc_ofiles
[count
]) != 0:
459 proc_fd_fglob
= proc_ofiles
[count
].fp_glob
460 if (unsigned(proc_fd_fglob
.fg_ops
.fo_type
) == 9):
461 yield Cast(proc_fd_fglob
.fg_data
, 'necp_fd_data *')
464 def GetNECPClientBitFields(necp
):
465 """ Return the bit fields in necp_client as string
467 returns: str - string representation of necp_client bit fields
470 bitfields_string
= ''
471 if necp
.result_read
!= 0:
472 bitfields_string
+= 'r'
474 bitfields_string
+= '-'
475 if necp
.allow_multiple_flows
!= 0:
476 bitfields_string
+= 'm'
478 bitfields_string
+= '-'
479 if necp
.background
!= 0:
480 bitfields_string
+= 'b'
482 bitfields_string
+= '-'
483 if necp
.background_update
!= 0:
484 bitfields_string
+= 'B'
486 bitfields_string
+= '-'
487 if necp
.platform_binary
!= 0:
488 bitfields_string
+= 'p'
490 bitfields_string
+= '-'
492 return bitfields_string
494 def GetNECPFlowBitFields(flow_registration
):
495 """ Return the bit fields in necp_client_flow_registration as string
497 returns: str - string representation of necp_client_flow_registration bit fields
500 bitfields_string
= ''
501 if flow_registration
.flow_result_read
!= 0:
502 bitfields_string
+= 'r'
504 bitfields_string
+= '-'
505 if flow_registration
.defunct
!= 0:
506 bitfields_string
+= 'd'
508 bitfields_string
+= '-'
510 return bitfields_string
512 @lldb_type_summary(['necp_fd_data *'])
513 @header('{:<20s} {:<8s}'.format('necp_fd_data', "flags"))
514 def GetNECPSummary(necp
):
515 """ Summarizes a necp_fd_data and related information
517 returns: str - summary of necp_fd_data
520 format_string
= '{o: <#020x} {u:<#08x}'
522 stats_arenas_string
= "\n\n\t%-18s %-39s %-4s %-10s\n" % ("stats_arenas", "mmap", "refs", "flags")
523 for sa
in IterateListEntry(necp
.stats_arena_list
, 'struct necp_arena_info *', 'nai_chain'):
524 stats_arenas_string
+= "\t0x%016x " % sa
525 stats_arenas_string
+= "[0x%016x-0x%016x) " % (sa
.nai_mmap
.ami_mapaddr
,(sa
.nai_mmap
.ami_mapaddr
+sa
.nai_mmap
.ami_mapsize
))
526 stats_arenas_string
+= "%4u " % sa
.nai_use_count
527 stats_arenas_string
+= "0x%08x " % sa
.nai_flags
528 stats_arenas_string
+= "\n"
531 for c
in IterateRBTreeEntry(necp
.clients
, 'struct necp_client *', 'link'):
532 clients_string
+= "\n\t%-18s %-36s %-4s %-5s\n" % ("necp_clients", "client_id", "refs", "flags")
533 clients_string
+= "\t0x%016x " % c
534 clients_string
+= "%36s " % GetUUIDSummary(c
.client_id
)
535 clients_string
+= "%4u " % c
.reference_count
536 clients_string
+= "%5s " % GetNECPClientBitFields(c
)
538 for f
in IterateRBTreeEntry(c
.flow_registrations
, 'struct necp_client_flow_registration *', 'client_link'):
540 clients_string
+= "\n\t\t%-18s %-36s %-2s %-18s %-18s %-18s\n" % ("flow_registration", "registraton_id", "flags", "stats_arena", "kstats_obj", "ustats_obj")
541 clients_string
+= "\t\t0x%016x " % f
542 clients_string
+= "%36s " % GetUUIDSummary(f
.registration_id
)
543 clients_string
+= "%2s " % GetNECPFlowBitFields(f
)
544 clients_string
+= "0x%016x " % f
.stats_arena
545 clients_string
+= "0x%016x " % f
.kstats_kaddr
546 clients_string
+= "0x%016x " % f
.ustats_uaddr
547 clients_string
+= "\n"
549 return format_string
.format(
551 u
=necp
.flags
) + stats_arenas_string
+ clients_string
553 @lldb_command('showprocnecp')
554 def ShowProcNECP(cmd_args
=None):
555 """ Show NECP descriptors for a given process.
557 usage: showprocnecp <proc_t>
561 raise ArgumentError('missing struct proc * argument')
563 proc
= kern
.GetValueFromAddress(cmd_args
[0], 'proc_t')
565 print GetNECPSummary
.header
566 for kc
in IterateProcNECP(proc
):
567 print GetNECPSummary(kc
)
569 def NexusTypePtr(nx
):
570 if nx
.nx_prov
.nxprov_params
.nxp_type
== GetEnumValue("nexus_type_t::NEXUS_TYPE_FLOW_SWITCH"):
571 return "(struct nx_flowswitch *){:18s}".format(hex(nx
.nx_arg
))
572 elif nx
.nx_prov
.nxprov_params
.nxp_type
== GetEnumValue("nexus_type_t::NEXUS_TYPE_NET_IF"):
573 return " (struct nx_netif *){:18s}".format(hex(nx
.nx_arg
))
574 elif nx
.nx_prov
.nxprov_params
.nxp_type
== GetEnumValue("nexus_type_t::NEXUS_TYPE_USER_PIPE"):
575 return " (struct nx_upipe *){:18s}".format(hex(nx
.nx_arg
))
576 elif nx
.nx_prov
.nxprov_params
.nxp_type
== GetEnumValue("nexus_type_t::NEXUS_TYPE_KERNEL_PIPE"):
577 return " (struct kern_nexus *){:18s}".format(hex(nx
))
581 def GetStructNexusSummary(nx
):
582 nexus_summary_string
= ""
583 nexus_summary_string
+= "{0:s} ".format(NexusTypePtr(nx
))
584 nexus_summary_string
+= "{0:30s} ".format(str(Cast(addressof(nx
.nx_prov
.nxprov_params
.nxp_name
), 'char *')))
585 nexus_summary_string
+= "rings: tx {:2d} rx {:2d} slots: {:4d} rx {:4d} bufsize {:5d} metasize {:5d} mhints {:2d} ".format(
586 nx
.nx_prov
.nxprov_params
.nxp_tx_rings
,
587 nx
.nx_prov
.nxprov_params
.nxp_rx_rings
,
588 nx
.nx_prov
.nxprov_params
.nxp_rx_slots
,
589 nx
.nx_prov
.nxprov_params
.nxp_tx_slots
,
590 nx
.nx_prov
.nxprov_params
.nxp_buf_size
,
591 nx
.nx_prov
.nxprov_params
.nxp_meta_size
,
592 nx
.nx_prov
.nxprov_params
.nxp_mhints
)
594 return nexus_summary_string
596 @lldb_command('shownexuses')
597 def ShowNexuses(cmd_args
=None):
603 nexuses
= kern
.globals.nx_head
604 for nx
in IterateRBTreeEntry(nexuses
, 'struct kern_nexus*', 'nx_link'):
605 nexus_summaries
.append(GetStructNexusSummary(nx
))
606 nexus_summaries
.sort()
607 for nx_str
in nexus_summaries
:
608 print "{0:s}".format(nx_str
)
610 def GetSockAddr4(in_addr
):
611 return inet_ntoa(struct
.pack("!I", in_addr
.sin_addr
))
613 def GetSockAddr6(in6_addr
):
614 addr
= in6_addr
.__u6_addr
.__u6_addr
8
615 addr_raw_string
= ":".join(["{0:02x}{0:02x}".format(unsigned(addr
[i
]),
616 unsigned(addr
[i
+1])) for i
in range(0, 16, 2)])
617 return inet_ntop(AF_INET6
, inet_pton(AF_INET6
, addr_raw_string
))
620 if fk
.fk_ipver
== 0x4:
621 src_str
= GetSockAddr4(fk
.fk_src
._v
4)
622 dst_str
= GetSockAddr4(fk
.fk_dst
._v
4)
623 elif fk
.fk_ipver
== 0x60:
624 src_str
= GetSockAddr6(fk
.fk_src
._v
6)
625 dst_str
= GetSockAddr6(fk
.fk_dst
._v
6)
627 return "unkown ipver"
629 return "src={},dst={},proto={},sport={},dport={}".format(src_str
, dst_str
,
630 unsigned(fk
.fk_proto
), ntohs(fk
.fk_sport
), ntohs(fk
.fk_dport
))
632 def FlowEntryStr(fe
):
633 return "(struct flow_entry*){} {} ".format(hex(fe
), FlowKeyStr(fe
.fe_key
))
635 def GetFlowEntryPid(fe
):
638 def GetFlowswitchFlowEntries(fsw
):
639 fm
= kern
.GetValueFromAddress(unsigned(fsw
.fsw_flow_mgr
), 'struct flow_mgr *')
640 cht
= kern
.GetValueFromAddress(unsigned(fm
.fm_flow_table
), 'struct cuckoo_hashtable *')
643 def GetCuckooNodeAsFLowEntry(node
, hashValue
):
644 fe
= containerof(node
, 'struct flow_entry', 'fe_cnode')
647 CuckooHashtableForeach(cht
, GetCuckooNodeAsFLowEntry
)
650 def IsNexusAFlowswitch(nx
):
651 return nx
.nx_prov
.nxprov_params
.nxp_type
== GetEnumValue('nexus_type_t::NEXUS_TYPE_FLOW_SWITCH')
653 def GetNexusAsFlowswitch(nx
):
654 return kern
.GetValueFromAddress(unsigned(nx
.nx_arg
), 'struct nx_flowswitch *')
656 def FlowswitchStr(fsw
):
657 return "{}:\n(struct nx_flowswitch *){}".format(str(fsw
.fsw_ifp
.if_xname
), hex(fsw
))
659 @lldb_command('showflowswitches')
660 def ShowFlowswitches(cmd_args
=None):
661 """ Show flow switches
663 usage: showflowswitches [ifname]
666 if len(cmd_args
) == 1:
669 nexuses
= kern
.globals.nx_head
670 for nx
in IterateRBTreeEntry(nexuses
, 'struct kern_nexus*', 'nx_link'):
671 if not IsNexusAFlowswitch(nx
):
673 fsw
= GetNexusAsFlowswitch(nx
)
674 if ifname
not in str(fsw
.fsw_ifp
.if_xname
):
676 print "{}".format(FlowswitchStr(fsw
))
677 flows
= GetFlowswitchFlowEntries(fsw
)
678 flows
.sort(key
=GetFlowEntryPid
)
680 print " {}".format(FlowEntryStr(fe
))
682 def CuckooHashtableForeachSlot(cht
, slotHandler
):
683 for i
in range(0, cht
._n
_buckets
):
685 if unsigned(b
._inuse
) == 0:
687 for j
in range(0, kern
.globals._CHT
_BUCKET
_SLOTS
):
689 if unsigned(s
._node
) != 0:
692 def CuckooHashtableForeach(cht
, handler
):
693 def CuckooHashtableSlotHandler(s
):
694 if unsigned(s
._node
) == 0:
697 while unsigned(node
) != 0:
698 handler(node
, s
._hash
)
700 CuckooHashtableForeachSlot(cht
, CuckooHashtableSlotHandler
)
702 @lldb_command('showcuckoohashtable')
703 def ShowCuckooHashtable(cmd_args
=None):
704 """ Show Cuckoo Hashtable.
706 usage: showcuckoohashtable <struct cuckoo_hashtable *>
709 raise ArgumentError('missing struct cuckoo_hashtable * argument')
711 cht
= kern
.GetValueFromAddress(cmd_args
[0], 'struct cuckoo_hashtable *')
713 print "(struct cuckoo_hashtable *){:18s} capacity {:d} entries {:d}".format(hex(cht
), cht
._capacity
, cht
._n
_entries
)
714 def CuckooHashtablePrintNode(node
, hashValue
):
715 print " node {} hash 0x{:08x}".format(hex(node
), int(hashValue
))
717 CuckooHashtableForeach(cht
, CuckooHashtablePrintNode
)
719 @lldb_command('showprotons')
720 def ShowProtoNS(cmd_args
=None):
721 """ Show the protons table
724 protons_tokens
= kern
.globals.protons_tokens
725 for pt
in IterateRBTreeEntry(protons_tokens
, 'struct protons_token *', 'pt_link'):
726 print "(struct protons_token *){} protocol {:3} pid {:5} epid {:5} ref {:2} flags {}".format(
727 hex(pt
), int(pt
.pt_protocol
), int(pt
.pt_pid
), int(pt
.pt_epid
),
728 int(pt
.pt_refcnt
.ref_count
), hex(pt
.pt_flags
))