/*
- * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira Networks.
+ * Copyright (c) 2008, 2009, 2010, 2011, 2012 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 error;
}
-/* Attempts to add 'netdev' as a port on 'dpif'. If successful, returns 0 and
- * sets '*port_nop' to the new port's port number (if 'port_nop' is non-null).
- * On failure, returns a positive errno value and sets '*port_nop' to
- * UINT16_MAX (if 'port_nop' is non-null). */
+/* Attempts to add 'netdev' as a port on 'dpif'. If 'port_nop' is
+ * non-null and its value is not UINT16_MAX, then attempts to use the
+ * value as the port number.
+ *
+ * If successful, returns 0 and sets '*port_nop' to the new port's port
+ * number (if 'port_nop' is non-null). On failure, returns a positive
+ * errno value and sets '*port_nop' to UINT16_MAX (if 'port_nop' is
+ * non-null). */
int
dpif_port_add(struct dpif *dpif, struct netdev *netdev, uint16_t *port_nop)
{
const char *netdev_name = netdev_get_name(netdev);
- uint16_t port_no;
+ uint16_t port_no = UINT16_MAX;
int error;
COVERAGE_INC(dpif_port_add);
+ if (port_nop) {
+ port_no = *port_nop;
+ }
+
error = dpif->dpif_class->port_add(dpif, netdev, &port_no);
if (!error) {
VLOG_DBG_RL(&dpmsg_rl, "%s: added %s as port %"PRIu16,
* as the OVS_USERSPACE_ATTR_PID attribute's value, for use in flows whose
* packets arrived on port 'port_no'.
*
+ * A 'port_no' of UINT16_MAX is a special case: it returns a reserved PID, not
+ * allocated to any port, that the client may use for special purposes.
+ *
* The return value is only meaningful when DPIF_UC_ACTION has been enabled in
* the 'dpif''s listen mask. It is allowed to change when DPIF_UC_ACTION is
* disabled and then re-enabled, so a client that does that must be prepared to
/* Extracts the flow stats for a packet. The 'flow' and 'packet'
* arguments must have been initialized through a call to flow_extract().
- */
+ * 'used' is stored into stats->used. */
void
dpif_flow_stats_extract(const struct flow *flow, const struct ofpbuf *packet,
- struct dpif_flow_stats *stats)
+ long long int used, struct dpif_flow_stats *stats)
{
stats->tcp_flags = packet_get_tcp_flags(packet, flow);
stats->n_bytes = packet->size;
stats->n_packets = 1;
- stats->used = time_msec();
+ stats->used = used;
}
/* Appends a human-readable representation of 'stats' to 's'. */
}
/* Polls for an upcall from 'dpif'. If successful, stores the upcall into
- * '*upcall'. Should only be called if dpif_recv_set() has been used to enable
- * receiving packets on 'dpif'.
+ * '*upcall', using 'buf' for storage. Should only be called if
+ * dpif_recv_set() has been used to enable receiving packets on 'dpif'.
*
- * The caller takes ownership of the data that 'upcall' points to.
- * 'upcall->key' and 'upcall->actions' (if nonnull) point into data owned by
- * 'upcall->packet', so their memory cannot be freed separately. (This is
+ * 'upcall->packet' and 'upcall->key' point into data in the caller-provided
+ * 'buf', so their memory cannot be freed separately from 'buf'. (This is
* hardly a great way to do things but it works out OK for the dpif providers
* and clients that exist so far.)
*
* Returns 0 if successful, otherwise a positive errno value. Returns EAGAIN
* if no upcall is immediately available. */
int
-dpif_recv(struct dpif *dpif, struct dpif_upcall *upcall)
+dpif_recv(struct dpif *dpif, struct dpif_upcall *upcall, struct ofpbuf *buf)
{
- int error = dpif->dpif_class->recv(dpif, upcall);
+ int error = dpif->dpif_class->recv(dpif, upcall, buf);
if (!error && !VLOG_DROP_DBG(&dpmsg_rl)) {
struct ds flow;
char *packet;