Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/bhyve/net_backends.c
Show First 20 Lines • Show All 104 Lines • ▼ Show 20 Lines | struct net_backend { | ||||
* returns a positive value 'len', the scatter-gather vector | * returns a positive value 'len', the scatter-gather vector | ||||
* provided by the caller contains a packet with such length. | * provided by the caller contains a packet with such length. | ||||
* The function returns 0 if the backend doesn't have a new packet to | * The function returns 0 if the backend doesn't have a new packet to | ||||
* receive. | * receive. | ||||
*/ | */ | ||||
ssize_t (*recv)(struct net_backend *be, struct iovec *iov, int iovcnt); | ssize_t (*recv)(struct net_backend *be, struct iovec *iov, int iovcnt); | ||||
/* | /* | ||||
* Ask the backend to enable or disable receive operation in the | |||||
* backend. On return from a disable operation, it is guaranteed | |||||
* that the receive callback won't be called until receive is | |||||
* enabled again. Note however that it is up to the caller to make | |||||
* sure that netbe_recv() is not currently being executed by another | |||||
* thread. | |||||
*/ | |||||
void (*recv_enable)(struct net_backend *be); | |||||
void (*recv_disable)(struct net_backend *be); | |||||
/* | |||||
* Ask the backend for the virtio-net features it is able to | * Ask the backend for the virtio-net features it is able to | ||||
* support. Possible features are TSO, UFO and checksum offloading | * support. Possible features are TSO, UFO and checksum offloading | ||||
* in both rx and tx direction and for both IPv4 and IPv6. | * in both rx and tx direction and for both IPv4 and IPv6. | ||||
*/ | */ | ||||
uint64_t (*get_cap)(struct net_backend *be); | uint64_t (*get_cap)(struct net_backend *be); | ||||
/* | /* | ||||
* Tell the backend to enable/disable the specified virtio-net | * Tell the backend to enable/disable the specified virtio-net | ||||
jhb: Maybe use a 'bool enable' instead of 'int state' as then the code reads a bit more obviously in… | |||||
Done Inline ActionsI agree it is more readable the way you suggest. Some people prefer the other way, though. vmaffione: I agree it is more readable the way you suggest. Some people prefer the other way, though. | |||||
* features (capabilities). | * features (capabilities). | ||||
*/ | */ | ||||
int (*set_cap)(struct net_backend *be, uint64_t features, | int (*set_cap)(struct net_backend *be, uint64_t features, | ||||
unsigned int vnet_hdr_len); | unsigned int vnet_hdr_len); | ||||
struct pci_vtnet_softc *sc; | struct pci_vtnet_softc *sc; | ||||
int fd; | int fd; | ||||
▲ Show 20 Lines • Show All 114 Lines • ▼ Show 20 Lines | tap_recv(struct net_backend *be, struct iovec *iov, int iovcnt) | ||||
if (ret < 0 && errno == EWOULDBLOCK) { | if (ret < 0 && errno == EWOULDBLOCK) { | ||||
return (0); | return (0); | ||||
} | } | ||||
return (ret); | return (ret); | ||||
} | } | ||||
static void | |||||
tap_recv_enable(struct net_backend *be) | |||||
{ | |||||
struct tap_priv *priv = (struct tap_priv *)be->opaque; | |||||
mevent_enable(priv->mevp); | |||||
} | |||||
static void | |||||
tap_recv_disable(struct net_backend *be) | |||||
{ | |||||
struct tap_priv *priv = (struct tap_priv *)be->opaque; | |||||
mevent_disable(priv->mevp); | |||||
} | |||||
static uint64_t | static uint64_t | ||||
tap_get_cap(struct net_backend *be) | tap_get_cap(struct net_backend *be) | ||||
{ | { | ||||
return (0); /* no capabilities for now */ | return (0); /* no capabilities for now */ | ||||
} | } | ||||
static int | static int | ||||
tap_set_cap(struct net_backend *be, uint64_t features, | tap_set_cap(struct net_backend *be, uint64_t features, | ||||
unsigned vnet_hdr_len) | unsigned vnet_hdr_len) | ||||
{ | { | ||||
return ((features || vnet_hdr_len) ? -1 : 0); | return ((features || vnet_hdr_len) ? -1 : 0); | ||||
} | } | ||||
static struct net_backend tap_backend = { | static struct net_backend tap_backend = { | ||||
.prefix = "tap", | .prefix = "tap", | ||||
.priv_size = sizeof(struct tap_priv), | .priv_size = sizeof(struct tap_priv), | ||||
.init = tap_init, | .init = tap_init, | ||||
.cleanup = tap_cleanup, | .cleanup = tap_cleanup, | ||||
.send = tap_send, | .send = tap_send, | ||||
.recv = tap_recv, | .recv = tap_recv, | ||||
.recv_enable = tap_recv_enable, | |||||
.recv_disable = tap_recv_disable, | |||||
.get_cap = tap_get_cap, | .get_cap = tap_get_cap, | ||||
.set_cap = tap_set_cap, | .set_cap = tap_set_cap, | ||||
}; | }; | ||||
/* A clone of the tap backend, with a different prefix. */ | /* A clone of the tap backend, with a different prefix. */ | ||||
static struct net_backend vmnet_backend = { | static struct net_backend vmnet_backend = { | ||||
.prefix = "vmnet", | .prefix = "vmnet", | ||||
.priv_size = sizeof(struct tap_priv), | .priv_size = sizeof(struct tap_priv), | ||||
.init = tap_init, | .init = tap_init, | ||||
.cleanup = tap_cleanup, | .cleanup = tap_cleanup, | ||||
.send = tap_send, | .send = tap_send, | ||||
.recv = tap_recv, | .recv = tap_recv, | ||||
.recv_enable = tap_recv_enable, | |||||
.recv_disable = tap_recv_disable, | |||||
.get_cap = tap_get_cap, | .get_cap = tap_get_cap, | ||||
.set_cap = tap_set_cap, | .set_cap = tap_set_cap, | ||||
}; | }; | ||||
DATA_SET(net_backend_set, tap_backend); | DATA_SET(net_backend_set, tap_backend); | ||||
DATA_SET(net_backend_set, vmnet_backend); | DATA_SET(net_backend_set, vmnet_backend); | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 273 Lines • ▼ Show 20 Lines | netmap_recv(struct net_backend *be, struct iovec *iov, int iovcnt) | ||||
} while (slot->flags & NS_MOREFRAG); | } while (slot->flags & NS_MOREFRAG); | ||||
/* Release slots to netmap. */ | /* Release slots to netmap. */ | ||||
ring->head = ring->cur = head; | ring->head = ring->cur = head; | ||||
return (totlen); | return (totlen); | ||||
} | } | ||||
static void | |||||
netmap_recv_enable(struct net_backend *be) | |||||
{ | |||||
struct netmap_priv *priv = (struct netmap_priv *)be->opaque; | |||||
mevent_enable(priv->mevp); | |||||
} | |||||
static void | |||||
netmap_recv_disable(struct net_backend *be) | |||||
{ | |||||
struct netmap_priv *priv = (struct netmap_priv *)be->opaque; | |||||
mevent_disable(priv->mevp); | |||||
} | |||||
static struct net_backend netmap_backend = { | static struct net_backend netmap_backend = { | ||||
.prefix = "netmap", | .prefix = "netmap", | ||||
.priv_size = sizeof(struct netmap_priv), | .priv_size = sizeof(struct netmap_priv), | ||||
.init = netmap_init, | .init = netmap_init, | ||||
.cleanup = netmap_cleanup, | .cleanup = netmap_cleanup, | ||||
.send = netmap_send, | .send = netmap_send, | ||||
.recv = netmap_recv, | .recv = netmap_recv, | ||||
.recv_enable = netmap_recv_enable, | |||||
.recv_disable = netmap_recv_disable, | |||||
.get_cap = netmap_get_cap, | .get_cap = netmap_get_cap, | ||||
.set_cap = netmap_set_cap, | .set_cap = netmap_set_cap, | ||||
}; | }; | ||||
/* A clone of the netmap backend, with a different prefix. */ | /* A clone of the netmap backend, with a different prefix. */ | ||||
static struct net_backend vale_backend = { | static struct net_backend vale_backend = { | ||||
.prefix = "vale", | .prefix = "vale", | ||||
.priv_size = sizeof(struct netmap_priv), | .priv_size = sizeof(struct netmap_priv), | ||||
.init = netmap_init, | .init = netmap_init, | ||||
.cleanup = netmap_cleanup, | .cleanup = netmap_cleanup, | ||||
.send = netmap_send, | .send = netmap_send, | ||||
.recv = netmap_recv, | .recv = netmap_recv, | ||||
.recv_enable = netmap_recv_enable, | |||||
.recv_disable = netmap_recv_disable, | |||||
.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); | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 199 Lines • ▼ Show 20 Lines | netbe_rx_discard(struct net_backend *be) | ||||
struct iovec iov; | struct iovec iov; | ||||
iov.iov_base = dummybuf; | iov.iov_base = dummybuf; | ||||
iov.iov_len = sizeof(dummybuf); | iov.iov_len = sizeof(dummybuf); | ||||
return netbe_recv(be, &iov, 1); | return netbe_recv(be, &iov, 1); | ||||
} | } | ||||
void | |||||
netbe_rx_disable(struct net_backend *be) | |||||
{ | |||||
return be->recv_enable(be); | |||||
} | |||||
void | |||||
netbe_rx_enable(struct net_backend *be) | |||||
{ | |||||
return be->recv_disable(be); | |||||
} |
Maybe use a 'bool enable' instead of 'int state' as then the code reads a bit more obviously in backends, e.g.
I kind of wish there was a better name of the function pointer than 'recv_enable' as it's also used to disable. I honestly wouldn't mind if you just had two callbacks 'recv_enable' and 'recv_disable' and dropped the 'state' parameter entirely. I think that would ultimately be the most readable.