diff mbox series

[ovs-dev,v2] netdev: Clean up class initialization.

Message ID 20180815173809.10991-1-blp@ovn.org
State Accepted
Delegated to: Ian Stokes
Headers show
Series [ovs-dev,v2] netdev: Clean up class initialization. | expand

Commit Message

Ben Pfaff Aug. 15, 2018, 5:38 p.m. UTC
The macros are hard to read.  This makes it a little more readable.

Signed-off-by: Ben Pfaff <blp@ovn.org>
---
v1->v2: Refactor DPDK_FLOW_OFFLOAD_API as Ian requested.

 configure.ac          |   1 +
 lib/netdev-dpdk.c     | 234 ++++++++++++----------------------
 lib/netdev-dpdk.h     |   4 +
 lib/netdev-dummy.c    | 134 ++++++++------------
 lib/netdev-linux.c    | 340 +++++++++++++++++++-------------------------------
 lib/netdev-linux.h    |  18 +--
 lib/netdev-provider.h |   2 -
 lib/netdev-vport.c    | 223 +++++++++++++++------------------
 8 files changed, 372 insertions(+), 584 deletions(-)

Comments

Stokes, Ian Aug. 22, 2018, 12:52 p.m. UTC | #1
> The macros are hard to read.  This makes it a little more readable.
> 
> Signed-off-by: Ben Pfaff <blp@ovn.org>
> ---
> v1->v2: Refactor DPDK_FLOW_OFFLOAD_API as Ian requested.

Thanks Ben, LGTM, will add this to this week's pull request for master unless there is any other input.

Thanks
Ian
Ben Pfaff Aug. 24, 2018, 7:40 p.m. UTC | #2
On Wed, Aug 22, 2018 at 12:52:47PM +0000, Stokes, Ian wrote:
> > The macros are hard to read.  This makes it a little more readable.
> > 
> > Signed-off-by: Ben Pfaff <blp@ovn.org>
> > ---
> > v1->v2: Refactor DPDK_FLOW_OFFLOAD_API as Ian requested.
> 
> Thanks Ben, LGTM, will add this to this week's pull request for master unless there is any other input.

Thanks.
diff mbox series

Patch

diff --git a/configure.ac b/configure.ac
index 09e5888d4215..6059ff4fa9e8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -173,6 +173,7 @@  OVS_ENABLE_OPTION([-Wduplicated-cond])
 OVS_ENABLE_OPTION([-Qunused-arguments])
 OVS_ENABLE_OPTION([-Wshadow])
 OVS_ENABLE_OPTION([-Wno-null-pointer-arithmetic])
+OVS_ENABLE_OPTION([-Warray-bounds-pointer-arithmetic])
 OVS_CONDITIONAL_CC_OPTION([-Wno-unused], [HAVE_WNO_UNUSED])
 OVS_CONDITIONAL_CC_OPTION([-Wno-unused-parameter], [HAVE_WNO_UNUSED_PARAMETER])
 OVS_ENABLE_WERROR
diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
index ac02a09acb9e..628d75a75024 100644
--- a/lib/netdev-dpdk.c
+++ b/lib/netdev-dpdk.c
@@ -4693,161 +4693,85 @@  netdev_dpdk_flow_del(struct netdev *netdev, const ovs_u128 *ufid,
                                         ufid, rte_flow);
 }
 
