> In case DP_HASH and RECIRC actions need to be executed in slow path, > current implementation simply don't handle them -- vswitchd simply > crashes. This patch fixes them by supply an implementation for them. > > RECIRC will be handled by the datapath, same as the output action. > > DP_HASH, on the other hand, is handled in the user space. Although the > resulting hash values may not match those computed by the datapath, it > is less expensive; current use case (bonding) does not require a strict > match to work properly. > > Reported-by: YAMAMOTO Takashi <yamam...@valinux.co.jp> > Signed-off-by: Andy Zhou <az...@nicira.com>
Acked-by: YAMAMOTO Takashi <yamam...@valinux.co.jp> > > --- > v1->v2: Addresses Ben's review feedback > fix the comment on why execute dp_hash in user space. > Add assert for unknown hash algorithm specification. > --- > lib/dpif.c | 4 ++-- > lib/odp-execute.c | 23 ++++++++++++++++++++++- > 2 files changed, 24 insertions(+), 3 deletions(-) > > diff --git a/lib/dpif.c b/lib/dpif.c > index 84dba28..ac73be1 100644 > --- a/lib/dpif.c > +++ b/lib/dpif.c > @@ -1069,6 +1069,7 @@ dpif_execute_helper_cb(void *aux_, struct ofpbuf > *packet, > switch ((enum ovs_action_attr)type) { > case OVS_ACTION_ATTR_OUTPUT: > case OVS_ACTION_ATTR_USERSPACE: > + case OVS_ACTION_ATTR_RECIRC: > execute.actions = action; > execute.actions_len = NLA_ALIGN(action->nla_len); > execute.packet = packet; > @@ -1077,6 +1078,7 @@ dpif_execute_helper_cb(void *aux_, struct ofpbuf > *packet, > aux->error = aux->dpif->dpif_class->execute(aux->dpif, &execute); > break; > > + case OVS_ACTION_ATTR_HASH: > case OVS_ACTION_ATTR_PUSH_VLAN: > case OVS_ACTION_ATTR_POP_VLAN: > case OVS_ACTION_ATTR_PUSH_MPLS: > @@ -1084,8 +1086,6 @@ dpif_execute_helper_cb(void *aux_, struct ofpbuf > *packet, > case OVS_ACTION_ATTR_SET: > case OVS_ACTION_ATTR_SAMPLE: > case OVS_ACTION_ATTR_UNSPEC: > - case OVS_ACTION_ATTR_RECIRC: > - case OVS_ACTION_ATTR_HASH: > case __OVS_ACTION_ATTR_MAX: > OVS_NOT_REACHED(); > } > diff --git a/lib/odp-execute.c b/lib/odp-execute.c > index 12ad679..cc18536 100644 > --- a/lib/odp-execute.c > +++ b/lib/odp-execute.c > @@ -26,6 +26,7 @@ > #include "ofpbuf.h" > #include "odp-util.h" > #include "packets.h" > +#include "flow.h" > #include "unaligned.h" > #include "util.h" > > @@ -208,7 +209,6 @@ odp_execute_actions__(void *dp, struct ofpbuf *packet, > bool steal, > case OVS_ACTION_ATTR_OUTPUT: > case OVS_ACTION_ATTR_USERSPACE: > case OVS_ACTION_ATTR_RECIRC: > - case OVS_ACTION_ATTR_HASH: > if (dp_execute_action) { > /* Allow 'dp_execute_action' to steal the packet data if we > do > * not need it any more. */ > @@ -219,6 +219,27 @@ odp_execute_actions__(void *dp, struct ofpbuf *packet, > bool steal, > } > break; > > + case OVS_ACTION_ATTR_HASH: { > + const struct ovs_action_hash *hash_act = nl_attr_get(a); > + > + /* Calculate a hash value directly. This might not match the > + * value computed by the datapath, but it is much less expensive, > + * and the current use case (bonding) does not require a strict > + * match to work properly. */ > + if (hash_act->hash_alg == OVS_HASH_ALG_L4) { > + struct flow flow; > + uint32_t hash; > + > + flow_extract(packet, md, &flow); > + hash = flow_hash_5tuple(&flow, hash_act->hash_basis); > + md->dp_hash = hash ? hash : 1; > + } else { > + /* Assert on unknown hash algorithm. */ > + OVS_NOT_REACHED(); > + } > + break; > + } > + > case OVS_ACTION_ATTR_PUSH_VLAN: { > const struct ovs_action_push_vlan *vlan = nl_attr_get(a); > eth_push_vlan(packet, htons(ETH_TYPE_VLAN), vlan->vlan_tci); > -- > 1.9.1 > > _______________________________________________ > dev mailing list > dev@openvswitch.org > http://openvswitch.org/mailman/listinfo/dev _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev