}
/* The size of the argument for each %OVS_KEY_ATTR_* Netlink attribute. */
-const u32 ovs_key_lens[OVS_KEY_ATTR_MAX + 1] = {
- [OVS_KEY_ATTR_ENCAP] = 0,
+const int ovs_key_lens[OVS_KEY_ATTR_MAX + 1] = {
+ [OVS_KEY_ATTR_ENCAP] = -1,
[OVS_KEY_ATTR_PRIORITY] = sizeof(u32),
[OVS_KEY_ATTR_IN_PORT] = sizeof(u32),
[OVS_KEY_ATTR_ETHERNET] = sizeof(struct ovs_key_ethernet),
attrs = 0;
nla_for_each_nested(nla, attr, rem) {
u16 type = nla_type(nla);
+ int expected_len;
- if (type > OVS_KEY_ATTR_MAX || attrs & (1ULL << type) ||
- nla_len(nla) != ovs_key_lens[type])
+ if (type > OVS_KEY_ATTR_MAX || attrs & (1ULL << type))
return -EINVAL;
+
+ expected_len = ovs_key_lens[type];
+ if (nla_len(nla) != expected_len && expected_len != -1)
+ return -EINVAL;
+
attrs |= 1ULL << type;
a[type] = nla;
}
nla_for_each_nested(nla, attr, rem) {
int type = nla_type(nla);
- if (type <= OVS_KEY_ATTR_MAX && ovs_key_lens[type] != 0) {
+ if (type <= OVS_KEY_ATTR_MAX && ovs_key_lens[type] > 0) {
if (nla_len(nla) != ovs_key_lens[type])
return -EINVAL;
u32 flow_hash(const struct sw_flow_key *key, int key_len);
struct sw_flow *flow_tbl_next(struct flow_table *table, u32 *bucket, u32 *idx);
-extern const u32 ovs_key_lens[OVS_KEY_ATTR_MAX + 1];
+extern const int ovs_key_lens[OVS_KEY_ATTR_MAX + 1];
#endif /* flow.h */