-#define DPDK_FLOW_OFFLOAD_API                                 \
-    NULL,                   /* flow_flush */                  \
-    NULL,                   /* flow_dump_create */            \
-    NULL,                   /* flow_dump_destroy */           \
-    NULL,                   /* flow_dump_next */              \
-    netdev_dpdk_flow_put,                                     \
-    NULL,                   /* flow_get */                    \
-    netdev_dpdk_flow_del,                                     \
-    NULL                    /* init_flow_api */
-
-
-#define NETDEV_DPDK_CLASS(NAME, INIT, CONSTRUCT, DESTRUCT,    \
-                          SET_CONFIG, SET_TX_MULTIQ, SEND,    \
-                          GET_CARRIER, GET_STATS,			  \
-                          GET_CUSTOM_STATS,					  \
-                          GET_FEATURES, GET_STATUS,           \
-                          RECONFIGURE, RXQ_RECV)              \
-{                                                             \
-    NAME,                                                     \
-    true,                       /* is_pmd */                  \
-    INIT,                       /* init */                    \
-    NULL,                       /* netdev_dpdk_run */         \
-    NULL,                       /* netdev_dpdk_wait */        \
-                                                              \
-    netdev_dpdk_alloc,                                        \
-    CONSTRUCT,                                                \
-    DESTRUCT,                                                 \
-    netdev_dpdk_dealloc,                                      \
-    netdev_dpdk_get_config,                                   \
-    SET_CONFIG,                                               \
-    NULL,                       /* get_tunnel_config */       \
-    NULL,                       /* build header */            \
-    NULL,                       /* push header */             \
-    NULL,                       /* pop header */              \
-    netdev_dpdk_get_numa_id,    /* get_numa_id */             \
-    SET_TX_MULTIQ,                                            \
-                                                              \
-    SEND,                       /* send */                    \
-    NULL,                       /* send_wait */               \
-                                                              \
-    netdev_dpdk_set_etheraddr,                                \
-    netdev_dpdk_get_etheraddr,                                \
-    netdev_dpdk_get_mtu,                                      \
-    netdev_dpdk_set_mtu,                                      \
-    netdev_dpdk_get_ifindex,                                  \
-    GET_CARRIER,                                              \
-    netdev_dpdk_get_carrier_resets,                           \
-    netdev_dpdk_set_miimon,                                   \
-    GET_STATS,                                                \
-    GET_CUSTOM_STATS,										  \
-    GET_FEATURES,                                             \
-    NULL,                       /* set_advertisements */      \
-    NULL,                       /* get_pt_mode */             \
-                                                              \
-    netdev_dpdk_set_policing,                                 \
-    netdev_dpdk_get_qos_types,                                \
-    NULL,                       /* get_qos_capabilities */    \
-    netdev_dpdk_get_qos,                                      \
-    netdev_dpdk_set_qos,                                      \
-    NULL,                       /* get_queue */               \
-    NULL,                       /* set_queue */               \
-    NULL,                       /* delete_queue */            \
-    NULL,                       /* get_queue_stats */         \
-    NULL,                       /* queue_dump_start */        \
-    NULL,                       /* queue_dump_next */         \
-    NULL,                       /* queue_dump_done */         \
-    NULL,                       /* dump_queue_stats */        \
-                                                              \
-    NULL,                       /* set_in4 */                 \
-    NULL,                       /* get_addr_list */           \
-    NULL,                       /* add_router */              \
-    NULL,                       /* get_next_hop */            \
-    GET_STATUS,                                               \
-    NULL,                       /* arp_lookup */              \
-                                                              \
-    netdev_dpdk_update_flags,                                 \
-    RECONFIGURE,                                              \
-                                                              \
-    netdev_dpdk_rxq_alloc,                                    \
-    netdev_dpdk_rxq_construct,                                \
-    netdev_dpdk_rxq_destruct,                                 \
-    netdev_dpdk_rxq_dealloc,                                  \
-    RXQ_RECV,                                                 \
-    NULL,                       /* rx_wait */                 \
-    NULL,                       /* rxq_drain */               \
-    DPDK_FLOW_OFFLOAD_API,                                    \
-    NULL                        /* get_block_id */            \
-}
-
-static const struct netdev_class dpdk_class =
-    NETDEV_DPDK_CLASS(
-        "dpdk",
-        netdev_dpdk_class_init,
-        netdev_dpdk_construct,
-        netdev_dpdk_destruct,
-        netdev_dpdk_set_config,
-        netdev_dpdk_set_tx_multiq,
-        netdev_dpdk_eth_send,
-        netdev_dpdk_get_carrier,
-        netdev_dpdk_get_stats,
-        netdev_dpdk_get_custom_stats,
-        netdev_dpdk_get_features,
-        netdev_dpdk_get_status,
-        netdev_dpdk_reconfigure,
-        netdev_dpdk_rxq_recv);
-
-static const struct netdev_class dpdk_ring_class =
-    NETDEV_DPDK_CLASS(
-        "dpdkr",
-        netdev_dpdk_class_init,
-        netdev_dpdk_ring_construct,
-        netdev_dpdk_destruct,
-        netdev_dpdk_ring_set_config,
-        netdev_dpdk_set_tx_multiq,
-        netdev_dpdk_ring_send,
-        netdev_dpdk_get_carrier,
-        netdev_dpdk_get_stats,
-        netdev_dpdk_get_custom_stats,
-        netdev_dpdk_get_features,
-        netdev_dpdk_get_status,
-        netdev_dpdk_reconfigure,
-        netdev_dpdk_rxq_recv);
-
-static const struct netdev_class dpdk_vhost_class =
-    NETDEV_DPDK_CLASS(
-        "dpdkvhostuser",
-        NULL,
-        netdev_dpdk_vhost_construct,
-        netdev_dpdk_vhost_destruct,
-        NULL,
-        NULL,
-        netdev_dpdk_vhost_send,
-        netdev_dpdk_vhost_get_carrier,
-        netdev_dpdk_vhost_get_stats,
-        NULL,
-        NULL,
-        netdev_dpdk_vhost_user_get_status,
-        netdev_dpdk_vhost_reconfigure,
-        netdev_dpdk_vhost_rxq_recv);
-static const struct netdev_class dpdk_vhost_client_class =
-    NETDEV_DPDK_CLASS(
-        "dpdkvhostuserclient",
-        NULL,
-        netdev_dpdk_vhost_client_construct,
-        netdev_dpdk_vhost_destruct,
-        netdev_dpdk_vhost_client_set_config,
-        NULL,
-        netdev_dpdk_vhost_send,
-        netdev_dpdk_vhost_get_carrier,
-        netdev_dpdk_vhost_get_stats,
-        NULL,
-        NULL,
-        netdev_dpdk_vhost_user_get_status,
-        netdev_dpdk_vhost_client_reconfigure,
-        netdev_dpdk_vhost_rxq_recv);
+#define NETDEV_DPDK_CLASS_COMMON                            \
+    .is_pmd = true,                                         \
+    .alloc = netdev_dpdk_alloc,                             \
+    .dealloc = netdev_dpdk_dealloc,                         \
+    .get_config = netdev_dpdk_get_config,                   \
+    .get_numa_id = netdev_dpdk_get_numa_id,                 \
+    .set_etheraddr = netdev_dpdk_set_etheraddr,             \
+    .get_etheraddr = netdev_dpdk_get_etheraddr,             \
+    .get_mtu = netdev_dpdk_get_mtu,                         \
+    .set_mtu = netdev_dpdk_set_mtu,                         \
+    .get_ifindex = netdev_dpdk_get_ifindex,                 \
+    .get_carrier_resets = netdev_dpdk_get_carrier_resets,   \
+    .set_miimon_interval = netdev_dpdk_set_miimon,          \
+    .set_policing = netdev_dpdk_set_policing,               \
+    .get_qos_types = netdev_dpdk_get_qos_types,             \
+    .get_qos = netdev_dpdk_get_qos,                         \
+    .set_qos = netdev_dpdk_set_qos,                         \
+    .update_flags = netdev_dpdk_update_flags,               \
+    .rxq_alloc = netdev_dpdk_rxq_alloc,                     \
+    .rxq_construct = netdev_dpdk_rxq_construct,             \
+    .rxq_destruct = netdev_dpdk_rxq_destruct,               \
+    .rxq_dealloc = netdev_dpdk_rxq_dealloc,                 \
+    DPDK_FLOW_OFFLOAD_API
+
+#define NETDEV_DPDK_CLASS_BASE                          \
+    NETDEV_DPDK_CLASS_COMMON,                           \
+    .init = netdev_dpdk_class_init,                     \
+    .destruct = netdev_dpdk_destruct,                   \
+    .set_tx_multiq = netdev_dpdk_set_tx_multiq,         \
+    .get_carrier = netdev_dpdk_get_carrier,             \
+    .get_stats = netdev_dpdk_get_stats,                 \
+    .get_custom_stats = netdev_dpdk_get_custom_stats,   \
+    .get_features = netdev_dpdk_get_features,           \
+    .get_status = netdev_dpdk_get_status,               \
+    .reconfigure = netdev_dpdk_reconfigure,             \
+    .rxq_recv = netdev_dpdk_rxq_recv
+
+static const struct netdev_class dpdk_class = {
+    .type = "dpdk",
+    NETDEV_DPDK_CLASS_BASE,
+    .construct = netdev_dpdk_construct,
+    .set_config = netdev_dpdk_set_config,
+    .send = netdev_dpdk_eth_send,
+};
+
+static const struct netdev_class dpdk_ring_class = {
+    .type = "dpdkr",
+    NETDEV_DPDK_CLASS_BASE,
+    .construct = netdev_dpdk_ring_construct,
+    .set_config = netdev_dpdk_ring_set_config,
+    .send = netdev_dpdk_ring_send,
+};
+
+static const struct netdev_class dpdk_vhost_class = {
+    .type = "dpdkvhostuser",
+    NETDEV_DPDK_CLASS_COMMON,
+    .construct = netdev_dpdk_vhost_construct,
+    .destruct = netdev_dpdk_vhost_destruct,
+    .send = netdev_dpdk_vhost_send,
+    .get_carrier = netdev_dpdk_vhost_get_carrier,
+    .get_stats = netdev_dpdk_vhost_get_stats,
+    .get_status = netdev_dpdk_vhost_user_get_status,
+    .reconfigure = netdev_dpdk_vhost_reconfigure,
+    .rxq_recv = netdev_dpdk_vhost_rxq_recv
+};
+
+static const struct netdev_class dpdk_vhost_client_class = {
+    .type = "dpdkvhostuserclient",
+    NETDEV_DPDK_CLASS_COMMON,
+    .construct = netdev_dpdk_vhost_client_construct,
+    .destruct = netdev_dpdk_vhost_destruct,
+    .set_config = netdev_dpdk_vhost_client_set_config,
+    .send = netdev_dpdk_vhost_send,
+    .get_carrier = netdev_dpdk_vhost_get_carrier,
+    .get_stats = netdev_dpdk_vhost_get_stats,
+    .get_status = netdev_dpdk_vhost_user_get_status,
+    .reconfigure = netdev_dpdk_vhost_client_reconfigure,
+    .rxq_recv = netdev_dpdk_vhost_rxq_recv
+};
 
 void
 netdev_dpdk_register(void)
