mirror of
https://github.com/openvswitch/ovs
synced 2025-10-15 14:17:18 +00:00
netdev: netdev_send accepts multiple packets
The netdev_send function has been modified to accept multiple packets, to allow netdev providers to amortize locking and queuing costs. This is especially true for netdev-dpdk. Later commits exploit the new API. Signed-off-by: Daniele Di Proietto <ddiproietto@vmware.com> Acked-by: Pravin B Shelar <pshelar@nicira.com>
This commit is contained in:
committed by
Pravin B Shelar
parent
910885540a
commit
f4fd623c4c
@@ -846,51 +846,61 @@ netdev_dummy_rxq_drain(struct netdev_rxq *rxq_)
|
||||
}
|
||||
|
||||
static int
|
||||
netdev_dummy_send(struct netdev *netdev, struct dpif_packet *pkt,
|
||||
netdev_dummy_send(struct netdev *netdev, struct dpif_packet **pkts, int cnt,
|
||||
bool may_steal)
|
||||
{
|
||||
struct netdev_dummy *dev = netdev_dummy_cast(netdev);
|
||||
const void *buffer = ofpbuf_data(&pkt->ofpbuf);
|
||||
size_t size = ofpbuf_size(&pkt->ofpbuf);
|
||||
int error = 0;
|
||||
int i;
|
||||
|
||||
if (size < ETH_HEADER_LEN) {
|
||||
return EMSGSIZE;
|
||||
} else {
|
||||
const struct eth_header *eth = buffer;
|
||||
int max_size;
|
||||
for (i = 0; i < cnt; i++) {
|
||||
const void *buffer = ofpbuf_data(&pkts[i]->ofpbuf);
|
||||
size_t size = ofpbuf_size(&pkts[i]->ofpbuf);
|
||||
|
||||
if (size < ETH_HEADER_LEN) {
|
||||
error = EMSGSIZE;
|
||||
break;
|
||||
} else {
|
||||
const struct eth_header *eth = buffer;
|
||||
int max_size;
|
||||
|
||||
ovs_mutex_lock(&dev->mutex);
|
||||
max_size = dev->mtu + ETH_HEADER_LEN;
|
||||
ovs_mutex_unlock(&dev->mutex);
|
||||
|
||||
if (eth->eth_type == htons(ETH_TYPE_VLAN)) {
|
||||
max_size += VLAN_HEADER_LEN;
|
||||
}
|
||||
if (size > max_size) {
|
||||
error = EMSGSIZE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ovs_mutex_lock(&dev->mutex);
|
||||
max_size = dev->mtu + ETH_HEADER_LEN;
|
||||
dev->stats.tx_packets++;
|
||||
dev->stats.tx_bytes += size;
|
||||
|
||||
dummy_packet_conn_send(&dev->conn, buffer, size);
|
||||
|
||||
if (dev->tx_pcap) {
|
||||
struct ofpbuf packet;
|
||||
|
||||
ofpbuf_use_const(&packet, buffer, size);
|
||||
ovs_pcap_write(dev->tx_pcap, &packet);
|
||||
fflush(dev->tx_pcap);
|
||||
}
|
||||
|
||||
ovs_mutex_unlock(&dev->mutex);
|
||||
|
||||
if (eth->eth_type == htons(ETH_TYPE_VLAN)) {
|
||||
max_size += VLAN_HEADER_LEN;
|
||||
}
|
||||
if (size > max_size) {
|
||||
return EMSGSIZE;
|
||||
}
|
||||
}
|
||||
|
||||
ovs_mutex_lock(&dev->mutex);
|
||||
dev->stats.tx_packets++;
|
||||
dev->stats.tx_bytes += size;
|
||||
|
||||
dummy_packet_conn_send(&dev->conn, buffer, size);
|
||||
|
||||
if (dev->tx_pcap) {
|
||||
struct ofpbuf packet;
|
||||
|
||||
ofpbuf_use_const(&packet, buffer, size);
|
||||
ovs_pcap_write(dev->tx_pcap, &packet);
|
||||
fflush(dev->tx_pcap);
|
||||
}
|
||||
|
||||
ovs_mutex_unlock(&dev->mutex);
|
||||
if (may_steal) {
|
||||
dpif_packet_delete(pkt);
|
||||
for (i = 0; i < cnt; i++) {
|
||||
dpif_packet_delete(pkts[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return error;
|
||||
}
|
||||
|
||||
static int
|
||||
|
Reference in New Issue
Block a user