git: 90b9a77ebeb8 - main - bhyve: support MTU configuration for SLIRP net backend
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 08 Jan 2026 17:09:32 UTC
The branch main has been updated by novel:
URL: https://cgit.FreeBSD.org/src/commit/?id=90b9a77ebeb8019fbd22b3cf992370cd9b0004a2
commit 90b9a77ebeb8019fbd22b3cf992370cd9b0004a2
Author: Roman Bogorodskiy <novel@FreeBSD.org>
AuthorDate: 2025-12-08 17:37:09 +0000
Commit: Roman Bogorodskiy <novel@FreeBSD.org>
CommitDate: 2026-01-08 17:01:13 +0000
bhyve: support MTU configuration for SLIRP net backend
Support configuring MTU for the SLIRP net backend, for example:
-s 1:0,virtio-net,slirp,mtu=2048,open
Update the manual page accordingly. While here, also document
MAC address configuration.
Reviewed by: markj
Approved by: markj
Sponsored by: The FreeBSD Foundation
MFC after: 1 month
Differential Revision: https://reviews.freebsd.org/D54133
---
usr.sbin/bhyve/bhyve.8 | 4 +++-
usr.sbin/bhyve/net_backend_slirp.c | 35 ++++++++++++++++++++++++++++++-----
usr.sbin/bhyve/slirp/slirp-helper.c | 22 ++++++++++++++--------
3 files changed, 47 insertions(+), 14 deletions(-)
diff --git a/usr.sbin/bhyve/bhyve.8 b/usr.sbin/bhyve/bhyve.8
index 496539f30885..4c73a119b1ed 100644
--- a/usr.sbin/bhyve/bhyve.8
+++ b/usr.sbin/bhyve/bhyve.8
@@ -25,7 +25,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd December 26, 2025
+.Dd January 5, 2026
.Dt BHYVE 8
.Os
.Sh NAME
@@ -542,6 +542,8 @@ considered unconnected.
.Cm slirp
.Op Cm \&,open
.Op Cm \&,hostfwd= Ar proto : Ar hostaddr : Ar hostport - Ar guestaddr : Ar guestport
+.Op Cm \&,mac= Ar xx:xx:xx:xx:xx:xx
+.Op Cm \&,mtu= Ar N
.Xc
.El
.Sm on
diff --git a/usr.sbin/bhyve/net_backend_slirp.c b/usr.sbin/bhyve/net_backend_slirp.c
index f2b483c5e314..6084ca31966d 100644
--- a/usr.sbin/bhyve/net_backend_slirp.c
+++ b/usr.sbin/bhyve/net_backend_slirp.c
@@ -62,15 +62,18 @@
#include "config.h"
#include "debug.h"
#include "mevent.h"
+#include "net_utils.h"
#include "net_backends.h"
#include "net_backends_priv.h"
-#define SLIRP_MTU 2048
+#define DEFAULT_MTU 2048
struct slirp_priv {
int s;
pid_t helper;
struct mevent *mevp;
+ size_t mtu;
+ uint8_t *buf;
};
extern char **environ;
@@ -86,6 +89,8 @@ slirp_init(struct net_backend *be, const char *devname __unused,
const char **argv;
char sockname[32];
int error, s[2];
+ const char *mtu_value;
+ size_t mtu;
if (socketpair(PF_LOCAL, SOCK_SEQPACKET | SOCK_NONBLOCK, 0, s) != 0) {
EPRINTLN("socketpair");
@@ -124,6 +129,25 @@ slirp_init(struct net_backend *be, const char *devname __unused,
EPRINTLN("nvlist_clone");
goto err;
}
+
+ mtu_value = get_config_value_node(config, "mtu");
+ if (mtu_value != NULL) {
+ if (net_parsemtu(mtu_value, &mtu)) {
+ EPRINTLN("Could not parse MTU");
+ goto err;
+ }
+ } else {
+ mtu = DEFAULT_MTU;
+ }
+ nvlist_add_number(config, "mtui", mtu);
+
+ priv->mtu = mtu;
+ priv->buf = malloc(mtu);
+ if (priv->buf == NULL) {
+ EPRINTLN("Could not allocate buffer");
+ goto err;
+ }
+
nvlist_add_string(config, "vmname", get_config_value("name"));
error = nvlist_send(s[0], config);
nvlist_destroy(config);
@@ -146,6 +170,7 @@ slirp_init(struct net_backend *be, const char *devname __unused,
return (0);
err:
+ free(priv->buf);
(void)close(s[0]);
(void)close(s[1]);
return (-1);
@@ -168,6 +193,8 @@ slirp_cleanup(struct net_backend *be)
{
struct slirp_priv *priv = NET_BE_PRIV(be);
+ free(priv->buf);
+
if (priv->helper > 0) {
int status;
@@ -184,17 +211,15 @@ static ssize_t
slirp_peek_recvlen(struct net_backend *be)
{
struct slirp_priv *priv = NET_BE_PRIV(be);
- uint8_t buf[SLIRP_MTU];
ssize_t n;
/*
* Copying into the buffer is totally unnecessary, but we don't
* implement MSG_TRUNC for SEQPACKET sockets.
*/
- n = recv(priv->s, buf, sizeof(buf), MSG_PEEK | MSG_DONTWAIT);
+ n = recv(priv->s, priv->buf, priv->mtu, MSG_PEEK | MSG_DONTWAIT);
if (n < 0)
return (errno == EWOULDBLOCK ? 0 : -1);
- assert((size_t)n <= SLIRP_MTU);
return (n);
}
@@ -218,7 +243,7 @@ slirp_recv(struct net_backend *be, const struct iovec *iov, int iovcnt)
return (0);
return (-1);
}
- assert(n <= SLIRP_MTU);
+ assert((size_t)n <= priv->mtu);
return (n);
}
diff --git a/usr.sbin/bhyve/slirp/slirp-helper.c b/usr.sbin/bhyve/slirp/slirp-helper.c
index 9fb9784662fe..36192c590eb1 100644
--- a/usr.sbin/bhyve/slirp/slirp-helper.c
+++ b/usr.sbin/bhyve/slirp/slirp-helper.c
@@ -38,8 +38,6 @@
#include "config.h"
#include "libslirp.h"
-#define SLIRP_MTU 2048
-
struct slirp_priv {
Slirp *slirp; /* libslirp handle */
int sock; /* data and control socket */
@@ -47,6 +45,8 @@ struct slirp_priv {
struct pollfd *pollfds;
size_t npollfds;
size_t lastpollfd;
+ size_t mtu;
+ uint8_t *buf;
};
typedef int (*slirp_add_hostxfwd_p_t)(Slirp *,
@@ -104,7 +104,7 @@ slirp_cb_send_packet(const void *buf, size_t len, void *param)
priv = param;
- assert(len <= SLIRP_MTU);
+ assert(len <= priv->mtu);
n = send(priv->sock, buf, len, MSG_EOR);
if (n < 0) {
warn("slirp_cb_send_packet: send");
@@ -289,16 +289,14 @@ slirp_pollfd_loop(struct slirp_priv *priv)
ssize_t n;
do {
- uint8_t buf[SLIRP_MTU];
-
- n = recv(priv->sock, buf, sizeof(buf),
+ n = recv(priv->sock, priv->buf, priv->mtu,
MSG_DONTWAIT);
if (n < 0) {
if (errno == EWOULDBLOCK)
break;
err(1, "recv");
}
- slirp_input_p(priv->slirp, buf, (int)n);
+ slirp_input_p(priv->slirp, priv->buf, (int)n);
} while (n >= 0);
}
}
@@ -464,6 +462,7 @@ main(int argc, char **argv)
const char *hostfwd, *vmname;
int ch, fd, sd;
bool restricted;
+ size_t mtu;
sd = -1;
while ((ch = getopt(argc, argv, "S:")) != -1) {
@@ -514,6 +513,13 @@ main(int argc, char **argv)
config = nvlist_recv(sd, 0);
if (config == NULL)
err(1, "nvlist_recv");
+
+ mtu = nvlist_get_number(config, "mtui");
+ priv.mtu = mtu;
+ priv.buf = malloc(mtu);
+ if (priv.buf == NULL)
+ err(1, "malloc");
+
vmname = get_config_value_node(config, "vmname");
if (vmname != NULL)
setproctitle("%s", vmname);
@@ -521,7 +527,7 @@ main(int argc, char **argv)
slirpconfig = (SlirpConfig){
.version = 4,
- .if_mtu = SLIRP_MTU,
+ .if_mtu = mtu,
.restricted = restricted,
.in_enabled = true,
.vnetwork.s_addr = htonl(0x0a000200), /* 10.0.2.0/24 */