diff --git a/lib/netdev-dpdk.h b/lib/netdev-dpdk.h
index b7d02a77dc72..cc0501d6879a 100644
--- a/lib/netdev-dpdk.h
+++ b/lib/netdev-dpdk.h
@@ -25,6 +25,10 @@  struct dp_packet;
 
 #ifdef DPDK_NETDEV
 
+#define DPDK_FLOW_OFFLOAD_API                   \
+    .flow_put = netdev_dpdk_flow_put,           \
+    .flow_del = netdev_dpdk_flow_del
+
 void netdev_dpdk_register(void);
 void free_dpdk_buf(struct dp_packet *);
 
diff --git a/lib/netdev-dummy.c b/lib/netdev-dummy.c
index d4984674fb53..2cf05634eae9 100644
--- a/lib/netdev-dummy.c
+++ b/lib/netdev-dummy.c
@@ -1393,90 +1393,56 @@  netdev_dummy_update_flags(struct netdev *netdev_,
 
 /* Helper functions. */
 
-#define NETDEV_DUMMY_CLASS(NAME, PMD, RECOFIGURE)               \
-{                                                               \
-    NAME,                                                       \
-    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_tx_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,                                     \
-    netdev_dummy_get_custom_stats,                              \
-                                                                \
-    NULL,                       /* get_features */              \
-    NULL,                       /* set_advertisements */        \
-    NULL,                       /* get_pt_mode */               \
-                                                                \
-    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,                              \
-                                                                \
-    NULL,                       /* set_in4 */                   \
-    netdev_dummy_get_addr_list,                                 \
-    NULL,                       /* add_router */                \
-    NULL,                       /* get_next_hop */              \
-    NULL,                       /* get_status */                \
-    NULL,                       /* arp_lookup */                \
-                                                                \
-    netdev_dummy_update_flags,                                  \
-    RECOFIGURE,                                                 \
-                                                                \
-    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,                                     \
-                                                                \
-    NO_OFFLOAD_API,                                             \
-    NULL                        /* get_block_id */              \
-}
-
-static const struct netdev_class dummy_class =
-    NETDEV_DUMMY_CLASS("dummy", false, NULL);
-
-static const struct netdev_class dummy_internal_class =
-    NETDEV_DUMMY_CLASS("dummy-internal", false, NULL);
-
-static const struct netdev_class dummy_pmd_class =
-    NETDEV_DUMMY_CLASS("dummy-pmd", true,
-                       netdev_dummy_reconfigure);
+#define NETDEV_DUMMY_CLASS_COMMON                       \
+    .run = netdev_dummy_run,                            \
+    .wait = netdev_dummy_wait,                          \
+    .alloc = netdev_dummy_alloc,                        \
+    .construct = netdev_dummy_construct,                \
+    .destruct = netdev_dummy_destruct,                  \
+    .dealloc = netdev_dummy_dealloc,                    \
+    .get_config = netdev_dummy_get_config,              \
+    .set_config = netdev_dummy_set_config,              \
+    .get_numa_id = netdev_dummy_get_numa_id,            \
+    .send = netdev_dummy_send,                          \
+    .set_etheraddr = netdev_dummy_set_etheraddr,        \
+    .get_etheraddr = netdev_dummy_get_etheraddr,        \
+    .get_mtu = netdev_dummy_get_mtu,                    \
+    .set_mtu = netdev_dummy_set_mtu,                    \
+    .get_ifindex = netdev_dummy_get_ifindex,            \
+    .get_stats = netdev_dummy_get_stats,                \
+    .get_custom_stats = netdev_dummy_get_custom_stats,  \
+    .get_queue = netdev_dummy_get_queue,                \
+    .get_queue_stats = netdev_dummy_get_queue_stats,    \
+    .queue_dump_start = netdev_dummy_queue_dump_start,  \
+    .queue_dump_next = netdev_dummy_queue_dump_next,    \
+    .queue_dump_done = netdev_dummy_queue_dump_done,    \
+    .dump_queue_stats = netdev_dummy_dump_queue_stats,  \
+    .get_addr_list = netdev_dummy_get_addr_list,        \
+    .update_flags = netdev_dummy_update_flags,          \
+    .rxq_alloc = netdev_dummy_rxq_alloc,                \
+    .rxq_construct = netdev_dummy_rxq_construct,        \
+    .rxq_destruct = netdev_dummy_rxq_destruct,          \
+    .rxq_dealloc = netdev_dummy_rxq_dealloc,            \
+    .rxq_recv = netdev_dummy_rxq_recv,                  \
+    .rxq_wait = netdev_dummy_rxq_wait,                  \
+    .rxq_drain = netdev_dummy_rxq_drain
+
+static const struct netdev_class dummy_class = {
+    NETDEV_DUMMY_CLASS_COMMON,
+    .type = "dummy"
+};
+
+static const struct netdev_class dummy_internal_class = {
+    NETDEV_DUMMY_CLASS_COMMON,
+    .type = "dummy-internal"
+};
+
+static const struct netdev_class dummy_pmd_class = {
+    NETDEV_DUMMY_CLASS_COMMON,
+    .type = "dummy-pmd",
+    .is_pmd = true,
+    .reconfigure = netdev_dummy_reconfigure
+};
 
 static void
 pkt_list_delete(struct ovs_list *l)
diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c
index 0c42268d9d6c..32e75d6fe98f 100644
--- a/lib/netdev-linux.c
+++ b/lib/netdev-linux.c
@@ -3158,113 +3158,77 @@  exit:
     return error;
 }
 
