/*
- * 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.
VLOG_DEFINE_THIS_MODULE(dpif_linux);
enum { MAX_PORTS = USHRT_MAX };
-enum { N_UPCALL_SOCKS = 16 };
-BUILD_ASSERT_DECL(IS_POW2(N_UPCALL_SOCKS));
+enum { N_UPCALL_SOCKS = 17 };
+BUILD_ASSERT_DECL(IS_POW2(N_UPCALL_SOCKS - 1));
+BUILD_ASSERT_DECL(N_UPCALL_SOCKS > 1);
BUILD_ASSERT_DECL(N_UPCALL_SOCKS <= 32); /* We use a 32-bit word as a mask. */
/* This ethtool flag was introduced in Linux 2.6.24, so it might be
if (dpif->epoll_fd < 0) {
return 0;
} else {
- int idx = port_no & (N_UPCALL_SOCKS - 1);
+ int idx;
+
+ idx = (port_no != UINT16_MAX
+ ? 1 + (port_no & (N_UPCALL_SOCKS - 2))
+ : 0);
return nl_sock_pid(dpif->upcall_socks[idx]);
}
}
}
static int
-dpif_linux_recv(struct dpif *dpif_, struct dpif_upcall *upcall)
+dpif_linux_recv(struct dpif *dpif_, struct dpif_upcall *upcall,
+ struct ofpbuf *buf)
{
struct dpif_linux *dpif = dpif_linux_cast(dpif_);
int read_tries = 0;
dpif->ready_mask &= ~(1u << indx);
for (;;) {
- struct ofpbuf *buf;
int dp_ifindex;
int error;
return EAGAIN;
}
- buf = ofpbuf_new(2048);
error = nl_sock_recv(upcall_sock, buf, false);
if (error) {
- ofpbuf_delete(buf);
if (error == EAGAIN) {
break;
}
if (!error && dp_ifindex == dpif->dp_ifindex) {
return 0;
}
-
- ofpbuf_delete(buf);
if (error) {
return error;
}