[ovs-dev] [bugfixes 1/3] dpif-linux: Always pass an actions attribute in dpif_flow_put().
Ben Pfaff
blp at nicira.com
Tue Feb 1 00:48:23 UTC 2011
The kernel expects that ODP_FLOW_NEW always has an ODP_FLOW_ATTR_ACTIONS
attribute, even though that attribute may be empty to drop all of the
packets in the flow. Similarly, ODP_FLOW_SET as used by
dpif_linux_flow_put() should always have such an attribute, since it is
used by OVS to update the flow's actions. So make it possible for
dpif_linux_flow_to_ofpbuf() to pass an empty actions attribute, and make
dpif_linux_flow_put() always force that behavior if the actions_len passed
to it is 0.
This fixes EINVAL error creating flows to drop packets.
---
lib/dpif-linux.c | 11 ++++++++---
1 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/lib/dpif-linux.c b/lib/dpif-linux.c
index 9b84145..2e35857 100644
--- a/lib/dpif-linux.c
+++ b/lib/dpif-linux.c
@@ -89,7 +89,10 @@ struct dpif_linux_flow {
*
* The 'stats' and 'used' members point to 64-bit data that might only be
* aligned on 32-bit boundaries, so get_unaligned_u64() should be used to
- * access their values. */
+ * access their values.
+ *
+ * If 'actions' is nonnull then ODP_FLOW_ATTR_ACTIONS will be included in
+ * the Netlink version of the command, even if actions_len is zero. */
const struct nlattr *key; /* ODP_FLOW_ATTR_KEY. */
size_t key_len;
const struct nlattr *actions; /* ODP_FLOW_ATTR_ACTIONS. */
@@ -541,6 +544,7 @@ dpif_linux_flow_put(struct dpif *dpif_, enum dpif_flow_put_flags flags,
{
struct dpif_linux *dpif = dpif_linux_cast(dpif_);
struct dpif_linux_flow request, reply;
+ struct nlattr dummy_action;
struct ofpbuf *buf;
int error;
@@ -549,7 +553,8 @@ dpif_linux_flow_put(struct dpif *dpif_, enum dpif_flow_put_flags flags,
request.dp_ifindex = dpif->dp_ifindex;
request.key = key;
request.key_len = key_len;
- request.actions = actions;
+ /* Ensure that ODP_FLOW_ATTR_ACTIONS will always be included. */
+ request.actions = actions ? actions : &dummy_action;
request.actions_len = actions_len;
if (flags & DPIF_FP_ZERO_STATS) {
request.clear = true;
@@ -1462,7 +1467,7 @@ dpif_linux_flow_to_ofpbuf(const struct dpif_linux_flow *flow,
nl_msg_put_unspec(buf, ODP_FLOW_ATTR_KEY, flow->key, flow->key_len);
}
- if (flow->actions_len) {
+ if (flow->actions || flow->actions_len) {
nl_msg_put_unspec(buf, ODP_FLOW_ATTR_ACTIONS,
flow->actions, flow->actions_len);
}
--
1.7.1
More information about the dev
mailing list