-#define NETDEV_LINUX_CLASS(NAME, CONSTRUCT, GET_STATS,          \
-                           GET_FEATURES, GET_STATUS,            \
-                           FLOW_OFFLOAD_API, GET_BLOCK_ID)      \
-{                                                               \
-    NAME,                                                       \
-    false,                      /* is_pmd */                    \
-                                                                \
-    NULL,                                                       \
-    netdev_linux_run,                                           \
-    netdev_linux_wait,                                          \
-                                                                \
-    netdev_linux_alloc,                                         \
-    CONSTRUCT,                                                  \
-    netdev_linux_destruct,                                      \
-    netdev_linux_dealloc,                                       \
-    NULL,                       /* get_config */                \
-    NULL,                       /* set_config */                \
-    NULL,                       /* get_tunnel_config */         \
-    NULL,                       /* build header */              \
-    NULL,                       /* push header */               \
-    NULL,                       /* pop header */                \
-    NULL,                       /* get_numa_id */               \
-    NULL,                       /* set_tx_multiq */             \
-                                                                \
-    netdev_linux_send,                                          \
-    netdev_linux_send_wait,                                     \
-                                                                \
-    netdev_linux_set_etheraddr,                                 \
-    netdev_linux_get_etheraddr,                                 \
-    netdev_linux_get_mtu,                                       \
-    netdev_linux_set_mtu,                                       \
-    netdev_linux_get_ifindex,                                   \
-    netdev_linux_get_carrier,                                   \
-    netdev_linux_get_carrier_resets,                            \
-    netdev_linux_set_miimon_interval,                           \
-    GET_STATS,                                                  \
-    NULL,														\
-                                                                \
-    GET_FEATURES,                                               \
-    netdev_linux_set_advertisements,                            \
-    NULL,                       /* get_pt_mode */               \
-                                                                \
-    netdev_linux_set_policing,                                  \
-    netdev_linux_get_qos_types,                                 \
-    netdev_linux_get_qos_capabilities,                          \
-    netdev_linux_get_qos,                                       \
-    netdev_linux_set_qos,                                       \
-    netdev_linux_get_queue,                                     \
-    netdev_linux_set_queue,                                     \
-    netdev_linux_delete_queue,                                  \
-    netdev_linux_get_queue_stats,                               \
-    netdev_linux_queue_dump_start,                              \
-    netdev_linux_queue_dump_next,                               \
-    netdev_linux_queue_dump_done,                               \
-    netdev_linux_dump_queue_stats,                              \
-                                                                \
-    netdev_linux_set_in4,                                       \
-    netdev_linux_get_addr_list,                                 \
-    netdev_linux_add_router,                                    \
-    netdev_linux_get_next_hop,                                  \
-    GET_STATUS,                                                 \
-    netdev_linux_arp_lookup,                                    \
-                                                                \
-    netdev_linux_update_flags,                                  \
-    NULL,                       /* reconfigure */               \
-                                                                \
-    netdev_linux_rxq_alloc,                                     \
-    netdev_linux_rxq_construct,                                 \
-    netdev_linux_rxq_destruct,                                  \
-    netdev_linux_rxq_dealloc,                                   \
-    netdev_linux_rxq_recv,                                      \
-    netdev_linux_rxq_wait,                                      \
-    netdev_linux_rxq_drain,                                     \
-                                                                \
-    FLOW_OFFLOAD_API,                                           \
-    GET_BLOCK_ID                                                \
-}
-
-const struct netdev_class netdev_linux_class =
-    NETDEV_LINUX_CLASS(
-        "system",
-        netdev_linux_construct,
-        netdev_linux_get_stats,
-        netdev_linux_get_features,
-        netdev_linux_get_status,
-        LINUX_FLOW_OFFLOAD_API,
-        netdev_linux_get_block_id);
-
-const struct netdev_class netdev_tap_class =
-    NETDEV_LINUX_CLASS(
-        "tap",
-        netdev_linux_construct_tap,
-        netdev_tap_get_stats,
-        netdev_linux_get_features,
-        netdev_linux_get_status,
-        NO_OFFLOAD_API,
-        NULL);
-
-const struct netdev_class netdev_internal_class =
-    NETDEV_LINUX_CLASS(
-        "internal",
-        netdev_linux_construct,
-        netdev_internal_get_stats,
-        NULL,                  /* get_features */
-        netdev_internal_get_status,
-        NO_OFFLOAD_API,
-        NULL);
+#define NETDEV_LINUX_CLASS_COMMON                               \
+    .run = netdev_linux_run,                                    \
+    .wait = netdev_linux_wait,                                  \
+    .alloc = netdev_linux_alloc,                                \
+    .destruct = netdev_linux_destruct,                          \
+    .dealloc = netdev_linux_dealloc,                            \
+    .send = netdev_linux_send,                                  \
+    .send_wait = netdev_linux_send_wait,                        \
+    .set_etheraddr = netdev_linux_set_etheraddr,                \
+    .get_etheraddr = netdev_linux_get_etheraddr,                \
+    .get_mtu = netdev_linux_get_mtu,                            \
+    .set_mtu = netdev_linux_set_mtu,                            \
+    .get_ifindex = netdev_linux_get_ifindex,                    \
+    .get_carrier = netdev_linux_get_carrier,                    \
+    .get_carrier_resets = netdev_linux_get_carrier_resets,      \
+    .set_miimon_interval = netdev_linux_set_miimon_interval,    \
+    .set_advertisements = netdev_linux_set_advertisements,      \
+    .set_policing = netdev_linux_set_policing,                  \
+    .get_qos_types = netdev_linux_get_qos_types,                \
+    .get_qos_capabilities = netdev_linux_get_qos_capabilities,  \
+    .get_qos = netdev_linux_get_qos,                            \
+    .set_qos = netdev_linux_set_qos,                            \
+    .get_queue = netdev_linux_get_queue,                        \
+    .set_queue = netdev_linux_set_queue,                        \
+    .delete_queue = netdev_linux_delete_queue,                  \
+    .get_queue_stats = netdev_linux_get_queue_stats,            \
+    .queue_dump_start = netdev_linux_queue_dump_start,          \
+    .queue_dump_next = netdev_linux_queue_dump_next,            \
+    .queue_dump_done = netdev_linux_queue_dump_done,            \
+    .dump_queue_stats = netdev_linux_dump_queue_stats,          \
+    .set_in4 = netdev_linux_set_in4,                            \
+    .get_addr_list = netdev_linux_get_addr_list,                \
+    .add_router = netdev_linux_add_router,                      \
+    .get_next_hop = netdev_linux_get_next_hop,                  \
+    .arp_lookup = netdev_linux_arp_lookup,                      \
+    .update_flags = netdev_linux_update_flags,                  \
+    .rxq_alloc = netdev_linux_rxq_alloc,                        \
+    .rxq_construct = netdev_linux_rxq_construct,                \
+    .rxq_destruct = netdev_linux_rxq_destruct,                  \
+    .rxq_dealloc = netdev_linux_rxq_dealloc,                    \
+    .rxq_recv = netdev_linux_rxq_recv,                          \
+    .rxq_wait = netdev_linux_rxq_wait,                          \
+    .rxq_drain = netdev_linux_rxq_drain
+
+const struct netdev_class netdev_linux_class = {
+    NETDEV_LINUX_CLASS_COMMON,
+    LINUX_FLOW_OFFLOAD_API,
+    .type = "system",
+    .construct = netdev_linux_construct,
+    .get_stats = netdev_linux_get_stats,
+    .get_features = netdev_linux_get_features,
+    .get_status = netdev_linux_get_status,
+    .get_block_id = netdev_linux_get_block_id
+};
+
+const struct netdev_class netdev_tap_class = {
+    NETDEV_LINUX_CLASS_COMMON,
+    .type = "tap",
+    .construct = netdev_linux_construct_tap,
+    .get_stats = netdev_tap_get_stats,
+    .get_features = netdev_linux_get_features,
+    .get_status = netdev_linux_get_status,
+};
+
+const struct netdev_class netdev_internal_class = {
+    NETDEV_LINUX_CLASS_COMMON,
+    .type = "internal",
+    .construct = netdev_linux_construct,
+    .get_stats = netdev_internal_get_stats,
+    .get_status = netdev_internal_get_status,
+};
 
 
 #define CODEL_N_QUEUES 0x0000
