Skip to content

Commit 920aa48

Browse files
committed
Merge tag 'net-pull-request' of https://github.com/jasowang/qemu into staging
# -----BEGIN PGP SIGNATURE----- # # iQEzBAABCAAdFiEEIV1G9IJGaJ7HfzVi7wSWWzmNYhEFAmfO1zkACgkQ7wSWWzmN # YhET+wf+PkaGeFTNUrOtWpl35fSMKlmOVbb1fkPfuhVBmeY2Vh1EIN3OjqnzdV0F # wxpuk+wwmFiuV1n6RNuMHQ0nz1mhgsSlZh93N5rArC/PUr3iViaT0cb82RjwxhaI # RODBhhy7V9WxEhT9hR8sCP2ky2mrKgcYbjiIEw+IvFZOVQa58rMr2h/cbAb/iH4l # 7T9Wba03JBqOS6qgzSFZOMxvqnYdVjhqXN8M6W9ngRJOjPEAkTB6Evwep6anRjcM # mCUOgkf2sgQwKve8pYAeTMkzXFctvTc/qCU4ZbN8XcoKVVxe2jllGQqdOpMskPEf # slOuINeW5M0K5gyjsb/huqcOTfDI2A== # =/Y0+ # -----END PGP SIGNATURE----- # gpg: Signature made Mon 10 Mar 2025 20:12:41 HKT # gpg: using RSA key 215D46F48246689EC77F3562EF04965B398D6211 # gpg: Good signature from "Jason Wang (Jason Wang on RedHat) <[email protected]>" [full] # Primary key fingerprint: 215D 46F4 8246 689E C77F 3562 EF04 965B 398D 6211 * tag 'net-pull-request' of https://github.com/jasowang/qemu: tap-linux: Open ipvtap and macvtap Revert "hw/net/net_tx_pkt: Fix overrun in update_sctp_checksum()" util/iov: Do not assert offset is in iov net: move backend cleanup to NIC cleanup net: parameterize the removing client from nc list Signed-off-by: Stefan Hajnoczi <[email protected]>
2 parents 6d1829f + ac2ff9b commit 920aa48

File tree

6 files changed

+51
-32
lines changed

6 files changed

+51
-32
lines changed

hw/net/net_tx_pkt.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -141,10 +141,6 @@ bool net_tx_pkt_update_sctp_checksum(struct NetTxPkt *pkt)
141141
uint32_t csum = 0;
142142
struct iovec *pl_start_frag = pkt->vec + NET_TX_PKT_PL_START_FRAG;
143143

144-
if (iov_size(pl_start_frag, pkt->payload_frags) < 8 + sizeof(csum)) {
145-
return false;
146-
}
147-
148144
if (iov_from_buf(pl_start_frag, pkt->payload_frags, 8, &csum, sizeof(csum)) < sizeof(csum)) {
149145
return false;
150146
}

include/qemu/iov.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ size_t iov_size(const struct iovec *iov, const unsigned int iov_cnt);
3131
* only part of data will be copied, up to the end of the iovec.
3232
* Number of bytes actually copied will be returned, which is
3333
* min(bytes, iov_size(iov)-offset)
34-
* `Offset' must point to the inside of iovec.
34+
* Returns 0 when `offset' points to the outside of iovec.
3535
*/
3636
size_t iov_from_buf_full(const struct iovec *iov, unsigned int iov_cnt,
3737
size_t offset, const void *buf, size_t bytes);
@@ -67,11 +67,12 @@ iov_to_buf(const struct iovec *iov, const unsigned int iov_cnt,
6767
/**
6868
* Set data bytes pointed out by iovec `iov' of size `iov_cnt' elements,
6969
* starting at byte offset `start', to value `fillc', repeating it
70-
* `bytes' number of times. `Offset' must point to the inside of iovec.
70+
* `bytes' number of times.
7171
* If `bytes' is large enough, only last bytes portion of iovec,
7272
* up to the end of it, will be filled with the specified value.
7373
* Function return actual number of bytes processed, which is
7474
* min(size, iov_size(iov) - offset).
75+
* Returns 0 when `offset' points to the outside of iovec.
7576
*/
7677
size_t iov_memset(const struct iovec *iov, const unsigned int iov_cnt,
7778
size_t offset, int fillc, size_t bytes);

net/net.c

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -381,9 +381,12 @@ NetClientState *qemu_get_peer(NetClientState *nc, int queue_index)
381381
return ncs->peer;
382382
}
383383

