Skip to content

Commit

Permalink
Merge tag 'net-pull-request' of https://github.com/jasowang/qemu into…
Browse files Browse the repository at this point in the history
… staging

# -----BEGIN PGP SIGNATURE-----
# Version: GnuPG v1
#
# iQEcBAABAgAGBQJj7xKYAAoJEO8Ells5jWIRDZQH/Rao24sq3j97qE5RzekvANzq
# GnHUyLnl3yeOSNumv2BJInZTvgUpYL2etGQr3DtGRwOrr7w1vKB3zhY3V3jQefkh
# f4rsEGkamL/qM2N2cGUIUSqevo7OGnP8aQojpEi4MWWZ30B3L6jqd4NqyA1gyndV
# 1eBkpR+BY2PjcLbgvFUZEXeAn/vapE5NKULXUGhg5mMvgwYH3CgZXpqqkxr876za
# S4rZMtReXKNeid14Z35SUjJdV2WKYmo/lN9+GQxF2YNLmDC3RtuFQVm038erSqvs
# uLVSg8tiIlCyOcSDpR/BARNrxVwzlJp5X6ocapHubS/i0Rp/Zo7ezSk/XWH1gfU=
# =UbzF
# -----END PGP SIGNATURE-----
# gpg: Signature made Fri 17 Feb 2023 05:37:28 GMT
# gpg:                using RSA key EF04965B398D6211
# gpg: Good signature from "Jason Wang (Jason Wang on RedHat) <[email protected]>" [marginal]
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg:          It is not certain that the signature belongs to the owner.
# Primary key fingerprint: 215D 46F4 8246 689E C77F  3562 EF04 965B 398D 6211

* tag 'net-pull-request' of https://github.com/jasowang/qemu:
  vdpa: fix VHOST_BACKEND_F_IOTLB_ASID flag check
  net: stream: add a new option to automatically reconnect
  vmnet: stop recieving events when VM is stopped
  net: Increase L2TPv3 buffer to fit jumboframes
  hw/net/vmxnet3: allow VMXNET3_MAX_MTU itself as a value
  hw/net/lan9118: log [read|write]b when mode_16bit is enabled rather than abort
  net: Replace "Supported NIC models" with "Available NIC models"
  net: Restore printing of the help text with "-nic help"
  net: Move the code to collect available NIC models to a separate function

Signed-off-by: Peter Maydell <[email protected]>
  • Loading branch information