@@ -3461,19 +3425,14 @@  codel_qdisc_set(struct netdev *netdev, const struct smap *details)
 }
 
 static const struct tc_ops tc_ops_codel = {
-    "codel",                      /* linux_name */
-    "linux-codel",                /* ovs_name */
-    CODEL_N_QUEUES,               /* n_queues */
-    codel_tc_install,
-    codel_tc_load,
-    codel_tc_destroy,
-    codel_qdisc_get,
-    codel_qdisc_set,
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-    NULL
+    .linux_name = "codel",
+    .ovs_name = "linux-codel",
+    .n_queues = CODEL_N_QUEUES,
+    .tc_install = codel_tc_install,
+    .tc_load = codel_tc_load,
+    .tc_destroy = codel_tc_destroy,
+    .qdisc_get = codel_qdisc_get,
+    .qdisc_set = codel_qdisc_set,
 };
 
 /* FQ-CoDel traffic control class. */
@@ -3703,19 +3662,14 @@  fqcodel_qdisc_set(struct netdev *netdev, const struct smap *details)
 }
 
 static const struct tc_ops tc_ops_fqcodel = {
-    "fq_codel",                      /* linux_name */
-    "linux-fq_codel",                /* ovs_name */
-    FQCODEL_N_QUEUES,                /* n_queues */
-    fqcodel_tc_install,
-    fqcodel_tc_load,
-    fqcodel_tc_destroy,
-    fqcodel_qdisc_get,
-    fqcodel_qdisc_set,
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-    NULL
+    .linux_name = "fq_codel",
+    .ovs_name = "linux-fq_codel",
+    .n_queues = FQCODEL_N_QUEUES,
+    .tc_install = fqcodel_tc_install,
+    .tc_load = fqcodel_tc_load,
+    .tc_destroy = fqcodel_tc_destroy,
+    .qdisc_get = fqcodel_qdisc_get,
+    .qdisc_set = fqcodel_qdisc_set,
 };
 
 /* SFQ traffic control class. */
@@ -3882,19 +3836,14 @@  sfq_qdisc_set(struct netdev *netdev, const struct smap *details)
 }
 
 static const struct tc_ops tc_ops_sfq = {
-    "sfq",                      /* linux_name */
-    "linux-sfq",                /* ovs_name */
-    SFQ_N_QUEUES,               /* n_queues */
-    sfq_tc_install,
-    sfq_tc_load,
-    sfq_tc_destroy,
-    sfq_qdisc_get,
-    sfq_qdisc_set,
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-    NULL
+    .linux_name = "sfq",
+    .ovs_name = "linux-sfq",
+    .n_queues = SFQ_N_QUEUES,
+    .tc_install = sfq_tc_install,
+    .tc_load = sfq_tc_load,
+    .tc_destroy = sfq_tc_destroy,
+    .qdisc_get = sfq_qdisc_get,
+    .qdisc_set = sfq_qdisc_set,
 };
 
 /* HTB traffic control class. */
