Print this page
Interpret sl3a_uport == 0 in SVP_R_VL3_ACK to indicate the VL3 IP is a
next-hop router.

@@ -388,11 +388,11 @@
         "svp/host",
         "svp/port",
         "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 };
 
 int

@@ -437,10 +437,11 @@
 svp_vl3_lookup_cb(svp_t *svp, svp_status_t status, const uint8_t *vl2mac,
     const struct in6_addr *uip, const uint16_t uport, void *arg)
 {
         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);
 
         if (status != SVP_S_OK) {

@@ -451,11 +452,36 @@
         }
 
         /* Inject the L2 mapping before the L3 */
         bcopy(uip, &point.otp_ip, sizeof (struct in6_addr));
         point.otp_port = uport;
+        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,
             VARPD_LOOKUP_OK);
         umem_cache_free(svp_lookup_cache, svl);

@@ -807,11 +833,11 @@
                 libvarpd_prop_set_nodefault(vph);
                 /* XXX KEBE ASKS should I just set high to UINT32_MAX? */
                 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);
                 libvarpd_prop_set_nodefault(vph);
                 break;

@@ -918,20 +944,20 @@
 
                 mutex_exit(&svp->svp_lock);
                 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;
                 }
 
                 mutex_exit(&svp->svp_lock);
                 return (0);

@@ -1036,16 +1062,20 @@
                 mutex_exit(&svp->svp_lock);
 
                 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);
         }
 
         return (EINVAL);

@@ -1108,16 +1138,16 @@
                         mutex_exit(&svp->svp_lock);
                         return (ret);
                 }
         }
 
-        /* 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);
                 }
 
                 if ((ret = nvlist_add_string(nvp, varpd_svp_props[5],

@@ -1210,19 +1240,19 @@
                         return (ret);
                 }
                 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) {
                         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);
         }
 
         svp->svp_hdl = hdl;
         *outp = svp;