/* Upcall messages. */
struct nl_sock *upcall_socks[N_UPCALL_SOCKS];
uint32_t ready_mask; /* 1-bit for each sock with unread messages. */
- unsigned int listen_mask; /* Mask of DPIF_UC_* bits. */
int epoll_fd; /* epoll fd that includes the upcall socks. */
/* Change notification. */
static void open_dpif(const struct dpif_linux_dp *, struct dpif **);
static bool dpif_linux_nln_parse(struct ofpbuf *, void *);
static void dpif_linux_port_changed(const void *vport, void *dpif);
-static uint32_t dpif_linux_port_get_pid__(const struct dpif *,
- uint16_t port_no,
- enum dpif_upcall_type);
+static uint32_t dpif_linux_port_get_pid(const struct dpif *, uint16_t port_no);
static void dpif_linux_vport_to_ofpbuf(const struct dpif_linux_vport *,
struct ofpbuf *);
uint32_t upcall_pid;
request.port_no = dpif_linux_pop_port(dpif);
- upcall_pid = dpif_linux_port_get_pid__(dpif_, request.port_no,
- DPIF_UC_MISS);
+ upcall_pid = dpif_linux_port_get_pid(dpif_, request.port_no);
request.upcall_pid = &upcall_pid;
error = dpif_linux_vport_transact(&request, &reply, &buf);
}
static uint32_t
-dpif_linux_port_get_pid__(const struct dpif *dpif_, uint16_t port_no,
- enum dpif_upcall_type upcall_type)
+dpif_linux_port_get_pid(const struct dpif *dpif_, uint16_t port_no)
{
struct dpif_linux *dpif = dpif_linux_cast(dpif_);
- if (!(dpif->listen_mask & (1u << upcall_type))) {
+ if (dpif->epoll_fd < 0) {
return 0;
} else {
int idx = port_no & (N_UPCALL_SOCKS - 1);
}
}
-static uint32_t
-dpif_linux_port_get_pid(const struct dpif *dpif, uint16_t port_no)
-{
- return dpif_linux_port_get_pid__(dpif, port_no, DPIF_UC_ACTION);
-}
-
static int
dpif_linux_flow_flush(struct dpif *dpif_)
{
free(txns);
}
-static int
-dpif_linux_recv_get_mask(const struct dpif *dpif_, int *listen_mask)
-{
- struct dpif_linux *dpif = dpif_linux_cast(dpif_);
- *listen_mask = dpif->listen_mask;
- return 0;
-}
-
static void
set_upcall_pids(struct dpif *dpif_)
{
int error;
DPIF_PORT_FOR_EACH (&port, &port_dump, &dpif->dpif) {
- uint32_t upcall_pid = dpif_linux_port_get_pid__(dpif_, port.port_no,
- DPIF_UC_MISS);
+ uint32_t upcall_pid = dpif_linux_port_get_pid(dpif_, port.port_no);
struct dpif_linux_vport vport_request;
dpif_linux_vport_init(&vport_request);
}
static int
-dpif_linux_recv_set_mask(struct dpif *dpif_, int listen_mask)
+dpif_linux_recv_set(struct dpif *dpif_, bool enable)
{
struct dpif_linux *dpif = dpif_linux_cast(dpif_);
- if (listen_mask == dpif->listen_mask) {
+ if ((dpif->epoll_fd >= 0) == enable) {
return 0;
}
- if (!listen_mask) {
+ if (!enable) {
destroy_upcall_socks(dpif);
- } else if (!dpif->listen_mask) {
+ } else {
int i;
int error;
dpif->ready_mask = 0;
}
- dpif->listen_mask = listen_mask;
set_upcall_pids(dpif_);
return 0;
struct dpif_linux *dpif = dpif_linux_cast(dpif_);
int read_tries = 0;
- if (!dpif->listen_mask) {
+ if (dpif->epoll_fd < 0) {
return EAGAIN;
}
}
error = parse_odp_packet(buf, upcall, &dp_ifindex);
- if (!error
- && dp_ifindex == dpif->dp_ifindex
- && dpif->listen_mask & (1u << upcall->type)) {
+ if (!error && dp_ifindex == dpif->dp_ifindex) {
return 0;
}
{
struct dpif_linux *dpif = dpif_linux_cast(dpif_);
- if (!dpif->listen_mask) {
+ if (dpif->epoll_fd < 0) {
return;
}
struct dpif_linux *dpif = dpif_linux_cast(dpif_);
int i;
- if (!dpif->listen_mask) {
+ if (dpif->epoll_fd < 0) {
return;
}
dpif_linux_flow_dump_done,
dpif_linux_execute,
dpif_linux_operate,
- dpif_linux_recv_get_mask,
- dpif_linux_recv_set_mask,
+ dpif_linux_recv_set,
dpif_linux_queue_to_priority,
dpif_linux_recv,
dpif_linux_recv_wait,
struct dpif_netdev {
struct dpif dpif;
struct dp_netdev *dp;
- int listen_mask;
unsigned int dp_serial;
};
dpif = xmalloc(sizeof *dpif);
dpif_init(&dpif->dpif, dp->class, dp->name, netflow_id >> 8, netflow_id);
dpif->dp = dp;
- dpif->listen_mask = 0;
dpif->dp_serial = dp->serial;
return &dpif->dpif;
}
static int
-dpif_netdev_recv_get_mask(const struct dpif *dpif, int *listen_mask)
+dpif_netdev_recv_set(struct dpif *dpif OVS_UNUSED, bool enable OVS_UNUSED)
{
- struct dpif_netdev *dpif_netdev = dpif_netdev_cast(dpif);
- *listen_mask = dpif_netdev->listen_mask;
- return 0;
-}
-
-static int
-dpif_netdev_recv_set_mask(struct dpif *dpif, int listen_mask)
-{
- struct dpif_netdev *dpif_netdev = dpif_netdev_cast(dpif);
- dpif_netdev->listen_mask = listen_mask;
return 0;
}
static struct dp_netdev_queue *
find_nonempty_queue(struct dpif *dpif)
{
- struct dpif_netdev *dpif_netdev = dpif_netdev_cast(dpif);
struct dp_netdev *dp = get_dp_netdev(dpif);
- int mask = dpif_netdev->listen_mask;
int i;
for (i = 0; i < N_QUEUES; i++) {
struct dp_netdev_queue *q = &dp->queues[i];
- if (q->head != q->tail && mask & (1u << i)) {
+ if (q->head != q->tail) {
return q;
}
}
dpif_netdev_flow_dump_done,
dpif_netdev_execute,
NULL, /* operate */
- dpif_netdev_recv_get_mask,
- dpif_netdev_recv_set_mask,
+ dpif_netdev_recv_set,
dpif_netdev_queue_to_priority,
dpif_netdev_recv,
dpif_netdev_recv_wait,
* 'dpif' can perform operations in batch faster than individually. */
void (*operate)(struct dpif *dpif, union dpif_op **ops, size_t n_ops);
- /* Retrieves 'dpif''s "listen mask" into '*listen_mask'. A 1-bit of value
- * 2**X set in '*listen_mask' indicates that 'dpif' will receive messages
- * of the type (from "enum dpif_upcall_type") with value X when its 'recv'
- * function is called. */
- int (*recv_get_mask)(const struct dpif *dpif, int *listen_mask);
-
- /* Sets 'dpif''s "listen mask" to 'listen_mask'. A 1-bit of value 2**X set
- * in '*listen_mask' requests that 'dpif' will receive messages of the type
- * (from "enum dpif_upcall_type") with value X when its 'recv' function is
- * called.
- *
- * Turning DPIF_UC_ACTION off and then back on is allowed to change Netlink
+ /* Enables or disables receiving packets with dpif_recv() for 'dpif'.
+ * Turning packet receive off and then back on is allowed to change Netlink
* PID assignments (see ->port_get_pid()). The client is responsible for
* updating flows as necessary if it does this. */
- int (*recv_set_mask)(struct dpif *dpif, int listen_mask);
+ int (*recv_set)(struct dpif *dpif, bool enable);
/* Translates OpenFlow queue ID 'queue_id' (in host byte order) into a
* priority value used for setting packet priority. */
uint32_t *priority);
/* Polls for an upcall from 'dpif'. If successful, stores the upcall into
- * '*upcall'. Only upcalls of the types selected with the set_listen_mask
- * member function should be received.
+ * '*upcall'. Should only be called if 'recv_set' has been used to enable
+ * receiving packets from 'dpif'.
*
* The caller takes ownership of the data that 'upcall' points to.
* 'upcall->key' and 'upcall->actions' (if nonnull) point into data owned
}
}
-static bool OVS_UNUSED
-is_valid_listen_mask(int listen_mask)
-{
- return !(listen_mask & ~((1u << DPIF_UC_MISS) |
- (1u << DPIF_UC_ACTION)));
-}
-
-/* Retrieves 'dpif''s "listen mask" into '*listen_mask'. A 1-bit of value 2**X
- * set in '*listen_mask' indicates that dpif_recv() will receive messages of
- * the type (from "enum dpif_upcall_type") with value X. Returns 0 if
- * successful, otherwise a positive errno value. */
-int
-dpif_recv_get_mask(const struct dpif *dpif, int *listen_mask)
-{
- int error = dpif->dpif_class->recv_get_mask(dpif, listen_mask);
- if (error) {
- *listen_mask = 0;
- }
- assert(is_valid_listen_mask(*listen_mask));
- log_operation(dpif, "recv_get_mask", error);
- return error;
-}
-
-/* Sets 'dpif''s "listen mask" to 'listen_mask'. A 1-bit of value 2**X set in
- * '*listen_mask' requests that dpif_recv() will receive messages of the type
- * (from "enum dpif_upcall_type") with value X. Returns 0 if successful,
- * otherwise a positive errno value.
+/* Enables or disables receiving packets with dpif_recv() on 'dpif'. Returns 0
+ * if successful, otherwise a positive errno value.
*
- * Turning DPIF_UC_ACTION off and then back on may change the Netlink PID
+ * Turning packet receive off and then back on may change the Netlink PID
* assignments returned by dpif_port_get_pid(). If the client does this, it
* must update all of the flows that have OVS_ACTION_ATTR_USERSPACE actions
* using the new PID assignment. */
int
-dpif_recv_set_mask(struct dpif *dpif, int listen_mask)
+dpif_recv_set(struct dpif *dpif, bool enable)
{
- int error;
-
- assert(is_valid_listen_mask(listen_mask));
-
- error = dpif->dpif_class->recv_set_mask(dpif, listen_mask);
- log_operation(dpif, "recv_set_mask", error);
+ int error = dpif->dpif_class->recv_set(dpif, enable);
+ log_operation(dpif, "recv_set", error);
return error;
}
/* Polls for an upcall from 'dpif'. If successful, stores the upcall into
- * '*upcall'. Only upcalls of the types selected with dpif_recv_set_mask()
- * member function will ordinarily be received (but if a message type is
- * enabled and then later disabled, some stragglers might pop up).
+ * '*upcall'. 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
uint64_t userdata; /* Argument to OVS_ACTION_ATTR_USERSPACE. */
};
-int dpif_recv_get_mask(const struct dpif *, int *listen_mask);
-int dpif_recv_set_mask(struct dpif *, int listen_mask);
+int dpif_recv_set(struct dpif *, bool enable);
int dpif_recv(struct dpif *, struct dpif_upcall *);
void dpif_recv_purge(struct dpif *);
void dpif_recv_wait(struct dpif *);
dpif_flow_flush(ofproto->dpif);
dpif_recv_purge(ofproto->dpif);
- error = dpif_recv_set_mask(ofproto->dpif,
- ((1u << DPIF_UC_MISS) |
- (1u << DPIF_UC_ACTION)));
+ error = dpif_recv_set(ofproto->dpif, true);
if (error) {
VLOG_ERR("failed to listen on datapath %s: %s", name, strerror(error));
dpif_close(ofproto->dpif);