[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