@@ -4364,19 +4313,19 @@  htb_class_dump_stats(const struct netdev *netdev OVS_UNUSED,
 }
 
 static const struct tc_ops tc_ops_htb = {
-    "htb",                      /* linux_name */
-    "linux-htb",                /* ovs_name */
-    HTB_N_QUEUES,               /* n_queues */
-    htb_tc_install,
-    htb_tc_load,
-    htb_tc_destroy,
-    htb_qdisc_get,
-    htb_qdisc_set,
-    htb_class_get,
-    htb_class_set,
-    htb_class_delete,
-    htb_class_get_stats,
-    htb_class_dump_stats
+    .linux_name = "htb",
+    .ovs_name = "linux-htb",
+    .n_queues = HTB_N_QUEUES,
+    .tc_install = htb_tc_install,
+    .tc_load = htb_tc_load,
+    .tc_destroy = htb_tc_destroy,
+    .qdisc_get = htb_qdisc_get,
+    .qdisc_set = htb_qdisc_set,
+    .class_get = htb_class_get,
+    .class_set = htb_class_set,
+    .class_delete = htb_class_delete,
+    .class_get_stats = htb_class_get_stats,
+    .class_dump_stats = htb_class_dump_stats
 };
 
 /* "linux-hfsc" traffic control class. */
@@ -4861,19 +4810,19 @@  hfsc_class_dump_stats(const struct netdev *netdev OVS_UNUSED,
 }
 
 static const struct tc_ops tc_ops_hfsc = {
-    "hfsc",                     /* linux_name */
-    "linux-hfsc",               /* ovs_name */
-    HFSC_N_QUEUES,              /* n_queues */
-    hfsc_tc_install,            /* tc_install */
-    hfsc_tc_load,               /* tc_load */
-    hfsc_tc_destroy,            /* tc_destroy */
-    hfsc_qdisc_get,             /* qdisc_get */
-    hfsc_qdisc_set,             /* qdisc_set */
-    hfsc_class_get,             /* class_get */
-    hfsc_class_set,             /* class_set */
-    hfsc_class_delete,          /* class_delete */
-    hfsc_class_get_stats,       /* class_get_stats */
-    hfsc_class_dump_stats       /* class_dump_stats */
+    .linux_name = "hfsc",
+    .ovs_name = "linux-hfsc",
+    .n_queues = HFSC_N_QUEUES,              /* n_queues */
+    .tc_install = hfsc_tc_install,
+    .tc_load = hfsc_tc_load,
+    .tc_destroy = hfsc_tc_destroy,
+    .qdisc_get = hfsc_qdisc_get,
+    .qdisc_set = hfsc_qdisc_set,
+    .class_get = hfsc_class_get,
+    .class_set = hfsc_class_set,
+    .class_delete = hfsc_class_delete,
+    .class_get_stats = hfsc_class_get_stats,
+    .class_dump_stats = hfsc_class_dump_stats,
 };
 
 /* "linux-noop" traffic control class. */
@@ -4903,19 +4852,9 @@  noop_tc_load(struct netdev *netdev, struct ofpbuf *nlmsg OVS_UNUSED)
 }
 
 static const struct tc_ops tc_ops_noop = {
-    NULL,                       /* linux_name */
-    "linux-noop",               /* ovs_name */
-    0,                          /* n_queues */
-    noop_tc_install,
-    noop_tc_load,
-    NULL,                       /* tc_destroy */
-    NULL,                       /* qdisc_get */
-    NULL,                       /* qdisc_set */
-    NULL,                       /* class_get */
-    NULL,                       /* class_set */
-    NULL,                       /* class_delete */
-    NULL,                       /* class_get_stats */
-    NULL                        /* class_dump_stats */
+    .ovs_name = "linux-noop",               /* ovs_name */
+    .tc_install = noop_tc_install,
+    .tc_load = noop_tc_load,
 };
 
 /* "linux-default" traffic control class.
@@ -4950,19 +4889,9 @@  default_tc_load(struct netdev *netdev, struct ofpbuf *nlmsg OVS_UNUSED)
 }
 
 static const struct tc_ops tc_ops_default = {
-    NULL,                       /* linux_name */
-    "",                         /* ovs_name */
-    0,                          /* n_queues */
-    default_tc_install,
-    default_tc_load,
-    NULL,                       /* tc_destroy */
-    NULL,                       /* qdisc_get */
-    NULL,                       /* qdisc_set */
-    NULL,                       /* class_get */
-    NULL,                       /* class_set */
-    NULL,                       /* class_delete */
-    NULL,                       /* class_get_stats */
-    NULL                        /* class_dump_stats */
+    .ovs_name = "",                         /* ovs_name */
+    .tc_install = default_tc_install,
+    .tc_load = default_tc_load,
 };
 
 /* "linux-other" traffic control class.
@@ -4982,19 +4911,8 @@  other_tc_load(struct netdev *netdev_, struct ofpbuf *nlmsg OVS_UNUSED)
 }
 
 static const struct tc_ops tc_ops_other = {
-    NULL,                       /* linux_name */
-    "linux-other",              /* ovs_name */
-    0,                          /* n_queues */
-    NULL,                       /* tc_install */
-    other_tc_load,
-    NULL,                       /* tc_destroy */
-    NULL,                       /* qdisc_get */
-    NULL,                       /* qdisc_set */
-    NULL,                       /* class_get */
-    NULL,                       /* class_set */
-    NULL,                       /* class_delete */
-    NULL,                       /* class_get_stats */
-    NULL                        /* class_dump_stats */
+    .ovs_name = "linux-other",
+    .tc_load = other_tc_load,
 };
 
 /* Traffic control. */
diff --git a/lib/netdev-linux.h b/lib/netdev-linux.h
index 880f86402a1e..17ca9120168a 100644
--- a/lib/netdev-linux.h
+++ b/lib/netdev-linux.h
@@ -29,14 +29,14 @@  int netdev_linux_ethtool_set_flag(struct netdev *netdev, uint32_t flag,
                                   const char *flag_name, bool enable);
 int linux_get_ifindex(const char *netdev_name);
 
