/*
- * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc.
+ * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2016 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
return netdev->n_rxq;
}
+int
+netdev_requested_n_rxq(const struct netdev *netdev)
+{
+ return netdev->requested_n_rxq;
+}
+
bool
netdev_is_pmd(const struct netdev *netdev)
{
struct netdev_registered_class *rc;
int error;
+ netdev_initialize();
+
ovs_mutex_lock(&netdev_class_mutex);
rc = netdev_lookup_class(type);
if (!rc) {
/* By default enable one tx and rx queue per netdev. */
netdev->n_txq = netdev->netdev_class->send ? 1 : 0;
netdev->n_rxq = netdev->netdev_class->rxq_alloc ? 1 : 0;
+ netdev->requested_n_rxq = netdev->n_rxq;
list_init(&netdev->saved_flags_list);
}
}
-/* Attempts to receive batch of packets from 'rx'.
- *
- * Returns EAGAIN immediately if no packet is ready to be received.
- *
- * Returns EMSGSIZE, and discards the packet, if the received packet is longer
- * than 'dp_packet_tailroom(buffer)'.
+/* Attempts to receive a batch of packets from 'rx'. 'pkts' should point to
+ * the beginning of an array of MAX_RX_BATCH pointers to dp_packet. If
+ * successful, this function stores pointers to up to MAX_RX_BATCH dp_packets
+ * into the array, transferring ownership of the packets to the caller, stores
+ * the number of received packets into '*cnt', and returns 0.
*
- * It is advised that the tailroom of 'buffer' should be
- * VLAN_HEADER_LEN bytes longer than the MTU to allow space for an
- * out-of-band VLAN header to be added to the packet. At the very least,
- * 'buffer' must have at least ETH_TOTAL_MIN bytes of tailroom.
+ * The implementation does not necessarily initialize any non-data members of
+ * 'pkts'. That is, the caller must initialize layer pointers and metadata
+ * itself, if desired, e.g. with pkt_metadata_init() and miniflow_extract().
*
- * This function may be set to null if it would always return EOPNOTSUPP
- * anyhow. */
+ * Returns EAGAIN immediately if no packet is ready to be received or another
+ * positive errno value if an error was encountered. */
int
-netdev_rxq_recv(struct netdev_rxq *rx, struct dp_packet **buffers, int *cnt)
+netdev_rxq_recv(struct netdev_rxq *rx, struct dp_packet **pkts, int *cnt)
{
int retval;
- retval = rx->netdev->netdev_class->rxq_recv(rx, buffers, cnt);
+ retval = rx->netdev->netdev_class->rxq_recv(rx, pkts, cnt);
if (!retval) {
COVERAGE_INC(netdev_received);
+ } else {
+ *cnt = 0;
}
return retval;
}
* If the function returns a non-zero value, some of the packets might have
* been sent anyway.
*
- * To retain ownership of 'buffer' caller can set may_steal to false.
+ * If 'may_steal' is false, the caller retains ownership of all the packets.
+ * If 'may_steal' is true, the caller transfers ownership of all the packets
+ * to the network device, regardless of success.
*
* The network device is expected to maintain one or more packet
* transmission queues, so that the caller does not ordinarily have to
netdev_send(struct netdev *netdev, int qid, struct dp_packet **buffers,
int cnt, bool may_steal)
{
- int error;
+ if (!netdev->netdev_class->send) {
+ if (may_steal) {
+ for (int i = 0; i < cnt; i++) {
+ dp_packet_delete(buffers[i]);
+ }
+ }
+ return EOPNOTSUPP;
+ }
- error = (netdev->netdev_class->send
- ? netdev->netdev_class->send(netdev, qid, buffers, cnt, may_steal)
- : EOPNOTSUPP);
+ int error = netdev->netdev_class->send(netdev, qid, buffers, cnt,
+ may_steal);
if (!error) {
COVERAGE_INC(netdev_sent);
}
for (i = 0; i < cnt; i++) {
netdev->netdev_class->push_header(buffers[i], data);
- buffers[i]->md = PKT_METADATA_INITIALIZER(u32_to_odp(data->out_port));
+ pkt_metadata_init(&buffers[i]->md, u32_to_odp(data->out_port));
}
return 0;
/* Attempts to set 'netdev''s MAC address to 'mac'. Returns 0 if successful,
* otherwise a positive errno value. */
int
-netdev_set_etheraddr(struct netdev *netdev, const uint8_t mac[ETH_ADDR_LEN])
+netdev_set_etheraddr(struct netdev *netdev, const struct eth_addr mac)
{
return netdev->netdev_class->set_etheraddr(netdev, mac);
}
* the MAC address into 'mac'. On failure, returns a positive errno value and
* clears 'mac' to all-zeros. */
int
-netdev_get_etheraddr(const struct netdev *netdev, uint8_t mac[ETH_ADDR_LEN])
+netdev_get_etheraddr(const struct netdev *netdev, struct eth_addr *mac)
{
return netdev->netdev_class->get_etheraddr(netdev, mac);
}
* ENXIO indicates that there is no ARP table entry for 'ip' on 'netdev'. */
int
netdev_arp_lookup(const struct netdev *netdev,
- ovs_be32 ip, uint8_t mac[ETH_ADDR_LEN])
+ ovs_be32 ip, struct eth_addr *mac)
{
int error = (netdev->netdev_class->arp_lookup
? netdev->netdev_class->arp_lookup(netdev, ip, mac)
: EOPNOTSUPP);
if (error) {
- memset(mac, 0, ETH_ADDR_LEN);
+ *mac = eth_addr_zero;
}
return error;
}
return netdev_get_name(netdev_rxq_get_netdev(rx));
}
+int
+netdev_rxq_get_queue_id(const struct netdev_rxq *rx)
+{
+ return rx->queue_id;
+}
+
static void
restore_all_flags(void *aux OVS_UNUSED)
{