qemu侧 网络包发送调试记录(二)
断点记录
(gdb) b e1000_class_init
Breakpoint 2 at 0x555555a0b55f: file ../hw/net/e1000.c, line 1775.
(gdb) b net_param_nic
Breakpoint 3 at 0x555555914ee1: file ../net/net.c, line 1493.
(gdb) b pci_e1000_realize
Breakpoint 4 at 0x555555a0b33a: file ../hw/net/e1000.c, line 1705.
(gdb) b pc_nic_init
Breakpoint 5 at 0x555555b6090a: file ../hw/i386/pc.c, line 1142.
// 内存输出
(gdb) x /6xb ni->macaddr.a
// 通过 数组的方法 输出多个值
(gdb) p {s->read_poll ,s->write_poll ,s->using_vnet_hdr ,s->has_ufo ,s->enabled}
$22 = {true, false, false, true, true}
(gdb) p *s
value of type `TAPState' requires 71216 bytes, which is more than max-value-size
网络后端初始化
net_param_nic
函数
// 在执行net_param_nic 完成
(gdb) p *ni
$6 = {macaddr = {a = "RT\230vT2"}, model = 0x555556aa6540 "e1000", name = 0x0,
devaddr = 0x0, netdev = 0x555556cf99b0, used = 1, instantiated = 0, nvectors = 0}
(gdb) x /6xb ni->macaddr.a
0x5555569c5be0 <nd_table>: 0x52 0x54 0x98 0x76 0x54 0x32
// netdev 就是下面的nc
net_client_init1
(gdb) ptype Netdev
type = struct Netdev {
char *id;
NetClientDriver type;
union {
NetLegacyNicOptions nic;
NetdevUserOptions user;
NetdevTapOptions tap;
NetdevL2TPv3Options l2tpv3;
NetdevSocketOptions socket;
NetdevVdeOptions vde;
NetdevBridgeOptions bridge;
NetdevHubPortOptions hubport;
NetdevNetmapOptions netmap;
NetdevVhostUserOptions vhost_user;
NetdevVhostVDPAOptions vhost_vdpa;
} u;
}
(gdb) ptype NetClientDriver
type = enum NetClientDriver {NET_CLIENT_DRIVER_NONE, NET_CLIENT_DRIVER_NIC,
NET_CLIENT_DRIVER_USER, NET_CLIENT_DRIVER_TAP, NET_CLIENT_DRIVER_L2TPV3,
NET_CLIENT_DRIVER_SOCKET, NET_CLIENT_DRIVER_VDE, NET_CLIENT_DRIVER_BRIDGE,
NET_CLIENT_DRIVER_HUBPORT, NET_CLIENT_DRIVER_NETMAP,
NET_CLIENT_DRIVER_VHOST_USER, NET_CLIENT_DRIVER_VHOST_VDPA,
NET_CLIENT_DRIVER__MAX}
(gdb) ptype NetdevTapOptions
type = struct NetdevTapOptions {
_Bool has_ifname;
char *ifname;
_Bool has_fd;
char *fd;
_Bool has_fds;
char *fds;
_Bool has_script;
char *script;
_Bool has_downscript;
char *downscript;
_Bool has_br;
char *br;
_Bool has_helper;
char *helper;
_Bool has_sndbuf;
uint64_t sndbuf;
_Bool has_vnet_hdr;
_Bool vnet_hdr;
_Bool has_vhost;
_Bool vhost;
_Bool has_vhostfd;
char *vhostfd;
_Bool has_vhostfds;
char *vhostfds;
_Bool has_vhostforce;
_Bool vhostforce;
_Bool has_queues;
uint32_t queues;
_Bool has_poll_us;
uint32_t poll_us;
}
(gdb) p *netdev
$8 = {id = 0x555556cdc950 "plr4", type = NET_CLIENT_DRIVER_TAP, u = { tap = {
has_ifname = true, ifname = 0x555556aa73a0 "tap1", has_fd = false, fd = 0x0,
has_fds = false, fds = 0x0, has_script = true, script = 0x555556ce4cb0 "no",
has_downscript = true, downscript = 0x555556ce6ef0 "no", has_br = false,
br = 0x0, has_helper = false, helper = 0x0, has_sndbuf = false, sndbuf = 0,
has_vnet_hdr = false, vnet_hdr = false, has_vhost = false, vhost = false,
has_vhostfd = false, vhostfd = 0x0, has_vhostfds = false, vhostfds = 0x0,
has_vhostforce = false, vhostforce = false, has_queues = false, queues = 0,
has_poll_us = false, poll_us = 0}, }
gdb) n
1064 if (net_client_init_fun[netdev->type](netdev, netdev->id, peer, errp) < 0) {
(gdb) s
net_init_tap (netdev=0x0, name=0x7fffffffe2e0 "\020", peer=0x555555865940 <_start>,
errp=0x7fffffffdde0) at ../net/tap.c:796
796 {
(gdb) n
1074 nc = qemu_find_netdev(netdev->id);
(gdb) n
1075 assert(nc);
(gdb) p *nc
$28 = {info = 0x5555568afb80 <net_tap_info>, link_down = 0, next = {}},
peer = 0x0, incoming_queue = 0x555556aa6900, model = "tap", name = "plr4",
info_str = "ifname=tap1,script=no,downscript=no",
receive_disabled = 0, destructor = 0x55555591208f <qemu_net_client_destructor>,
queue_index = 0, rxfilter_notify_enabled = 0, vring_enable = 0, vnet_hdr_len = 0,
is_netdev = false, do_not_pad = false, is_datapath = true, filters = {}}
net_init_tap
// 直接执行末尾的else 分支
(gdb) n
966 g_autofree char *default_script = NULL;
// 这里是在qemu 命令行里指定 tap 名称,并且在创建的时候指定归属哪个用户,所以不需要sudo 执行
(gdb) n
982 pstrcpy(ifname, sizeof ifname, tap->ifname);
net_init_tap_one
// 进入函数后,查看传入的参数
(gdb) f
#0 net_init_tap_one (tap=0x555556ce7740, peer=0x0, model=0x5555561311ad "tap",
name=0x555556cdc950 "plr4", ifname=0x7fffffffde10 "tap1",
script=0x555556ce4cb0 "no", downscript=0x555556ce6ef0 "no", vhostfdname=0x0,
vnet_hdr=1, fd=12, errp=0x7fffffffddc8) at ../net/tap.c:680
680 Error *err = NULL;
(gdb) f
#0 net_tap_fd_init (peer=0x0, model=0x5555561311ad "tap",
name=0x555556cdc950 "plr4", fd=12, vnet_hdr=1) at ../net/tap.c:395
395 nc = qemu_new_net_client(&net_tap_info, peer, model, name);
(gdb) f
#0 qemu_new_net_client (info=0x5555568afb80 <net_tap_info>, peer=0x0,
model=0x5555561311ad "tap", name=0x555556cdc950 "plr4") at ../net/net.c:273
273 assert(info->size >= sizeof(NetClientState));
(gdb) n
net_tap_fd_init (peer=0x0, model=0x5555561311ad "tap", name=0x555556cdc950 "plr4",
fd=12, vnet_hdr=1) at ../net/tap.c:397
397 s = DO_UPCAST(TAPState, nc, nc);
(gdb) p *nc
$15 = {info = 0x5555568afb80 <net_tap_info>, link_down = 0, next = {},
peer = 0x0, incoming_queue = 0x555556aa6900, model = 0x555556aa6940 "tap",
name = 0x555556aa68e0 "plr4", info_str = '\000' <repeats 255 times>,
receive_disabled = 0, destructor = 0x55555591208f <qemu_net_client_destructor>,
queue_index = 0, rxfilter_notify_enabled = 0, vring_enable = 0, vnet_hdr_len = 0,
is_netdev = false, do_not_pad = false, is_datapath = true, filters = {
tqh_first = 0x0, tqh_circ = {tql_next = 0x0, tql_prev = 0x555556cf9b18}}}
// 回到 net_init_tap_one
(gdb) n
684 tap_set_sndbuf(s->fd, tap, &err);
(gdb) p *(s->nc.incoming_queue)
$20 = {opaque = 0x555556cf99b0, nq_maxlen = 10000, nq_count = 0,
deliver = 0x555555913408 <qemu_deliver_packet_iov>, packets = {tqh_first = 0x0,
tqh_circ = {tql_next = 0x0, tql_prev = 0x555556aa6918}}, delivering = 0}
(gdb) p &(s->nc)
$21 = (NetClientState *) 0x555556cf99b0
(gdb) p {s->read_poll ,s->write_poll ,s->using_vnet_hdr ,s->has_ufo ,s->enabled}
$22 = {true, false, false, true, true}
// 这个可能让刚开始传入的包长度多10
(gdb) p s->host_vnet_hdr_len
$23 = 10
(gdb) p s->vhost_net
$24 = (VHostNetState *) 0x0
网络前端初始化
pci_nic_init_nofail
(gdb) p nb_nics
$32 = 1
(gdb) f
#0 pci_nic_init_nofail (nd=0x5555569c5be0 <nd_table>, rootbus=0x555556e44ba0,
default_model=0x555556aa6540 "e1000", default_devaddr=0x0) at ../hw/pci/pci.c:1945
// 直接 设置一个新的断点跳过循环
(gdb) n
1983 next = list->next;
(gdb) b 1989
(gdb) p *pci_nic_models
$35 = {pdata = 0x555557742020, len = 26}
(gdb) p devaddr
$39 = 0x0
// 对设备初始化
(gdb) n
2034 pci_realize_and_unref(pci_dev, bus, &error_fatal);
(gdb) n
Thread 1 "qemu-system-x86" hit Breakpoint 4, pci_e1000_realize (pci_dev=0x55555774d110, errp=0x7fffffffda88) at ../hw/net/e1000.c:1705
1705 {
前端网卡设备初始化
pci_e1000_realize
函数
(gdb) s
DEVICE (obj=0x55555774d110) at /home/ostest/linux-test/qemu7/include/hw/qdev-core.h:17
17 OBJECT_DECLARE_TYPE(DeviceState, DeviceClass, DEVICE)
(gdb) s
1707 E1000State *d = E1000(pci_dev);
(gdb) s
E1000 (obj=0x55555774d110) at ../hw/net/e1000.c:159
159 DECLARE_OBJ_CHECKERS(E1000State, E1000BaseClass,E1000, TYPE_E1000_BASE)
(gdb) p d->nic
$49 = (NICState *) 0x0
(gdb) p d->conf
$50 = {macaddr = {a = "RT\230vT2"}, peers = {ncs = {0x555556cf99b0,
0x0 <repeats 1023 times>}, queues = 1}, bootindex = -1}
(gdb) p d->conf->peers->ncs[0]
$52 = (NetClientState *) 0x555556cf99b0
(gdb) p *d->conf->peers->ncs[0]
$53 = {info = 0x5555568afb80 <net_tap_info>, link_down = 0, next = {},
peer = 0x0, incoming_queue = 0x555556aa6900, model = 0x555556aa6940 "tap",
name = 0x555556aa68e0 "plr4", }
(gdb) n
1740 d->autoneg_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, e1000_autoneg_timer, d);
(gdb) p *d->nic
$55 = {ncs = 0x555557740570, conf = 0x55555774db18, opaque = 0x55555774d110,
peer_deleted = false}
(gdb) p *d->nic->ncs
$57 = {info = 0x5555568d0520 <net_e1000_info>, link_down = 0, next = {tqe_next = 0x0,
tqe_circ = {tql_next = 0x0, tql_prev = 0x555556cf99c0}}, peer = 0x555556cf99b0,
incoming_queue = 0x5555577406f0, model = 0x555557740410 "e1000",
name = 0x555557740430 "e1000.0",
info_str = "model=e1000,macaddr=52:54:98:76:54:32",, }
(gdb) p *d->nic->conf
$58 = {macaddr = {a = "RT\230vT2"}, peers = {ncs = {0x555556cf99b0,
0x0 <repeats 1023 times>}, queues = 1}, bootindex = -1}
(gdb) p *d->nic->ncs->peer
$59 = {info = 0x5555568afb80 <net_tap_info>, link_down = 0, next = {}, peer = 0x555557740570, }
(gdb) p d
$60 = (E1000State *) 0x55555774d110
(gdb) p {d->autoneg_timer,d->mit_timer,d->flush_queue_timer}
$63 = {0x555557740730, 0x555557740770, 0x5555577407b0}