-#define LINUX_FLOW_OFFLOAD_API                                  \
-            netdev_tc_flow_flush,                               \
-            netdev_tc_flow_dump_create,                         \
-            netdev_tc_flow_dump_destroy,                        \
-            netdev_tc_flow_dump_next,                           \
-            netdev_tc_flow_put,                                 \
-            netdev_tc_flow_get,                                 \
-            netdev_tc_flow_del,                                 \
-            netdev_tc_init_flow_api
+#define LINUX_FLOW_OFFLOAD_API                          \
+   .flow_flush = netdev_tc_flow_flush,                  \
+   .flow_dump_create = netdev_tc_flow_dump_create,      \
+   .flow_dump_destroy = netdev_tc_flow_dump_destroy,    \
+   .flow_dump_next = netdev_tc_flow_dump_next,          \
+   .flow_put = netdev_tc_flow_put,                      \
+   .flow_get = netdev_tc_flow_get,                      \
+   .flow_del = netdev_tc_flow_del,                      \
+   .init_flow_api = netdev_tc_init_flow_api
 
 #endif /* netdev-linux.h */
diff --git a/lib/netdev-provider.h b/lib/netdev-provider.h
index 1a572f5b8fdc..5a79473511cb 100644
--- a/lib/netdev-provider.h
+++ b/lib/netdev-provider.h
@@ -893,6 +893,4 @@  extern const struct netdev_class netdev_tap_class;
 }
 #endif
 
-#define NO_OFFLOAD_API NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
-
 #endif /* netdev.h */
diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c
index 2290de96c278..8f8411c9c519 100644
--- a/lib/netdev-vport.c
+++ b/lib/netdev-vport.c
@@ -936,7 +936,7 @@  set_patch_config(struct netdev *dev_, const struct smap *args, char **errp)
 }
 
 static int
-get_stats(const struct netdev *netdev, struct netdev_stats *stats)
+netdev_vport_get_stats(const struct netdev *netdev, struct netdev_stats *stats)
 {
     struct netdev_vport *dev = netdev_vport_cast(netdev);
 
@@ -952,7 +952,7 @@  get_stats(const struct netdev *netdev, struct netdev_stats *stats)
 }
 
 static enum netdev_pt_mode
-get_pt_mode(const struct netdev *netdev)
+netdev_vport_get_pt_mode(const struct netdev *netdev)
 {
     struct netdev_vport *dev = netdev_vport_cast(netdev);
 
@@ -972,98 +972,32 @@  netdev_vport_get_ifindex(const struct netdev *netdev_)
 }
 
 #define NETDEV_VPORT_GET_IFINDEX netdev_vport_get_ifindex
-#define NETDEV_FLOW_OFFLOAD_API LINUX_FLOW_OFFLOAD_API
+#define NETDEV_FLOW_OFFLOAD_API , LINUX_FLOW_OFFLOAD_API
 #else /* !__linux__ */
 #define NETDEV_VPORT_GET_IFINDEX NULL
-#define NETDEV_FLOW_OFFLOAD_API NO_OFFLOAD_API
+#define NETDEV_FLOW_OFFLOAD_API
 #endif /* __linux__ */
 
-#define VPORT_FUNCTIONS(GET_CONFIG, SET_CONFIG,             \
-                        GET_TUNNEL_CONFIG, GET_STATUS,      \
-                        BUILD_HEADER,                       \
-                        PUSH_HEADER, POP_HEADER,            \
-                        GET_IFINDEX)                        \
-    NULL,                                                   \
-    netdev_vport_run,                                       \
-    netdev_vport_wait,                                      \
-                                                            \
-    netdev_vport_alloc,                                     \
-    netdev_vport_construct,                                 \
-    netdev_vport_destruct,                                  \
-    netdev_vport_dealloc,                                   \
-    GET_CONFIG,                                             \
-    SET_CONFIG,                                             \
-    GET_TUNNEL_CONFIG,                                      \
-    BUILD_HEADER,                                           \
-    PUSH_HEADER,                                            \
-    POP_HEADER,                                             \
-    NULL,                       /* get_numa_id */           \
-    NULL,                       /* set_tx_multiq */         \
-                                                            \
-    NULL,                       /* send */                  \
-    NULL,                       /* send_wait */             \
-                                                            \
-    netdev_vport_set_etheraddr,                             \
-    netdev_vport_get_etheraddr,                             \
-    NULL,                       /* get_mtu */               \
-    NULL,                       /* set_mtu */               \
-    GET_IFINDEX,                                            \
-    NULL,                       /* get_carrier */           \
-    NULL,                       /* get_carrier_resets */    \
-    NULL,                       /* get_miimon */            \
-    get_stats,                                              \
-    NULL,                       /* get_custom_stats */      \
-                                                            \
-    NULL,                       /* get_features */          \
-    NULL,                       /* set_advertisements */    \
-    get_pt_mode,                                            \
-                                                            \
-    NULL,                       /* set_policing */          \
-    NULL,                       /* get_qos_types */         \
-    NULL,                       /* get_qos_capabilities */  \
-    NULL,                       /* get_qos */               \
-    NULL,                       /* set_qos */               \
-    NULL,                       /* get_queue */             \
-    NULL,                       /* set_queue */             \
-    NULL,                       /* delete_queue */          \
-    NULL,                       /* get_queue_stats */       \
-    NULL,                       /* queue_dump_start */      \
-    NULL,                       /* queue_dump_next */       \
-    NULL,                       /* queue_dump_done */       \
-    NULL,                       /* dump_queue_stats */      \
-                                                            \
-    NULL,                       /* set_in4 */               \
-    NULL,                       /* get_addr_list */         \
-    NULL,                       /* add_router */            \
-    NULL,                       /* get_next_hop */          \
-    GET_STATUS,                                             \
-    NULL,                       /* arp_lookup */            \
-                                                            \
-    netdev_vport_update_flags,                              \
-    NULL,                       /* reconfigure */           \
-                                                            \
-    NULL,                   /* rx_alloc */                  \
-    NULL,                   /* rx_construct */              \
-    NULL,                   /* rx_destruct */               \
-    NULL,                   /* rx_dealloc */                \
-    NULL,                   /* rx_recv */                   \
-    NULL,                   /* rx_wait */                   \
-    NULL,                   /* rx_drain */                  \
-                                                            \
-    NETDEV_FLOW_OFFLOAD_API,                                 \
-    NULL                    /* get_block_id */
-
-
-#define TUNNEL_CLASS(NAME, DPIF_PORT, BUILD_HEADER, PUSH_HEADER, POP_HEADER,   \
-                     GET_IFINDEX)                                              \
-    { DPIF_PORT,                                                               \
-        { NAME, false,                                                         \
-          VPORT_FUNCTIONS(get_tunnel_config,                                   \
-                          set_tunnel_config,                                   \
-                          get_netdev_tunnel_config,                            \
-                          tunnel_get_status,                                   \
-                          BUILD_HEADER, PUSH_HEADER, POP_HEADER,               \
-                          GET_IFINDEX) }}
+#define VPORT_FUNCTIONS_COMMON                      \
+    .run = netdev_vport_run,                        \
+    .wait = netdev_vport_wait,                      \
+    .alloc = netdev_vport_alloc,                    \
+    .construct = netdev_vport_construct,            \
+    .destruct = netdev_vport_destruct,              \
+    .dealloc = netdev_vport_dealloc,                \
+    .set_etheraddr = netdev_vport_set_etheraddr,    \
+    .get_etheraddr = netdev_vport_get_etheraddr,    \
+    .get_stats = netdev_vport_get_stats,            \
+    .get_pt_mode = netdev_vport_get_pt_mode,        \
+    .update_flags = netdev_vport_update_flags       \
+    NETDEV_FLOW_OFFLOAD_API
+
+#define TUNNEL_FUNCTIONS_COMMON                     \
+    VPORT_FUNCTIONS_COMMON,                         \
+    .get_config = get_tunnel_config,                \
+    .set_config = set_tunnel_config,                \
+    .get_tunnel_config = get_netdev_tunnel_config,  \
+    .get_status = tunnel_get_status
 
 void
 netdev_vport_tunnel_register(void)
