#include "ofpbuf.h"
#include "packets.h"
#include "poll-loop.h"
-#include "queue.h"
#include "shash.h"
#include "timeval.h"
#include "util.h"
bool destroyed;
bool drop_frags; /* Drop all IP fragments, if true. */
- struct ovs_queue queues[N_QUEUES]; /* Messages queued for dpif_recv(). */
+ struct list queues[N_QUEUES]; /* Contain ofpbufs queued for dpif_recv(). */
+ size_t queue_len[N_QUEUES]; /* Number of packets in each queue. */
struct hmap flow_table; /* Flow table. */
/* Statistics. */
dp->open_cnt = 0;
dp->drop_frags = false;
for (i = 0; i < N_QUEUES; i++) {
- queue_init(&dp->queues[i]);
+ list_init(&dp->queues[i]);
}
hmap_init(&dp->flow_table);
list_init(&dp->port_list);
do_del_port(dp, port->port_no);
}
for (i = 0; i < N_QUEUES; i++) {
- queue_destroy(&dp->queues[i]);
+ ofpbuf_list_delete(&dp->queues[i]);
}
hmap_destroy(&dp->flow_table);
free(dp->name);
/* We need a deep copy of 'packet' since we're going to modify its
* data. */
ofpbuf_init(©, DP_NETDEV_HEADROOM + packet->size);
- copy.data = (char*)copy.base + DP_NETDEV_HEADROOM;
+ ofpbuf_reserve(©, DP_NETDEV_HEADROOM);
ofpbuf_put(©, packet->data, packet->size);
} else {
/* We still need a shallow copy of 'packet', even though we won't
}
}
-static struct ovs_queue *
+static int
find_nonempty_queue(struct dpif *dpif)
{
struct dpif_netdev *dpif_netdev = dpif_netdev_cast(dpif);
int i;
for (i = 0; i < N_QUEUES; i++) {
- struct ovs_queue *q = &dp->queues[i];
- if (q->n && mask & (1u << i)) {
- return q;
+ struct list *queue = &dp->queues[i];
+ if (!list_is_empty(queue) && mask & (1u << i)) {
+ return i;
}
}
- return NULL;
+ return -1;
}
static int
dpif_netdev_recv(struct dpif *dpif, struct ofpbuf **bufp)
{
- struct ovs_queue *q = find_nonempty_queue(dpif);
- if (q) {
- *bufp = queue_pop_head(q);
+ int queue_idx = find_nonempty_queue(dpif);
+ if (queue_idx >= 0) {
+ struct dp_netdev *dp = get_dp_netdev(dpif);
+
+ *bufp = ofpbuf_from_list(list_pop_front(&dp->queues[queue_idx]));
+ dp->queue_len[queue_idx]--;
+
return 0;
} else {
return EAGAIN;
static void
dpif_netdev_recv_wait(struct dpif *dpif)
{
- struct ovs_queue *q = find_nonempty_queue(dpif);
- if (q) {
+ if (find_nonempty_queue(dpif) >= 0) {
poll_immediate_wake();
} else {
/* No messages ready to be received, and dp_wait() will ensure that we
int error;
/* Reset packet contents. */
- packet.data = (char*)packet.base + DP_NETDEV_HEADROOM;
- packet.size = 0;
+ ofpbuf_clear(&packet);
+ ofpbuf_reserve(&packet, DP_NETDEV_HEADROOM);
error = netdev_recv(port->netdev, &packet);
if (!error) {
memcpy(tmp.eth_src, veh->veth_src, ETH_ADDR_LEN);
tmp.eth_type = veh->veth_next_type;
- packet->size -= VLAN_HEADER_LEN;
- packet->data = (char*)packet->data + VLAN_HEADER_LEN;
+ ofpbuf_pull(packet, VLAN_HEADER_LEN);
packet->l2 = (char*)packet->l2 + VLAN_HEADER_LEN;
memcpy(packet->data, &tmp, sizeof tmp);
}
dp_netdev_output_control(struct dp_netdev *dp, const struct ofpbuf *packet,
int queue_no, int port_no, uint32_t arg)
{
- struct ovs_queue *q = &dp->queues[queue_no];
struct odp_msg *header;
struct ofpbuf *msg;
size_t msg_size;
- if (q->n >= MAX_QUEUE_LEN) {
+ if (dp->queue_len[queue_no] >= MAX_QUEUE_LEN) {
dp->n_lost++;
return ENOBUFS;
}
header->port = port_no;
header->arg = arg;
ofpbuf_put(msg, packet->data, packet->size);
- queue_push_tail(q, msg);
+ list_push_back(&dp->queues[queue_no], &msg->list_node);
+ dp->queue_len[queue_no]++;
return 0;
}