{
enum odp_key_fitness fitness;
- fitness = odp_tun_key_from_attr(a, tun_key);
+ fitness = odp_tun_key_from_attr(a, true, tun_key);
ovs_assert(fitness != ODP_FIT_ERROR);
}
case OVS_KEY_ATTR_DP_HASH:
md->dp_hash = nl_attr_get_u32(a);
- dp_packet_set_dp_hash(packet, md->dp_hash);
break;
case OVS_KEY_ATTR_RECIRC_ID:
case OVS_KEY_ATTR_DP_HASH:
md->dp_hash = nl_attr_get_u32(a)
- | (dp_packet_get_dp_hash(packet) & ~*get_mask(a, uint32_t));
- dp_packet_set_dp_hash(packet, md->dp_hash);
+ | (md->dp_hash & ~*get_mask(a, uint32_t));
break;
case OVS_KEY_ATTR_RECIRC_ID:
nl_attr_get_size(subactions), dp_execute_action);
}
+static bool
+requires_datapath_assistance(const struct nlattr *a)
+{
+ enum ovs_action_attr type = nl_attr_type(a);
+
+ switch (type) {
+ /* These only make sense in the context of a datapath. */
+ case OVS_ACTION_ATTR_OUTPUT:
+ case OVS_ACTION_ATTR_TUNNEL_PUSH:
+ case OVS_ACTION_ATTR_TUNNEL_POP:
+ case OVS_ACTION_ATTR_USERSPACE:
+ case OVS_ACTION_ATTR_RECIRC:
+ return true;
+
+ case OVS_ACTION_ATTR_SET:
+ case OVS_ACTION_ATTR_SET_MASKED:
+ case OVS_ACTION_ATTR_PUSH_VLAN:
+ case OVS_ACTION_ATTR_POP_VLAN:
+ case OVS_ACTION_ATTR_SAMPLE:
+ case OVS_ACTION_ATTR_HASH:
+ case OVS_ACTION_ATTR_PUSH_MPLS:
+ case OVS_ACTION_ATTR_POP_MPLS:
+ return false;
+
+ case OVS_ACTION_ATTR_UNSPEC:
+ case __OVS_ACTION_ATTR_MAX:
+ OVS_NOT_REACHED();
+ }
+
+ return false;
+}
+
void
odp_execute_actions(void *dp, struct dp_packet **packets, int cnt, bool steal,
const struct nlattr *actions, size_t actions_len,
int type = nl_attr_type(a);
bool last_action = (left <= NLA_ALIGN(a->nla_len));
- switch ((enum ovs_action_attr) type) {
- /* These only make sense in the context of a datapath. */
- case OVS_ACTION_ATTR_OUTPUT:
- case OVS_ACTION_ATTR_TUNNEL_PUSH:
- case OVS_ACTION_ATTR_TUNNEL_POP:
- case OVS_ACTION_ATTR_USERSPACE:
- case OVS_ACTION_ATTR_RECIRC:
+ if (requires_datapath_assistance(a)) {
if (dp_execute_action) {
/* Allow 'dp_execute_action' to steal the packet data if we do
* not need it any more. */
return;
}
}
- break;
+ continue;
+ }
+ switch ((enum ovs_action_attr) type) {
case OVS_ACTION_ATTR_HASH: {
const struct ovs_action_hash *hash_act = nl_attr_get(a);
flow_extract(packets[i], &flow);
hash = flow_hash_5tuple(&flow, hash_act->hash_basis);
- /* We also store the hash value with each packet */
- dp_packet_set_dp_hash(packets[i], hash ? hash : 1);
+ packets[i]->md.dp_hash = hash;
}
} else {
/* Assert on unknown hash algorithm. */
const struct ovs_action_push_vlan *vlan = nl_attr_get(a);
for (i = 0; i < cnt; i++) {
- eth_push_vlan(packets[i], htons(ETH_TYPE_VLAN), vlan->vlan_tci);
+ eth_push_vlan(packets[i], vlan->vlan_tpid, vlan->vlan_tci);
}
break;
}
}
break;
+ case OVS_ACTION_ATTR_OUTPUT:
+ case OVS_ACTION_ATTR_TUNNEL_PUSH:
+ case OVS_ACTION_ATTR_TUNNEL_POP:
+ case OVS_ACTION_ATTR_USERSPACE:
+ case OVS_ACTION_ATTR_RECIRC:
case OVS_ACTION_ATTR_UNSPEC:
case __OVS_ACTION_ATTR_MAX:
OVS_NOT_REACHED();