Print this page
Interpret sl3a_uport == 0 in SVP_R_VL3_ACK to indicate the VL3 IP is a
next-hop router.
        
*** 388,398 ****
          "svp/host",
          "svp/port",
          "svp/underlay_ip",
          "svp/underlay_port",
          "svp/dcid",
!         "svp/router_mac"
  };
  
  static const uint8_t svp_bcast[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
  
  int
--- 388,398 ----
          "svp/host",
          "svp/port",
          "svp/underlay_ip",
          "svp/underlay_port",
          "svp/dcid",
!         "svp/router_oui"
  };
  
  static const uint8_t svp_bcast[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
  
  int
*** 437,446 ****
--- 437,447 ----
  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,461 ****
--- 452,487 ----
          }
  
          /* 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,817 ****
                  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 */
                  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;
--- 833,843 ----
                  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_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,937 ****
  
                  mutex_exit(&svp->svp_lock);
                  return (0);
          }
  
!         /* svp/router_mac */
          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)) {
                          *sizep = 0;
                  } else {
!                         bcopy(&svp->svp_router_mac, buf, ETHERADDRL);
                          *sizep = ETHERADDRL;
                  }
  
                  mutex_exit(&svp->svp_lock);
                  return (0);
--- 944,963 ----
  
                  mutex_exit(&svp->svp_lock);
                  return (0);
          }
  
!         /* 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_oui)) {
                          *sizep = 0;
                  } else {
!                         bcopy(&svp->svp_router_oui, buf, ETHERADDRL);
                          *sizep = ETHERADDRL;
                  }
  
                  mutex_exit(&svp->svp_lock);
                  return (0);
*** 1036,1051 ****
                  mutex_exit(&svp->svp_lock);
  
                  return (0);
          }
  
!         /* svp/router_mac */
          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);
                  mutex_exit(&svp->svp_lock);
                  return (0);
          }
  
          return (EINVAL);
--- 1062,1081 ----
                  mutex_exit(&svp->svp_lock);
  
                  return (0);
          }
  
!         /* 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_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,1123 ****
                          mutex_exit(&svp->svp_lock);
                          return (ret);
                  }
          }
  
!         /* svp/router_mac */
!         if (!ether_is_zero(&svp->svp_router_mac)) {
                  char buf[ETHERADDRSTRL];
  
                  /* XXX KEBE SAYS See underlay_ip... */
!                 if (ether_ntoa_r(&svp->svp_router_mac, buf) == NULL) {
                          libvarpd_panic("unexpected ether_ntoa_r failure: %d",
                              errno);
                  }
  
                  if ((ret = nvlist_add_string(nvp, varpd_svp_props[5],
--- 1138,1153 ----
                          mutex_exit(&svp->svp_lock);
                          return (ret);
                  }
          }
  
!         /* 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_oui, buf) == NULL) {
                          libvarpd_panic("unexpected ether_ntoa_r failure: %d",
                              errno);
                  }
  
                  if ((ret = nvlist_add_string(nvp, varpd_svp_props[5],
*** 1210,1228 ****
                          return (ret);
                  }
                  svp->svp_dcid = 0;
          }
  
!         /* svp/router_mac */
          if ((ret = nvlist_lookup_string(nvp, varpd_svp_props[5],
              ðerstr)) != 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) {
                  libvarpd_panic("unexpected ether_aton_r failure: %d", errno);
          }
  
          svp->svp_hdl = hdl;
          *outp = svp;
--- 1240,1258 ----
                          return (ret);
                  }
                  svp->svp_dcid = 0;
          }
  
!         /* svp/router_oui */
          if ((ret = nvlist_lookup_string(nvp, varpd_svp_props[5],
              ðerstr)) != 0) {
                  if (ret != ENOENT) {
                          varpd_svp_destroy(svp);
                          return (ret);
                  }
!                 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;