384-
static void qemu_cleanup_net_client(NetClientState *nc)
384+
static void qemu_cleanup_net_client(NetClientState *nc,
385+
bool remove_from_net_clients)
385386
{
386-
QTAILQ_REMOVE(&net_clients, nc, next);
387+
if (remove_from_net_clients) {
388+
QTAILQ_REMOVE(&net_clients, nc, next);
389+
}
387390

388391
if (nc->info->cleanup) {
389392
nc->info->cleanup(nc);
@@ -425,7 +428,13 @@ void qemu_del_net_client(NetClientState *nc)
425428
object_unparent(OBJECT(nf));
426429
}
427430

428-
/* If there is a peer NIC, delete and cleanup client, but do not free. */
431+
/*
432+
* If there is a peer NIC, transfer ownership to it. Delete the client
433+
* from net_client list but do not cleanup nor free. This way NIC can
434+
* still access to members of the backend.
435+
*
436+
* The cleanup and free will be done when the NIC is free.
437+
*/
429438
if (nc->peer && nc->peer->info->type == NET_CLIENT_DRIVER_NIC) {
430439
NICState *nic = qemu_get_nic(nc->peer);
431440
if (nic->peer_deleted) {
@@ -435,21 +444,18 @@ void qemu_del_net_client(NetClientState *nc)
435444

436445
for (i = 0; i < queues; i++) {
437446
ncs[i]->peer->link_down = true;
447+
QTAILQ_REMOVE(&net_clients, ncs[i], next);
438448
}
439449

440450
if (nc->peer->info->link_status_changed) {
441451
nc->peer->info->link_status_changed(nc->peer);
442452
}
443453

444-
for (i = 0; i < queues; i++) {
445-
qemu_cleanup_net_client(ncs[i]);
446-
}
447-
448454
return;
449455
}
450456

451457
for (i = 0; i < queues; i++) {
452-
qemu_cleanup_net_client(ncs[i]);
458+
qemu_cleanup_net_client(ncs[i], true);
453459
qemu_free_net_client(ncs[i]);
454460
}
455461
}
@@ -462,8 +468,12 @@ void qemu_del_nic(NICState *nic)
462468

463469
for (i = 0; i < queues; i++) {
464470
NetClientState *nc = qemu_get_subqueue(nic, i);
465-
/* If this is a peer NIC and peer has already been deleted, free it now. */
471+
/*
472+
* If this is a peer NIC and peer has already been deleted, clean it up
473+
* and free it now.
474+
*/
466475
if (nic->peer_deleted) {
476+
qemu_cleanup_net_client(nc->peer, false);
467477
qemu_free_net_client(nc->peer);
468478
} else if (nc->peer) {
469479
/* if there are RX packets pending, complete them */
@@ -474,7 +484,7 @@ void qemu_del_nic(NICState *nic)
474484
for (i = queues - 1; i >= 0; i--) {
475485
NetClientState *nc = qemu_get_subqueue(nic, i);
476486

477-
qemu_cleanup_net_client(nc);
487+
qemu_cleanup_net_client(nc, true);
478488
qemu_free_net_client(nc);
479489
}
480490

@@ -1678,13 +1688,27 @@ void net_cleanup(void)
16781688
* of the latest NET_CLIENT_DRIVER_NIC, and operate on *p as we walk
16791689
* the list.
16801690
*
1691+
* However, the NIC may have peers that trust to be clean beyond this
1692+
* point. For example, if they have been removed with device_del.
1693+
*
16811694
* The 'nc' variable isn't part of the list traversal; it's purely
16821695
* for convenience as too much '(*p)->' has a tendency to make the
16831696
* readers' eyes bleed.
16841697
*/
16851698
while (*p) {
16861699
nc = *p;
16871700
if (nc->info->type == NET_CLIENT_DRIVER_NIC) {
1701+
NICState *nic = qemu_get_nic(nc);
1702+
1703+
if (nic->peer_deleted) {
1704+
int queues = MAX(nic->conf->peers.queues, 1);
1705+
1706+
for (int i = 0; i < queues; i++) {
1707+
nc = qemu_get_subqueue(nic, i);
1708+
qemu_cleanup_net_client(nc->peer, false);
1709+
}
1710+
}
1711+
16881712
/* Skip NET_CLIENT_DRIVER_NIC entries */
16891713
p = &QTAILQ_NEXT(nc, next);
16901714
} else {

net/tap-linux.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,21 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr,
4545
int len = sizeof(struct virtio_net_hdr);
4646
unsigned int features;
4747

48-
fd = RETRY_ON_EINTR(open(PATH_NET_TUN, O_RDWR));
48+
49+
ret = if_nametoindex(ifname);
50+
if (ret) {
51+
g_autofree char *file = g_strdup_printf("/dev/tap%d", ret);
52+
fd = open(file, O_RDWR);
53+
} else {
54+
fd = -1;
55+
}
56+
4957
if (fd < 0) {
50-
error_setg_errno(errp, errno, "could not open %s", PATH_NET_TUN);
51-
return -1;
58+
fd = RETRY_ON_EINTR(open(PATH_NET_TUN, O_RDWR));
59+
if (fd < 0) {
60+
error_setg_errno(errp, errno, "could not open %s", PATH_NET_TUN);
61+
return -1;
62+
}
5263
}
5364
memset(&ifr, 0, sizeof(ifr));
5465
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;

net/vhost-vdpa.c

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -224,14 +224,6 @@ static void vhost_vdpa_cleanup(NetClientState *nc)
224224
{
225225
VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
226226

227-
/*
228-
* If a peer NIC is attached, do not cleanup anything.
229-
* Cleanup will happen as a part of qemu_cleanup() -> net_cleanup()
230-
* when the guest is shutting down.
231-
*/
232-
if (nc->peer && nc->peer->info->type == NET_CLIENT_DRIVER_NIC) {
233-
return;
234-
}
235227
munmap(s->cvq_cmd_out_buffer, vhost_vdpa_net_cvq_cmd_page_len());
236228
munmap(s->status, vhost_vdpa_net_cvq_cmd_page_len());
237229
if (s->vhost_net) {

util/iov.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ size_t iov_from_buf_full(const struct iovec *iov, unsigned int iov_cnt,
3737
offset -= iov[i].iov_len;
3838
}
3939
}
40-
assert(offset == 0);
4140
return done;
4241
}
4342

@@ -56,7 +55,6 @@ size_t iov_to_buf_full(const struct iovec *iov, const unsigned int iov_cnt,
5655
offset -= iov[i].iov_len;
5756
}
5857
}
59-
assert(offset == 0);
6058
return done;
6159
}
6260

@@ -75,7 +73,6 @@ size_t iov_memset(const struct iovec *iov, const unsigned int iov_cnt,
7573
offset -= iov[i].iov_len;
7674
}
7775
}
78-
assert(offset == 0);
7976
return done;
8077
}
8178

@@ -277,7 +274,6 @@ unsigned iov_copy(struct iovec *dst_iov, unsigned int dst_iov_cnt,
277274
bytes -= len;
278275
offset = 0;
279276
}
280-
assert(offset == 0);
281277
return j;
282278
}
283279

@@ -348,7 +344,6 @@ size_t qemu_iovec_concat_iov(QEMUIOVector *dst,
348344
soffset -= src_iov[i].iov_len;
349345
}
350346
}
351-
assert(soffset == 0); /* offset beyond end of src */
352347

353348
return done;
354349
}

0 commit comments

Comments
 (0)