 +int ovs_vale_send(struct net_device *dev, struct sk_buff *skb)
 +{
 +	struct ovs_vale_dst *dst = OVCB(skb)->dst;
-+#ifndef NETMAP_API_4
 +	struct netmap_vp_adapter *vpna;
-+#endif
 +	u_int dport;
 +
 +	if (!skb_owned_by_vale(skb))
 +		return 0;
-+#ifdef NETMAP_API_4
-+	if (unlikely(!(dev->priv_flags & IFCAP_NETMAP))) { /* e.g., VALE port */
-+#else
 +	if (netmap_ifp_to_vp(dev) == NULL) { /* Not a VALE port */
-+#endif
 +		dst->port = NM_BDG_NOPORT;
 +		goto consumed;
 +	}
 +	/* set the destination index of the bridge.
 +	 * XXX If it is already set, we broadcast this packet
 +	 */
-+#ifdef NETMAP_API_4
-+	dport = ovs_is_internal_dev(dev) ? SWNA(dev)->bdg_port :
-+					NA(dev)->bdg_port;
-+#else
 +	vpna = ovs_is_internal_dev(dev) ? netmap_ifp_to_host_vp(dev) :
 +		netmap_ifp_to_vp(dev);
 +	if (unlikely(!vpna)) {

+	bzero(&sskb, sizeof(sskb));
+	sskb.dev = dev;
+	sskb.len += buf_len;
+#ifdef NETMAP_API_4
+	sskb.truesize = NETMAP_BUF_SIZE - shlen;
+#else
+	sskb.truesize = NETMAP_BUF_SIZE(&na->up) - shlen;
+#endif
+	sskb.head_frag = 1;
+	sskb.data = sskb.head = (unsigned char *)buf;
+	skb_reset_tail_pointer(&sskb);
+	/* Ensure sskb.end points shinfo */
+#ifdef NETMAP_API_4
+	sskb.end = sskb.tail + NETMAP_BUF_SIZE - shlen;
+#else
+	sskb.end = sskb.tail + NETMAP_BUF_SIZE(&na->up) - shlen;
+#endif
+	sskb.mac_header = (typeof(sskb.mac_header))~0U;
+	sskb.transport_header = (typeof(skb->transport_header))~0U;
+

+	na.nm_txsync = na.nm_rxsync = NULL;
+	na.nm_register = vport_internal_netmap_reg;
+	na.na_flags |= NAF_SW_ONLY;
+	na.num_tx_rings = na.num_rx_rings = 1;
+	na.nm_config = vport_internal_update_config;
+	netmap_attach(&na);
+	((struct netmap_hw_adapter *)NA(na.ifp))->nm_ndo.ndo_get_stats64 =
+		internal_dev_get_stats;
+	/* do we need these ?*/
+}
diff --git a/datapath/vport-netdev.c b/datapath/vport-netdev.c
index de85087..769e1cc 100644
--- a/datapath/vport-netdev.c
+++ b/datapath/vport-netdev.c
@@ -34,6 +34,9 @@
