Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/bhyve/net_backends.c
Show First 20 Lines • Show All 92 Lines • ▼ Show 20 Lines | struct net_backend { | ||||
const char *prefix; /* prefix matching this backend */ | const char *prefix; /* prefix matching this backend */ | ||||
/* | /* | ||||
* Routines used to initialize and cleanup the resources needed | * Routines used to initialize and cleanup the resources needed | ||||
* by a backend. The cleanup function is used internally, | * by a backend. The cleanup function is used internally, | ||||
* and should not be called by the frontend. | * and should not be called by the frontend. | ||||
*/ | */ | ||||
int (*init)(struct net_backend *be, const char *devname, | int (*init)(struct net_backend *be, const char *devname, | ||||
nvlist_t *nvl, net_be_rxeof_t cb, void *param); | config_node_t *node, net_be_rxeof_t cb, void *param); | ||||
void (*cleanup)(struct net_backend *be); | void (*cleanup)(struct net_backend *be); | ||||
/* | /* | ||||
* Called to serve a guest transmit request. The scatter-gather | * Called to serve a guest transmit request. The scatter-gather | ||||
* vector provided by the caller has 'iovcnt' elements and contains | * vector provided by the caller has 'iovcnt' elements and contains | ||||
* the packet to send. | * the packet to send. | ||||
*/ | */ | ||||
ssize_t (*send)(struct net_backend *be, const struct iovec *iov, | ssize_t (*send)(struct net_backend *be, const struct iovec *iov, | ||||
▲ Show 20 Lines • Show All 91 Lines • ▼ Show 20 Lines | tap_cleanup(struct net_backend *be) | ||||
if (be->fd != -1) { | if (be->fd != -1) { | ||||
close(be->fd); | close(be->fd); | ||||
be->fd = -1; | be->fd = -1; | ||||
} | } | ||||
} | } | ||||
static int | static int | ||||
tap_init(struct net_backend *be, const char *devname, | tap_init(struct net_backend *be, const char *devname, | ||||
nvlist_t *nvl, net_be_rxeof_t cb, void *param) | config_node_t *node, net_be_rxeof_t cb, void *param) | ||||
yuripv: indentation? | |||||
{ | { | ||||
struct tap_priv *priv = (struct tap_priv *)be->opaque; | struct tap_priv *priv = (struct tap_priv *)be->opaque; | ||||
char tbuf[80]; | char tbuf[80]; | ||||
int opt = 1; | int opt = 1; | ||||
#ifndef WITHOUT_CAPSICUM | #ifndef WITHOUT_CAPSICUM | ||||
cap_rights_t rights; | cap_rights_t rights; | ||||
#endif | #endif | ||||
▲ Show 20 Lines • Show All 177 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* Netgraph backend | * Netgraph backend | ||||
*/ | */ | ||||
#define NG_SBUF_MAX_SIZE (4 * 1024 * 1024) | #define NG_SBUF_MAX_SIZE (4 * 1024 * 1024) | ||||
static int | static int | ||||
ng_init(struct net_backend *be, const char *devname, | ng_init(struct net_backend *be, const char *devname, | ||||
nvlist_t *nvl, net_be_rxeof_t cb, void *param) | config_node_t *node, net_be_rxeof_t cb, void *param) | ||||
yuripvUnsubmitted Done Inline Actionsindentation? yuripv: indentation? | |||||
{ | { | ||||
struct tap_priv *p = (struct tap_priv *)be->opaque; | struct tap_priv *p = (struct tap_priv *)be->opaque; | ||||
struct ngm_connect ngc; | struct ngm_connect ngc; | ||||
const char *value, *nodename; | const char *value, *nodename; | ||||
int sbsz; | int sbsz; | ||||
int ctrl_sock; | int ctrl_sock; | ||||
int flags; | int flags; | ||||
unsigned long maxsbsz; | unsigned long maxsbsz; | ||||
size_t msbsz; | size_t msbsz; | ||||
#ifndef WITHOUT_CAPSICUM | #ifndef WITHOUT_CAPSICUM | ||||
cap_rights_t rights; | cap_rights_t rights; | ||||
#endif | #endif | ||||
if (cb == NULL) { | if (cb == NULL) { | ||||
WPRINTF(("Netgraph backend requires non-NULL callback")); | WPRINTF(("Netgraph backend requires non-NULL callback")); | ||||
return (-1); | return (-1); | ||||
} | } | ||||
be->fd = -1; | be->fd = -1; | ||||
memset(&ngc, 0, sizeof(ngc)); | memset(&ngc, 0, sizeof(ngc)); | ||||
value = get_config_value_node(nvl, "path"); | value = get_config_value_node(node, "path"); | ||||
if (value == NULL) { | if (value == NULL) { | ||||
WPRINTF(("path must be provided")); | WPRINTF(("path must be provided")); | ||||
return (-1); | return (-1); | ||||
} | } | ||||
strncpy(ngc.path, value, NG_PATHSIZ - 1); | strncpy(ngc.path, value, NG_PATHSIZ - 1); | ||||
value = get_config_value_node(nvl, "hook"); | value = get_config_value_node(node, "hook"); | ||||
if (value == NULL) | if (value == NULL) | ||||
value = "vmlink"; | value = "vmlink"; | ||||
strncpy(ngc.ourhook, value, NG_HOOKSIZ - 1); | strncpy(ngc.ourhook, value, NG_HOOKSIZ - 1); | ||||
value = get_config_value_node(nvl, "peerhook"); | value = get_config_value_node(node, "peerhook"); | ||||
if (value == NULL) { | if (value == NULL) { | ||||
WPRINTF(("peer hook must be provided")); | WPRINTF(("peer hook must be provided")); | ||||
return (-1); | return (-1); | ||||
} | } | ||||
strncpy(ngc.peerhook, value, NG_HOOKSIZ - 1); | strncpy(ngc.peerhook, value, NG_HOOKSIZ - 1); | ||||
nodename = get_config_value_node(nvl, "socket"); | nodename = get_config_value_node(node, "socket"); | ||||
if (NgMkSockNode(nodename, | if (NgMkSockNode(nodename, | ||||
&ctrl_sock, &be->fd) < 0) { | &ctrl_sock, &be->fd) < 0) { | ||||
WPRINTF(("can't get Netgraph sockets")); | WPRINTF(("can't get Netgraph sockets")); | ||||
return (-1); | return (-1); | ||||
} | } | ||||
if (NgSendMsg(ctrl_sock, ".", | if (NgSendMsg(ctrl_sock, ".", | ||||
NGM_GENERIC_COOKIE, | NGM_GENERIC_COOKIE, | ||||
▲ Show 20 Lines • Show All 174 Lines • ▼ Show 20 Lines | netmap_set_cap(struct net_backend *be, uint64_t features, | ||||
unsigned vnet_hdr_len) | unsigned vnet_hdr_len) | ||||
{ | { | ||||
return (netmap_set_vnet_hdr_len(be, vnet_hdr_len)); | return (netmap_set_vnet_hdr_len(be, vnet_hdr_len)); | ||||
} | } | ||||
static int | static int | ||||
netmap_init(struct net_backend *be, const char *devname, | netmap_init(struct net_backend *be, const char *devname, | ||||
nvlist_t *nvl, net_be_rxeof_t cb, void *param) | config_node_t *node, net_be_rxeof_t cb, void *param) | ||||
yuripvUnsubmitted Done Inline Actionsindentation? yuripv: indentation? | |||||
{ | { | ||||
struct netmap_priv *priv = (struct netmap_priv *)be->opaque; | struct netmap_priv *priv = (struct netmap_priv *)be->opaque; | ||||
strlcpy(priv->ifname, devname, sizeof(priv->ifname)); | strlcpy(priv->ifname, devname, sizeof(priv->ifname)); | ||||
priv->ifname[sizeof(priv->ifname) - 1] = '\0'; | priv->ifname[sizeof(priv->ifname) - 1] = '\0'; | ||||
priv->nmd = nm_open(priv->ifname, NULL, NETMAP_NO_TX_POLL, NULL); | priv->nmd = nm_open(priv->ifname, NULL, NETMAP_NO_TX_POLL, NULL); | ||||
if (priv->nmd == NULL) { | if (priv->nmd == NULL) { | ||||
▲ Show 20 Lines • Show All 244 Lines • ▼ Show 20 Lines | static struct net_backend vale_backend = { | ||||
.get_cap = netmap_get_cap, | .get_cap = netmap_get_cap, | ||||
.set_cap = netmap_set_cap, | .set_cap = netmap_set_cap, | ||||
}; | }; | ||||
DATA_SET(net_backend_set, netmap_backend); | DATA_SET(net_backend_set, netmap_backend); | ||||
DATA_SET(net_backend_set, vale_backend); | DATA_SET(net_backend_set, vale_backend); | ||||
int | int | ||||
netbe_legacy_config(nvlist_t *nvl, const char *opts) | netbe_legacy_config(config_node_t *node, const char *opts) | ||||
{ | { | ||||
char *backend, *cp; | char *backend, *cp; | ||||
if (opts == NULL) | if (opts == NULL) | ||||
return (0); | return (0); | ||||
cp = strchr(opts, ','); | cp = strchr(opts, ','); | ||||
if (cp == NULL) { | if (cp == NULL) { | ||||
set_config_value_node(nvl, "backend", opts); | set_config_value_node(node, "backend", opts); | ||||
return (0); | return (0); | ||||
} | } | ||||
backend = strndup(opts, cp - opts); | backend = strndup(opts, cp - opts); | ||||
set_config_value_node(nvl, "backend", backend); | set_config_value_node(node, "backend", backend); | ||||
free(backend); | free(backend); | ||||
return (pci_parse_legacy_config(nvl, cp + 1)); | return (pci_parse_legacy_config(node, cp + 1)); | ||||
} | } | ||||
/* | /* | ||||
* Initialize a backend and attach to the frontend. | * Initialize a backend and attach to the frontend. | ||||
* This is called during frontend initialization. | * This is called during frontend initialization. | ||||
* @ret is a pointer to the backend to be initialized | * @ret is a pointer to the backend to be initialized | ||||
* @devname is the backend-name as supplied on the command line, | * @devname is the backend-name as supplied on the command line, | ||||
* e.g. -s 2:0,frontend-name,backend-name[,other-args] | * e.g. -s 2:0,frontend-name,backend-name[,other-args] | ||||
* @cb is the receive callback supplied by the frontend, | * @cb is the receive callback supplied by the frontend, | ||||
* and it is invoked in the event loop when a receive | * and it is invoked in the event loop when a receive | ||||
* event is generated in the hypervisor, | * event is generated in the hypervisor, | ||||
* @param is a pointer to the frontend, and normally used as | * @param is a pointer to the frontend, and normally used as | ||||
* the argument for the callback. | * the argument for the callback. | ||||
*/ | */ | ||||
int | int | ||||
netbe_init(struct net_backend **ret, nvlist_t *nvl, net_be_rxeof_t cb, | netbe_init(struct net_backend **ret, config_node_t *node, net_be_rxeof_t cb, | ||||
void *param) | void *param) | ||||
{ | { | ||||
struct net_backend **pbe, *nbe, *tbe = NULL; | struct net_backend **pbe, *nbe, *tbe = NULL; | ||||
const char *value; | const char *value; | ||||
char *devname; | char *devname; | ||||
int err; | int err; | ||||
value = get_config_value_node(nvl, "backend"); | value = get_config_value_node(node, "backend"); | ||||
if (value == NULL) { | if (value == NULL) { | ||||
return (-1); | return (-1); | ||||
} | } | ||||
devname = strdup(value); | devname = strdup(value); | ||||
/* | /* | ||||
* Find the network backend that matches the user-provided | * Find the network backend that matches the user-provided | ||||
* device name. net_backend_set is built using a linker set. | * device name. net_backend_set is built using a linker set. | ||||
Show All 21 Lines | netbe_init(struct net_backend **ret, config_node_t *node, net_be_rxeof_t cb, | ||||
nbe = calloc(1, sizeof(*nbe) + tbe->priv_size); | nbe = calloc(1, sizeof(*nbe) + tbe->priv_size); | ||||
*nbe = *tbe; /* copy the template */ | *nbe = *tbe; /* copy the template */ | ||||
nbe->fd = -1; | nbe->fd = -1; | ||||
nbe->sc = param; | nbe->sc = param; | ||||
nbe->be_vnet_hdr_len = 0; | nbe->be_vnet_hdr_len = 0; | ||||
nbe->fe_vnet_hdr_len = 0; | nbe->fe_vnet_hdr_len = 0; | ||||
/* Initialize the backend. */ | /* Initialize the backend. */ | ||||
err = nbe->init(nbe, devname, nvl, cb, param); | err = nbe->init(nbe, devname, node, cb, param); | ||||
if (err) { | if (err) { | ||||
free(devname); | free(devname); | ||||
free(nbe); | free(nbe); | ||||
return (err); | return (err); | ||||
} | } | ||||
*ret = nbe; | *ret = nbe; | ||||
free(devname); | free(devname); | ||||
▲ Show 20 Lines • Show All 112 Lines • Show Last 20 Lines |
indentation?