diff --git a/lib/dummy.c b/lib/dummy.c
index 5caceee..e674f56 100644
--- a/lib/dummy.c
+++ b/lib/dummy.c
@@ -30,19 +30,33 @@
 void
 dummy_enable(const char *arg)
 {
-    enum dummy_level level;
+    enum dummy_level level = DUMMY_OVERRIDE_NONE;
+    enum dummy_type type = DUMMY_NON_PMD;
+    const char *s = arg;
 
-    if (!arg || !arg[0]) {
-        level = DUMMY_OVERRIDE_NONE;
-    } else if (!strcmp(arg, "system")) {
-        level = DUMMY_OVERRIDE_SYSTEM;
-    } else if (!strcmp(arg, "override")) {
-        level = DUMMY_OVERRIDE_ALL;
-    } else {
-        ovs_fatal(0, "%s: unknown dummy level", arg);
+    while (s && s[0]) {
+        size_t d = strcspn(s, ", \t\r\n");
+
+        if (!d) {
+            s++;
+            continue;
+        }
+
+        if (!strncmp(arg, "system", d)) {
+            level = DUMMY_OVERRIDE_SYSTEM;
+        } else if (!strncmp(arg, "override", d)) {
+            level = DUMMY_OVERRIDE_ALL;
+        } else if (!strncmp(arg, "pmd", d)) {
+            type = DUMMY_PMD;
+        } else if (!strncmp(arg, "non-pmd", d)) {
+            type = DUMMY_NON_PMD;
+        } else {
+            ovs_fatal(0, "%s: unknown dummy option", arg);
+        }
+        s += d;
     }
 
-    netdev_dummy_register(level);
+    netdev_dummy_register(level, type);
     dpif_dummy_register(level);
     timeval_dummy_register();
     vlandev_dummy_enable();
diff --git a/lib/dummy.h b/lib/dummy.h
index 5b8a841..3d668fa 100644
--- a/lib/dummy.h
+++ b/lib/dummy.h
@@ -30,12 +30,18 @@ enum dummy_level {
     DUMMY_OVERRIDE_ALL,         /* Replace all types by dummy. */
 };
 
+/* Type of dummy inreface. */
+enum dummy_type {
+    DUMMY_NON_PMD,              /* Use non-PMD dummy class. */
+    DUMMY_PMD,                  /* Force using PMD dummy class. */
+};
+
 /* For client programs to call directly to enable dummy support. */
 void dummy_enable(const char *arg);
 
 /* Implementation details. */
 void dpif_dummy_register(enum dummy_level);
-void netdev_dummy_register(enum dummy_level);
+void netdev_dummy_register(enum dummy_level, enum dummy_type);
 void timeval_dummy_register(void);
 void vlandev_dummy_enable(void);
 void ofpact_dummy_enable(void);
diff --git a/lib/netdev-dummy.c b/lib/netdev-dummy.c
index 6fa1169..0e536e8 100644
--- a/lib/netdev-dummy.c
+++ b/lib/netdev-dummy.c
@@ -806,6 +806,12 @@ netdev_dummy_set_config(struct netdev *netdev_, const struct smap *args)
     return 0;
 }
 
+static int
+netdev_dummy_get_numa_id(const struct netdev *netdev_ OVS_UNUSED)
+{
+    return 0;
+}
+
 static struct netdev_rxq *
 netdev_dummy_rxq_alloc(void)
 {
@@ -1193,74 +1199,78 @@ netdev_dummy_update_flags(struct netdev *netdev_,
 
 /* Helper functions. */
 
-static const struct netdev_class dummy_class = {
-    "dummy",
-    false,                      /* is_pmd */
-    NULL,                       /* init */
-    netdev_dummy_run,
-    netdev_dummy_wait,
-
-    netdev_dummy_alloc,
-    netdev_dummy_construct,
-    netdev_dummy_destruct,
-    netdev_dummy_dealloc,
-    netdev_dummy_get_config,
-    netdev_dummy_set_config,
-    NULL,                       /* get_tunnel_config */
-    NULL,                       /* build header */
-    NULL,                       /* push header */
-    NULL,                       /* pop header */
-    NULL,                       /* get_numa_id */
-    NULL,                       /* set_multiq */
-
-    netdev_dummy_send,          /* send */
-    NULL,                       /* send_wait */
-
-    netdev_dummy_set_etheraddr,
-    netdev_dummy_get_etheraddr,
-    netdev_dummy_get_mtu,
-    netdev_dummy_set_mtu,
-    netdev_dummy_get_ifindex,
-    NULL,                       /* get_carrier */
-    NULL,                       /* get_carrier_resets */
-    NULL,                       /* get_miimon */
-    netdev_dummy_get_stats,
-
-    NULL,                       /* get_features */
-    NULL,                       /* set_advertisements */
-
-    NULL,                       /* set_policing */
-    NULL,                       /* get_qos_types */
-    NULL,                       /* get_qos_capabilities */
-    NULL,                       /* get_qos */
-    NULL,                       /* set_qos */
-    netdev_dummy_get_queue,
-    NULL,                       /* set_queue */
-    NULL,                       /* delete_queue */
-    netdev_dummy_get_queue_stats,
-    netdev_dummy_queue_dump_start,
-    netdev_dummy_queue_dump_next,
-    netdev_dummy_queue_dump_done,
-    netdev_dummy_dump_queue_stats,
-
-    netdev_dummy_get_in4,       /* get_in4 */
-    NULL,                       /* set_in4 */
-    netdev_dummy_get_in6,       /* get_in6 */
-    NULL,                       /* add_router */
-    NULL,                       /* get_next_hop */
-    NULL,                       /* get_status */
-    NULL,                       /* arp_lookup */
-
-    netdev_dummy_update_flags,
-
-    netdev_dummy_rxq_alloc,
-    netdev_dummy_rxq_construct,
-    netdev_dummy_rxq_destruct,
-    netdev_dummy_rxq_dealloc,
-    netdev_dummy_rxq_recv,
-    netdev_dummy_rxq_wait,
-    netdev_dummy_rxq_drain,
-};
+#define NETDEV_DUMMY_CLASS(PMD)                                 \
+{                                                               \
+    "dummy",                                                    \
+    PMD,                        /* is_pmd */                    \
+    NULL,                       /* init */                      \
+    netdev_dummy_run,                                           \
+    netdev_dummy_wait,                                          \
+                                                                \
+    netdev_dummy_alloc,                                         \
+    netdev_dummy_construct,                                     \
+    netdev_dummy_destruct,                                      \
+    netdev_dummy_dealloc,                                       \
+    netdev_dummy_get_config,                                    \
+    netdev_dummy_set_config,                                    \
+    NULL,                       /* get_tunnel_config */         \
+    NULL,                       /* build header */              \
+    NULL,                       /* push header */               \
+    NULL,                       /* pop header */                \
+    netdev_dummy_get_numa_id,                                   \
+    NULL,                       /* set_multiq */                \
+                                                                \
+    netdev_dummy_send,          /* send */                      \
+    NULL,                       /* send_wait */                 \
+                                                                \
+    netdev_dummy_set_etheraddr,                                 \
+    netdev_dummy_get_etheraddr,                                 \
+    netdev_dummy_get_mtu,                                       \
+    netdev_dummy_set_mtu,                                       \
+    netdev_dummy_get_ifindex,                                   \
+    NULL,                       /* get_carrier */               \
+    NULL,                       /* get_carrier_resets */        \
+    NULL,                       /* get_miimon */                \
+    netdev_dummy_get_stats,                                     \
+                                                                \
+    NULL,                       /* get_features */              \
+    NULL,                       /* set_advertisements */        \
+                                                                \
+    NULL,                       /* set_policing */              \
+    NULL,                       /* get_qos_types */             \
+    NULL,                       /* get_qos_capabilities */      \
+    NULL,                       /* get_qos */                   \
+    NULL,                       /* set_qos */                   \
+    netdev_dummy_get_queue,                                     \
+    NULL,                       /* set_queue */                 \
+    NULL,                       /* delete_queue */              \
+    netdev_dummy_get_queue_stats,                               \
+    netdev_dummy_queue_dump_start,                              \
+    netdev_dummy_queue_dump_next,                               \
+    netdev_dummy_queue_dump_done,                               \
+    netdev_dummy_dump_queue_stats,                              \
+                                                                \
+    netdev_dummy_get_in4,       /* get_in4 */                   \
+    NULL,                       /* set_in4 */                   \
+    netdev_dummy_get_in6,       /* get_in6 */                   \
+    NULL,                       /* add_router */                \
+    NULL,                       /* get_next_hop */              \
+    NULL,                       /* get_status */                \
+    NULL,                       /* arp_lookup */                \
+                                                                \
+    netdev_dummy_update_flags,                                  \
+                                                                \
+    netdev_dummy_rxq_alloc,                                     \
+    netdev_dummy_rxq_construct,                                 \
+    netdev_dummy_rxq_destruct,                                  \
+    netdev_dummy_rxq_dealloc,                                   \
+    netdev_dummy_rxq_recv,                                      \
+    netdev_dummy_rxq_wait,                                      \
+    netdev_dummy_rxq_drain,                                     \
+}
+
+static const struct netdev_class dummy_class = NETDEV_DUMMY_CLASS(false);
+static const struct netdev_class dummy_pmd_class = NETDEV_DUMMY_CLASS(true);
 
 static void
 pkt_list_delete(struct ovs_list *l)
@@ -1558,13 +1568,17 @@ netdev_dummy_ip6addr(struct unixctl_conn *conn, int argc OVS_UNUSED,
 
 
 static void
-netdev_dummy_override(const char *type)
+netdev_dummy_override(const char *type, enum dummy_type dummy_type)
 {
     if (!netdev_unregister_provider(type)) {
         struct netdev_class *class;
         int error;
 
-        class = xmemdup(&dummy_class, sizeof dummy_class);
+        if (dummy_type == DUMMY_NON_PMD) {
+            class = xmemdup(&dummy_class, sizeof dummy_class);
+        } else {
+            class = xmemdup(&dummy_pmd_class, sizeof dummy_pmd_class);
+        }
         class->type = xstrdup(type);
         error = netdev_register_provider(class);
         if (error) {
@@ -1577,7 +1591,7 @@ netdev_dummy_override(const char *type)
 }
 
 void
-netdev_dummy_register(enum dummy_level level)
+netdev_dummy_register(enum dummy_level level, enum dummy_type dummy_type)
 {
     unixctl_command_register("netdev-dummy/receive", "name packet|flow...",
                              2, INT_MAX, netdev_dummy_receive, NULL);
@@ -1602,14 +1616,19 @@ netdev_dummy_register(enum dummy_level level)
         netdev_enumerate_types(&types);
         SSET_FOR_EACH (type, &types) {
             if (strcmp(type, "patch")) {
-                netdev_dummy_override(type);
+                netdev_dummy_override(type, dummy_type);
             }
         }
         sset_destroy(&types);
     } else if (level == DUMMY_OVERRIDE_SYSTEM) {
-        netdev_dummy_override("system");
+        netdev_dummy_override("system", dummy_type);
+    }
+
+    if (dummy_type == DUMMY_NON_PMD) {
+        netdev_register_provider(&dummy_class);
+    } else {
+        netdev_register_provider(&dummy_pmd_class);
     }
-    netdev_register_provider(&dummy_class);
 
     netdev_vport_tunnel_register();
 }
