mirror of
https://github.com/openvswitch/ovs
synced 2025-08-31 14:25:26 +00:00
netdev: Send ofpbuf directly to netdev.
DPDK netdev need to access ofpbuf while sending buffer. Following patch changes netdev_send accordingly. Signed-off-by: Pravin B Shelar <pshelar@nicira.com> Acked-by: Thomas Graf <tgraf@redhat.com>
This commit is contained in:
@@ -1937,7 +1937,7 @@ dp_execute_cb(void *aux_, struct ofpbuf *packet,
|
||||
case OVS_ACTION_ATTR_OUTPUT:
|
||||
p = dp_netdev_lookup_port(aux->dp, u32_to_odp(nl_attr_get_u32(a)));
|
||||
if (p) {
|
||||
netdev_send(p->netdev, packet);
|
||||
netdev_send(p->netdev, packet, may_steal);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1951,6 +1951,10 @@ dp_execute_cb(void *aux_, struct ofpbuf *packet,
|
||||
% aux->dp->n_handlers,
|
||||
DPIF_UC_ACTION, aux->key,
|
||||
userdata);
|
||||
|
||||
if (may_steal) {
|
||||
ofpbuf_delete(packet);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OVS_ACTION_ATTR_PUSH_VLAN:
|
||||
@@ -1964,9 +1968,6 @@ dp_execute_cb(void *aux_, struct ofpbuf *packet,
|
||||
OVS_NOT_REACHED();
|
||||
}
|
||||
|
||||
if (may_steal) {
|
||||
ofpbuf_delete(packet);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -683,10 +683,12 @@ netdev_bsd_rx_drain(struct netdev_rx *rx_)
|
||||
* system or a tap device.
|
||||
*/
|
||||
static int
|
||||
netdev_bsd_send(struct netdev *netdev_, const void *data, size_t size)
|
||||
netdev_bsd_send(struct netdev *netdev_, struct ofpbuf *pkt, bool may_steal)
|
||||
{
|
||||
struct netdev_bsd *dev = netdev_bsd_cast(netdev_);
|
||||
const char *name = netdev_get_name(netdev_);
|
||||
const void *data = pkt->data;
|
||||
size_t size = pkt->size;
|
||||
int error;
|
||||
|
||||
ovs_mutex_lock(&dev->mutex);
|
||||
@@ -723,6 +725,10 @@ netdev_bsd_send(struct netdev *netdev_, const void *data, size_t size)
|
||||
}
|
||||
|
||||
ovs_mutex_unlock(&dev->mutex);
|
||||
if (may_steal) {
|
||||
ofpbuf_delete(pkt);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@@ -818,9 +818,11 @@ netdev_dummy_rx_drain(struct netdev_rx *rx_)
|
||||
}
|
||||
|
||||
static int
|
||||
netdev_dummy_send(struct netdev *netdev, const void *buffer, size_t size)
|
||||
netdev_dummy_send(struct netdev *netdev, struct ofpbuf *pkt, bool may_steal)
|
||||
{
|
||||
struct netdev_dummy *dev = netdev_dummy_cast(netdev);
|
||||
const void *buffer = pkt->data;
|
||||
size_t size = pkt->size;
|
||||
|
||||
if (size < ETH_HEADER_LEN) {
|
||||
return EMSGSIZE;
|
||||
@@ -855,6 +857,9 @@ netdev_dummy_send(struct netdev *netdev, const void *buffer, size_t size)
|
||||
}
|
||||
|
||||
ovs_mutex_unlock(&dev->mutex);
|
||||
if (may_steal) {
|
||||
ofpbuf_delete(pkt);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -1054,8 +1054,11 @@ netdev_linux_rx_drain(struct netdev_rx *rx_)
|
||||
* The kernel maintains a packet transmission queue, so the caller is not
|
||||
* expected to do additional queuing of packets. */
|
||||
static int
|
||||
netdev_linux_send(struct netdev *netdev_, const void *data, size_t size)
|
||||
netdev_linux_send(struct netdev *netdev_, struct ofpbuf *pkt, bool may_steal)
|
||||
{
|
||||
const void *data = pkt->data;
|
||||
size_t size = pkt->size;
|
||||
|
||||
for (;;) {
|
||||
ssize_t retval;
|
||||
|
||||
@@ -1106,6 +1109,10 @@ netdev_linux_send(struct netdev *netdev_, const void *data, size_t size)
|
||||
retval = write(netdev->tap_fd, data, size);
|
||||
}
|
||||
|
||||
if (may_steal) {
|
||||
ofpbuf_delete(pkt);
|
||||
}
|
||||
|
||||
if (retval < 0) {
|
||||
/* The Linux AF_PACKET implementation never blocks waiting for room
|
||||
* for packets, instead returning ENOBUFS. Translate this into
|
||||
|
@@ -223,13 +223,13 @@ struct netdev_class {
|
||||
const struct netdev_tunnel_config *
|
||||
(*get_tunnel_config)(const struct netdev *netdev);
|
||||
|
||||
/* Sends the 'size'-byte packet in 'buffer' on 'netdev'. Returns 0 if
|
||||
* successful, otherwise a positive errno value. Returns EAGAIN without
|
||||
* blocking if the packet cannot be queued immediately. Returns EMSGSIZE
|
||||
* if a partial packet was transmitted or if the packet is too big or too
|
||||
* small to transmit on the device.
|
||||
/* Sends the buffer on 'netdev'.
|
||||
* Returns 0 if successful, otherwise a positive errno value. Returns
|
||||
* EAGAIN without blocking if the packet cannot be queued immediately.
|
||||
* Returns EMSGSIZE if a partial packet was transmitted or if the packet
|
||||
* is too big or too small to transmit on the device.
|
||||
*
|
||||
* The caller retains ownership of 'buffer' in all cases.
|
||||
* To retain ownership of 'buffer' caller can set may_steal to false.
|
||||
*
|
||||
* The network device is expected to maintain a packet transmission queue,
|
||||
* so that the caller does not ordinarily have to do additional queuing of
|
||||
@@ -241,7 +241,7 @@ struct netdev_class {
|
||||
* network device from being usefully used by the netdev-based "userspace
|
||||
* datapath". It will also prevent the OVS implementation of bonding from
|
||||
* working properly over 'netdev'.) */
|
||||
int (*send)(struct netdev *netdev, const void *buffer, size_t size);
|
||||
int (*send)(struct netdev *netdev, struct ofpbuf *buffer, bool may_steal);
|
||||
|
||||
/* Registers with the poll loop to wake up from the next call to
|
||||
* poll_block() when the packet transmission queue for 'netdev' has
|
||||
|
@@ -599,7 +599,7 @@ netdev_rx_drain(struct netdev_rx *rx)
|
||||
* immediately. Returns EMSGSIZE if a partial packet was transmitted or if
|
||||
* the packet is too big or too small to transmit on the device.
|
||||
*
|
||||
* The caller retains ownership of 'buffer' in all cases.
|
||||
* To retain ownership of 'buffer' caller can set may_steal to false.
|
||||
*
|
||||
* The kernel maintains a packet transmission queue, so the caller is not
|
||||
* expected to do additional queuing of packets.
|
||||
@@ -607,12 +607,12 @@ netdev_rx_drain(struct netdev_rx *rx)
|
||||
* Some network devices may not implement support for this function. In such
|
||||
* cases this function will always return EOPNOTSUPP. */
|
||||
int
|
||||
netdev_send(struct netdev *netdev, const struct ofpbuf *buffer)
|
||||
netdev_send(struct netdev *netdev, struct ofpbuf *buffer, bool may_steal)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = (netdev->netdev_class->send
|
||||
? netdev->netdev_class->send(netdev, buffer->data, buffer->size)
|
||||
? netdev->netdev_class->send(netdev, buffer, may_steal)
|
||||
: EOPNOTSUPP);
|
||||
if (!error) {
|
||||
COVERAGE_INC(netdev_sent);
|
||||
|
@@ -166,7 +166,7 @@ void netdev_rx_wait(struct netdev_rx *);
|
||||
int netdev_rx_drain(struct netdev_rx *);
|
||||
|
||||
/* Packet transmission. */
|
||||
int netdev_send(struct netdev *, const struct ofpbuf *);
|
||||
int netdev_send(struct netdev *, struct ofpbuf *, bool may_steal);
|
||||
void netdev_send_wait(struct netdev *);
|
||||
|
||||
/* Hardware address. */
|
||||
|
Reference in New Issue
Block a user