datapath: Describe policy for extending flow key, implement needed changes.
[sliver-openvswitch.git] / ofproto / ofproto-dpif.c
index b296154..9356800 100644 (file)
@@ -2885,10 +2885,10 @@ facet_account(struct ofproto_dpif *ofproto, struct facet *facet)
      * hash bucket.) */
     vlan_tci = facet->flow.vlan_tci;
     NL_ATTR_FOR_EACH_UNSAFE (a, left, facet->actions, facet->actions_len) {
+        const struct ovs_action_push_vlan *vlan;
         struct ofport_dpif *port;
 
         switch (nl_attr_type(a)) {
-        const struct nlattr *nested;
         case OVS_ACTION_ATTR_OUTPUT:
             port = get_odp_port(ofproto, nl_attr_get_u32(a));
             if (port && port->bundle && port->bundle->bond) {
@@ -2897,20 +2897,13 @@ facet_account(struct ofproto_dpif *ofproto, struct facet *facet)
             }
             break;
 
-        case OVS_ACTION_ATTR_POP:
-            if (nl_attr_get_u16(a) == OVS_KEY_ATTR_8021Q) {
-                vlan_tci = htons(0);
-            }
+        case OVS_ACTION_ATTR_POP_VLAN:
+            vlan_tci = htons(0);
             break;
 
-        case OVS_ACTION_ATTR_PUSH:
-            nested = nl_attr_get(a);
-            if (nl_attr_type(nested) == OVS_KEY_ATTR_8021Q) {
-                const struct ovs_key_8021q *q_key;
-
-                q_key = nl_attr_get_unspec(nested, sizeof(*q_key));
-                vlan_tci = q_key->q_tci;
-            }
+        case OVS_ACTION_ATTR_PUSH_VLAN:
+            vlan = nl_attr_get(a);
+            vlan_tci = vlan->vlan_tci;
             break;
         }
     }
@@ -3586,13 +3579,10 @@ fix_sflow_action(struct action_xlate_ctx *ctx)
 }
 
 static void
-commit_action__(struct ofpbuf *odp_actions,
-                enum ovs_action_attr act_type,
-                enum ovs_key_attr key_type,
-                const void *key, size_t key_size)
+commit_set_action(struct ofpbuf *odp_actions, enum ovs_key_attr key_type,
+                  const void *key, size_t key_size)
 {
-    size_t offset = nl_msg_start_nested(odp_actions, act_type);
-
+    size_t offset = nl_msg_start_nested(odp_actions, OVS_ACTION_ATTR_SET);
     nl_msg_put_unspec(odp_actions, key_type, key, key_size);
     nl_msg_end_nested(odp_actions, offset);
 }
@@ -3606,8 +3596,8 @@ commit_set_tun_id_action(const struct flow *flow, struct flow *base,
     }
     base->tun_id = flow->tun_id;
 
-    commit_action__(odp_actions, OVS_ACTION_ATTR_SET,
-             OVS_KEY_ATTR_TUN_ID, &base->tun_id, sizeof(base->tun_id));
+    commit_set_action(odp_actions, OVS_KEY_ATTR_TUN_ID,
+                      &base->tun_id, sizeof(base->tun_id));
 }
 
 static void
@@ -3627,8 +3617,8 @@ commit_set_ether_addr_action(const struct flow *flow, struct flow *base,
     memcpy(eth_key.eth_src, base->dl_src, ETH_ADDR_LEN);
     memcpy(eth_key.eth_dst, base->dl_dst, ETH_ADDR_LEN);
 
-    commit_action__(odp_actions, OVS_ACTION_ATTR_SET,
-             OVS_KEY_ATTR_ETHERNET, &eth_key, sizeof(eth_key));
+    commit_set_action(odp_actions, OVS_KEY_ATTR_ETHERNET,
+                      &eth_key, sizeof(eth_key));
 }
 
 static void
@@ -3641,18 +3631,16 @@ commit_vlan_action(struct action_xlate_ctx *ctx, ovs_be16 new_tci)
     }
 
     if (base->vlan_tci & htons(VLAN_CFI)) {
-        nl_msg_put_u16(ctx->odp_actions, OVS_ACTION_ATTR_POP,
-                                       OVS_KEY_ATTR_8021Q);
+        nl_msg_put_flag(ctx->odp_actions, OVS_ACTION_ATTR_POP_VLAN);
     }
 
     if (new_tci & htons(VLAN_CFI)) {
-        struct ovs_key_8021q q_key;
-
-        q_key.q_tpid = htons(ETH_TYPE_VLAN);
-        q_key.q_tci = new_tci & ~htons(VLAN_CFI);
+        struct ovs_action_push_vlan vlan;
 
-        commit_action__(ctx->odp_actions, OVS_ACTION_ATTR_PUSH,
-                            OVS_KEY_ATTR_8021Q, &q_key, sizeof(q_key));
+        vlan.vlan_tpid = htons(ETH_TYPE_VLAN);
+        vlan.vlan_tci = new_tci & ~htons(VLAN_CFI);
+        nl_msg_put_unspec(ctx->odp_actions, OVS_ACTION_ATTR_PUSH_VLAN,
+                          &vlan, sizeof vlan);
     }
     base->vlan_tci = new_tci;
 }
@@ -3685,8 +3673,8 @@ commit_set_nw_action(const struct flow *flow, struct flow *base,
                           : base->nw_frag == FLOW_NW_FRAG_ANY
                           ? OVS_FRAG_TYPE_FIRST : OVS_FRAG_TYPE_LATER);
 
-    commit_action__(odp_actions, OVS_ACTION_ATTR_SET,
-             OVS_KEY_ATTR_IPV4, &ipv4_key, sizeof(ipv4_key));
+    commit_set_action(odp_actions, OVS_KEY_ATTR_IPV4,
+                      &ipv4_key, sizeof(ipv4_key));
 }
 
 static void
@@ -3708,8 +3696,8 @@ commit_set_port_action(const struct flow *flow, struct flow *base,
         port_key.tcp_src = base->tp_src = flow->tp_src;
         port_key.tcp_dst = base->tp_dst = flow->tp_dst;
 
-        commit_action__(odp_actions, OVS_ACTION_ATTR_SET,
-             OVS_KEY_ATTR_TCP, &port_key, sizeof(port_key));
+        commit_set_action(odp_actions, OVS_KEY_ATTR_TCP,
+                          &port_key, sizeof(port_key));
 
     } else if (flow->nw_proto == IPPROTO_UDP) {
         struct ovs_key_udp port_key;
@@ -3717,8 +3705,8 @@ commit_set_port_action(const struct flow *flow, struct flow *base,
         port_key.udp_src = base->tp_src = flow->tp_src;
         port_key.udp_dst = base->tp_dst = flow->tp_dst;
 
-        commit_action__(odp_actions, OVS_ACTION_ATTR_SET,
-             OVS_KEY_ATTR_UDP, &port_key, sizeof(port_key));
+        commit_set_action(odp_actions, OVS_KEY_ATTR_UDP,
+                          &port_key, sizeof(port_key));
     }
 }
 
@@ -3731,9 +3719,8 @@ commit_set_priority_action(const struct flow *flow, struct flow *base,
     }
     base->priority = flow->priority;
 
-    commit_action__(odp_actions, OVS_ACTION_ATTR_SET,
-                    OVS_KEY_ATTR_PRIORITY, &base->priority,
-                    sizeof(base->priority));
+    commit_set_action(odp_actions, OVS_KEY_ATTR_PRIORITY,
+                      &base->priority, sizeof(base->priority));
 }
 
 static void