2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-22 01:51:26 +00:00

xlate: Correct handling of double encap() actions

When the same encap() header was pushed twice onto a packet (e.g in the
case of NSH in NSH), the translation logic only generated a datapath push
action for the first encap() action. The second encap() did not emit a
push action because the packet type was unchanged.

commit_encap_decap_action() (renamed from commit_packet_type_change) must
solely rely on ctx->pending_encap to generate an datapath push action.

Similarly, the first decap() action on a double header packet does not
change the packet_type either. Add a corresponding ctx->pending_decap
flag and use that to trigger emitting a datapath pop action.

Fixes: f839892a2 ("OF support and translation of generic encap and decap")
Fixes: 1fc11c594 ("Generic encap and decap support for NSH")

Signed-off-by: Jan Scheurich <jan.scheurich@ericsson.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
This commit is contained in:
Jan Scheurich 2018-04-05 16:11:03 +02:00 committed by Ben Pfaff
parent 4b337e489b
commit 88ec1e0aa3
3 changed files with 13 additions and 11 deletions

View File

@ -7446,17 +7446,13 @@ odp_put_push_nsh_action(struct ofpbuf *odp_actions,
}
static void
commit_packet_type_change(const struct flow *flow,
commit_encap_decap_action(const struct flow *flow,
struct flow *base_flow,
struct ofpbuf *odp_actions,
struct flow_wildcards *wc,
bool pending_encap,
bool pending_encap, bool pending_decap,
struct ofpbuf *encap_data)
{
if (flow->packet_type == base_flow->packet_type) {
return;
}
if (pending_encap) {
switch (ntohl(flow->packet_type)) {
case PT_ETH: {
@ -7481,7 +7477,7 @@ commit_packet_type_change(const struct flow *flow,
* The check is done at action translation. */
OVS_NOT_REACHED();
}
} else {
} else if (pending_decap || flow->packet_type != base_flow->packet_type) {
/* This is an explicit or implicit decap case. */
if (pt_ns(flow->packet_type) == OFPHTN_ETHERTYPE &&
base_flow->packet_type == htonl(PT_ETH)) {
@ -7520,14 +7516,14 @@ commit_packet_type_change(const struct flow *flow,
enum slow_path_reason
commit_odp_actions(const struct flow *flow, struct flow *base,
struct ofpbuf *odp_actions, struct flow_wildcards *wc,
bool use_masked, bool pending_encap,
bool use_masked, bool pending_encap, bool pending_decap,
struct ofpbuf *encap_data)
{
enum slow_path_reason slow1, slow2;
bool mpls_done = false;
commit_packet_type_change(flow, base, odp_actions, wc,
pending_encap, encap_data);
commit_encap_decap_action(flow, base, odp_actions, wc,
pending_encap, pending_decap, encap_data);
commit_set_ether_action(flow, base, odp_actions, wc, use_masked);
/* Make packet a non-MPLS packet before committing L3/4 actions,
* which would otherwise do nothing. */

View File

@ -283,6 +283,7 @@ enum slow_path_reason commit_odp_actions(const struct flow *,
struct flow_wildcards *wc,
bool use_masked,
bool pending_encap,
bool pending_decap,
struct ofpbuf *encap_data);
/* ofproto-dpif interface.

View File

@ -243,6 +243,8 @@ struct xlate_ctx {
* true. */
bool pending_encap; /* True when waiting to commit a pending
* encap action. */
bool pending_decap; /* True when waiting to commit a pending
* decap action. */
struct ofpbuf *encap_data; /* May contain a pointer to an ofpbuf with
* context for the datapath encap action.*/
@ -3477,8 +3479,9 @@ xlate_commit_actions(struct xlate_ctx *ctx)
ctx->xout->slow |= commit_odp_actions(&ctx->xin->flow, &ctx->base_flow,
ctx->odp_actions, ctx->wc,
use_masked, ctx->pending_encap,
ctx->encap_data);
ctx->pending_decap, ctx->encap_data);
ctx->pending_encap = false;
ctx->pending_decap = false;
ofpbuf_delete(ctx->encap_data);
ctx->encap_data = NULL;
}
@ -5989,6 +5992,7 @@ xlate_generic_decap_action(struct xlate_ctx *ctx,
break;
}
ctx->wc->masks.nsh.np = UINT8_MAX;
ctx->pending_decap = true;
/* Trigger recirculation. */
return true;
default:
@ -6859,6 +6863,7 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout)
.in_action_set = false,
.in_packet_out = xin->in_packet_out,
.pending_encap = false,
.pending_decap = false,
.encap_data = NULL,
.table_id = 0,