netdev-dpif: Add metadata to dpif-packet.
[cascardo/ovs.git] / ofproto / ofproto-dpif-xlate.c
index 57afa80..07a1f29 100644 (file)
@@ -352,6 +352,7 @@ static struct xport *get_ofp_port(const struct xbridge *, ofp_port_t ofp_port);
 static struct skb_priority_to_dscp *get_skb_priority(const struct xport *,
                                                      uint32_t skb_priority);
 static void clear_skb_priorities(struct xport *);
+static size_t count_skb_priorities(const struct xport *);
 static bool dscp_from_skb_priority(const struct xport *, uint32_t skb_priority,
                                    uint8_t *dscp);
 
@@ -2578,10 +2579,13 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port,
     flow_pkt_mark = flow->pkt_mark;
     flow_nw_tos = flow->nw_tos;
 
-    if (dscp_from_skb_priority(xport, flow->skb_priority, &dscp)) {
-        wc->masks.nw_tos |= IP_DSCP_MASK;
-        flow->nw_tos &= ~IP_DSCP_MASK;
-        flow->nw_tos |= dscp;
+    if (count_skb_priorities(xport)) {
+        memset(&wc->masks.skb_priority, 0xff, sizeof wc->masks.skb_priority);
+        if (dscp_from_skb_priority(xport, flow->skb_priority, &dscp)) {
+            wc->masks.nw_tos |= IP_DSCP_MASK;
+            flow->nw_tos &= ~IP_DSCP_MASK;
+            flow->nw_tos |= dscp;
+        }
     }
 
     if (xport->is_tunnel) {
@@ -3011,7 +3015,6 @@ execute_controller_action(struct xlate_ctx *ctx, int len,
 {
     struct ofproto_packet_in *pin;
     struct dpif_packet *packet;
-    struct pkt_metadata md = PKT_METADATA_INITIALIZER(0);
 
     ctx->xout->slow |= SLOW_CONTROLLER;
     if (!ctx->xin->packet) {
@@ -3025,7 +3028,7 @@ execute_controller_action(struct xlate_ctx *ctx, int len,
                                           &ctx->xout->wc,
                                           ctx->xbridge->masked_set_action);
 
-    odp_execute_actions(NULL, &packet, 1, false, &md,
+    odp_execute_actions(NULL, &packet, 1, false,
                         ofpbuf_data(ctx->xout->odp_actions),
                         ofpbuf_size(ctx->xout->odp_actions), NULL);
 
@@ -3238,24 +3241,23 @@ static bool
 compose_dec_mpls_ttl_action(struct xlate_ctx *ctx)
 {
     struct flow *flow = &ctx->xin->flow;
-    uint8_t ttl = mpls_lse_to_ttl(flow->mpls_lse[0]);
     struct flow_wildcards *wc = &ctx->xout->wc;
 
-    memset(&wc->masks.mpls_lse, 0xff, sizeof wc->masks.mpls_lse);
     if (eth_type_mpls(flow->dl_type)) {
+        uint8_t ttl = mpls_lse_to_ttl(flow->mpls_lse[0]);
+
+        wc->masks.mpls_lse[0] |= htonl(MPLS_TTL_MASK);
         if (ttl > 1) {
             ttl--;
             set_mpls_lse_ttl(&flow->mpls_lse[0], ttl);
             return false;
         } else {
             execute_controller_action(ctx, UINT16_MAX, OFPR_INVALID_TTL, 0);
-
-            /* Stop processing for current table. */
-            return true;
         }
-    } else {
-        return true;
     }
+
+    /* Stop processing for current table. */
+    return true;
 }
 
 static void
@@ -3607,9 +3609,6 @@ ofpact_needs_recirculation_after_mpls(const struct xlate_ctx *ctx,
         return (mf_is_l3_or_higher(ofpact_get_REG_MOVE(a)->dst.field) ||
                 mf_is_l3_or_higher(ofpact_get_REG_MOVE(a)->src.field));
 
-    case OFPACT_REG_LOAD:
-        return mf_is_l3_or_higher(ofpact_get_REG_LOAD(a)->dst.field);
-
     case OFPACT_SET_FIELD:
         return mf_is_l3_or_higher(ofpact_get_SET_FIELD(a)->field);
 
@@ -3671,6 +3670,8 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
             break;
 
         case OFPACT_ENQUEUE:
+            memset(&wc->masks.skb_priority, 0xff,
+                   sizeof wc->masks.skb_priority);
             xlate_enqueue_action(ctx, ofpact_get_ENQUEUE(a));
             break;
 
@@ -3777,10 +3778,14 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
             break;
 
         case OFPACT_SET_QUEUE:
+            memset(&wc->masks.skb_priority, 0xff,
+                   sizeof wc->masks.skb_priority);
             xlate_set_queue_action(ctx, ofpact_get_SET_QUEUE(a)->queue_id);
             break;
 
         case OFPACT_POP_QUEUE:
+            memset(&wc->masks.skb_priority, 0xff,
+                   sizeof wc->masks.skb_priority);
             flow->skb_priority = ctx->orig_skb_priority;
             break;
 
@@ -3788,10 +3793,6 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
             nxm_execute_reg_move(ofpact_get_REG_MOVE(a), flow, wc);
             break;
 
-        case OFPACT_REG_LOAD:
-            nxm_execute_reg_load(ofpact_get_REG_LOAD(a), flow, wc);
-            break;
-
         case OFPACT_SET_FIELD:
             set_field = ofpact_get_SET_FIELD(a);
             mf = set_field->field;
@@ -3810,7 +3811,8 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
             }
 
             mf_mask_field_and_prereqs(mf, &wc->masks);
-            mf_set_flow_value(mf, &set_field->value, flow);
+            mf_set_flow_value_masked(mf, &set_field->value, &set_field->mask,
+                                     flow);
             break;
 
         case OFPACT_STACK_PUSH:
@@ -4018,6 +4020,12 @@ dscp_from_skb_priority(const struct xport *xport, uint32_t skb_priority,
     return pdscp != NULL;
 }
 
+static size_t
+count_skb_priorities(const struct xport *xport)
+{
+    return hmap_count(&xport->skb_priorities);
+}
+
 static void
 clear_skb_priorities(struct xport *xport)
 {
@@ -4195,7 +4203,6 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout)
 
     flow_wildcards_init_catchall(wc);
     memset(&wc->masks.in_port, 0xff, sizeof wc->masks.in_port);
-    memset(&wc->masks.skb_priority, 0xff, sizeof wc->masks.skb_priority);
     memset(&wc->masks.dl_type, 0xff, sizeof wc->masks.dl_type);
     if (is_ip_any(flow)) {
         wc->masks.nw_frag |= FLOW_NW_FRAG_MASK;