The branch main has been updated by novel:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=90b9a77ebeb8019fbd22b3cf992370cd9b0004a2

commit 90b9a77ebeb8019fbd22b3cf992370cd9b0004a2
Author:     Roman Bogorodskiy <[email protected]>
AuthorDate: 2025-12-08 17:37:09 +0000
Commit:     Roman Bogorodskiy <[email protected]>
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 */

Reply via email to