--- old/usr/src/lib/varpd/svp/common/libvarpd_svp.c	Tue Mar 20 20:02:28 2018
+++ new/usr/src/lib/varpd/svp/common/libvarpd_svp.c	Tue Mar 20 20:02:28 2018
@@ -390,7 +390,7 @@
 	"svp/underlay_ip",
 	"svp/underlay_port",
 	"svp/dcid",
-	"svp/router_mac"
+	"svp/router_oui"
 };
 
 static const uint8_t svp_bcast[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
@@ -439,6 +439,7 @@
 {
 	overlay_target_point_t point;
 	svp_lookup_t *svl = arg;
+	uint8_t nexthop_mac[6] = { 0, 0, 0, 0, 0, 0 };
 
 	assert(svp != NULL);
 	assert(svl != NULL);
@@ -453,7 +454,32 @@
 	/* Inject the L2 mapping before the L3 */
 	bcopy(uip, &point.otp_ip, sizeof (struct in6_addr));
 	point.otp_port = uport;
-	libvarpd_inject_varp(svp->svp_hdl, vl2mac, &point);
+	if (uport != 0) {
+		/* Normal L3 lookup result... */
+		libvarpd_inject_varp(svp->svp_hdl, vl2mac, &point);
+	} else {
+		/*
+		 * Oh my, we have a next-hop router IP.
+		 * Set the MAC to the ouid+vid concatenated
+		 * special-router-MAC. Overlay down below will know
+		 * that uport == 0 means the MAC is a special one.
+		 */
+		if (bcmp(svp->svp_router_oui, nexthop_mac, ETHERADDRL) == 0) {
+			/*
+			 * We don't have a router_oui, so we can't support
+			 * special-router-MAC.  Drop it.
+			 */
+			libvarpd_plugin_arp_reply(svl->svl_u.svl_vl3.svl_vah,
+			    VARPD_LOOKUP_DROP);
+			umem_cache_free(svp_lookup_cache, svl);
+			return;
+		}
+		vl2mac = nexthop_mac;
+		bcopy(svp->svp_router_oui, vl2mac, 3);
+		vl2mac[3] = (svp->svp_vid >> 16) & 0xff;
+		vl2mac[4] = (svp->svp_vid >> 8) & 0xff;
+		vl2mac[5] = svp->svp_vid & 0xff;
+	}
 
 	bcopy(vl2mac, svl->svl_u.svl_vl3.svl_out, ETHERADDRL);
 	libvarpd_plugin_arp_reply(svl->svl_u.svl_vl3.svl_vah,
@@ -809,7 +835,7 @@
 		libvarpd_prop_set_range_uint32(vph, 1, UINT32_MAX - 1);
 		break;
 	case 5:
-		/* svp/router_mac */
+		/* svp/router_oui */
 		libvarpd_prop_set_name(vph, varpd_svp_props[5]);
 		libvarpd_prop_set_prot(vph, OVERLAY_PROP_PERM_RRW);
 		libvarpd_prop_set_type(vph, OVERLAY_PROP_T_ETHER);
@@ -920,16 +946,16 @@
 		return (0);
 	}
 
-	/* svp/router_mac */
+	/* svp/router_oui */
 	if (strcmp(pname, varpd_svp_props[5]) == 0) {
 		if (*sizep < ETHERADDRL)
 			return (EOVERFLOW);
 		mutex_enter(&svp->svp_lock);
 
-		if (ether_is_zero(&svp->svp_router_mac)) {
+		if (ether_is_zero(&svp->svp_router_oui)) {
 			*sizep = 0;
 		} else {
-			bcopy(&svp->svp_router_mac, buf, ETHERADDRL);
+			bcopy(&svp->svp_router_oui, buf, ETHERADDRL);
 			*sizep = ETHERADDRL;
 		}
 
@@ -1038,12 +1064,16 @@
 		return (0);
 	}
 
-	/* svp/router_mac */
+	/* svp/router_oui */
 	if (strcmp(pname, varpd_svp_props[5]) == 0) {
 		if (size < ETHERADDRL)
 			return (EOVERFLOW);
 		mutex_enter(&svp->svp_lock);
-		bcopy(buf, &svp->svp_router_mac, ETHERADDRL);
+		bcopy(buf, &svp->svp_router_oui, ETHERADDRL);
+		/* Zero-out the low three bytes. */
+		svp->svp_router_oui[3] = 0;
+		svp->svp_router_oui[4] = 0;
+		svp->svp_router_oui[5] = 0;
 		mutex_exit(&svp->svp_lock);
 		return (0);
 	}
@@ -1110,12 +1140,12 @@
 		}
 	}
 
-	/* svp/router_mac */
-	if (!ether_is_zero(&svp->svp_router_mac)) {
+	/* svp/router_oui */
+	if (!ether_is_zero(&svp->svp_router_oui)) {
 		char buf[ETHERADDRSTRL];
 
 		/* XXX KEBE SAYS See underlay_ip... */
-		if (ether_ntoa_r(&svp->svp_router_mac, buf) == NULL) {
+		if (ether_ntoa_r(&svp->svp_router_oui, buf) == NULL) {
 			libvarpd_panic("unexpected ether_ntoa_r failure: %d",
 			    errno);
 		}
@@ -1212,7 +1242,7 @@
 		svp->svp_dcid = 0;
 	}
 
-	/* svp/router_mac */
+	/* svp/router_oui */
 	if ((ret = nvlist_lookup_string(nvp, varpd_svp_props[5],
 	    &etherstr)) != 0) {
 		if (ret != ENOENT) {
@@ -1219,8 +1249,8 @@
 			varpd_svp_destroy(svp);
 			return (ret);
 		}
-		bzero(&svp->svp_router_mac, ETHERADDRL);
-	} else if (ether_aton_r(etherstr, &svp->svp_router_mac) == NULL) {
+		bzero(&svp->svp_router_oui, ETHERADDRL);
+	} else if (ether_aton_r(etherstr, &svp->svp_router_oui) == NULL) {
 		libvarpd_panic("unexpected ether_aton_r failure: %d", errno);
 	}
 
--- old/usr/src/lib/varpd/svp/common/libvarpd_svp.h	Tue Mar 20 20:02:28 2018
+++ new/usr/src/lib/varpd/svp/common/libvarpd_svp.h	Tue Mar 20 20:02:28 2018
@@ -277,7 +277,8 @@
 	uint32_t		svp_dcid;	/* svp_lock (but write-once?) */
 	boolean_t		svp_huip;	/* svp_lock */
 	struct in6_addr		svp_uip;	/* svp_lock */
-	struct ether_addr	svp_router_mac;	/* svp_lock (but write-once?) */
+	/* NOTE: lower-3 bytes are 0s. */
+	uint8_t		svp_router_oui[6];	/* svp_lock (but write-once?) */
 };
 
 extern bunyan_logger_t *svp_bunyan;
--- old/usr/src/lib/varpd/svp/common/libvarpd_svp_prot.h	Tue Mar 20 20:02:28 2018
+++ new/usr/src/lib/varpd/svp/common/libvarpd_svp_prot.h	Tue Mar 20 20:02:28 2018
@@ -74,7 +74,7 @@
 } svp_status_t;
 
 /*
- * A client issues the SVP_R_VL2_REQ whenever it needs to perform a VLS->UL3
+ * A client issues the SVP_R_VL2_REQ whenever it needs to perform a VL2->UL3
  * lookup. Requests have the following structure:
  */
 typedef struct svp_vl2_req {
@@ -253,6 +253,7 @@
  * to send overlay packets to the appropriate far-remote CNs.
  */
 typedef struct svp_route_ack {
+	uint32_t	sra_status;	/* Status. */
 	uint32_t	sra_dcid;	/* Far-remote Data Center ID. */
 	uint32_t	sra_vnetid;	/* Far-remote vnet ID. */
 	uint16_t	sra_vlan;	/* Far-remote VLAN ID. */
