Print this page
Restore SVP_R_ROUTE_REQ, and all that goes with it.
Interpret sl3a_uport == 0 in SVP_R_VL3_ACK to indicate the VL3 IP is a next-hop router.

*** 359,369 **** typedef enum svp_lookup_type { SVP_L_UNKNOWN = 0x0, SVP_L_VL2 = 0x1, SVP_L_VL3 = 0x2, ! SVP_L_RVL3 = 0x3 } svp_lookup_type_t; typedef struct svp_lookup { int svl_type; union { --- 359,369 ---- typedef enum svp_lookup_type { SVP_L_UNKNOWN = 0x0, SVP_L_VL2 = 0x1, SVP_L_VL3 = 0x2, ! SVP_L_ROUTE = 0x3 } svp_lookup_type_t; typedef struct svp_lookup { int svl_type; union {
*** 373,387 **** } svl_vl2; struct svl_lookup_vl3 { varpd_arp_handle_t *svl_vah; uint8_t *svl_out; } svl_vl3; ! struct svl_lookup_rvl3 { varpd_query_handle_t *svl_handle; overlay_target_point_t *svl_point; overlay_target_route_t *svl_route; ! } svl_rvl3; } svl_u; svp_query_t svl_query; } svp_lookup_t; static const char *varpd_svp_props[] = { --- 373,387 ---- } svl_vl2; struct svl_lookup_vl3 { varpd_arp_handle_t *svl_vah; uint8_t *svl_out; } svl_vl3; ! struct svl_lookup_route { varpd_query_handle_t *svl_handle; overlay_target_point_t *svl_point; overlay_target_route_t *svl_route; ! } svl_route; } svl_u; svp_query_t svl_query; } svp_lookup_t; static const char *varpd_svp_props[] = {
*** 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
*** 435,446 **** static void 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; assert(svp != NULL); assert(svl != NULL); if (status != SVP_S_OK) { --- 435,448 ---- static void 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) { ! /* Initialize address-holders to 0 for comparisons-to-zeroes later. */ ! overlay_target_point_t point = { 0 }; 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) {
*** 449,461 **** --- 451,489 ---- umem_cache_free(svp_lookup_cache, svl); return; } /* Inject the L2 mapping before the L3 */ + if (uport != 0 && + bcmp(uip, &point.otp_ip, sizeof (struct in6_addr)) != 0) { + /* Normal L3 lookup result... */ bcopy(uip, &point.otp_ip, sizeof (struct in6_addr)); point.otp_port = uport; 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; + } + bcopy(svp->svp_router_oui, nexthop_mac, 3); + nexthop_mac[3] = (svp->svp_vid >> 16) & 0xff; + nexthop_mac[4] = (svp->svp_vid >> 8) & 0xff; + nexthop_mac[5] = svp->svp_vid & 0xff; + vl2mac = nexthop_mac; + } 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);
*** 492,526 **** static void svp_shootdown_cb(svp_t *svp, const uint8_t *vl2mac, const struct in6_addr *uip, const uint16_t uport) { /* ! * We should probably do a conditional invlaidation here. */ libvarpd_inject_varp(svp->svp_hdl, vl2mac, NULL); } static void ! svp_rvl3_lookup_cb(svp_t *svp, svp_status_t status, /* XXX KEBE SAYS MORE */ void *arg) { svp_lookup_t *svl = arg; overlay_target_point_t *otp; overlay_target_route_t *otr; if (status != SVP_S_OK) { ! libvarpd_plugin_query_reply(svl->svl_u.svl_rvl3.svl_handle, VARPD_LOOKUP_DROP); umem_cache_free(svp_lookup_cache, svl); return; } ! otp = svl->svl_u.svl_rvl3.svl_point; ! otr = svl->svl_u.svl_rvl3.svl_route; ! /* XXX KEBE SAYS FILL ME IN! */ ! libvarpd_plugin_query_reply(svl->svl_u.svl_rvl3.svl_handle, VARPD_LOOKUP_OK); umem_cache_free(svp_lookup_cache, svl); } static svp_cb_t svp_defops = { --- 520,565 ---- static void svp_shootdown_cb(svp_t *svp, const uint8_t *vl2mac, const struct in6_addr *uip, const uint16_t uport) { /* ! * We should probably do a conditional invalidation here. */ libvarpd_inject_varp(svp->svp_hdl, vl2mac, NULL); } static void ! svp_route_lookup_cb(svp_t *svp, svp_status_t status, uint32_t dcid, ! uint32_t vnetid, uint16_t vlan, uint8_t *srcmac, uint8_t *dstmac, ! uint16_t ul3_port, uint8_t *ul3_addr, uint8_t srcpfx, uint8_t dstpfx, void *arg) { svp_lookup_t *svl = arg; overlay_target_point_t *otp; overlay_target_route_t *otr; if (status != SVP_S_OK) { ! libvarpd_plugin_query_reply(svl->svl_u.svl_route.svl_handle, VARPD_LOOKUP_DROP); umem_cache_free(svp_lookup_cache, svl); return; } ! otp = svl->svl_u.svl_route.svl_point; ! bcopy(dstmac, otp->otp_mac, ETHERADDRL); ! bcopy(ul3_addr, &otp->otp_ip, sizeof (struct in6_addr)); ! otp->otp_port = ul3_port; ! otr = svl->svl_u.svl_route.svl_route; ! otr->otr_vnet = vnetid; ! otr->otr_vlan = vlan; ! bcopy(srcmac, otr->otr_srcmac, ETHERADDRL); ! otr->otr_dcid = dcid; ! otr->otr_src_prefixlen = srcpfx; ! otr->otr_dst_prefixlen = dstpfx; ! ! libvarpd_plugin_query_reply(svl->svl_u.svl_route.svl_handle, VARPD_LOOKUP_OK); umem_cache_free(svp_lookup_cache, svl); } static svp_cb_t svp_defops = {
*** 527,537 **** svp_vl2_lookup_cb, svp_vl3_lookup_cb, svp_vl2_invalidate_cb, svp_vl3_inject_cb, svp_shootdown_cb, ! svp_rvl3_lookup_cb, }; static boolean_t varpd_svp_valid_dest(overlay_plugin_dest_t dest) { --- 566,576 ---- svp_vl2_lookup_cb, svp_vl3_lookup_cb, svp_vl2_invalidate_cb, svp_vl3_inject_cb, svp_shootdown_cb, ! svp_route_lookup_cb, }; static boolean_t varpd_svp_valid_dest(overlay_plugin_dest_t dest) {
*** 635,646 **** * * Assume kernel's overlay module is caching well, so we are directly * going to query (i.e. no caching up here of actual destinations). * * Our existing remote sever (svp_remote), but with the new message ! * SVP_R_REMOTE_VL3_REQ. Our naming of these functions already has ! * "remote" in it, but we'll use "rvl3" instead of "vl3". */ /* XXX KEBE SAYS DO SOME otl verification too... */ if (IN6_IS_ADDR_V4MAPPED(src)) { if (!IN6_IS_ADDR_V4MAPPED(dst)) { --- 674,684 ---- * * Assume kernel's overlay module is caching well, so we are directly * going to query (i.e. no caching up here of actual destinations). * * Our existing remote sever (svp_remote), but with the new message ! * SVP_R_ROUTE_REQ. */ /* XXX KEBE SAYS DO SOME otl verification too... */ if (IN6_IS_ADDR_V4MAPPED(src)) { if (!IN6_IS_ADDR_V4MAPPED(dst)) {
*** 660,676 **** if (slp == NULL) { libvarpd_plugin_query_reply(vqh, VARPD_LOOKUP_DROP); return; } ! slp->svl_type = SVP_L_RVL3; ! slp->svl_u.svl_rvl3.svl_handle = vqh; ! slp->svl_u.svl_rvl3.svl_point = otp; ! slp->svl_u.svl_rvl3.svl_route = otr; ! /* XXX KEBE SAYS FILL IN ARGS PROPERLY... */ ! svp_remote_rvl3_lookup(svp, &slp->svl_query, src, dst, type, otl->otl_vnetid, (uint16_t)otl->otl_vlan, slp); } static void varpd_svp_lookup(void *arg, varpd_query_handle_t *vqh, --- 698,713 ---- if (slp == NULL) { libvarpd_plugin_query_reply(vqh, VARPD_LOOKUP_DROP); return; } ! slp->svl_type = SVP_L_ROUTE; ! slp->svl_u.svl_route.svl_handle = vqh; ! slp->svl_u.svl_route.svl_point = otp; ! slp->svl_u.svl_route.svl_route = otr; ! svp_remote_route_lookup(svp, &slp->svl_query, src, dst, otl->otl_vnetid, (uint16_t)otl->otl_vlan, slp); } static void varpd_svp_lookup(void *arg, varpd_query_handle_t *vqh,
*** 798,808 **** 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; --- 835,845 ---- 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;
*** 909,928 **** 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); --- 946,965 ---- 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);
*** 1027,1042 **** 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); --- 1064,1083 ---- 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);
*** 1099,1114 **** 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], --- 1140,1156 ---- 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((struct ether_addr *)&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],
*** 1201,1219 **** return (ret); } svp->svp_dcid = 0; } ! /* svp/router_mac */ 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) { libvarpd_panic("unexpected ether_aton_r failure: %d", errno); } svp->svp_hdl = hdl; *outp = svp; --- 1243,1262 ---- return (ret); } svp->svp_dcid = 0; } ! /* 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_oui, ETHERADDRL); ! } else if (ether_aton_r(etherstr, ! (struct ether_addr *)&svp->svp_router_oui) == NULL) { libvarpd_panic("unexpected ether_aton_r failure: %d", errno); } svp->svp_hdl = hdl; *outp = svp;