tunnel: Don't wildcard TTL and TOS in some circumstances.
[sliver-openvswitch.git] / ofproto / ofproto-dpif-xlate.c
index e46a854..f506c28 100644 (file)
@@ -466,8 +466,7 @@ update_learning_table(struct ofproto_dpif *ofproto,
                     in_bundle->name, vlan);
 
         mac->port.p = in_bundle;
-        tag_set_add(&ofproto->backer->revalidate_set,
-                    mac_learning_changed(ofproto->ml, mac));
+        mac_learning_changed(ofproto->ml, mac);
     }
 }
 
@@ -796,8 +795,8 @@ compose_output_action__(struct xlate_ctx *ctx, uint16_t ofp_port,
     ovs_be16 flow_vlan_tci;
     uint32_t flow_skb_mark;
     uint8_t flow_nw_tos;
-    struct priority_to_dscp *pdscp;
     uint32_t out_port, odp_port;
+    uint8_t dscp;
 
     /* If 'struct flow' gets additional metadata, we'll need to zero it out
      * before traversing a patch port. */
@@ -817,34 +816,25 @@ compose_output_action__(struct xlate_ctx *ctx, uint16_t ofp_port,
     if (netdev_vport_is_patch(ofport->up.netdev)) {
         struct ofport_dpif *peer = ofport_get_peer(ofport);
         struct flow old_flow = ctx->xin->flow;
-        const struct ofproto_dpif *peer_ofproto;
         enum slow_path_reason special;
-        struct ofport_dpif *in_port;
 
         if (!peer) {
             xlate_report(ctx, "Nonexistent patch port peer");
             return;
         }
 
-        peer_ofproto = ofproto_dpif_cast(peer->up.ofproto);
-        if (peer_ofproto->backer != ctx->ofproto->backer) {
-            xlate_report(ctx, "Patch port peer on a different datapath");
-            return;
-        }
-
         ctx->ofproto = ofproto_dpif_cast(peer->up.ofproto);
         flow->in_port = peer->up.ofp_port;
         flow->metadata = htonll(0);
         memset(&flow->tunnel, 0, sizeof flow->tunnel);
         memset(flow->regs, 0, sizeof flow->regs);
 
-        in_port = get_ofp_port(ctx->ofproto, flow->in_port);
-        special = process_special(ctx->ofproto, &ctx->xin->flow, in_port,
+        special = process_special(ctx->ofproto, &ctx->xin->flow, peer,
                                   ctx->xin->packet);
         if (special) {
             ctx->xout->slow = special;
-        } else if (!in_port || may_receive(in_port, ctx)) {
-            if (!in_port || stp_forward_in_state(in_port->stp_state)) {
+        } else if (may_receive(peer, ctx)) {
+            if (stp_forward_in_state(peer->stp_state)) {
                 xlate_table_action(ctx, flow->in_port, 0, true);
             } else {
                 /* Forwarding is disabled by STP.  Let OFPP_NORMAL and the
@@ -872,10 +862,9 @@ compose_output_action__(struct xlate_ctx *ctx, uint16_t ofp_port,
     flow_skb_mark = flow->skb_mark;
     flow_nw_tos = flow->nw_tos;
 
-    pdscp = get_priority(ofport, flow->skb_priority);
-    if (pdscp) {
+    if (ofproto_dpif_dscp_from_priority(ofport, flow->skb_priority, &dscp)) {
         flow->nw_tos &= ~IP_DSCP_MASK;
-        flow->nw_tos |= pdscp->dscp;
+        flow->nw_tos |= dscp;
     }
 
     if (ofport->tnl_port) {
@@ -884,7 +873,7 @@ compose_output_action__(struct xlate_ctx *ctx, uint16_t ofp_port,
           * matches, while explicit set actions on tunnel metadata are.
           */
         struct flow_tnl flow_tnl = flow->tunnel;
-        odp_port = tnl_port_send(ofport->tnl_port, flow);
+        odp_port = tnl_port_send(ofport->tnl_port, flow, &ctx->xout->wc);
         if (odp_port == OVSP_NONE) {
             xlate_report(ctx, "Tunneling decided against output");
             goto out; /* restore flow_nw_tos */
@@ -1287,8 +1276,7 @@ xlate_enqueue_action(struct xlate_ctx *ctx,
     int error;
 
     /* Translate queue to priority. */
-    error = dpif_queue_to_priority(ctx->ofproto->backer->dpif,
-                                   queue_id, &priority);
+    error = ofproto_dpif_queue_to_priority(ctx->ofproto, queue_id, &priority);
     if (error) {
         /* Fall back to ordinary output action. */
         xlate_output_action(ctx, enqueue->port, 0, false);
@@ -1321,8 +1309,8 @@ xlate_set_queue_action(struct xlate_ctx *ctx, uint32_t queue_id)
 {
     uint32_t skb_priority;
 
-    if (!dpif_queue_to_priority(ctx->ofproto->backer->dpif,
-                                queue_id, &skb_priority)) {
+    if (!ofproto_dpif_queue_to_priority(ctx->ofproto, queue_id,
+                                        &skb_priority)) {
         ctx->xin->flow.skb_priority = skb_priority;
     } else {
         /* Couldn't translate queue to a priority.  Nothing to do.  A warning