break;
}
default:
- OVS_NOT_REACHED();
+ ds_put_cstr(ds, ",<error: unknown mdtype>");
+ break;
}
ds_put_format(ds, ")");
}
int n1 = -1;
if (ovs_scan(&s[n], ",tunnel_out_port=%"SCNi32")%n",
&tunnel_out_port, &n1)) {
- odp_put_userspace_action(pid, user_data, user_data_size,
- tunnel_out_port, include_actions, actions);
- res = n + n1;
+ res = odp_put_userspace_action(pid, user_data, user_data_size,
+ tunnel_out_port, include_actions,
+ actions, NULL);
+ if (!res) {
+ res = n + n1;
+ }
goto out;
} else if (s[n] == ')') {
- odp_put_userspace_action(pid, user_data, user_data_size,
- ODPP_NONE, include_actions, actions);
- res = n + 1;
+ res = odp_put_userspace_action(pid, user_data, user_data_size,
+ ODPP_NONE, include_actions,
+ actions, NULL);
+ if (!res) {
+ res = n + 1;
+ }
goto out;
}
}
/* Appends an OVS_ACTION_ATTR_USERSPACE action to 'odp_actions' that specifies
* Netlink PID 'pid'. If 'userdata' is nonnull, adds a userdata attribute
- * whose contents are the 'userdata_size' bytes at 'userdata' and returns the
- * offset within 'odp_actions' of the start of the cookie. (If 'userdata' is
- * null, then the return value is not meaningful.) */
-size_t
+ * whose contents are the 'userdata_size' bytes at 'userdata' and sets
+ * 'odp_actions_ofs' if nonnull with the offset within 'odp_actions' of the
+ * start of the cookie. (If 'userdata' is null, then the 'odp_actions_ofs'
+ * value is not meaningful.)
+ *
+ * Returns negative error code on failure. */
+int
odp_put_userspace_action(uint32_t pid,
const void *userdata, size_t userdata_size,
odp_port_t tunnel_out_port,
bool include_actions,
- struct ofpbuf *odp_actions)
+ struct ofpbuf *odp_actions, size_t *odp_actions_ofs)
{
size_t userdata_ofs;
size_t offset;
offset = nl_msg_start_nested(odp_actions, OVS_ACTION_ATTR_USERSPACE);
nl_msg_put_u32(odp_actions, OVS_USERSPACE_ATTR_PID, pid);
if (userdata) {
+ if (nl_attr_oversized(userdata_size)) {
+ return -E2BIG;
+ }
userdata_ofs = odp_actions->size + NLA_HDRLEN;
/* The OVS kernel module before OVS 1.11 and the upstream Linux kernel
if (include_actions) {
nl_msg_put_flag(odp_actions, OVS_USERSPACE_ATTR_ACTIONS);
}
+ if (nl_attr_oversized(odp_actions->size - offset - NLA_HDRLEN)) {
+ return -E2BIG;
+ }
nl_msg_end_nested(odp_actions, offset);
- return userdata_ofs;
+ if (odp_actions_ofs) {
+ *odp_actions_ofs = userdata_ofs;
+ }
+
+ return 0;
}
void