X-Git-Url: http://git.cascardo.eti.br/?a=blobdiff_plain;f=lib%2Fdpif.c;h=8ec8200f7f41f68112fd9d580897b3b7ce1733fc;hb=2187d8c72ad9695379f6ba30619bf25fb09db699;hp=48b2d1e922843303a17062f4a4e3da25f67b030f;hpb=803485697dd690490395a81685dd547bf38810af;p=cascardo%2Fovs.git diff --git a/lib/dpif.c b/lib/dpif.c index 48b2d1e92..8ec8200f7 100644 --- a/lib/dpif.c +++ b/lib/dpif.c @@ -1112,20 +1112,41 @@ dpif_execute_helper_cb(void *aux_, struct ofpbuf *packet, const struct nlattr *action, bool may_steal OVS_UNUSED) { struct dpif_execute_helper_aux *aux = aux_; - struct dpif_execute execute; int type = nl_attr_type(action); 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); + case OVS_ACTION_ATTR_RECIRC: { + struct dpif_execute execute; + struct ofpbuf execute_actions; + uint64_t stub[256 / 8]; + + if (md->tunnel.ip_dst) { + /* The Linux kernel datapath throws away the tunnel information + * that we supply as metadata. We have to use a "set" action to + * supply it. */ + ofpbuf_use_stub(&execute_actions, stub, sizeof stub); + odp_put_tunnel_action(&md->tunnel, &execute_actions); + ofpbuf_put(&execute_actions, action, NLA_ALIGN(action->nla_len)); + + execute.actions = ofpbuf_data(&execute_actions); + execute.actions_len = ofpbuf_size(&execute_actions); + } else { + execute.actions = action; + execute.actions_len = NLA_ALIGN(action->nla_len); + } + execute.packet = packet; execute.md = *md; execute.needs_help = false; aux->error = aux->dpif->dpif_class->execute(aux->dpif, &execute); + + if (md->tunnel.ip_dst) { + ofpbuf_uninit(&execute_actions); + } break; + } case OVS_ACTION_ATTR_HASH: case OVS_ACTION_ATTR_PUSH_VLAN: