Index: head/usr.sbin/bhyve/net_backends.h =================================================================== --- head/usr.sbin/bhyve/net_backends.h +++ head/usr.sbin/bhyve/net_backends.h @@ -37,7 +37,7 @@ /* Interface between network frontends and the network backends. */ typedef void (*net_be_rxeof_t)(int, enum ev_type, void *param); -int netbe_init(net_backend_t **be, const char *devname, net_be_rxeof_t cb, +int netbe_init(net_backend_t **be, const char *opts, net_be_rxeof_t cb, void *param); void netbe_cleanup(net_backend_t *be); uint64_t netbe_get_cap(net_backend_t *be); Index: head/usr.sbin/bhyve/net_backends.c =================================================================== --- head/usr.sbin/bhyve/net_backends.c +++ head/usr.sbin/bhyve/net_backends.c @@ -91,7 +91,7 @@ * and should not be called by the frontend. */ int (*init)(struct net_backend *be, const char *devname, - net_be_rxeof_t cb, void *param); + const char *opts, net_be_rxeof_t cb, void *param); void (*cleanup)(struct net_backend *be); /* @@ -199,7 +199,7 @@ static int tap_init(struct net_backend *be, const char *devname, - net_be_rxeof_t cb, void *param) + const char *opts, net_be_rxeof_t cb, void *param) { struct tap_priv *priv = (struct tap_priv *)be->opaque; char tbuf[80]; @@ -473,7 +473,7 @@ static int netmap_init(struct net_backend *be, const char *devname, - net_be_rxeof_t cb, void *param) + const char *opts, net_be_rxeof_t cb, void *param) { struct netmap_priv *priv = (struct netmap_priv *)be->opaque; @@ -746,12 +746,22 @@ * the argument for the callback. */ int -netbe_init(struct net_backend **ret, const char *devname, net_be_rxeof_t cb, +netbe_init(struct net_backend **ret, const char *opts, net_be_rxeof_t cb, void *param) { struct net_backend **pbe, *nbe, *tbe = NULL; + char *devname; + char *options; int err; + devname = options = strdup(opts); + + if (devname == NULL) { + return (-1); + } + + devname = strsep(&options, ","); + /* * Find the network backend that matches the user-provided * device name. net_backend_set is built using a linker set. @@ -771,8 +781,11 @@ } *ret = NULL; - if (tbe == NULL) + if (tbe == NULL) { + free(devname); return (EINVAL); + } + nbe = calloc(1, sizeof(*nbe) + tbe->priv_size); *nbe = *tbe; /* copy the template */ nbe->fd = -1; @@ -781,13 +794,15 @@ nbe->fe_vnet_hdr_len = 0; /* Initialize the backend. */ - err = nbe->init(nbe, devname, cb, param); + err = nbe->init(nbe, devname, options, cb, param); if (err) { + free(devname); free(nbe); return (err); } *ret = nbe; + free(devname); return (0); } Index: head/usr.sbin/bhyve/pci_e82545.c =================================================================== --- head/usr.sbin/bhyve/pci_e82545.c +++ head/usr.sbin/bhyve/pci_e82545.c @@ -2281,7 +2281,7 @@ { char nstr[80]; struct e82545_softc *sc; - char *devname; + char *optscopy; char *vtopts; int mac_provided; @@ -2332,7 +2332,7 @@ if (opts != NULL) { int err = 0; - devname = vtopts = strdup(opts); + optscopy = vtopts = strdup(opts); (void) strsep(&vtopts, ","); /* @@ -2357,15 +2357,18 @@ } } + free(optscopy); + if (err) { - free(devname); + free(sc); return (err); } - err = netbe_init(&sc->esc_be, devname, e82545_rx_callback, sc); - free(devname); - if (err) + err = netbe_init(&sc->esc_be, opts, e82545_rx_callback, sc); + if (err) { + free(sc); return (err); + } } if (!mac_provided) { Index: head/usr.sbin/bhyve/pci_virtio_net.c =================================================================== --- head/usr.sbin/bhyve/pci_virtio_net.c +++ head/usr.sbin/bhyve/pci_virtio_net.c @@ -577,12 +577,12 @@ mac_provided = 0; mtu_provided = 0; if (opts != NULL) { - char *devname; + char *optscopy; char *vtopts; int err = 0; /* Get the device name. */ - devname = vtopts = strdup(opts); + optscopy = vtopts = strdup(opts); (void) strsep(&vtopts, ","); /* @@ -618,15 +618,16 @@ } } + free(optscopy); + if (err) { - free(devname); free(sc); return (err); } - err = netbe_init(&sc->vsc_be, devname, pci_vtnet_rx_callback, + err = netbe_init(&sc->vsc_be, opts, pci_vtnet_rx_callback, sc); - free(devname); + if (err) { free(sc); return (err);