def coerce(self, obj: drgn.Object) -> drgn.Object: """ This function attemts to massage the input object into an object of a different type. """ # same type is fine if obj.type_ == self.type: return obj # "void *" can be coerced to any pointer type if (obj.type_.kind is drgn.TypeKind.POINTER and obj.type_.primitive is drgn.PrimitiveType.C_VOID): return drgn.cast(self.type, obj) # integers can be coerced to any pointer typo if obj.type_.kind is drgn.TypeKind.INT: return drgn.cast(self.type, obj) # "type" can be coerced to "type *" if obj.type_.kind is not drgn.TypeKind.POINTER and obj.address_of_( ).type_ == self.type: return obj.address_of_() raise TypeError("can not coerce {} to {}".format(obj.type_, self.type))
def test_dir(self): obj = Object(self.prog, "int", value=0) self.assertEqual(dir(obj), sorted(object.__dir__(obj))) obj = Object(self.prog, self.point_type, address=0xFFFF0000) self.assertEqual(dir(obj), sorted(object.__dir__(obj) + ["x", "y"])) self.assertEqual(dir(obj.address_of_()), dir(obj))
def flow_table2(name, table): print("\nflow table name: %s\nflow table id: %x leve: %x, type: %x (FS_FT_FDB: %d, FS_FT_NIC_RX: %d)" % \ (name, table.id.value_(), table.level.value_(), table.type, prog['FS_FT_FDB'], prog['FS_FT_NIC_RX'])) print("mlx5_flow_table %lx" % table.address_of_()) # print("flow table address") # print("%lx" % table.value_()) fs_node = Object(prog, 'struct fs_node', address=table.address_of_()) # print("%lx" % fs_node.address_of_()) # print(fs_node) group_addr = fs_node.address_of_() # print("fs_node address") # print("%lx" % group_addr.value_()) group_addr = fs_node.children.address_of_() # print(group_addr) for group in list_for_each_entry('struct fs_node', group_addr, 'list'): print("mlx5_flow_group %lx" % group) fte_addr = group.children.address_of_() for fte in list_for_each_entry('struct fs_node', fte_addr, 'list'): fs_fte = Object(prog, 'struct fs_fte', address=fte.value_()) print_match(fs_fte) dest_addr = fte.children.address_of_() for dest in list_for_each_entry('struct fs_node', dest_addr, 'list'): rule = Object(prog, 'struct mlx5_flow_rule', address=dest.value_()) print_dest(rule)
def flow_table(name, table): print("\nflow table name: %s\nflow table id: %x table_level: %x, \ type: %x (FS_FT_FDB: %d, FS_FT_NIC_RX: %d, max_fte: %d, %x), refcount: %d" % \ (name, table.id.value_(), table.level.value_(), table.type, \ prog['FS_FT_FDB'], prog['FS_FT_NIC_RX'], table.max_fte, table.max_fte, \ table.node.refcount.refs.counter)) print("mlx5_flow_table %lx" % table.value_()) # print("flow table address") # print("%lx" % table.value_()) fs_node = Object(prog, 'struct fs_node', address=table.value_()) # print("%lx" % fs_node.address_of_()) # print(fs_node) group_addr = fs_node.address_of_() # print("fs_node address") # print("%lx" % group_addr.value_()) group_addr = fs_node.children.address_of_() # print(group_addr) for group in list_for_each_entry('struct fs_node', group_addr, 'list'): print("mlx5_flow_group %lx" % group) fte_addr = group.children.address_of_() for fte in list_for_each_entry('struct fs_node', fte_addr, 'list'): fs_fte = Object(prog, 'struct fs_fte', address=fte.value_()) print_match(fs_fte) if fs_fte.action.action & 0x40: print("modify_hdr id: %x" % fs_fte.action.modify_hdr.id) dest_addr = fte.children.address_of_() for dest in list_for_each_entry('struct fs_node', dest_addr, 'list'): rule = Object(prog, 'struct mlx5_flow_rule', address=dest.value_()) print_dest(rule)
def print_tuple_rhash_tuple(tuple_rhash): tuple = tuple_rhash.tuple dir = tuple.dir.value_() if dir == 0: flow_offload = cast("struct flow_offload *", tuple_rhash) print_flow_offload(flow_offload, dir) else: flow_offload = Object(prog, 'struct flow_offload', address=tuple_rhash.value_() - \ prog.type('struct flow_offload_tuple_rhash').size) print_flow_offload(flow_offload.address_of_(), dir) print_flow_offload_tuple(tuple)
def per_cpu(var: Object, cpu: IntegerLike) -> Object: """ Return the per-CPU variable for a given CPU. >>> print(repr(prog["runqueues"])) Object(prog, 'struct rq', address=0x278c0) >>> per_cpu(prog["runqueues"], 6).curr.comm (char [16])"python3" :param var: Per-CPU variable, i.e., ``type __percpu`` (not a pointer; use :func:`per_cpu_ptr()` for that). :param cpu: CPU number. :return: ``type`` object. """ return per_cpu_ptr(var.address_of_(), cpu)[0]
def test_address_of(self): obj = Object(self.prog, "int", address=0xFFFF0000) self.assertIdentical( obj.address_of_(), Object(self.prog, "int *", value=0xFFFF0000) ) obj = obj.read_() self.assertRaisesRegex( ValueError, "cannot take address of value", obj.address_of_ ) obj = Object(self.prog, "int", address=0xFFFF0000, bit_field_size=4) self.assertRaisesRegex( ValueError, "cannot take address of bit field", obj.address_of_ ) obj = Object(self.prog, "int", address=0xFFFF0000, bit_offset=4) self.assertRaisesRegex( ValueError, "cannot take address of bit field", obj.address_of_ )
# continue addr = dev.value_() # if "enp" in name: kind = get_kind(dev) if kind != "vxlan": continue print("\n================================\n") print("%-20s, ifindex: %5i%20x\t" % (name, dev.ifindex, addr), end="") print_ip_address(dev) print("dev.priv_flags: %10x\t" % dev.priv_flags, end='\t') count = get_pcpu_refcnt(dev) print("refcnt: %10d" % count, end='') print("") vxlan_dev_addr = addr + prog.type('struct net_device').size vxlan_dev = Object(prog, 'struct vxlan_dev', address=vxlan_dev_addr) print("vxlan_dev: %x" % vxlan_dev.address_of_()) # print(vxlan_dev) # print(vxlan_dev.cfg) # # ip link add name $vx type vxlan id $vni dev $link remote $link_remote_ip dstport $vxlan_port # vxlan_dev.cfg.remote_ifindex is the ifindex of $link # if don't specify, it is 0 # print("vxlan_dev.cfg.remote_ifindex: %d" % vxlan_dev.cfg.remote_ifindex, end='\t') print("vxlan_dev.cfg.vni: %x" % vxlan_dev.cfg.vni) vxlan_sock = vxlan_dev.vn4_sock print("") print("#define VXLAN_F_UDP_ZERO_CSUM6_RX 0x100") print("#define VXLAN_F_COLLECT_METADATA 0x2000 (external)")
#!/usr/local/bin/drgn -k from drgn.helpers.linux import * from drgn import Object import time import sys import os sys.path.append(".") import lib gen = prog['init_net'].gen id = prog['fib_notifier_net_id'] print("fib_notifier_net_id: %d" % id) ptr = gen.ptr[id] fib_notifier_net = Object(prog, 'struct fib_notifier_net', address=ptr.value_()) print("fib_notifier_net %lx" % fib_notifier_net.address_of_()) # print(fib_notifier_net) fib_chain = fib_notifier_net.fib_chain # print(fib_chain) head = fib_chain.head while head.value_(): print(head) head = head.next
nla_type = nlattr.nla_type if nla_type == prog['OVS_ACTION_ATTR_OUTPUT']: addr = nlattr.address_of_().value_() + prog.type('struct nlattr').size port = Object(prog, 'int', address=addr) print("\toutput port: %d" % port.value_()) def print_flow_stat(stat): print("\tpacket_count: %d" % stat[0].packet_count) if lib.kernel("4.19.36+") == False: for i in range(n_buckets): for flow in hlist_for_each_entry('struct sw_flow', ufid_ti.buckets[i].address_of_(), 'ufid_table'): print_flow_key(flow.key) else: for i in range(num): array = buckets.parts[i].value_() print("\narray %d: %lx" % (i, array)) for j in range(elems_per_part): head = Object(prog, 'struct hlist_head', address=array) for flow in hlist_for_each_entry('struct sw_flow', head.address_of_(), 'ufid_table'): print("") print_flow_key(flow.key) print_flow_act(flow.sf_acts) print_flow_stat(flow.stats) array = array + element_size
def is_list_empty(l: drgn.Object) -> bool: """ True if list is empty, False otherwise. """ assert sdb.type_canonical_name(l.type_) == 'struct list_head' return int(l.address_of_().value_()) == int(l.next.value_())
# print(auxiliary_driver) probe = auxiliary_driver.probe print(address_to_name(hex(probe))) remove = auxiliary_driver.remove print(address_to_name(hex(remove))) shutdown = auxiliary_driver.shutdown print(address_to_name(hex(shutdown))) # print(devlink._net) # print(devlink.ops.reload_down) # print(devlink.ops.reload_up) mlx5_core_dev = Object(prog, 'struct mlx5_core_dev', address=devlink.priv.address_of_().value_()) print("mlx5_core_dev %x" % (mlx5_core_dev.address_of_())) for port in list_for_each_entry('struct devlink_port', devlink.port_list.address_of_(), 'list'): print("\tport index: %x" % port.index) if port.index & 0xffff == 0xffff: print(port.attrs) print("=== devlink_port ===") for port in list_for_each_entry('struct devlink_port', devlink.port_list.address_of_(), 'list'): print("\n\tport index: %x" % port.index) # if port.index & 0xffff == 0xffff: # print(port.attrs)
#!/usr/local/bin/drgn -k from drgn.helpers.linux import * from drgn import Object import time import sys import os sys.path.append("..") import lib gen = prog['init_net'].gen id = prog['tcf_action_net_id'] print("tcf_action_net_id: %d" % id) ptr = gen.ptr[id] tcf_action_net = Object(prog, 'struct tcf_action_net', address=ptr.value_()) print("tcf_action_net %lx" % tcf_action_net.address_of_()) for cb in list_for_each_entry('struct tcf_action_egdev_cb', tcf_action_net.egdev_list.address_of_(), 'list'): print(cb) func = cb.cb.value_() func = lib.address_to_name(hex(func)) print(func) priv = cb.cb_priv priv = Object(prog, 'struct mlx5e_priv', address=priv.value_()) print(priv.netdev.name.string_().decode())
print("nf_flowtable %lx" % mlx5_ct_ft.nf_ft) print("mlx5_ct_ft.ct_entries_ht:") ct_entries_ht = mlx5_ct_ft.ct_entries_ht for j, mlx5_ct_entry in enumerate( hash(ct_entries_ht, 'struct mlx5_ct_entry', 'node')): print("mlx5_ct_entry %lx" % mlx5_ct_entry) print("\tcookie is flow_offload_tuple %lx" % mlx5_ct_entry.cookie) print("\trestore_cookie is 'ct | ctinfo' %lx" % mlx5_ct_entry.restore_cookie) print('') for k in range(2): mlx5_ct_zone_rule = mlx5_ct_entry.zone_rules[k] print("\tmlx5_ct_entry.zone_rules[%d]" % k) print("\tmlx5_ct_zone_rule %lx" % mlx5_ct_zone_rule.address_of_()) print("\tmlx5_esw_flow_attr %lx" % mlx5_ct_zone_rule.attr.address_of_()) # print_mlx6_esw_flow_attr(mlx5_ct_zone_rule.attr) # mlx5_flow_handle = mlx5_ct_zone_rule.rule # nat = mlx5_ct_zone_rule.nat # print("\tmlx5_ct_entry.zone_rules[%d].rule: nat: %d(tupleid is unique for mlx5_ct_entry.mlx5_ct_zone_rule[nat], it is used to restore ctinfo)" % (k, nat)) # print("\t\tmlx5_ct_zone_rule.rule") # print_mlx5_flow_handle(mlx5_flow_handle) print('') flow_table("mlx5_ct_ft.pre_ct.ft", mlx5_ct_ft.pre_ct.ft) flow_table("mlx5_ct_ft.pre_ct_nat.ft", mlx5_ct_ft.pre_ct_nat.ft) # print("\tmlx5_ct_entry.zone_rules[1].rule") # mlx5_flow_handle = mlx5_ct_entry.zone_rules[1].rule
print("=== mlx5e_rep_priv.uplink_priv.ct_priv.post_ct ===") # print("mlx5_flow_table %lx" % ct_priv.post_ct) flow_table("ct_priv.post_ct", ct_priv.post_ct) ############################### fte_ids = ct_priv.fte_ids print("=== mlx5e_rep_priv.uplink_priv.ct_priv.fte_ids ===") for node in radix_tree_for_each(fte_ids.idr_rt): mlx5_ct_flow = Object(prog, 'struct mlx5_ct_flow', address=node[1].value_()) # print(mlx5_ct_flow) print("mlx5_ct_flow %lx" % mlx5_ct_flow.address_of_()) print("\tfte_id: %d" % mlx5_ct_flow.fte_id, end='\t') print("chain_mapping: %d" % mlx5_ct_flow.chain_mapping, end='\t') print('') print("\tmlx5_ct_flow.pre_ct_attr") # print(mlx5_ct_flow.pre_ct_attr) print_mlx5_esw_flow_attr(mlx5_ct_flow.pre_ct_attr) print("\tmlx5_ct_flow.post_ct_attr") # print(mlx5_ct_flow.post_ct_attr) print_mlx5_esw_flow_attr(mlx5_ct_flow.post_ct_attr) print("\tmlx5_ct_flow.pre_ct_rule") print_mlx5_flow_handle(mlx5_ct_flow.pre_ct_rule)
# print(table) entries = [] for i, flow in enumerate( hash(flow_offload_table.rhashtable, 'struct flow_offload_tuple_rhash', 'node')): print("index: %d:" % i, end=' ') flow_offload_tuple_rhash = Object(prog, 'struct flow_offload_tuple_rhash', address=flow.value_()) dir = flow_offload_tuple_rhash.tuple.dst.dir size = prog.type('struct flow_offload_tuple_rhash').size # print("size: %lx" % (size)) print("flow_offload_tuple_rhash %lx" % (flow_offload_tuple_rhash.address_of_())) if dir == 0: offset = 0 if dir == 1: offset = size flow_offload_entry = flow_offload_tuple_rhash.address_of_().value_( ) - offset if flow_offload_entry not in entries: entries.append(flow_offload_entry) print("") print( "num of flow_offload_entry entries (two flow_offload_tuple_rhash share one flow_offload_entry): %d" % len(entries))
#!/usr/local/bin/drgn -k from drgn.helpers.linux import * from drgn import Object import time import sys import os libpath = os.path.dirname(os.path.realpath("__file__")) sys.path.append(libpath) import lib gen = prog['init_net'].gen id = prog['ovs_net_id'] print("ovs_net_id: %d" % id) ptr = gen.ptr[id] ovs_net = Object(prog, 'struct ovs_net', address=ptr.value_()) print("ovs_net %lx" % ovs_net.address_of_()) print(ovs_net) for dp in list_for_each_entry('struct datapath', ovs_net.dps.address_of_(), 'list_node'): print(dp)
print("\n%20s ingress_sched_data %20x" % (name, addr)) chain_list_addr = block.chain_list.address_of_() for chain in list_for_each_entry('struct tcf_chain', chain_list_addr, 'list'): if (chain.value_() == 0): print("chain 0, continue") continue # print("tcf_chain %lx" % chain.value_()) # print("chain index: %d, 0x%x" % (chain.index, chain.index)) tcf_proto = chain.filter_chain while True: # print("tcf_proto %lx" % tcf_proto.value_()) if (tcf_proto.value_() == 0): break head = Object(prog, 'struct cls_fl_head', address=tcf_proto.root.value_()) # print(head) for node in radix_tree_for_each(head.handle_idr.idr_rt): # print("%lx" % node[1].value_()) f = Object(prog, 'struct cls_fl_filter', address=node[1].value_()) print("cls_fl_filter %lx" % f.address_of_().value_()) # print("==========================================\n") tcf_proto = tcf_proto.next if tcf_proto.value_() == 0: break