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],
ð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) {
+ 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;