pm215 committed Feb 21, 2023
2 parents 4919d0c + 525ae11 commit 79b677d
Show file tree
Hide file tree
Showing 13 changed files with 272 additions and 61 deletions.
17 changes: 8 additions & 9 deletions hw/net/lan9118.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
#include "migration/vmstate.h"
#include "net/net.h"
#include "net/eth.h"
#include "hw/hw.h"
#include "hw/irq.h"
#include "hw/net/lan9118.h"
#include "hw/ptimer.h"
Expand All @@ -32,12 +31,8 @@
#ifdef DEBUG_LAN9118
#define DPRINTF(fmt, ...) \
do { printf("lan9118: " fmt , ## __VA_ARGS__); } while (0)
#define BADF(fmt, ...) \
do { hw_error("lan9118: error: " fmt , ## __VA_ARGS__);} while (0)
#else
#define DPRINTF(fmt, ...) do {} while(0)
#define BADF(fmt, ...) \
do { fprintf(stderr, "lan9118: error: " fmt , ## __VA_ARGS__);} while (0)
#endif

/* The tx and rx fifo ports are a range of aliased 32-bit registers */
Expand Down Expand Up @@ -848,7 +843,8 @@ static uint32_t do_phy_read(lan9118_state *s, int reg)
case 30: /* Interrupt mask */
return s->phy_int_mask;
default:
BADF("PHY read reg %d\n", reg);
qemu_log_mask(LOG_GUEST_ERROR,
"do_phy_read: PHY read reg %d\n", reg);
return 0;
}
}
Expand Down Expand Up @@ -876,7 +872,8 @@ static void do_phy_write(lan9118_state *s, int reg, uint32_t val)
phy_update_irq(s);
break;
default:
BADF("PHY write reg %d = 0x%04x\n", reg, val);
qemu_log_mask(LOG_GUEST_ERROR,
"do_phy_write: PHY write reg %d = 0x%04x\n", reg, val);
}
}

Expand Down Expand Up @@ -1209,7 +1206,8 @@ static void lan9118_16bit_mode_write(void *opaque, hwaddr offset,
return;
}

hw_error("lan9118_write: Bad size 0x%x\n", size);
qemu_log_mask(LOG_GUEST_ERROR,
"lan9118_16bit_mode_write: Bad size 0x%x\n", size);
}

static uint64_t lan9118_readl(void *opaque, hwaddr offset,
Expand Down Expand Up @@ -1324,7 +1322,8 @@ static uint64_t lan9118_16bit_mode_read(void *opaque, hwaddr offset,
return lan9118_readl(opaque, offset, size);
}

hw_error("lan9118_read: Bad size 0x%x\n", size);
qemu_log_mask(LOG_GUEST_ERROR,
"lan9118_16bit_mode_read: Bad size 0x%x\n", size);
return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion hw/net/vmxnet3.c
Original file line number Diff line number Diff line change
Expand Up @@ -1441,7 +1441,7 @@ static void vmxnet3_activate_device(VMXNET3State *s)
vmxnet3_setup_rx_filtering(s);
/* Cache fields from shared memory */
s->mtu = VMXNET3_READ_DRV_SHARED32(d, s->drv_shmem, devRead.misc.mtu);
assert(VMXNET3_MIN_MTU <= s->mtu && s->mtu < VMXNET3_MAX_MTU);
assert(VMXNET3_MIN_MTU <= s->mtu && s->mtu <= VMXNET3_MAX_MTU);
VMW_CFPRN("MTU is %u", s->mtu);

s->max_rx_frags =
Expand Down
29 changes: 1 addition & 28 deletions hw/pci/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -1789,7 +1789,6 @@ PCIDevice *pci_nic_init_nofail(NICInfo *nd, PCIBus *rootbus,
const char *default_devaddr)
{
const char *devaddr = nd->devaddr ? nd->devaddr : default_devaddr;
GSList *list;
GPtrArray *pci_nic_models;
PCIBus *bus;
PCIDevice *pci_dev;
Expand All @@ -1804,33 +1803,7 @@ PCIDevice *pci_nic_init_nofail(NICInfo *nd, PCIBus *rootbus,
nd->model = g_strdup("virtio-net-pci");
}

list = object_class_get_list_sorted(TYPE_PCI_DEVICE, false);
pci_nic_models = g_ptr_array_new();
while (list) {
DeviceClass *dc = OBJECT_CLASS_CHECK(DeviceClass, list->data,
TYPE_DEVICE);
GSList *next;
if (test_bit(DEVICE_CATEGORY_NETWORK, dc->categories) &&
dc->user_creatable) {
const char *name = object_class_get_name(list->data);
/*
* A network device might also be something else than a NIC, see
* e.g. the "rocker" device. Thus we have to look for the "netdev"
* property, too. Unfortunately, some devices like virtio-net only
* create this property during instance_init, so we have to create
* a temporary instance here to be able to check it.
*/
Object *obj = object_new_with_class(OBJECT_CLASS(dc));
if (object_property_find(obj, "netdev")) {
g_ptr_array_add(pci_nic_models, (gpointer)name);
}
object_unref(obj);
}
next = list->next;
g_slist_free_1(list);
list = next;
}
g_ptr_array_add(pci_nic_models, NULL);
pci_nic_models = qemu_get_nic_models(TYPE_PCI_DEVICE);

if (qemu_show_nic_models(nd->model, (const char **)pci_nic_models->pdata)) {
exit(0);
Expand Down
14 changes: 14 additions & 0 deletions include/net/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,20 @@ void net_socket_rs_init(SocketReadState *rs,
bool vnet_hdr);
NetClientState *qemu_get_peer(NetClientState *nc, int queue_index);

/**
* qemu_get_nic_models:
* @device_type: Defines which devices should be taken into consideration
* (e.g. TYPE_DEVICE for all devices, or TYPE_PCI_DEVICE for PCI)
*
* Get an array of pointers to names of NIC devices that are available in
* the QEMU binary. The array is terminated with a NULL pointer entry.
* The caller is responsible for freeing the memory when it is not required
* anymore, e.g. with g_ptr_array_free(..., true).
*
* Returns: Pointer to the array that contains the pointers to the names.
*/
GPtrArray *qemu_get_nic_models(const char *device_type);

/* NIC info */

#define MAX_NICS 8
Expand Down
2 changes: 1 addition & 1 deletion net/l2tpv3.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
*/

#define BUFFER_ALIGN sysconf(_SC_PAGESIZE)
#define BUFFER_SIZE 2048
#define BUFFER_SIZE 16384
#define IOVSIZE 2
#define MAX_L2TPV3_MSGCNT 64
#define MAX_L2TPV3_IOVCNT (MAX_L2TPV3_MSGCNT * IOVSIZE)
Expand Down
50 changes: 47 additions & 3 deletions net/net.c
Original file line number Diff line number Diff line change
Expand Up @@ -899,6 +899,40 @@ static int nic_get_free_idx(void)
return -1;
}

GPtrArray *qemu_get_nic_models(const char *device_type)
{
GPtrArray *nic_models = g_ptr_array_new();
GSList *list = object_class_get_list_sorted(device_type, false);

while (list) {
DeviceClass *dc = OBJECT_CLASS_CHECK(DeviceClass, list->data,
TYPE_DEVICE);
GSList *next;
if (test_bit(DEVICE_CATEGORY_NETWORK, dc->categories) &&
dc->user_creatable) {
const char *name = object_class_get_name(list->data);
/*
* A network device might also be something else than a NIC, see
* e.g. the "rocker" device. Thus we have to look for the "netdev"
* property, too. Unfortunately, some devices like virtio-net only
* create this property during instance_init, so we have to create
* a temporary instance here to be able to check it.
*/
Object *obj = object_new_with_class(OBJECT_CLASS(dc));
if (object_property_find(obj, "netdev")) {
g_ptr_array_add(nic_models, (gpointer)name);
}
object_unref(obj);
}
next = list->next;
g_slist_free_1(list);
list = next;
}
g_ptr_array_add(nic_models, NULL);

return nic_models;
}

int qemu_show_nic_models(const char *arg, const char *const *models)
{
int i;
Expand All @@ -907,7 +941,7 @@ int qemu_show_nic_models(const char *arg, const char *const *models)
return 0;
}

printf("Supported NIC models:\n");
printf("Available NIC models:\n");
for (i = 0 ; models[i]; i++) {
printf("%s\n", models[i]);
}
Expand Down Expand Up @@ -1508,8 +1542,18 @@ static int net_param_nic(void *dummy, QemuOpts *opts, Error **errp)
const char *type;

type = qemu_opt_get(opts, "type");
if (type && g_str_equal(type, "none")) {
return 0; /* Nothing to do, default_net is cleared in vl.c */
if (type) {
if (g_str_equal(type, "none")) {
return 0; /* Nothing to do, default_net is cleared in vl.c */
}
if (is_help_option(type)) {
GPtrArray *nic_models = qemu_get_nic_models(TYPE_DEVICE);
show_netdevs();
printf("\n");
qemu_show_nic_models(type, (const char **)nic_models->pdata);
g_ptr_array_free(nic_models, true);
exit(0);
}
}

idx = nic_get_free_idx();
Expand Down
53 changes: 52 additions & 1 deletion net/stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
#include "io/channel-socket.h"
#include "io/net-listener.h"
#include "qapi/qapi-events-net.h"
#include "qapi/qapi-visit-sockets.h"
#include "qapi/clone-visitor.h"

typedef struct NetStreamState {
NetClientState nc;
Expand All @@ -49,11 +51,15 @@ typedef struct NetStreamState {
guint ioc_write_tag;
SocketReadState rs;
unsigned int send_index; /* number of bytes sent*/
uint32_t reconnect;
guint timer_tag;
SocketAddress *addr;
} NetStreamState;

static void net_stream_listen(QIONetListener *listener,
QIOChannelSocket *cioc,
void *opaque);
static void net_stream_arm_reconnect(NetStreamState *s);

static gboolean net_stream_writable(QIOChannel *ioc,
GIOCondition condition,
Expand Down Expand Up @@ -170,6 +176,7 @@ static gboolean net_stream_send(QIOChannel *ioc,
qemu_set_info_str(&s->nc, "%s", "");

qapi_event_send_netdev_stream_disconnected(s->nc.name);
net_stream_arm_reconnect(s);

return G_SOURCE_REMOVE;
}
Expand All @@ -187,6 +194,14 @@ static gboolean net_stream_send(QIOChannel *ioc,
static void net_stream_cleanup(NetClientState *nc)
{
NetStreamState *s = DO_UPCAST(NetStreamState, nc, nc);
if (s->timer_tag) {
g_source_remove(s->timer_tag);
s->timer_tag = 0;
}
if (s->addr) {
qapi_free_SocketAddress(s->addr);
s->addr = NULL;
}
if (s->ioc) {
if (QIO_CHANNEL_SOCKET(s->ioc)->fd != -1) {
if (s->ioc_read_tag) {
Expand Down Expand Up @@ -346,12 +361,37 @@ static void net_stream_client_connected(QIOTask *task, gpointer opaque)
error:
object_unref(OBJECT(s->ioc));
s->ioc = NULL;
net_stream_arm_reconnect(s);
}

static gboolean net_stream_reconnect(gpointer data)
{
NetStreamState *s = data;
QIOChannelSocket *sioc;

s->timer_tag = 0;

sioc = qio_channel_socket_new();
s->ioc = QIO_CHANNEL(sioc);
qio_channel_socket_connect_async(sioc, s->addr,
net_stream_client_connected, s,
NULL, NULL);
return G_SOURCE_REMOVE;
}

static void net_stream_arm_reconnect(NetStreamState *s)
{
if (s->reconnect && s->timer_tag == 0) {
s->timer_tag = g_timeout_add_seconds(s->reconnect,
net_stream_reconnect, s);
}
}

static int net_stream_client_init(NetClientState *peer,
const char *model,
const char *name,
SocketAddress *addr,
uint32_t reconnect,
Error **errp)
{
NetStreamState *s;
Expand All @@ -364,6 +404,10 @@ static int net_stream_client_init(NetClientState *peer,
s->ioc = QIO_CHANNEL(sioc);
s->nc.link_down = true;

s->reconnect = reconnect;
if (reconnect) {
s->addr = QAPI_CLONE(SocketAddress, addr);
}
qio_channel_socket_connect_async(sioc, addr,
net_stream_client_connected, s,
NULL, NULL);
Expand All @@ -380,7 +424,14 @@ int net_init_stream(const Netdev *netdev, const char *name,
sock = &netdev->u.stream;

if (!sock->has_server || !sock->server) {
return net_stream_client_init(peer, "stream", name, sock->addr, errp);
return net_stream_client_init(peer, "stream", name, sock->addr,
sock->has_reconnect ? sock->reconnect : 0,
errp);
}
if (sock->has_reconnect) {
error_setg(errp, "'reconnect' option is incompatible with "
"socket in server mode");
return -1;
}
return net_stream_server_init(peer, "stream", name, sock->addr, errp);
}
2 changes: 1 addition & 1 deletion net/vhost-vdpa.c
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ static int vhost_vdpa_net_cvq_start(NetClientState *nc)
g_strerror(errno), errno);
return -1;
}
if (!(backend_features & VHOST_BACKEND_F_IOTLB_ASID) ||
if (!(backend_features & BIT_ULL(VHOST_BACKEND_F_IOTLB_ASID)) ||
!vhost_vdpa_net_valid_svq_features(v->dev->features, NULL)) {
return 0;
}
Expand Down
Loading

0 comments on commit 79b677d

Please sign in to comment.