DPDK netdev need to access ofpbuf while sending buffer. Following patch changes netdev_send accordingly.
Signed-off-by: Pravin B Shelar <pshe...@nicira.com> --- v1-v2: - Fix comments. --- lib/dpif-netdev.c | 9 +++++---- lib/netdev-bsd.c | 8 +++++++- lib/netdev-dummy.c | 7 ++++++- lib/netdev-linux.c | 9 ++++++++- lib/netdev-provider.h | 14 +++++++------- lib/netdev.c | 6 +++--- lib/netdev.h | 2 +- 7 files changed, 37 insertions(+), 18 deletions(-) diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 5cb85c4..8990073 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -1936,7 +1936,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; @@ -1950,6 +1950,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: @@ -1963,9 +1967,6 @@ dp_execute_cb(void *aux_, struct ofpbuf *packet, OVS_NOT_REACHED(); } - if (may_steal) { - ofpbuf_delete(packet); - } } static void diff --git a/lib/netdev-bsd.c b/lib/netdev-bsd.c index 2cc852b..48a0fce 100644 --- a/lib/netdev-bsd.c +++ b/lib/netdev-bsd.c @@ -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; } diff --git a/lib/netdev-dummy.c b/lib/netdev-dummy.c index ecd7317..a1d1b79 100644 --- a/lib/netdev-dummy.c +++ b/lib/netdev-dummy.c @@ -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; } diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c index 2aa674a..5d7bfa1 100644 --- a/lib/netdev-linux.c +++ b/lib/netdev-linux.c @@ -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 diff --git a/lib/netdev-provider.h b/lib/netdev-provider.h index 166733f..b5aa857 100644 --- a/lib/netdev-provider.h +++ b/lib/netdev-provider.h @@ -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 diff --git a/lib/netdev.c b/lib/netdev.c index 0d7b69d..0d408bf 100644 --- a/lib/netdev.c +++ b/lib/netdev.c @@ -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); diff --git a/lib/netdev.h b/lib/netdev.h index a4dd99b..bbd717f 100644 --- a/lib/netdev.h +++ b/lib/netdev.h @@ -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. */ -- 1.7.9.5 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev