diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index e037eab2adbe..2b374e3af97f 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -2378,10 +2378,11 @@ static int
 mark_to_flow_disassociate(struct dp_netdev_pmd_thread *pmd,
                           struct dp_netdev_flow *flow)
 {
-    int ret = 0;
-    uint32_t mark = flow->mark;
+    const char *dpif_type_str = dpif_normalize_type(pmd->dp->class->type);
     struct cmap_node *mark_node = CONST_CAST(struct cmap_node *,
                                              &flow->mark_node);
+    uint32_t mark = flow->mark;
+    int ret = 0;
 
     cmap_remove(&flow_mark.mark_to_flow, mark_node, hash_int(mark, 0));
     flow->mark = INVALID_FLOW_MARK;
@@ -2394,7 +2395,7 @@ mark_to_flow_disassociate(struct dp_netdev_pmd_thread *pmd,
         struct netdev *port;
         odp_port_t in_port = flow->flow.in_port.odp_port;
 
-        port = netdev_ports_get(in_port, pmd->dp->class);
+        port = netdev_ports_get(in_port, dpif_type_str);
         if (port) {
             /* Taking a global 'port_mutex' to fulfill thread safety
              * restrictions for the netdev-offload-dpdk module. */
@@ -2501,9 +2502,9 @@ static int
 dp_netdev_flow_offload_put(struct dp_flow_offload_item *offload)
 {
     struct dp_netdev_pmd_thread *pmd = offload->pmd;
-    const struct dpif_class *dpif_class = pmd->dp->class;
     struct dp_netdev_flow *flow = offload->flow;
     odp_port_t in_port = flow->flow.in_port.odp_port;
+    const char *dpif_type_str = dpif_normalize_type(pmd->dp->class->type);
     bool modification = offload->op == DP_NETDEV_FLOW_OFFLOAD_OP_MOD;
     struct offload_info info;
     struct netdev *port;
@@ -2539,9 +2540,8 @@ dp_netdev_flow_offload_put(struct dp_flow_offload_item *offload)
         }
     }
     info.flow_mark = mark;
-    info.dpif_class = dpif_class;
 
-    port = netdev_ports_get(in_port, pmd->dp->class);
+    port = netdev_ports_get(in_port, dpif_type_str);
     if (!port || netdev_vport_is_vport_class(port->netdev_class)) {
         netdev_close(port);
         goto err_free;
@@ -3154,7 +3154,8 @@ dpif_netdev_get_flow_offload_status(const struct dp_netdev *dp,
         return false;
     }
 
-    netdev = netdev_ports_get(netdev_flow->flow.in_port.odp_port, dp->class);
+    netdev = netdev_ports_get(netdev_flow->flow.in_port.odp_port,
+                              dpif_normalize_type(dp->class->type));
     if (!netdev) {
         return false;
     }
diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c
index 18322e879934..7da4fb54d94f 100644
--- a/lib/dpif-netlink.c
+++ b/lib/dpif-netlink.c
@@ -1120,6 +1120,7 @@ dpif_netlink_port_get_pid(const struct dpif *dpif_, odp_port_t port_no)
 static int
 dpif_netlink_flow_flush(struct dpif *dpif_)
 {
+    const char *dpif_type_str = dpif_normalize_type(dpif_type(dpif_));
     const struct dpif_netlink *dpif = dpif_netlink_cast(dpif_);
     struct dpif_netlink_flow flow;
 
@@ -1128,7 +1129,7 @@ dpif_netlink_flow_flush(struct dpif *dpif_)
     flow.dp_ifindex = dpif->dp_ifindex;
 
     if (netdev_is_flow_api_enabled()) {
-        netdev_ports_flow_flush(dpif_->dpif_class);
+        netdev_ports_flow_flush(dpif_type_str);
     }
 
     return dpif_netlink_flow_transact(&flow, NULL, NULL);
@@ -1445,7 +1446,7 @@ start_netdev_dump(const struct dpif *dpif_,
     ovs_mutex_lock(&dump->netdev_lock);
     dump->netdev_current_dump = 0;
     dump->netdev_dumps
-        = netdev_ports_flow_dump_create(dpif_->dpif_class,
+        = netdev_ports_flow_dump_create(dpif_normalize_type(dpif_type(dpif_)),
                                         &dump->netdev_dumps_num,
                                         dump->up.terse);
     ovs_mutex_unlock(&dump->netdev_lock);
@@ -2002,6 +2003,7 @@ dpif_netlink_operate__(struct dpif_netlink *dpif,
 static int
 parse_flow_get(struct dpif_netlink *dpif, struct dpif_flow_get *get)
 {
+    const char *dpif_type_str = dpif_normalize_type(dpif_type(&dpif->dpif));
     struct dpif_flow *dpif_flow = get->flow;
     struct match match;
     struct nlattr *actions;
@@ -2016,8 +2018,8 @@ parse_flow_get(struct dpif_netlink *dpif, struct dpif_flow_get *get)
     int err;
 
     ofpbuf_use_stack(&buf, &act_buf, sizeof act_buf);
-    err = netdev_ports_flow_get(dpif->dpif.dpif_class, &match,
-                                &actions, get->ufid, &stats, &attrs, &buf);
+    err = netdev_ports_flow_get(dpif_type_str, &match, &actions, get->ufid,
+                                &stats, &attrs, &buf);
     if (err) {
         return err;
     }
@@ -2042,8 +2044,8 @@ parse_flow_get(struct dpif_netlink *dpif, struct dpif_flow_get *get)
 static int
 parse_flow_put(struct dpif_netlink *dpif, struct dpif_flow_put *put)
 {
+    const char *dpif_type_str = dpif_normalize_type(dpif_type(&dpif->dpif));
     static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20);
-    const struct dpif_class *dpif_class = dpif->dpif.dpif_class;
     struct match match;
     odp_port_t in_port;
     const struct nlattr *nla;
@@ -2065,7 +2067,7 @@ parse_flow_put(struct dpif_netlink *dpif, struct dpif_flow_put *put)
     }
 
     in_port = match.flow.in_port.odp_port;
-    dev = netdev_ports_get(in_port, dpif_class);
+    dev = netdev_ports_get(in_port, dpif_type_str);
     if (!dev) {
         return EOPNOTSUPP;
     }
@@ -2078,7 +2080,7 @@ parse_flow_put(struct dpif_netlink *dpif, struct dpif_flow_put *put)
             odp_port_t out_port;
 
             out_port = nl_attr_get_odp_port(nla);
-            outdev = netdev_ports_get(out_port, dpif_class);
+            outdev = netdev_ports_get(out_port, dpif_type_str);
             if (!outdev) {
                 err = EOPNOTSUPP;
                 goto out;
@@ -2094,7 +2096,6 @@ parse_flow_put(struct dpif_netlink *dpif, struct dpif_flow_put *put)
         }
     }
 
-    info.dpif_class = dpif_class;
     info.tp_dst_port = dst_port;
     info.tunnel_csum_on = csum_on;
     info.recirc_id_shared_with_tc = (dpif->user_features
@@ -2198,8 +2199,10 @@ try_send_to_netdev(struct dpif_netlink *dpif, struct dpif_op *op)
             break;
         }
 
-        err = netdev_ports_flow_del(dpif->dpif.dpif_class, del->ufid,
-                                    del->stats);
+        err = netdev_ports_flow_del(
+                                dpif_normalize_type(dpif_type(&dpif->dpif)),
+                                del->ufid,
+                                del->stats);
         log_flow_del_message(&dpif->dpif, &this_module, del, 0);
         break;
     }
diff --git a/lib/dpif.c b/lib/dpif.c
index c529a93f1be0..7cac3a629e6d 100644
--- a/lib/dpif.c
+++ b/lib/dpif.c
@@ -347,6 +347,7 @@ do_open(const char *name, const char *type, bool create, struct dpif **dpifp)
     error = registered_class->dpif_class->open(registered_class->dpif_class,
                                                name, create, &dpif);
     if (!error) {
+        const char *dpif_type_str = dpif_normalize_type(dpif_type(dpif));
         struct dpif_port_dump port_dump;
         struct dpif_port dpif_port;
 
@@ -363,7 +364,7 @@ do_open(const char *name, const char *type, bool create, struct dpif **dpifp)
             err = netdev_open(dpif_port.name, dpif_port.type, &netdev);
 
             if (!err) {
-                netdev_ports_insert(netdev, dpif->dpif_class, &dpif_port);
+                netdev_ports_insert(netdev, dpif_type_str, &dpif_port);
                 netdev_close(netdev);
             } else {
                 VLOG_WARN("could not open netdev %s type %s: %s",
@@ -427,14 +428,15 @@ dpif_create_and_open(const char *name, const char *type, struct dpif **dpifp)
 
 static void
 dpif_remove_netdev_ports(struct dpif *dpif) {
-        struct dpif_port_dump port_dump;
-        struct dpif_port dpif_port;
+    const char *dpif_type_str = dpif_normalize_type(dpif_type(dpif));
+    struct dpif_port_dump port_dump;
+    struct dpif_port dpif_port;
 
-        DPIF_PORT_FOR_EACH (&dpif_port, &port_dump, dpif) {
-            if (!dpif_is_tap_port(dpif_port.type)) {
-                netdev_ports_remove(dpif_port.port_no, dpif->dpif_class);
-            }
+    DPIF_PORT_FOR_EACH (&dpif_port, &port_dump, dpif) {
+        if (!dpif_is_tap_port(dpif_port.type)) {
+            netdev_ports_remove(dpif_port.port_no, dpif_type_str);
         }
+    }
 }
 
 /* Closes and frees the connection to 'dpif'.  Does not destroy the datapath
@@ -597,12 +599,13 @@ dpif_port_add(struct dpif *dpif, struct netdev *netdev, odp_port_t *port_nop)
 
         if (!dpif_is_tap_port(netdev_get_type(netdev))) {
 
+            const char *dpif_type_str = dpif_normalize_type(dpif_type(dpif));
             struct dpif_port dpif_port;
 
             dpif_port.type = CONST_CAST(char *, netdev_get_type(netdev));
             dpif_port.name = CONST_CAST(char *, netdev_name);
             dpif_port.port_no = port_no;
-            netdev_ports_insert(netdev, dpif->dpif_class, &dpif_port);
+            netdev_ports_insert(netdev, dpif_type_str, &dpif_port);
         }
     } else {
         VLOG_WARN_RL(&error_rl, "%s: failed to add %s as port: %s",
@@ -634,7 +637,7 @@ dpif_port_del(struct dpif *dpif, odp_port_t port_no, bool local_delete)
         }
     }
 
-    netdev_ports_remove(port_no, dpif->dpif_class);
+    netdev_ports_remove(port_no, dpif_normalize_type(dpif_type(dpif)));
     return error;
 }
 
diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c
index 26a75f0f282d..2facd1aebba7 100644
--- a/lib/netdev-offload-dpdk.c
+++ b/lib/netdev-offload-dpdk.c
@@ -860,15 +860,14 @@ add_port_id_action(struct flow_actions *actions,
 static int
 add_output_action(struct netdev *netdev,
                   struct flow_actions *actions,
-                  const struct nlattr *nla,
-                  struct offload_info *info)
+                  const struct nlattr *nla)
 {
     struct netdev *outdev;
     odp_port_t port;
     int ret = 0;
 
     port = nl_attr_get_odp_port(nla);
-    outdev = netdev_ports_get(port, info->dpif_class);
+    outdev = netdev_ports_get(port, netdev->dpif_type);
     if (outdev == NULL) {
         VLOG_DBG_RL(&rl, "Cannot find netdev for odp port %"PRIu32, port);
         return -1;
@@ -1033,8 +1032,7 @@ static int
 parse_flow_actions(struct netdev *netdev,
                    struct flow_actions *actions,
                    struct nlattr *nl_actions,
-                   size_t nl_actions_len,
-                   struct offload_info *info)
+                   size_t nl_actions_len)
 {
     struct nlattr *nla;
     size_t left;
@@ -1042,7 +1040,7 @@ parse_flow_actions(struct netdev *netdev,
     add_count_action(actions);
     NL_ATTR_FOR_EACH_UNSAFE (nla, left, nl_actions, nl_actions_len) {
         if (nl_attr_type(nla) == OVS_ACTION_ATTR_OUTPUT) {
-            if (add_output_action(netdev, actions, nla, info)) {
+            if (add_output_action(netdev, actions, nla)) {
                 return -1;
             }
         } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_DROP) {
@@ -1084,8 +1082,7 @@ static struct rte_flow *
 netdev_offload_dpdk_actions(struct netdev *netdev,
                             struct flow_patterns *patterns,
                             struct nlattr *nl_actions,
-                            size_t actions_len,
-                            struct offload_info *info)
+                            size_t actions_len)
 {
     const struct rte_flow_attr flow_attr = { .ingress = 1, .transfer = 1 };
     struct flow_actions actions = { .actions = NULL, .cnt = 0 };
@@ -1093,7 +1090,7 @@ netdev_offload_dpdk_actions(struct netdev *netdev,
     struct rte_flow_error error;
     int ret;
 
-    ret = parse_flow_actions(netdev, &actions, nl_actions, actions_len, info);
+    ret = parse_flow_actions(netdev, &actions, nl_actions, actions_len);
     if (ret) {
         goto out;
     }
@@ -1123,7 +1120,7 @@ netdev_offload_dpdk_add_flow(struct netdev *netdev,
     }
 
     flow = netdev_offload_dpdk_actions(netdev, &patterns, nl_actions,
-                                       actions_len, info);
+                                       actions_len);
     if (!flow) {
         /* If we failed to offload the rule actions fallback to MARK+RSS
          * actions.
diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c
index e50e00f23ccb..2c9c6f4cae8b 100644
--- a/lib/netdev-offload-tc.c
+++ b/lib/netdev-offload-tc.c
@@ -1714,7 +1714,8 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match,
         action = &flower.actions[flower.action_count];
         if (nl_attr_type(nla) == OVS_ACTION_ATTR_OUTPUT) {
             odp_port_t port = nl_attr_get_odp_port(nla);
-            struct netdev *outdev = netdev_ports_get(port, info->dpif_class);
+            struct netdev *outdev = netdev_ports_get(
+                                        port, netdev_get_dpif_type(netdev));
 
             if (!outdev) {
                 VLOG_DBG_RL(&rl, "Can't find netdev for output port %d", port);
diff --git a/lib/netdev-offload.c b/lib/netdev-offload.c
index ab97a292ebac..2da3bc701a61 100644
--- a/lib/netdev-offload.c
+++ b/lib/netdev-offload.c
@@ -383,11 +383,10 @@ static struct hmap ifindex_to_port OVS_GUARDED_BY(netdev_hmap_rwlock)
     = HMAP_INITIALIZER(&ifindex_to_port);
 
 struct port_to_netdev_data {
-    struct hmap_node portno_node; /* By (dpif_class, dpif_port.port_no). */
-    struct hmap_node ifindex_node; /* By (dpif_class, ifindex). */
+    struct hmap_node portno_node; /* By (dpif_type, dpif_port.port_no). */
+    struct hmap_node ifindex_node; /* By (dpif_type, ifindex). */
     struct netdev *netdev;
     struct dpif_port dpif_port;
-    const struct dpif_class *dpif_class;
     int ifindex;
 };
 
@@ -423,13 +422,13 @@ netdev_is_flow_api_enabled(void)
 }
 
 void
-netdev_ports_flow_flush(const struct dpif_class *dpif_class)
+netdev_ports_flow_flush(const char *dpif_type)
 {
     struct port_to_netdev_data *data;
 
     ovs_rwlock_rdlock(&netdev_hmap_rwlock);
     HMAP_FOR_EACH (data, portno_node, &port_to_netdev) {
-        if (data->dpif_class == dpif_class) {
+        if (netdev_get_dpif_type(data->netdev) == dpif_type) {
             netdev_flow_flush(data->netdev);
         }
     }
@@ -437,8 +436,7 @@ netdev_ports_flow_flush(const struct dpif_class *dpif_class)
 }
 
 struct netdev_flow_dump **
-netdev_ports_flow_dump_create(const struct dpif_class *dpif_class, int *ports,
-                              bool terse)
+netdev_ports_flow_dump_create(const char *dpif_type, int *ports, bool terse)
 {
     struct port_to_netdev_data *data;
     struct netdev_flow_dump **dumps;
@@ -447,7 +445,7 @@ netdev_ports_flow_dump_create(const struct dpif_class *dpif_class, int *ports,
 
     ovs_rwlock_rdlock(&netdev_hmap_rwlock);
     HMAP_FOR_EACH (data, portno_node, &port_to_netdev) {
-        if (data->dpif_class == dpif_class) {
+        if (netdev_get_dpif_type(data->netdev) == dpif_type) {
             count++;
         }
     }
@@ -455,7 +453,7 @@ netdev_ports_flow_dump_create(const struct dpif_class *dpif_class, int *ports,
     dumps = count ? xzalloc(sizeof *dumps * count) : NULL;
 
     HMAP_FOR_EACH (data, portno_node, &port_to_netdev) {
-        if (data->dpif_class == dpif_class) {
+        if (netdev_get_dpif_type(data->netdev) == dpif_type) {
             if (netdev_flow_dump_create(data->netdev, &dumps[i], terse)) {
                 continue;
             }
@@ -471,15 +469,14 @@ netdev_ports_flow_dump_create(const struct dpif_class *dpif_class, int *ports,
 }
 
 int
-netdev_ports_flow_del(const struct dpif_class *dpif_class,
-                      const ovs_u128 *ufid,
+netdev_ports_flow_del(const char *dpif_type, const ovs_u128 *ufid,
                       struct dpif_flow_stats *stats)
 {
     struct port_to_netdev_data *data;
 
     ovs_rwlock_rdlock(&netdev_hmap_rwlock);
     HMAP_FOR_EACH (data, portno_node, &port_to_netdev) {
-        if (data->dpif_class == dpif_class
+        if (netdev_get_dpif_type(data->netdev) == dpif_type
             && !netdev_flow_del(data->netdev, ufid, stats)) {
             ovs_rwlock_unlock(&netdev_hmap_rwlock);
             return 0;
@@ -491,7 +488,7 @@ netdev_ports_flow_del(const struct dpif_class *dpif_class,
 }
 
 int
-netdev_ports_flow_get(const struct dpif_class *dpif_class, struct match *match,
+netdev_ports_flow_get(const char *dpif_type, struct match *match,
                       struct nlattr **actions, const ovs_u128 *ufid,
                       struct dpif_flow_stats *stats,
                       struct dpif_flow_attrs *attrs, struct ofpbuf *buf)
@@ -500,7 +497,7 @@ netdev_ports_flow_get(const struct dpif_class *dpif_class, struct match *match,
 
     ovs_rwlock_rdlock(&netdev_hmap_rwlock);
     HMAP_FOR_EACH (data, portno_node, &port_to_netdev) {
-        if (data->dpif_class == dpif_class
+        if (netdev_get_dpif_type(data->netdev) == dpif_type
             && !netdev_flow_get(data->netdev, match, actions,
                                 ufid, stats, attrs, buf)) {
             ovs_rwlock_unlock(&netdev_hmap_rwlock);
@@ -512,21 +509,21 @@ netdev_ports_flow_get(const struct dpif_class *dpif_class, struct match *match,
 }
 
 static uint32_t
-netdev_ports_hash(odp_port_t port, const struct dpif_class *dpif_class)
+netdev_ports_hash(odp_port_t port, const char *dpif_type)
 {
-    return hash_int(odp_to_u32(port), hash_pointer(dpif_class, 0));
+    return hash_int(odp_to_u32(port), hash_pointer(dpif_type, 0));
 }
 
 static struct port_to_netdev_data *
-netdev_ports_lookup(odp_port_t port_no, const struct dpif_class *dpif_class)
+netdev_ports_lookup(odp_port_t port_no, const char *dpif_type)
     OVS_REQ_RDLOCK(netdev_hmap_rwlock)
 {
     struct port_to_netdev_data *data;
 
     HMAP_FOR_EACH_WITH_HASH (data, portno_node,
-                             netdev_ports_hash(port_no, dpif_class),
+                             netdev_ports_hash(port_no, dpif_type),
                              &port_to_netdev) {
-        if (data->dpif_class == dpif_class
+        if (netdev_get_dpif_type(data->netdev) == dpif_type
             && data->dpif_port.port_no == port_no) {
             return data;
         }
@@ -535,7 +532,7 @@ netdev_ports_lookup(odp_port_t port_no, const struct dpif_class *dpif_class)
 }
 
 int
-netdev_ports_insert(struct netdev *netdev, const struct dpif_class *dpif_class,
+netdev_ports_insert(struct netdev *netdev, const char *dpif_type,
                     struct dpif_port *dpif_port)
 {
     struct port_to_netdev_data *data;
@@ -546,19 +543,20 @@ netdev_ports_insert(struct netdev *netdev, const struct dpif_class *dpif_class,
     }
 
     ovs_rwlock_wrlock(&netdev_hmap_rwlock);
-    if (netdev_ports_lookup(dpif_port->port_no, dpif_class)) {
+    if (netdev_ports_lookup(dpif_port->port_no, dpif_type)) {
         ovs_rwlock_unlock(&netdev_hmap_rwlock);
         return EEXIST;
     }
 
     data = xzalloc(sizeof *data);
     data->netdev = netdev_ref(netdev);
-    data->dpif_class = dpif_class;
     dpif_port_clone(&data->dpif_port, dpif_port);
     data->ifindex = ifindex;
 
+    netdev_set_dpif_type(netdev, dpif_type);
+
     hmap_insert(&port_to_netdev, &data->portno_node,
-                netdev_ports_hash(dpif_port->port_no, dpif_class));
+                netdev_ports_hash(dpif_port->port_no, dpif_type));
     hmap_insert(&ifindex_to_port, &data->ifindex_node, ifindex);
     ovs_rwlock_unlock(&netdev_hmap_rwlock);
 
@@ -568,13 +566,13 @@ netdev_ports_insert(struct netdev *netdev, const struct dpif_class *dpif_class,
 }
 
 struct netdev *
-netdev_ports_get(odp_port_t port_no, const struct dpif_class *dpif_class)
+netdev_ports_get(odp_port_t port_no, const char *dpif_type)
 {
     struct port_to_netdev_data *data;
     struct netdev *ret = NULL;
 
     ovs_rwlock_rdlock(&netdev_hmap_rwlock);
-    data = netdev_ports_lookup(port_no, dpif_class);
+    data = netdev_ports_lookup(port_no, dpif_type);
     if (data) {
         ret = netdev_ref(data->netdev);
     }
@@ -584,13 +582,13 @@ netdev_ports_get(odp_port_t port_no, const struct dpif_class *dpif_class)
 }
 
 int
-netdev_ports_remove(odp_port_t port_no, const struct dpif_class *dpif_class)
+netdev_ports_remove(odp_port_t port_no, const char *dpif_type)
 {
     struct port_to_netdev_data *data;
     int ret = ENOENT;
 
     ovs_rwlock_wrlock(&netdev_hmap_rwlock);
-    data = netdev_ports_lookup(port_no, dpif_class);
+    data = netdev_ports_lookup(port_no, dpif_type);
     if (data) {
         dpif_port_destroy(&data->dpif_port);
         netdev_close(data->netdev); /* unref and possibly close */
diff --git a/lib/netdev-offload.h b/lib/netdev-offload.h
index 87f5852c8d60..4c0ed2ae8a20 100644
--- a/lib/netdev-offload.h
+++ b/lib/netdev-offload.h
@@ -62,7 +62,6 @@ struct netdev_flow_dump {
 
 /* Flow offloading. */
 struct offload_info {
-    const struct dpif_class *dpif_class;
     ovs_be16 tp_dst_port; /* Destination port for tunnel in SET action */
     uint8_t tunnel_csum_on; /* Tunnel header with checksum */
 
@@ -105,22 +104,21 @@ bool netdev_is_flow_api_enabled(void);
 void netdev_set_flow_api_enabled(const struct smap *ovs_other_config);
 bool netdev_is_offload_rebalance_policy_enabled(void);
 
-struct dpif_class;
 struct dpif_port;
-int netdev_ports_insert(struct netdev *, const struct dpif_class *,
+int netdev_ports_insert(struct netdev *, const char *dpif_type,
                         struct dpif_port *);
-struct netdev *netdev_ports_get(odp_port_t port, const struct dpif_class *);
-int netdev_ports_remove(odp_port_t port, const struct dpif_class *);
+struct netdev *netdev_ports_get(odp_port_t port, const char *dpif_type);
+int netdev_ports_remove(odp_port_t port, const char *dpif_type);
 odp_port_t netdev_ifindex_to_odp_port(int ifindex);
 
 struct netdev_flow_dump **netdev_ports_flow_dump_create(
-                                        const struct dpif_class *,
+                                        const char *dpif_type,
                                         int *ports,
                                         bool terse);
-void netdev_ports_flow_flush(const struct dpif_class *);
-int netdev_ports_flow_del(const struct dpif_class *, const ovs_u128 *ufid,
+void netdev_ports_flow_flush(const char *dpif_type);
+int netdev_ports_flow_del(const char *dpif_type, const ovs_u128 *ufid,
                           struct dpif_flow_stats *stats);
-int netdev_ports_flow_get(const struct dpif_class *, struct match *match,
+int netdev_ports_flow_get(const char *dpif_type, struct match *match,
                           struct nlattr **actions,
                           const ovs_u128 *ufid,
                           struct dpif_flow_stats *stats,
diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c
index 920f29a6f36a..72751b9b3c8d 100644
--- a/ofproto/ofproto-dpif-upcall.c
+++ b/ofproto/ofproto-dpif-upcall.c
@@ -2501,8 +2501,7 @@ ukey_netdev_unref(struct udpif_key *ukey)
 static void
 ukey_to_flow_netdev(struct udpif *udpif, struct udpif_key *ukey)
 {
-    const struct dpif *dpif = udpif->dpif;
-    const struct dpif_class *dpif_class = dpif->dpif_class;
+    const char *dpif_type_str = dpif_normalize_type(dpif_type(udpif->dpif));
     const struct nlattr *k;
     unsigned int left;
 
@@ -2515,7 +2514,7 @@ ukey_to_flow_netdev(struct udpif *udpif, struct udpif_key *ukey)
 
         if (type == OVS_KEY_ATTR_IN_PORT) {
             ukey->in_netdev = netdev_ports_get(nl_attr_get_odp_port(k),
-                                               dpif_class);
+                                               dpif_type_str);
         } else if (type == OVS_KEY_ATTR_TUNNEL) {
             struct flow_tnl tnl;
             enum odp_key_fitness res;
