mpls: Allow l3 and l4 actions to prior to a push_mpls action
[sliver-openvswitch.git] / lib / odp-util.c
index 54e5b12..f9e9321 100644 (file)
@@ -2323,9 +2323,9 @@ commit_set_nw_action(const struct flow *flow, struct flow *base,
         return;
     }
 
-    if (flow->dl_type == htons(ETH_TYPE_IP)) {
+    if (base->dl_type == htons(ETH_TYPE_IP)) {
         commit_set_ipv4_action(flow, base, odp_actions);
-    } else if (flow->dl_type == htons(ETH_TYPE_IPV6)) {
+    } else if (base->dl_type == htons(ETH_TYPE_IPV6)) {
         commit_set_ipv6_action(flow, base, odp_actions);
     }
 }
@@ -2334,7 +2334,7 @@ static void
 commit_set_port_action(const struct flow *flow, struct flow *base,
                        struct ofpbuf *odp_actions)
 {
-    if (!base->tp_src && !base->tp_dst) {
+    if (!is_ip_any(base) || (!base->tp_src && !base->tp_dst)) {
         return;
     }
 
@@ -2398,9 +2398,13 @@ commit_odp_actions(const struct flow *flow, struct flow *base,
 {
     commit_set_ether_addr_action(flow, base, odp_actions);
     commit_vlan_action(flow, base, odp_actions);
-    commit_mpls_action(flow, base, odp_actions);
     commit_set_nw_action(flow, base, odp_actions);
     commit_set_port_action(flow, base, odp_actions);
+    /* Commiting MPLS actions should occur after committing nw and port
+     * actions. This is because committing MPLS actions may alter a packet so
+     * that it is no longer IP and thus nw and port actions are no longer valid.
+     */
+    commit_mpls_action(flow, base, odp_actions);
     commit_set_priority_action(flow, base, odp_actions);
     commit_set_skb_mark_action(flow, base, odp_actions);
 }