dpif-netdev: Also allow "dummy" netdevs in a dpif-netdev.
[openvswitch] / ofproto / ofproto-dpif.c
index 9a7132141960a6f109d36f147152033ef54a7ac1..7174748b5205a5c3fd1161cc2142f1f136af16c9 100644 (file)
@@ -813,6 +813,20 @@ get_cfm_fault(const struct ofport *ofport_)
 
     return ofport->cfm ? cfm_get_fault(ofport->cfm) : -1;
 }
+
+static int
+get_cfm_remote_mpids(const struct ofport *ofport_, const uint64_t **rmps,
+                     size_t *n_rmps)
+{
+    struct ofport_dpif *ofport = ofport_dpif_cast(ofport_);
+
+    if (ofport->cfm) {
+        cfm_get_remote_mpids(ofport->cfm, rmps, n_rmps);
+        return 0;
+    } else {
+        return -1;
+    }
+}
 \f
 /* Bundles. */
 
@@ -2275,11 +2289,11 @@ facet_account(struct ofproto_dpif *ofproto, struct facet *facet)
             }
             break;
 
-        case OVS_ACTION_ATTR_STRIP_VLAN:
+        case OVS_ACTION_ATTR_POP_VLAN:
             vlan_tci = htons(0);
             break;
 
-        case OVS_ACTION_ATTR_SET_DL_TCI:
+        case OVS_ACTION_ATTR_PUSH_VLAN:
             vlan_tci = nl_attr_get_be16(a);
             break;
         }
@@ -2843,9 +2857,12 @@ commit_odp_actions(struct action_xlate_ctx *ctx)
 
     if (base->vlan_tci != flow->vlan_tci) {
         if (!(flow->vlan_tci & htons(VLAN_CFI))) {
-            nl_msg_put_flag(odp_actions, OVS_ACTION_ATTR_STRIP_VLAN);
+            nl_msg_put_flag(odp_actions, OVS_ACTION_ATTR_POP_VLAN);
         } else {
-            nl_msg_put_be16(odp_actions, OVS_ACTION_ATTR_SET_DL_TCI,
+            if (base->vlan_tci != htons(0)) {
+                nl_msg_put_flag(odp_actions, OVS_ACTION_ATTR_POP_VLAN);
+            }
+            nl_msg_put_be16(odp_actions, OVS_ACTION_ATTR_PUSH_VLAN,
                             flow->vlan_tci & ~htons(VLAN_CFI));
         }
         base->vlan_tci = flow->vlan_tci;
@@ -3337,6 +3354,7 @@ xlate_actions(struct action_xlate_ctx *ctx,
     ctx->priority = 0;
     ctx->base_priority = 0;
     ctx->base_flow = ctx->flow;
+    ctx->base_flow.tun_id = 0;
     ctx->table_id = 0;
 
     if (process_special(ctx->ofproto, &ctx->flow, ctx->packet)) {
@@ -3642,13 +3660,17 @@ compose_actions(struct action_xlate_ctx *ctx, uint16_t vlan,
         }
         if (dst->vlan != cur_vlan) {
             if (dst->vlan == OFP_VLAN_NONE) {
-                nl_msg_put_flag(ctx->odp_actions, OVS_ACTION_ATTR_STRIP_VLAN);
+                nl_msg_put_flag(ctx->odp_actions, OVS_ACTION_ATTR_POP_VLAN);
             } else {
                 ovs_be16 tci;
+
+                if (cur_vlan != OFP_VLAN_NONE) {
+                     nl_msg_put_flag(ctx->odp_actions, OVS_ACTION_ATTR_POP_VLAN);
+                }
                 tci = htons(dst->vlan & VLAN_VID_MASK);
                 tci |= ctx->flow.vlan_tci & htons(VLAN_PCP_MASK);
                 nl_msg_put_be16(ctx->odp_actions,
-                                OVS_ACTION_ATTR_SET_DL_TCI, tci);
+                                OVS_ACTION_ATTR_PUSH_VLAN, tci);
             }
             cur_vlan = dst->vlan;
         }
@@ -4077,8 +4099,8 @@ ofproto_unixctl_trace(struct unixctl_conn *conn, const char *args_,
     arg1 = strtok_r(NULL, " ", &save_ptr);
     arg2 = strtok_r(NULL, " ", &save_ptr);
     arg3 = strtok_r(NULL, "", &save_ptr); /* Get entire rest of line. */
-    if (dpname && arg1 && !arg2 && !arg3) {
-        /* ofproto/trace dpname flow */
+    if (dpname && arg1 && (!arg2 || !strcmp(arg2, "-generate")) && !arg3) {
+        /* ofproto/trace dpname flow [-generate] */
         int error;
 
         /* Convert string to datapath key. */
@@ -4095,6 +4117,12 @@ ofproto_unixctl_trace(struct unixctl_conn *conn, const char *args_,
             unixctl_command_reply(conn, 501, "Invalid flow");
             goto exit;
         }
+
+        /* Generate a packet, if requested. */
+        if (arg2) {
+            packet = ofpbuf_new(0);
+            flow_compose(packet, &flow);
+        }
     } else if (dpname && arg1 && arg2 && arg3) {
         /* ofproto/trace dpname tun_id in_port packet */
         uint16_t in_port;
@@ -4252,6 +4280,7 @@ const struct ofproto_class ofproto_dpif_class = {
     set_sflow,
     set_cfm,
     get_cfm_fault,
+    get_cfm_remote_mpids,
     bundle_set,
     bundle_remove,
     mirror_set,