*
* 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. */
{
struct dpif_linux *dpif = dpif_linux_cast(dpif_);
struct dpif_linux_flow request, reply;
+ struct nlattr dummy_action;
struct ofpbuf *buf;
int error;
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;
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);
}