@@ -1071,32 +1005,74 @@  netdev_vport_tunnel_register(void)
     /* The name of the dpif_port should be short enough to accomodate adding
      * a port number to the end if one is necessary. */
     static const struct vport_class vport_classes[] = {
-        TUNNEL_CLASS("geneve", "genev_sys", netdev_geneve_build_header,
-                                            netdev_tnl_push_udp_header,
-                                            netdev_geneve_pop_header,
-                                            NETDEV_VPORT_GET_IFINDEX),
-        TUNNEL_CLASS("gre", "gre_sys", netdev_gre_build_header,
-                                       netdev_gre_push_header,
-                                       netdev_gre_pop_header,
-                                       NULL),
-        TUNNEL_CLASS("vxlan", "vxlan_sys", netdev_vxlan_build_header,
-                                           netdev_tnl_push_udp_header,
-                                           netdev_vxlan_pop_header,
-                                           NETDEV_VPORT_GET_IFINDEX),
-        TUNNEL_CLASS("lisp", "lisp_sys", NULL, NULL, NULL, NULL),
-        TUNNEL_CLASS("stt", "stt_sys", NULL, NULL, NULL, NULL),
-        TUNNEL_CLASS("erspan", "erspan_sys", netdev_erspan_build_header,
-                                             netdev_erspan_push_header,
-                                             netdev_erspan_pop_header,
-                                             NULL),
-        TUNNEL_CLASS("ip6erspan", "ip6erspan_sys", netdev_erspan_build_header,
-                                                   netdev_erspan_push_header,
-                                                   netdev_erspan_pop_header,
-                                                   NULL),
-        TUNNEL_CLASS("ip6gre", "ip6gre_sys", netdev_gre_build_header,
-                                             netdev_gre_push_header,
-                                             netdev_gre_pop_header,
-                                             NULL),
+        { "genev_sys",
+          {
+              TUNNEL_FUNCTIONS_COMMON,
+              .type = "geneve",
+              .build_header = netdev_geneve_build_header,
+              .push_header = netdev_tnl_push_udp_header,
+              .pop_header = netdev_geneve_pop_header,
+              .get_ifindex = NETDEV_VPORT_GET_IFINDEX,
+          }
+        },
+        { "gre_sys",
+          {
+              TUNNEL_FUNCTIONS_COMMON,
+              .type = "gre",
+              .build_header = netdev_gre_build_header,
+              .push_header = netdev_gre_push_header,
+              .pop_header = netdev_gre_pop_header
+          }
+        },
+        { "vxlan_sys",
+          {
+              TUNNEL_FUNCTIONS_COMMON,
+              .type = "vxlan",
+              .build_header = netdev_vxlan_build_header,
+              .push_header = netdev_tnl_push_udp_header,
+              .pop_header = netdev_vxlan_pop_header,
+              .get_ifindex = NETDEV_VPORT_GET_IFINDEX
+          }
+        },
+        { "lisp_sys",
+          {
+              TUNNEL_FUNCTIONS_COMMON,
+              .type = "lisp"
+          }
+        },
+        { "stt_sys",
+          {
+              TUNNEL_FUNCTIONS_COMMON,
+              .type = "stt"
+          }
+        },
+        { "erspan_sys",
+          {
+              TUNNEL_FUNCTIONS_COMMON,
+              .type = "erspan",
+              .build_header = netdev_erspan_build_header,
+              .push_header = netdev_erspan_push_header,
+              .pop_header = netdev_erspan_pop_header
+          }
+        },
+        { "ip6erspan_sys",
+          {
+              TUNNEL_FUNCTIONS_COMMON,
+              .type = "ip6erspan",
+              .build_header = netdev_erspan_build_header,
+              .push_header = netdev_erspan_push_header,
+              .pop_header = netdev_erspan_pop_header
+          }
+        },
+        { "ip6gre_sys",
+          {
+              TUNNEL_FUNCTIONS_COMMON,
+              .type = "ip6gre",
+              .build_header = netdev_gre_build_header,
+              .push_header = netdev_gre_push_header,
+              .pop_header = netdev_gre_pop_header
+          }
+        },
     };
     static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
 
@@ -1117,12 +1093,13 @@  netdev_vport_tunnel_register(void)
 void
 netdev_vport_patch_register(void)
 {
-    static const struct vport_class patch_class =
-        { NULL,
-            { "patch", false,
-              VPORT_FUNCTIONS(get_patch_config,
-                              set_patch_config,
-                              NULL,
-                              NULL, NULL, NULL, NULL, NULL) }};
+    static const struct vport_class patch_class = {
+        NULL,
+        { VPORT_FUNCTIONS_COMMON,
+          .type = "patch",
+          .get_config = get_patch_config,
+          .set_config = set_patch_config,
+        }
+    };
     netdev_register_provider(&patch_class.netdev_class);
 }