[ovs-dev] [PATCH 9/9] ofproto-dpif-xlate: Do not include non existing MPLS lse in wc.

Daniele Di Proietto diproiettod at vmware.com
Thu Dec 10 02:27:42 UTC 2015


An action list like

actions=push_mpls:0x8847,load:10->OXM_OF_MPLS_LABEL[]

will generate an exact match on the newly pushed mpls label, because the
load action needs to unwildcard its target to work properly.  This
doesn't make sense, because the original flow didn't have that label. An
invalid mask like this will cause the flow to be deleted by
revalidation.

Fix the problem by storing the original number of mpls labels and
clearing the ones that do not make sense in xlate_wc_finish().

Signed-off-by: Daniele Di Proietto <diproiettod at vmware.com>
---
 ofproto/ofproto-dpif-xlate.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index eff938b..dc7d3af 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -309,6 +309,9 @@ struct xlate_ctx {
     /* Pointer to an embedded NAT action in a conntrack action, or NULL. */
     struct ofpact_nat *ct_nat_action;
 
+    /* Remember the number of mpls labels in the original flow. */
+    unsigned orig_n_mpls_lse;
+
     /* OpenFlow 1.1+ action set.
      *
      * 'action_set' accumulates "struct ofpact"s added by OFPACT_WRITE_ACTIONS.
@@ -4999,6 +5002,8 @@ xlate_wc_init(struct xlate_ctx *ctx)
 static void
 xlate_wc_finish(struct xlate_ctx *ctx)
 {
+    size_t i;
+
     /* Clear the metadata and register wildcard masks, because we won't
      * use non-header fields as part of the cache. */
     flow_wildcards_clear_non_packet_fields(ctx->wc);
@@ -5021,6 +5026,15 @@ xlate_wc_finish(struct xlate_ctx *ctx)
     if (ctx->wc->masks.vlan_tci) {
         ctx->wc->masks.vlan_tci |= htons(VLAN_CFI);
     }
+
+    /* A set action on an MPLS label after a push_mpls action might
+     * unwildcard a label that was not in the original flow. We must
+     * make sure that the generated wildcard doesn't try to match on
+     * non existing labels. */
+    for (i = ctx->orig_n_mpls_lse; i < FLOW_MAX_MPLS_LABELS; i++) {
+        ctx->wc->masks.mpls_lse[i] = 0;
+    }
+
 }
 
 /* Translates the flow, actions, or rule in 'xin' into datapath actions in
@@ -5118,6 +5132,9 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout)
         xlate_wc_init(&ctx);
     }
 
+    /* Store the number of MPLS lse in the original flow */
+    ctx.orig_n_mpls_lse = flow_count_mpls_labels(flow, ctx.wc);
+
     COVERAGE_INC(xlate_actions);
 
     if (xin->recirc) {
-- 
2.1.4




More information about the dev mailing list