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
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user